我们之前介绍的是报价机NestOffer的核心部分Nest_3_OfferMain,我们在本节将继续介绍Nest_3_MiningContract与Nest_3_OfferPrice。
返回总章 我们之前介绍的是报价机NestOffer的核心部分Nest_3_OfferMain,我们在本节将继续介绍Nest_3_MiningContract与Nest_3_OfferPrice。 1.Nest_3_OfferMain报价系统,调用挖矿合约Nest_3_MiningContract,调用Nest_3_OfferPrice报价系统。 2.Nest_3_MiningContract是报价机的辅助部分,主要是负责矿池存储和出矿逻辑。 3.Nest_3_OfferPrice则主要进行报价过程中的价格查询与调用。 我们将在下面进行更加详细的说明。
Nest_3_MiningContract较为简单,都是跟出块的产量有关。
/**
* @title Mining contract
挖矿合约
* @dev Mining pool + mining logic
矿池存储 + 出矿逻辑
*/
contract Nest_3_MiningContract {
using address_make_payable for address;
using SafeMath for uint256;
uint256 _blockAttenuation = 2400000; // Block decay time interval
// 区块衰减间隔
uint256[10] _attenuationAmount; // Mining decay amount
// 挖矿数量衰减
uint256 _afterMiningAmount = 40 ether; // Stable period mining amount
// 平稳期出矿量
uint256 _firstBlockNum; // Starting mining block
// 起始挖矿区块
uint256 _latestMining; // Latest offering block
// 最新报价区块
Nest_3_VoteFactory _voteFactory; // Voting contract
// 投票合约(这个需要先弄)
ERC20 _nestContract; // NEST contract address
// NEST 合约
address _offerFactoryAddress; // Offering contract address
// 报价工厂合约地址
// Current block, current block mining amount
//当前区块,当前块出矿量
event OreDrawingLog(uint256 nowBlock, uint256 blockAmount);
/**
* @dev Initialization method
初始化方法
* @param voteFactory voting contract address
Current block, current block mining amount
做一个假的nest.v3.offerMain,然后就弄,
*/
constructor(address voteFactory) public {
_voteFactory = Nest_3_VoteFactory(address(voteFactory));
_offerFactoryAddress = address(_voteFactory.checkAddress("nest.v3.offerMain"));
_nestContract = ERC20(address(_voteFactory.checkAddress("nest")));
// Initiate mining parameters
//初始化挖矿参数
_firstBlockNum = 6236588;
_latestMining = block.number;
uint256 blockAmount = 400 ether;
for (uint256 i = 0; i < 10; i ++) {
_attenuationAmount[i] = blockAmount;
blockAmount = blockAmount.mul(8).div(10);
}
}
/**
* @dev Reset voting contract
重置投票合约
* @param voteFactory Voting contract address
投票合约地址
*/
function changeMapping(address voteFactory) public onlyOwner {
_voteFactory = Nest_3_VoteFactory(address(voteFactory));
_offerFactoryAddress = address(_voteFactory.checkAddress("nest.v3.offerMain"));
_nestContract = ERC20(address(_voteFactory.checkAddress("nest")));
}
/**
* @dev Offering mining
报价出矿
* @return Current block mining amount
当前区块出矿量
*/
function oreDrawing() public returns (uint256) {
require(address(msg.sender) == _offerFactoryAddress, "No authority");
//这个说明,报价是由nest.v3.offerMain提出的
// Update mining amount list
//更新出矿量列表
uint256 miningAmount = changeBlockAmountList();
//这个就是获得多少币的关键函数
// Transfer NEST
if (_nestContract.balanceOf(address(this)) < miningAmount){
//这里balanceOf说的是这个智能合约地址里面有没有nest
miningAmount = _nestContract.balanceOf(address(this));
}
if (miningAmount > 0) {
_nestContract.transfer(address(msg.sender), miningAmount);
emit OreDrawingLog(block.number,miningAmount);
}
//如果里面的币够,就发送出去
return miningAmount;
}
/**
* @dev Update mining amount list
更新出矿量列表
*/
function changeBlockAmountList() private returns (uint256) {
uint256 createBlock = _firstBlockNum;//6236588
uint256 recentlyUsedBlock = _latestMining;//初始化的时候,是以当时的block.number为时间点
uint256 attenuationPointNow = block.number.sub(createBlock).div(_blockAttenuation);
//block.number-createBlock/_blockAttenuation,为衰减系数
uint256 miningAmount = 0;
uint256 attenuation;
if (attenuationPointNow > 9) {
attenuation = _afterMiningAmount;
} else {
attenuation = _attenuationAmount[attenuationPointNow];//大概是400
}
miningAmount = attenuation.mul(block.number.sub(recentlyUsedBlock));//400x(当前块数-初始化时的块数)
_latestMining = block.number;
return miningAmount;
}
/**
* @dev Transfer all NEST
转移所有 NEST
* @param target Transfer target address
target 转移目标地址
*/
function takeOutNest(address target) public onlyOwner {
_nestContract.transfer(address(target),_nestContract.balanceOf(address(this)));
}
// Check block decay time interval
//查看区块衰减间隔
function checkBlockAttenuation() public view returns(uint256) {
return _blockAttenuation;
}
// Check latest offering block
//查看最新报价区块
function checkLatestMining() public view returns(uint256) {
return _latestMining;
}
// Check mining amount decay
//查看挖矿数量衰减
function checkAttenuationAmount(uint256 num) public view returns(uint256) {
return _attenuationAmount[num];
}
// Check NEST balance
//查看 NEST 余额
function checkNestBalance() public view returns(uint256) {
return _nestContract.balanceOf(address(this));
}
// Modify block decay time interval
//修改区块衰减间隔
function changeBlockAttenuation(uint256 blockNum) public onlyOwner {
require(blockNum > 0);
_blockAttenuation = blockNum;
}
// Modify mining amount decay
//修改挖矿数量衰减
function changeAttenuationAmount(uint256 firstAmount, uint256 top, uint256 bottom) public onlyOwner {
uint256 blockAmount = firstAmount;
for (uint256 i = 0; i < 10; i ++) {
_attenuationAmount[i] = blockAmount;
blockAmount = blockAmount.mul(top).div(bottom);
}
}
// Administrator only
modifier onlyOwner(){
require(_voteFactory.checkOwners(msg.sender), "No authority");
_;
}
}
Nest_3_OfferPrice主要负责与价格相关的内容。 主要分定义部分,增加报价,和更新报价,之后剩下的内容都比较简单,就不说了。
using SafeMath for uint256;
using address_make_payable for address;
using SafeERC20 for ERC20;
Nest_3_VoteFactory _voteFactory; // Voting contract
// 投票合约
ERC20 _nestToken; // NestToken
Nest_NToken_TokenMapping _tokenMapping; // NToken mapping
// NToken映射
Nest_3_OfferMain _offerMain; // Offering main contract
// 报价工厂合约
Nest_3_Abonus _abonus; // Bonus pool
// 分红池
address _nTokeOfferMain; // NToken offering main contract
// NToken报价工厂合约
address _destructionAddress; // Destruction contract address
// 销毁合约地址
address _nTokenAuction; // NToken auction contract address
// NToken拍卖合约地址
struct PriceInfo { // Block price
// 区块价格
uint256 ethAmount; // ETH 数量 // ETH amount
uint256 erc20Amount; // ERC20 数量 // Erc20 amount
uint256 frontBlock; // 上一个生效区块 // Last effective block
address offerOwner; // 报价地址 // Offering address
}
struct TokenInfo { // token报价信息 // Token offer information
mapping(uint256 => PriceInfo) priceInfoList; // 区块价格列表,区块号 => 区块价格 // Block price list, block number => block price
uint256 latestOffer; // 最新生效区块 // Latest effective block
uint256 priceCostLeast; // 价格 ETH 最少费用 // Minimum ETH cost for prices
uint256 priceCostMost; // 价格 ETH 最多费用 // Maximum ETH cost for prices
uint256 priceCostSingle; // 价格 ETH 单条数据费用 // ETH cost for single data
uint256 priceCostUser; // 价格 ETH 费用用户比例 // User ratio of cost
}
uint256 destructionAmount = 10000 ether; // 调用价格销毁 NEST 数量 // Amount of NEST to destroy to call prices
uint256 effectTime = 1 days; // 可以调用价格等待时间 // Waiting time to start calling prices
mapping(address => TokenInfo) _tokenInfo; // token报价信息 // Token offer information
mapping(address => bool) _blocklist; // 禁止名单 // Block list
mapping(address => uint256) _addressEffect; // 调用价格地址生效时间 // Effective time of address to call prices
mapping(address => bool) _offerMainMapping; // 报价合约映射 // Offering contract mapping
// Real-time price token, ETH amount, erc20 amount
// 实时价格 token, eth数量, erc20数量
event NowTokenPrice(address a, uint256 b, uint256 c);
/**
* @dev Initialization method
初始化方法
* @param voteFactory Voting contract address
voteFactory 投票合约地址
*/
constructor (address voteFactory) public {
Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory));
_voteFactory = voteFactoryMap;
_offerMain = Nest_3_OfferMain(address(voteFactoryMap.checkAddress("nest.v3.offerMain")));
_nTokeOfferMain = address(voteFactoryMap.checkAddress("nest.nToken.offerMain"));
_abonus = Nest_3_Abonus(address(voteFactoryMap.checkAddress("nest.v3.abonus")));
_destructionAddress = address(voteFactoryMap.checkAddress("nest.v3.destruction"));
_nestToken = ERC20(address(voteFactoryMap.checkAddress("nest")));
_tokenMapping = Nest_NToken_TokenMapping(address(voteFactoryMap.checkAddress("nest.nToken.tokenMapping")));
_nTokenAuction = address(voteFactoryMap.checkAddress("nest.nToken.tokenAuction"));
_offerMainMapping[address(_offerMain)] = true;
_offerMainMapping[address(_nTokeOfferMain)] = true;
}
/**
* @dev Modify voting contract
修改投票射合约
* @param voteFactory Voting contract address
投票合约地址
*/
function changeMapping(address voteFactory) public onlyOwner {
Nest_3_VoteFactory voteFactoryMap = Nest_3_VoteFactory(address(voteFactory));
_voteFactory = voteFactoryMap;
_offerMain = Nest_3_OfferMain(address(voteFactoryMap.checkAddress("nest.v3.offerMain")));
_nTokeOfferMain = address(voteFactoryMap.checkAddress("nest.nToken.offerMain"));
_abonus = Nest_3_Abonus(address(voteFactoryMap.checkAddress("nest.v3.abonus")));
_destructionAddress = address(voteFactoryMap.checkAddress("nest.v3.destruction"));
_nestToken = ERC20(address(voteFactoryMap.checkAddress("nest")));
_tokenMapping = Nest_NToken_TokenMapping(address(voteFactoryMap.checkAddress("nest.nToken.tokenMapping")));
_nTokenAuction = address(voteFactoryMap.checkAddress("nest.nToken.tokenAuction"));
_offerMainMapping[address(_offerMain)] = true;
_offerMainMapping[address(_nTokeOfferMain)] = true;
}
/**
* @dev Initialize token price charge parameters
初始化 token 价格收费参数
* @param tokenAddress Token address
tokenAddress token地址
*/
function addPriceCost(address tokenAddress) public {
require(msg.sender == _nTokenAuction);
TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
tokenInfo.priceCostLeast = 0.001 ether;
tokenInfo.priceCostMost = 0.01 ether;
tokenInfo.priceCostSingle = 0.0001 ether;
tokenInfo.priceCostUser = 2;
}
/**
* @dev Add price
增加价格
* @param ethAmount ETH amount
eth数量
* @param tokenAmount Erc20 amount
erc20数量
* @param endBlock Effective price block
生效价格区块
* @param tokenAddress Erc20 address
erc20地址
* @param offerOwner Offering address
报价地址
*/
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);
priceInfo.offerOwner = offerOwner;
if (endBlock != tokenInfo.latestOffer) {
// If different block offer
// 不同区块报价
priceInfo.frontBlock = tokenInfo.latestOffer;
tokenInfo.latestOffer = endBlock;
}
}
/**
* @dev Price modification in taker orders
吃单修改价格
* @param ethAmount ETH amount
* @param tokenAmount Erc20 amount
* @param tokenAddress Token address
* @param endBlock Block of effective price
生效价格区块
*/
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);
}
/**
* @dev Update and check the latest price
更新并查看最新价格
* @param tokenAddress Token address
* @return ethAmount ETH amount
* @return erc20Amount Erc20 amount
* @return blockNum Price block
*/
function updateAndCheckPriceNow(address tokenAddress) public payable returns(uint256 ethAmount, uint256 erc20Amount, uint256 blockNum) {
require(checkUseNestPrice(address(msg.sender)));
TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
uint256 checkBlock = tokenInfo.latestOffer;
while(checkBlock > 0 && (checkBlock >= block.number || tokenInfo.priceInfoList[checkBlock].ethAmount == 0)) {
checkBlock = tokenInfo.priceInfoList[checkBlock].frontBlock;
}
require(checkBlock != 0);
PriceInfo memory priceInfo = tokenInfo.priceInfoList[checkBlock];
address nToken = _tokenMapping.checkTokenMapping(tokenAddress);
if (nToken == address(0x0)) {
_abonus.switchToEth.value(tokenInfo.priceCostLeast.sub(tokenInfo.priceCostLeast.mul(tokenInfo.priceCostUser).div(10)))(address(_nestToken));
} else {
_abonus.switchToEth.value(tokenInfo.priceCostLeast.sub(tokenInfo.priceCostLeast.mul(tokenInfo.priceCostUser).div(10)))(address(nToken));
}
repayEth(priceInfo.offerOwner, tokenInfo.priceCostLeast.mul(tokenInfo.priceCostUser).div(10));
repayEth(address(msg.sender), msg.value.sub(tokenInfo.priceCostLeast));
emit NowTokenPrice(tokenAddress,priceInfo.ethAmount, priceInfo.erc20Amount);
return (priceInfo.ethAmount,priceInfo.erc20Amount, checkBlock);
}
/**
* @dev Update and check the latest price-internal use
更新并查看最新价格-内部使用
* @param tokenAddress Token address
* @return ethAmount ETH amount
* @return erc20Amount Erc20 amount
*/
function updateAndCheckPricePrivate(address tokenAddress) public view onlyOfferMain returns(uint256 ethAmount, uint256 erc20Amount) {
TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
uint256 checkBlock = tokenInfo.latestOffer;
while(checkBlock > 0 && (checkBlock >= block.number || tokenInfo.priceInfoList[checkBlock].ethAmount == 0)) {
checkBlock = tokenInfo.priceInfoList[checkBlock].frontBlock;
}
if (checkBlock == 0) {
return (0,0);
}
PriceInfo memory priceInfo = tokenInfo.priceInfoList[checkBlock];
return (priceInfo.ethAmount,priceInfo.erc20Amount);
}
/**
* @dev Update and check the effective price list
更新并查看生效价格列表
* @param tokenAddress Token address
* @param num Number of prices to check
* @return uint256[] price list
*/
function updateAndCheckPriceList(address tokenAddress, uint256 num) public payable returns (uint256[] memory) {
require(checkUseNestPrice(address(msg.sender)));
TokenInfo storage tokenInfo = _tokenInfo[tokenAddress];
// Charge
uint256 thisPay = tokenInfo.priceCostSingle.mul(num);
if (thisPay < tokenInfo.priceCostLeast) {
thisPay=tokenInfo.priceCostLeast;
} else if (thisPay > tokenInfo.priceCostMost) {
thisPay = tokenInfo.priceCostMost;
}
// Extract data
uint256 length = num.mul(3);
uint256 index = 0;
uint256[] memory data = new uint256[](length);
address latestOfferOwner = address(0x0);
uint256 checkBlock = tokenInfo.latestOffer;
while(index < length && checkBlock > 0){
if (checkBlock < block.number && tokenInfo.priceInfoList[checkBlock].ethAmount != 0) {
// Add return data
data[index++] = tokenInfo.priceInfoList[checkBlock].ethAmount;
data[index++] = tokenInfo.priceInfoList[checkBlock].erc20Amount;
data[index++] = checkBlock;
if (latestOfferOwner == address(0x0)) {
latestOfferOwner = tokenInfo.priceInfoList[checkBlock].offerOwner;
}
}
checkBlock = tokenInfo.priceInfoList[checkBlock].frontBlock;
}
require(latestOfferOwner != address(0x0));
require(length == data.length);
// Allocation
address nToken = _tokenMapping.checkTokenMapping(tokenAddress);
if (nToken == address(0x0)) {
_abonus.switchToEth.value(thisPay.sub(thisPay.mul(tokenInfo.priceCostUser).div(10)))(address(_nestToken));
} else {
_abonus.switchToEth.value(thisPay.sub(thisPay.mul(tokenInfo.priceCostUser).div(10)))(address(nToken));
}
repayEth(latestOfferOwner, thisPay.mul(tokenInfo.priceCostUser).div(10));
repayEth(address(msg.sender), msg.value.sub(thisPay));
return data;
}
// Activate the price checking function
// 激活使用价格合约
function activation() public {
_nestToken.safeTransferFrom(address(msg.sender), _destructionAddress, destructionAmount);
_addressEffect[address(msg.sender)] = now.add(effectTime);
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!