NEST预言机-获取链上价格
介绍
NEST预言机采用双边报价机制生成链上价格,质押双边资产来保证价格的准确性。是完全去中心化的链上价格生成机制。
白皮书:https://nestprotocol.org/doc/zhnestwhitepaper.pdf
github:https://github.com/NEST-Protocol
详细的介绍可以查看https://nestprotocol.org/
尝试获取链上价格
了解机制
- NEST预言机以区块为单位生成价格,如果区块内没有价格,则使用最近的区块价格。
- 使用报价的方式生成区块价格,如果一个区块内有多笔报价,则加权平均。
- 每笔报价有25区块的验证时间(吃单),如果验证时间内没有被吃单则代表市场认可这笔报价,将会在报价区块后的25个区块价格生效。
“获取价格合约”github:https://github.com/NEST-Protocol/NEST-oracle-V3/blob/master/NestOffer/Nest_3_OfferPrice.sol
代码解析
增加价格
function addPrice(uint256 ethAmount, uint256 tokenAmount, uint256 endBlock, address tokenAddress, address offerOwner) public onlyOfferMain{
// Add effective block price information
TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
PriceInfo storage priceInfo = tokenInfo.priceInfoList[endBlock];
priceInfo.ethAmount = priceInfo.ethAmount.add(ethAmount);
priceInfo.erc20Amount = priceInfo.erc20Amount.add(tokenAmount);
if (endBlock != tokenInfo.latestOffer) {
// If different block offer
priceInfo.frontBlock = tokenInfo.latestOffer;
tokenInfo.latestOffer = endBlock;
}
}
该方法限制了只有“报价合约”才可以调用,保证添加到价格合约中的价格数据的数据源正确。
输入参数 | 描述 |
---|---|
ethAmount | 报价ETH数量 |
tokenAmount | 报价ERC20数量 |
endBlock | 价格生效区块号 |
tokenAddress | 报价ERC20地址 |
offerOwner | 报价者地址 |
PriceInfo storage priceInfo = tokenInfo.priceInfoList[endBlock];
priceInfo.ethAmount = priceInfo.ethAmount.add(ethAmount);
priceInfo.erc20Amount = priceInfo.erc20Amount.add(tokenAmount);
这三行代码实现在同一个区块内加权平均。
修改价格
function changePrice(uint256 ethAmount, uint256 tokenAmount, address tokenAddress, uint256 endBlock) public onlyOfferMain {
TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
PriceInfo storage priceInfo = tokenInfo.priceInfoList[endBlock];
priceInfo.ethAmount = priceInfo.ethAmount.sub(ethAmount);
priceInfo.erc20Amount = priceInfo.erc20Amount.sub(tokenAmount);
}
同样限制了只有“报价合约”才有权限调用。只有在触发吃单操作后,才会修改对应生效区块中的价格,将”添加价格“时的报价数量按照”吃单“规模减掉。
输入参数 | 描述 |
---|---|
ethAmount | 吃单ETH数量 |
tokenAmount | 吃单ERC20数量 |
tokenAddress | 报价ERC20地址 |
endBlock | 价格生效区块号 |
获取价格(最新)
function updateAndCheckPriceNow(address tokenAddress) public payable returns(uint256 ethAmount, uint256 erc20Amount, uint256 blockNum) {
require(checkUseNestPrice(address(msg.sender)));