在Matic网络上使用Chainlink预言机

自从今年初Matic网络上线后,得力于它的安全和可扩展的基础设施以及即时交易特性,它快速成为以太坊开发者中受欢迎的Layer 2解决方案。Matic的高性能,低手续费的基础设施为DeFi应用程序促进大规模应用提供了一个可行的平台。与此相似,在区块链预言机领域,Chainlink已经成为DeFi协议优先选择的预言机解决方案,Chainlink的喂价(Price Feeds现在正在守护着价值数亿美元的价值资产。在本篇技术文章中,我们将向你展示如何在Matic的DeFi应用中使用Chainlink的预言机,以及如何使用Chainlink的喂价来给予应用访问高质量的、防篡改的数据,这些数据不易遭受诸如预言机漏洞和闪电攻击等风险。

对可扩展和安全DeFi协议的需求

本年度已经见证了DeFi协议的大爆发,DeFi的总价值锁定(TVL)从一月份的6.8亿美元快速增长到现在的超过140亿美元。随着TVL的增长,链上交易数量也达到了新的水平,但同时也引起了一些不必要的关注,作恶者们为了自身的利益开始利用这些协议漏洞。

由于DeFi的增长带来的链上交易数量水平的提升使得以太坊的性能变得拥堵,这也归因于以太坊区块链自身的可扩展性的限制和吞吐量低的问题。这引起了一系列困扰用户使用DeFi协议体验和冗长交易时间的关联反应。(P.S. 拥堵会导致高昂的gas费,否则矿工不会打包;同时交易确认时间延长,除非给更高的gas费)

交易速度缓慢以及交易费用高昂是阻碍DeFi跨入主流的最重要的两个限制因素。诸如Matic这种Layer 2网络能够解锁下一阶段的DeFi的增长,这得益于它的增强的可扩展性,高吞吐量以及低成本的交易等性质。Matic侧链也是可组合的,并且完全与EVM兼容。DeFi的一大核心价值在于它的无需许可的可组合性,Matic为这些寻求构建各种有价值的DeFi应用的开发者们提供了一个极具吸引力的选择,这些DeFi应用可扩展,能提供低成本交易,能确保无需许可的组合性,并提供无缝的用户体验。

但是,这些DeFi应用仍然需要访问高质量的可信的外部数据。正如我们在本年度多次看到的那样,DeFi协议可能会遭受多种形式的攻击,如价格预言机攻击等,作恶者结合闪电贷和低质量的预言机来操纵市场来达到对他们有利的局面,损害的是其他用户的利益。

Chainlink的喂价机制降低了DeFi应用容易遭受这些攻击的风险,采用的方式是提供多种高质量的数据提供方的汇总数据,这些数据由Chainlink网络上的去中心化的预言机来发布上链。Chainlink的去中心化架构以及广泛的高质量数据源确保了最终价格反映的是广泛的市场的覆盖范围,这事实上意味着此价格是聚合了整个市场上一系列不同的价格后确定的,而不只是其中的一个小小的子集。

现在我们理解了在Matic网络上构建DeFi协议的优势,以及Chainlink预言机和喂价机制在其中扮演的重要角色,我们将展示在Matic网络上构建DeFi应用时使用Chainlink喂价的案例。

在Matic网络上使用Chainlink喂价机制

Chainlink的喂价机制使用多种高质量的数据输入,并将它们与Chainlink预言机网络相结合,该预言机会将价格数据喂到参考合约(reference contracts),在此合约中数据结果将会聚合。DeFi协议非常重视数据质量和完整性,这一点尤为重要。Chainlink喂价机制为这些想要保护自身免受各种由于数据质量问题或者传输问题导致的攻击的协议提供了最佳的、经过严格考验的生产环境解决方案。

下面的两个教程内容也可以通过Remix中的这个完整的智能合约来查看。

在Matic网络上使用Chainlink喂价机制的和预言机的第一步是设置你的MetaMask钱包,使用它来连接Matic的Mumbai测试网络,然后你就可以获取一定的Mumbai测试网上的MATIC代币,并在DeFi智能合约中使用。

Matic Mumbai
在MetaMask中设置Matic Mumbai测试网

获取测试网 Matic代币

MATIC是Matic网络上的本地代币,可以类比于以太坊上的ETH代币。为了和Matic网络交互,MATIC代币会用来支付gas费用。为了获取Mumbai测试网的MATIC代币,前往MATIC水龙头,选择MATIC代币和Mumbai测试网络,输入MetaMask钱包地址,并点击提交。

Testnet MATIC
Obtaining testnet MATIC 获取测试网MATIC代币
Confirm Details

注意:提交后还需要确认,并可前往浏览器查看此交易:https://explorer-mumbai.maticvigil.com/tx/0x742aa8e4c1fb12105b424840e435193b1b24324e2d77d926d4903fcc54142772/internal-transactions

检查钱包可以发现获取了测试代币(获取两次,每次0.1 MATIC):

Matic Mumbai Testnet

创建智能合约

在Matic网络上使用Chainlink喂价机制开始构建智能合约最容易的方式是使用标准的价格消费者(Price Consumer)合约。这是基本的标准合约,能够向Chainlink的喂价机制发起请求。我们将在Remix编辑器中打开合约,并且修改它以满足我们自己的需求。本文的演示会采用ETH/USD价格获取。第一步是构造函数中初始化Matic的喂价参考合约,其中,在Mumbai测试网上部署的ETH/USD喂价参考合约地址是:0x0715A7794a1dc8e42615F059dD6e406A6594651A。

priceFeed = AggregatorV3Interface(0x0715A7794a1dc8e42615F059dD6e406A6594651A);

接下来,我们需要一个函数来从价格获取聚合合约(Price Feed Aggregator contract)中获取最新价格,该聚合合约在上面的构造器中实例化。为了完成这个目标,我们在聚合合约中已经有了一个函数叫作latestRoundData,这是一个会返回当前聚合合约状态的函数,并且在本案例中,我们将取出当前的价格并且返回。

function getLatestPrice() public view returns (int) {
(
uint80 roundID,
int price,
uint startedAt,
uint timeStamp,
uint80 answeredInRound
) =priceFeed.latestRoundData();
returnprice;
}```

部署和测试智能合约

现在我们可以部署并测试我们的智能合约。在Remix中编译智能合约,然后在部署的页面,将环境改为“Injected Web3”,并确保钱包地址是含有MATIC代币的地址,点击部署(deploy)按钮,并跟随操作后续步骤。最终结果就是成功部署智能合约到Matic Mumbai测试网。

部署完成后,我们只需要简单的执行”getLatestPrice”函数。结果将为ETH/USD聚合合约中的函数返回的最新的价格数据,这可以用在Matic网络上的DeFi应用中。

ETH/USD
ETH/USD喂价结果

在Matic网络上使用Chainlink预言机

在Matic上可能有一些场景中智能合约需要链下数据,而这些数据是Chainlink的喂价没有提供的。这也是我们需要使用Chainlink预言机的地方。我们现在修改我们的智能合约来获取使用Chainlink的喂价器不能提供的市场价格,在这个案例中,我们使用ETH/EUR价格。

获取测试网的LINK代币

你需要获取一些测试网的LINK代币来发送请求给Chainlink的预言机。为了获取Mumbai测试网的LINK代币,需要加入Matic的Discord社群,并贴上你的MetaMask钱包地址,请求Matic团队成员发送一些Mumbai测试网的LINK代币。一旦你获取了一些MATIC和LINK到钱包中,就可以进入到智能合约的步骤了。

创建智能合约

在Matic中使用Chainlink预言机建立智能合约的最简单方法是使用标准的Chainlink APIConsumer合约。这是基础的标准合约,用于通过Chainlink预言机发起请求获取外部数据。我们在Remix中修改此合约以满足自己的需求。

首先我们需要重命名“volume”参数为“ethPrice”,然后“requestVolumeData”函数名修改为“requestEthereumPrice”。完成后,我们需要修改构造函数为:

  • Mumbai测试网上LINK代币地址为0x70d1F773A9f81C852087B77F6Ae6d3032B02D2AB,我们将其传到“setChainlinkToken”函数中
  • 正如在Matic文档中表明的,有一个在Mumbai测试网上运行的预言机合约,地址在0x1cf7D49BE7e0c6AC30dEd720623490B64F572E1,我们设置预言机变量为这个值
  • 我们将使用的API将通过HTTP GET请求,返回的值是一个无符号整数。运行在Mumbai测试网上的预言机有很多不同的作业规范(job specifications)可以使用。根据Matic文档中列出的作业,满足我们需求的是这个:d8fcf41ee8984d3b8b0eae7b74eca7dd,因为我们想要执行HTTP GET请求,并且返回数据是无符号整数,所以我们设置“jobId”变量为这个值
  • 修改“fee”变量为1LINK,移除“0.1”前缀即可。这是随着外部数据请求一块发送到预言机的支付数据(为此请求支付LINK代币)。
constructor() public {
setChainlinkToken(0x70d1F773A9f81C852087B77F6Ae6d3032B02D2AB);
oracle = 0x1cf7D49BE7e0c6AC30dEd720623490B64F572E17;
jobId = "d8fcf41ee8984d3b8b0eae7b74eca7dd";
fee = 10 ** 18; // 1 LINK
}

现在我们完成了构造函数,我们可以移步到“requestEthereumPrice”函数和“fulfill”函数。

Chainlink预言机满足请求的工作原理是采用Chainlink的请求和响应设计模式,其中链上函数会创建并发送请求,预言机检测到请求,然后响应会发送到相同合约的另一个函数。在我们的例子中,“requestEthereumPrice”函数会创建和发送请求,“fulfill”函数会处理响应,响应规范定义在this.fulfill.selector中。

我们将要消费的ETH/EUR价格数据API是来自crypto.com的公开API。浏览器中点开此链接,你可以看到返回数据的JSON格式。

在我们的“requestEthereumPrice”函数中,我们将其修改如下:

  • 设置URL为ETH/EUR接口端点
  • 设置请求中“path”变量为“EUR”,该路径是我们想要发现并返回的JSON响应的路径,该端点输出结果中包含现在的ETH价格
  • 将结果乘以100,因为Solidity不会处理含有小数点的数据
  • 将请求发送到Chainlink预言机
function requestEthereumPrice() public returns (bytes32 requestId)
{
Chainlink.Requestmemory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
// Set the URL to perform the GET request on
request.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=EUR");
// Set the path to find the desired data in the API response, where the response format is:
// {"USD":243.33}
request.add("path", "EUR");
// Multiply the result by 100 to remove decimals
request.addInt("times", 100);
// Sends the request
returnsendChainlinkRequestTo(oracle, request, fee);
}

在“fulfill”函数中,我们可以看到预言机发回一个响应到_price参数中,然后该参数值在合约中保存到了ethereumPrice变量。

function fulfill(bytes32 _requestId, uint256 _price) public recordChainlinkFulfillment(_requestId)
{
ethereumPrice =_price;
}

现在我们的合约准备好了,可以编译并部署到Matic Mumbai测试网。

部署并测试合约

在Remix中编译合约,然后部署合约到Mumbai测试网,这几个步骤我们在前面喂价合约中已经做过一遍。

下一步是为合约中添加一定的LINK代币,所以它能发送请求到Chainlink预言机。为了完成这个步骤,拿到部署的合约的地址,然后通过MetaMask钱包发送1LINK代币到此地址中。

Gas Limit
给合约充LINK代币

一旦合约部署完成并且充值完LINK,我们可以点击“requestEthereumPrice”按钮调用函数,发送请求到Chainlink预言机来获取当前的以太坊价格。我们也将发送LINK作为支付到Chainlink的预言机来完成此请求。

Test Contract
测试部署的合约

请求完成后,Chainlink预言机会完成它,然后合约中的“fulfill”函数会被Chainlink结点预言机合约调用。这会花费几秒钟的时间来完成 ,然后我们可以通过执行“ethereumPrice”的getter函数来查看API请求结果。这个结果应该是当前的以EUR计价的ETH价格,现在就保存到了合约,等待运行在Matic网络上的DeFi应用来消费这个数据。

Returned Result
查看返回结果

总结

Matic网络本身具有快速、便宜且可靠的交易特性,为构建DeFi协议提供了切实可行的Layer 2解决方案。而Chainlink预言机和Chainlink的喂价器进一步增强了在Matic上构建DeFi协议的价值主张,Chainlink预言机和Chainlink的喂价器使得这些协议可以访问外部数据和事件,包括可以用在各种各样的有价值的DeFi应用中的高质量的聚合价格数据,如去中心化交易所(DEX),流动性池,借贷协议,去中心化保险以及自动化做市商(AMMs)等等。

如果你是开发者,想要快速为你的应用连接到Chainlink的价格参考数据,访问开发者文档,并接入Discord技术讨论。如果你想要安排一个电话来更深入讨论Matic/Chainlink的集成,请在此处联系。

Website |  Twitter | Reddit | YouTube | Telegram | Events | GitHub | Price Feeds | DeFi

Need Integration Support?
Talk to an expert
Faucets
Get testnet tokens
Read the Docs
Technical documentation