前言
2020~2021是一个Defi的时代,很多公链都开始反对EVM,开始搞web3.0。包含,Algorand,BCH,BSC,NEO和Conflux等等等等。很多公链生态利用都是呈现爆发式呈现,例如Gamefi,多种Defi协定。然而,Defi各种生态里,预言机服务是十分十分重要的一个服务。很多Defi协定都须要一个预言机合约进行报价,为了解决新生公链生态没有预言机的问题,我开源了我在TriangleDAO写的一个中心化区块链预言机。外围团队 or 外围社区人员能够部署到对应的链上,做一个长期的中心化区块链预言机计划。这同样也适宜联盟链,联盟链应该是很少或者简直没有预言机服务的吧。
开源地址:
https://github.com/shanxuanch...
技术架构 ( v1.0)
外围其实是2个合约:一个是TriangleOracle.sol,另外一个PriceFeed.sol。
TriangleOracle.sol继承了IERC2362规范,次要是2个函数:一个是putPirce和ValueFor。有一个定时的过程每5分钟会从Binance和Okex读取价格,而后触发putPrice,把价格写到链上。
pragma solidity 0.6.11;import "./Ownable.sol";import "./Interfaces/IERC2362.sol";contract TriangleOracle is Ownable, IERC2362 { // 32 + 16 + 16 = 64 bytes // default 1e+18 struct PriceOracle { int256 price; // 16 bytes uint256 timestamp; uint256 status; // 16 bytes } PriceOracle latestPrice; event PutLatestTokenPrice(int256 price, uint256 timestamp, uint256 status); function putPrice(bytes32 _id, int256 price, uint256 timestamp) public onlyOwner { uint256 _status = 200; latestPrice = PriceOracle ({ price: price, timestamp: timestamp, status: _status }); emit PutLatestTokenPrice(price,timestamp, _status); } function valueFor(bytes32 _id) external view override returns(int256,uint256,uint256) { return (latestPrice.price, latestPrice.timestamp, latestPrice.status); }}
PriceFeed合约的职责是读TriangleOracle.sol的价格,而后把价格保留到lastGoodPrice这个变量中,以便其余合约读取这个价格。这里有其余逻辑,例如scale。比拟重要的是,这里波及到可更新和合约交互的逻辑,让我对智能合约的了解晋升了一个数量级。
// SPDX-License-Identifier: MITpragma solidity 0.6.11;import "./Dependencies/SafeMath.sol";import "./Interfaces/IERC2362.sol";import "./Interfaces/IPriceFeed.sol";import "./Dependencies/Initializable.sol";import "./Dependencies/CheckContract.sol";contract PriceFeed is CheckContract, IPriceFeed, Initializable { using SafeMath for uint256; uint constant public TARGET_DIGITS = 18; // CFX/USDT assertID bytes32 constant public assetID = bytes32(0x65784185a07d3add5e7a99a6ddd4477e3c8caad717bac3ba3c3361d99a978c29); struct WitnetResponse { int256 value; uint256 _timestamp; uint256 status; } IERC2362 public witnet; uint public lastGoodPrice; event LastGoodPriceUpdated(uint _lastGoodPrice); // --- Dependency setters --- function initialize(address _IWitnetCFXUSDTAddress) public initializer { checkContract(_IWitnetCFXUSDTAddress); witnet = IERC2362(_IWitnetCFXUSDTAddress); WitnetResponse memory witnetResponse = _getCurrentWitnetResponse(assetID); _storePrice(witnetResponse); } function getPrice() external view returns (uint) { return lastGoodPrice; } function fetchPrice() external override returns (uint) { WitnetResponse memory witnetResponse = _getCurrentWitnetResponse(assetID); _storePrice(witnetResponse); return lastGoodPrice; } function _getCurrentWitnetResponse(bytes32 _assetID) internal view returns(WitnetResponse memory response) { try witnet.valueFor(_assetID) returns ( int256 value, uint256 _timestamp, uint256 status ) { response.value = value; response._timestamp = _timestamp; response.status = status; } catch { // If call to Chainlink aggregator reverts, return a zero response with success = false return response; } } function _storePrice(WitnetResponse memory witnetResponse) internal { require(witnetResponse.status == 200, "witnet Response is not 200. response error."); uint goodPrice = _scaleWitnetPriceByDigits(uint(witnetResponse.value), 6); if (goodPrice != lastGoodPrice) { lastGoodPrice = goodPrice; emit LastGoodPriceUpdated(lastGoodPrice); } } function _scaleWitnetPriceByDigits(uint _price, uint _answerDigits) internal pure returns (uint) { /* * Convert the price returned by the Chainlink oracle to an 18-digit decimal for use by Liquity. * At date of Liquity launch, Chainlink uses an 8-digit price, but we also handle the possibility of * future changes. * */ uint price; if (_answerDigits >= TARGET_DIGITS) { // Scale the returned price value down to Liquity's target precision price = _price.div(10 ** (_answerDigits - TARGET_DIGITS)); } else if (_answerDigits < TARGET_DIGITS) { // Scale the returned price value up to Liquity's target precision price = _price.mul(10 ** (TARGET_DIGITS - _answerDigits)); } return price; }}
总结
地址:https://github.com/shanxuanch...
总体而言没有什么技术难度,就是一个定时脚步读写工作而已。中心化的预言机服务是比较简单的,然而去中心化就十分有难度了。当初为止有靠近$300W的TVL了,尽管token的价格稳定很大,然而我心田十分有信念。起因?可能是我提前晓得各种利好吧。如果Token解锁了,我想所有帮忙我一路上爬过去的人都散发一部分token,想了想,可能这是我去北京之前惟一能拿得出手的礼物了。