nest3.0从架构解析到克隆四(NestOffer之Nest_3_MiningContract、Nest_3_OfferPrice)

我们之前介绍的是报价机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

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

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);
    }
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
问答区块链
问答区块链
致力于人工智能与区块链相结合下的智能设备自治