* @return 请求 ID
}
case err := <-sub.Err():
}
auth.GasLimit = uint64(300000)
* @dev 提交的参数必需是`oracleRequest`要领所记录的哈希参数
events := make(chan types.Log)
function requestEthereumPrice(address _oracle, string _jobId)
本文从预言机的观念开始,通过一个简朴的获取ETH价值的例子,讲授了请求/响应模式的Chainlink预言机的根基进程,但愿对你领略预言机与Chainlink的运行道理有所辅佐。
险些每一个合约系统,城市有事件记录的成果,好比以太坊中的EventLog成果。
* 将会挪用回调地点的回调函数,`require`查抄时不会报错,以便节点可以得到酬金
{
CallContract(“b7b502b…164b42c”)
/**
var sampleEvent struct {
return _callbackAddress.call(_callbackFunctionId, _requestId, _data); // solhint-disable-line avoid-low-level-calls
address requester,
// 构建生意业务提交功效,需要提供私钥用于签署生意业务
// 发出获取请求,即发出一个事件日志
)
* @param _expiration 请求者可以打消之前节点应响应的到期时间
* @return 外部挪用乐成的状态值
* @param _value 转移数量
· 请求/响应(request–response)
本文我们来从技能上简述一下Chainlink的根基道理。假如用最短的一句话表明什么是Chainlink,可以说Chainlink一个去中心化的预言机项目,所觉得了领略Chainlink的事情道理,我们首先要大白什么是预言机。
Back in ancient times, an oracle was someone who offered advice or a prophecy thought to have come directly from a divine source. In modern usage, any good source of information can be called an oracle.
function fulfillOracleRequest(
func SubscribeEventLog() {
将一些列的请求参数组好后,挪用sendChainlinkRequestTo 要领将请求发出。sendChainlinkRequestTo是界说在Chainlink提供的库中的一个接口要领,界说如下:
* @notice 由Chainlink节点挪用来完成请求
*/
Transfer(msg.sender, _to, _value, _data);
}
* @param _data 返回给消费者合约的数据
预言机的英文为Oracle,和著名的数据库处事提供商Oracle(甲骨文)重名,可是两者除了名字沟通觉得并没有任何关系。Oracle这个单词是什么意思,下面是我在vocabulary.com上查到的Oracle的寄义:
log.Info(string(ej))
req.add(“get”, “https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD”);
* @param _payment 请求发送的LINK数量
{
ej, _ := ev.MarshalJSON()
uint256 _payment,
// 理会数据
function transferAndCall(address _to, uint _value, bytes _data)
public
* 发出 ChainlinkRequested 事件.
returns (bool)
function updateWeather (uint256 _temperature) public {
log.Error(err)
require(gasleft() >= MINIMUM_CONSUMER_GAS_LIMIT, “Must provide consumer enough gas”);
tx, err := instance.UpdateWeather(auth, big.NewInt(29))
// callback(addr+functionId) as it is untrusted.
* @param _callbackAddress 完成要领的回调地点
链下,我们启动一个历程,以订阅topic的方法获取日志信息,之后通过构建一个transaction,提交一个功效到合约中。
· 当即读取(immediate-read)
bytes4 _callbackFunctionId,
_payment,
{
event OracleRequest(
req.add(“path”, “USD”);
sub, err := EthClient.SubscribeFilterLogs(ctx, query, events)
function requestTemperature (string memory _city) public {
event RequestTemperature (bytes city);
bytes32 indexed specId,
// See: https://solidity.readthedocs.io/en/develop/security-considerations.html#use-the-checks-effects-interactions-pattern
case ev := <-events:
contract WeatherOracle {
* @dev 建设并存储一个请求ID, 增加当地的nonce值, 并利用`transferAndCall` 要领发送LINK,
returns (bool success)
super.transfer(_to, _value);
requests += 1;
}
for {
auth.Value = big.NewInt(0)
delete commitments[_requestId];
* @param _data 通报给吸收合约的特别数据
Topics: [][]common.Hash{
* @param _req 完成初始化的Chainlink请求
Chainlink是一个去中心化的预言机项目,它的浸染就是以最安详的方法向区块链提供现实世界中发生的数据。Chainlink在根基的预言机道理的实现方法之上,环绕LINK token通过经济鼓励成立了一个良性轮回的生态系统。Chainlink预言机需要通过LINK token的转账来实现触发。
uint256 dataVersion,
Chainlink根基道理
uint256 cancelExpiration,
// 预言机回调要领,预言机获取到数据后通过这个要领将数据提交到链上
contractFallback(_to, _value, _data);
Oracle合约在收到转账之后,会触发onTokenTransfer要领,该要了解查抄转账的有效性,并通过发出OracleRequest事件记录更为具体的数据信息:
// 监听事件订阅
_callbackAddress.call(_callbackFunctionId, _requestId, _data);
require(commitments[_requestId] == paramsHash, “Params do not match request ID”);
* @notice 向指定的oracle地点建设一个请求
那么要实现向区块链提供数据,应该怎么做呢?区块链能留下的只有账本,而区块链所能输入的只有生意业务。我们就从这两个方面入手。
// 订阅相关主题的日志事件
_req.nonce = requests;
它所实现的成果就是从指定的API(cryptocompare)获取ETH/USD的生意业务价值。函数传入的参数是指定的oracle地点和jobId。
withdrawableTokens = withdrawableTokens.add(_payment);
err = ta.Unpack(&sampleEvent, “RequestTemperature”, ev.Data)
sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
},
bytes4 callbackFunctionId,
bytes data
将这次转账的具体信息(发送方、吸收方、金额、数据)记录到日志中。
* @param _payment 为Oracle发放付款金额 (以wei为单元)
* @param _callbackFunctionId 完成要领的回调函数
return requestId;
auth.Nonce = big.NewInt(int64(nonce))
这样一次请求就全部完成了。
abi.encodePacked(
bytes32 paramsHash = keccak256(
nonce, err := EthClient.PendingNonceAt(ctx, addr)
* @dev 将token和特别数据一起转移给一个合约地点
return true;
auth.GasPrice = gasPrice
而基于LINK ERC677 token完成的预言机成果,就属于个中的请求/响应模式。这是一种较为巨大的模式,上图中展示的是一个不含有聚合进程的简朴请求/相应流程。 /**
}
上面的代码很是简朴,界说了一个变量用来存储功效,一个要领用于发出请求,一个要领用于吸收功效。
// 加载合约的ABI文件
if (isContract(_to)) {
require(link.transferAndCall(_oracle, _payment, encodeRequest(_req)), “unable to transferAndCall to oracle”);
address callbackAddr,
{
instance, err := event.NewEvent(common.HexToAddress(“0x8A421906e9562AA1c71e5a32De1cf75161C5A463”), EthClient)
_callbackAddress,
break
public
address _callbackAddress,
uint256 payment,
/**
Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), this, this.fulfillEthereumPrice.selector);
_callbackFunctionId,
onlyOwner
requestId = keccak256(abi.encodePacked(this, requests));
bytes32 _data
预言机
gasPrice, err := EthClient.SuggestGasPrice(ctx)
声明:以下代码仅供演示预言机道理,没有做参数检测和错误处理惩罚,请不要在出产情况中利用。
{
*/
uint256 _expiration,
pendingRequests[requestId] = _oracle;
正如以太坊的界说,区块链是一个生意业务驱动的状态机(a transaction-based state machine),它能做的工作很是简朴,就是通过向区块链提交事务/生意业务(transaction),来将区块链从一个状态转酿成另一个状态。为了保持共鸣,EVM的执行进程必需完全确定,而且仅基于以太坊状态和签名生意业务的共享上下文。这发生了两个出格重要的效果:一个是EVM和智能合约没有内涵的随机性来历;另一个是外部数据只能作为生意业务的数据载荷引入。用通俗的话讲,区块链没有主动获取数据的本领,它能用的只有区块链本身自己的数据。数据的缺失导致智能合约的应用范畴很是少,今朝大部门的应用都是环绕着token来展开的。
addr := PrivateKeyToAddress(keyStr)
个中的Transfer(msg.sender, _to, _value, _data);是发出一个事件日志:
ta, err := abi.JSON(strings.NewReader(AbiJsonStr))
)
common.BytesToHash(topic),
中文的或许意思是:在古代,oracle是一个提出发起或预言的人,他的发起或预言被认为是直接来自于神。在现代用法中,任何好的信息来历都可以称为oracle。
function sendChainlinkRequestTo(address _oracle, Chainlink.Request memory _req, uint256 _payment)
);
emit ChainlinkRequested(requestId);
bytes32 requestId,
}
* 建设到方针oracle合约地点的请求
* @param _to 转移到的目标地点
}
},
}
在《能干以太坊(Matering Ethereum)》一书中,提出了三种预言机的设计模式,别离是
log.Info(string(sampleEvent.City))
isValidRequest(_requestId)
);
}
这样就不难领略了,Oracle转达了万能全知的神的旨意,而甲骨文最初就是用来占卜休咎时的记录,也在其时也被认为是神谕,转达了神的意思。所以不管是“预言机”照旧“甲骨文”都表达了“信息源”的意思。
// 获取到订阅的动静
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。