预言机详解系列之Chainlink(上)
在区块链领域中,预言机是一种能够为链上智能合约提供外部信息的系统。作为连接智能合约和区块链以外世界的中间件,预言机扮演着极其关键的基础设施角色,它的主要功能是为区块链中的智能合约提供数据。
例如,如果我们在以太坊网络上创建一个智能合约,而这个合约需要访问原油某天的交易量数据。然而智能合约本身无法获取这种链下的现实世界数据,因此需要通过预言机来实现。在这种情况下,智能合约会将所需日期的原油交易量写入事件日志,然后,链下会启动一个进程来监控并订阅这个事件日志,当监听到交易中的请求时,该进程会通过提交链上交易,调用合约的相关方法,把指定日期的原油交易量信息上传到智能合约中。
预言机实质上是提供服务的一方,ChainLink 在设计预言机框架的时候首先想到的是预言机的用户如何向提供服务的预言机支付服务费用。但由于标准的同质化 Token 合约 ERC 20 无法满足支付后提供服务这样的一个需求,因此 ChainLink 自己提出了一个适用于预言机服务场景的标准——ERC 677 。
从上面的代码中可以看到,ERC 677 其实只是在标准 ERC 20 的基础上增加了一个 transferAndCall 方法。该方法将支付和服务请求合二为一,满足了预言机业务场景的需求。
当用户进行 transferAndCall 进行转账时,除了 ERC 20 的转账以外,还会判断 to 地址是否为一个合约地址,如果是,则调用该 to 地址的 onTokenTransfer 方法。(这里 ERC 677 Receiver 里面只有一个方法:onTokenTransfer)
我们也可以去到 Etherscan 上查看 LINK 代币的合约源码:https://etherscan.io/address/0x514910771af9ca656af840dff83e8264ecf986ca#code
可以看到 LINK Token 在实现的时候除了多对 _to 地址进行了校验以外,都是实实在在继承了 ERC 677 的 transferAndCall 方法。注意:在请求预言机服务之前,要先确定该预言机是否可信,因为预言机为消费者提供服务之前需要先付款。(人人都能提供预言机服务)
当预言机的消费者使用 transferAndCall 方法支付费用并请求预言机的服务,这里这个 to 地址就是被请求的预言机的地址了。预言机中的 onTokenTransfer 方法首先会校验转账是否为 LINK 代币(onlyLINK),其实就是判断 msg.sender 是否为 Link 代币合约的地址。然后会判断 _data 的长度有没有超过最大限度。最后会判断_data 中是不是以“oracleRequest”开头的 function selector。当然这里的 function selector 可以根据预言机所提供的服务进行定制,不一定非要是“oracleRequest”,具体看这个预言机对外暴露什么样的接口了。
当这些 modifier 都判断通过后,再检查当前的函数调用者和转账金额是否跟 _data 中的相同。这一些列的安全检查都通过后,才通过一个 delegatecall 来 call 当前这个 oracle 合约。当然,因为已经检查过 _data 中的 function selector 了,所以其实是 call 的 oracleRequest 方法。
首先,将 oracle 请求者和他发送过来的 nonce 拼接然后进行哈希,作为本次请求的 requestId,并通过查检查 commitments 映射看是否是唯一的 id。检查没问题的话,就设置一个过期时间,并将 requestId 添加到 commitments 中去,并将 _payment、_callbackAddress、_callbackFunctionId 和 expiration 进行拼接作为 value。最重要的是,发出一个 OracleRequest 事件,该事件中包含了请求数据 _data,是一种 Concise Binary Object Representation(CBOR) 数据。该编码格式轻量简洁,可以简单理解为二进制形式 JSON 格式。这个数据可以是各种各样的形式,看链下节点是如何设计的了。
例如:一个 Chainlink: ETH/USD Aggregator,有一笔交易包含了 OracleRequest 事件:
首先进行检查:
onlyAuthorizedNode:函数调用者 (msg.sender) 必须是合约的 owner 或在授权的列表内;
isValidRequest:依旧去 commitments 映射中检查是否存在该 requestId;
将 payment、callbackAddress、_callbackFunctionId 和 expiration 进行拼接,检查是否是该 requestId 在 commitments 映射中对应的值。
如果这些检查都通过了的话,那么将这次的请求的花费累加到 withdrawableTokens 中,记录可以取款的数额。之后将该 _requestId 从 commitments 映射中删除。最后计算一下剩余的 gas 量,看是否大于 MINIMUM_CONSUMER_GAS_LIMIT,即回调发出请求的合约的回调函数执行最小需要的 gas 量。
如果上述检查都通过了,那么可以用 call 的形式正式调用请求者合约的回调函数。
回应 request 应该尽量迅速,因此这里推荐使用 ZAN 的节点服务(https://zan.top/home/node-service?chInfo=ch_WZ)来提高响应速度。可以在节点服务控制台找到获取对应的 RPC 链接以提高链下发送交易的速度。
3.2 回调函数
之前我们从 oracleRequest 中知道了回调函数的 id 是 6 A 9705 B 4 ,查询得到该方法为「 chainlinkCallback(bytes 32, int 256 」
validateChainlinkCallback 是一个可以自定义的函数,这里有一个 modifier:
在 pendingRequests 里面检查该 _requestId 对应请求的 oracle 是否匹配。并发出事件 ChainlinkFulfilled:
如果校验都通过了的话,那么就可以对 responds 做进一步的处理了,这里是对 answers 映射进行更新。那么如果是价格预言机的话,则是将回应的价格数据赋给 currentPrice 做相应的价格更新:
以上是通用预言机服务的完整流程。
我们以 Chainlink 提供的「 TestnetConsumer 」合约中的一个「 requestEthereumPrice 」方法为例来简单讲一下价格预言机请求响应的流程。这个函数定义如下:
它所实现的功能就是从指定的 API(cryptocompare) 获取 ETH/USD 的交易价格。函数传入的参数是指定的 oracle 地址和 jobId。将一些列的请求参数组好后,调用「 sendChainlinkRequestTo 」方法将请求发出。「 sendChainlinkRequestTo 」是定义在 Chainlink 提供的库中的一个接口方法,定义如下:
Oracle 合约在收到转账之后,会触发「 onTokenTransfer 」方法,该方法会检查转账的有效性,并通过发出「 OracleRequest 」事件记录更为详细的数据信息。
这个日志会在 oracle 合约的日志中找到。链下的节点会订阅该主题的日志,在获取到记录的日志信息之后,节点会解析出请求的具体信息,通过网络的 API 调用,获取到请求的结果。之后通过提交事务的方式,调用 Oracle 合约中的「 fulfillOracleRequest 」方法,将数据提交到链上。
这个方法会在进行一系列的检验之后,会将结果通过之前记录的回调地址与回调函数,返回给消费者合约。
那我作为开发者我只想要用已有的币对价格,而不需要自己指定这些 url 可不可以呢?
答案是可以。第一种使用方式,官方给的示例代码是这样的:
首先,每个交易对都有一个单独的 Price Feed,也叫 Aggregator,其实就是一个个 AggregatorProxy,像下面这样:
具体这个 interface 实现比较简单,可以参考 AAVE/ETH 这个 pair:https://etherscan.io/address/0x6Df09E975c830ECae5bd4eD9d90f3A95a4f88012#code
总共有 5 个查询方法:
decimals():返回的价格数据的精度位数,一般为 8 或 18
description():一般为交易对名称,比如 ETH / USD
version():主要用来标识 Proxy 所指向的 Aggregator 类型
getRoundData(_roundId):根据 round ID 获取当时的价格数据
latestRoundData():获取最新的价格数据
大部分应用场景下,合约可能只需要读取最新价格,即调用最后一个方法,其返回参数中,answer 就是最新价格。
另外,大部分应用读取 token 的价格都是统一以 USD 为计价单位的,若如此,你会发现,以 USD 为计价单位的 Pair,精度位数都是统一为 8 位的,所以一般情况下也无需根据不同 token 处理不同精度的问题。
本文由 ZAN Team(X 账号 @zan_team) 的 XiG(X 账号 @SHXiGi)撰写。
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
您可能感兴趣
-
美SEC正式公布加密货币托管圆桌会议议程及参会成员
深潮 TechFlow 消息,4 月 17 日,据美国证券交易委员会(SEC)官方公告,SEC 加密货币工作组将于 4 月 25 日举办主题为"了解你的托管人:加密货币托管关键考量"的圆桌会议。会议将
-
今日加密货币市值前100代币涨跌:XCN 涨 8.74%,OM 跌 12.35%
深潮 TechFlow 消息,4 月 17 日,据 Coinmarketcap 数据,今日加密货币市值前 100 代币表现如下,涨幅前五:Onyxcoin(XCN)涨 8.74%,现价 0.0188
-
WhiteBIT荣膺Liquidity 2025黄金合作伙伴,并推出全新机构服务
欧洲主流加密货币交易所之一 WhiteBIT 宣布,以黄金合作伙伴的身份出席由 LTP 举办的顶级机构数字资产峰会 Liquidity 2025 ,并在这场全球金融对前沿话中展示了其最新的机构服务套件
-
链上流动性变迁:15 个月的起伏,谁在炒作退潮后仍屹立不倒?
原文标题:Where is Onchain Volume Rotating? 原文作者:Stacy Muur 原文编译:Tim,PANews在过去的15个月里,DeFi的流动性版图已在各链间重塑,那些
-
链上流动性的迁移:起落 15 个月,谁在炒作退潮后屹立不倒?
DeFi的未来不在于多链扩展,而属于那些能将行业叙事转化为用户习惯的协议。作者:Stacy Muur编译:Tim,PANews在过去的15个月里,DeFi的流动性版图已在各链间重塑,那些由炒作热潮驱动
-
SuiPlay 空投启动,Saga 造富效应能在 2025 年再现吗?
未发货先空投,「边玩边赚」硬件的造富叙事还能跑通吗?撰文:叮当(@XiaMiPP)SuiPlay 0X 1 玩家已开始「收福利」?4 月 11 日,SuiPlay 官方发布消息称:现已联合多个合作伙伴
-
TechFlowhttps://www.techflowpost.com
那个拒绝为马斯克生孩子的女孩 从一个舆论风暴到另一个舆论风暴,无业游民 Tiffany Fong 的幸运人生。撰文:shushu,律动Twitter 上拥有 34 万粉丝的女 KOL Tiffany Fong 最近陷入了一段莫名其
-
KiloEx 黑客攻击事件最新进展:已向香港警方报案,目前黑客尚未转移资金
深潮 TechFlow 消息,4 月 17 日,据 KiloEx 官方消息,针对 4 月 15 日发生的黑客攻击事件,交易所已向香港警方报案并立案,目前正与刑事及网络犯罪部门合作追查黑客身份。Kilo
- 成交量排行
- 币种热搜榜
