http://www.7klian.com

Chainlink预言机根基道理(三)

      function transferAndCall(address _to, uint _value, bytes _data)
        bytes data
    event OracleRequest(
        address callbackAddr,
      }
        super.transfer(_to, _value);
       * 发出 ChainlinkRequested 事件.
        req.add(“get”, “https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD”);
      */
            _callbackAddress,
        return requestId;
        public
        require(gasleft() >= MINIMUM_CONSUMER_GAS_LIMIT, “Must provide consumer enough gas”);
        sendChainlinkRequestTo(_oracle, req, ORACLE_PAYMENT);
        external
     /**
      * @dev 将token和特别数据一起转移给一个合约地点
       * @notice 由Chainlink节点挪用来完成请求
       */
      function sendChainlinkRequestTo(address _oracle, Chainlink.Request memory _req, uint256 _payment)
    _callbackAddress.call(_callbackFunctionId, _requestId, _data);
      )
       * @dev 建设并存储一个请求ID, 增加当地的nonce值, 并利用`transferAndCall` 要领发送LINK,
       * @param _oracle 发送请求至的oracle地点
        return _callbackAddress.call(_callbackFunctionId, _requestId, _data); // solhint-disable-line avoid-low-level-calls
       * @param _payment 为Oracle发放付款金额 (以wei为单元)

我们以Chainlink提供的TestnetConsumer合约中的一个requestEthereumPrice 要领为例来简朴讲一下请求响应的流程。这个函数界说如下:
        bytes32 requestId,
       * @param _payment 请求发送的LINK数量
        withdrawableTokens = withdrawableTokens.add(_payment);
        address _callbackAddress,
        uint256 dataVersion,
        }
       * 建设到方针oracle合约地点的请求
        address requester,
    * 将会挪用回调地点的回调函数,`require`查抄时不会报错,以便节点可以得到酬金
这个日志会在oracle合约的日志中找到,如图中下方所示。链下的节点会订阅该主题的日志,在获取到记录的日志信息之后,节点会理会出请求的详细信息,通过网络的API挪用,,获取到请求的功效。之后通过提交事务的方法,挪用Oracle合约中的fulfillOracleRequest要领,将数据提交到链上。fulfillOracleRequest界说如下:
    
        Transfer(msg.sender, _to, _value, _data);
      * @param _data 通报给吸收合约的特别数据
        req.addInt(“times”, 100);
       * @dev 提交的参数必需是`oracleRequest`要领所记录的哈希参数
总结
        _req.nonce = requests;
        bytes4 callbackFunctionId,
这个要了解在举办一系列的检讨之后,会将功效通过之前记录的回调地点与回调函数,返回给消费者合约:
        return true;
            _callbackFunctionId,
       * @return 外部挪用乐成的状态值
它所实现的成果就是从指定的API(cryptocompare)获取ETH/USD的生意业务价值。函数传入的参数是指定的oracle地点和jobId。将一些列的请求参数组好后,挪用sendChainlinkRequestTo 要领将请求发出。
        bytes32 indexed specId,
       * @return 请求 ID
      * @param _value 转移数量
        requestId = keccak256(abi.encodePacked(this, requests));
        
        internal
本文从预言机的观念开始,通过一个简朴的获取ETH价值的例子,讲授了请求/响应模式的Chainlink预言机的根基进程,但愿对你领略预言机与Chainlink的运行道理有所辅佐。

将这次转账的具体信息(发送方、吸收方、金额、数据)记录到日志中。
        uint256 _expiration,
        onlyAuthorizedNode
    function requestEthereumPrice(address _oracle, string _jobId)
     /**
       */
        require(link.transferAndCall(_oracle, _payment, encodeRequest(_req)), “unable to transferAndCall to oracle”);
      }
    event Transfer(address indexed from, address indexed to, uint value, bytes data);
      }
        returns (bool success)
        pendingRequests[requestId] = _oracle;
        bytes4 _callbackFunctionId,
    /**
        bytes32 paramsHash = keccak256(
       * @param _data 返回给消费者合约的数据
        bytes32 _requestId,
            _payment,
        onlyOwner
      {
      );
        bytes32 _data
个中link.transferAndCall要领等于ERC677界说的token转账要领,与ERC20的transfer要领对比,它多了一个data字段,可以在转账的同时携带数据。这里就将之前打包好的请求数据放在了data字段,跟从转账一起发送到了oracle合约。transferAndCall 要领界说如下:
        );
Oracle合约在收到转账之后,会触发onTokenTransfer要领,该要了解查抄转账的有效性,并通过发出OracleRequest事件记录更为具体的数据信息:
       * @notice 向指定的oracle地点建设一个请求
        Chainlink.Request memory req = buildChainlinkRequest(stringToBytes32(_jobId), this, this.fulfillEthereumPrice.selector);
        if (isContract(_to)) {
个中的Transfer(msg.sender, _to, _value, _data);是发出一个事件日志:

        returns (bytes32 requestId)
      function fulfillOracleRequest(
       * @param _req 完成初始化的Chainlink请求
        uint256 _payment,
            _expiration
        returns (bool)
      {
        uint256 cancelExpiration,
          )
      * @param _to 转移到的目标地点
       * @param _callbackFunctionId 完成要领的回调函数
这样一次请求就全部完成了。
       * @param _expiration 请求者可以打消之前节点应响应的到期时间
          contractFallback(_to, _value, _data);
        require(commitments[_requestId] == paramsHash, “Params do not match request ID”);
       * @param _requestId 请求ID必需与请求者所匹配
      {
       * @param _callbackAddress 完成要领的回调地点
        public
        isValidRequest(_requestId)
          abi.encodePacked(
        delete commitments[_requestId];
      }
        emit ChainlinkRequested(requestId);
      {
sendChainlinkRequestTo是界说在Chainlink提供的库中的一个接口要领,界说如下:
        uint256 payment,
        req.add(“path”, “USD”);
        requests += 1;

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

相关文章阅读