关于nest2.0智能合约的架构解析三(NEST_MiningSave,NESTAbonus)

本文对预言机NEST里面NEST_MiningSave,NESTAbonus继续进行解析。

[返回总章](https://learnblockchain.cn/article/2125) 我们上一篇文章对NESTtoken与IBMapping做了解析,本文则对NEST_MiningSave,NESTAbonus继续进行解析。 # 什么是modifier 首先说一下modifier在solidity中做的是什么工作。简单说就是给继承这个modifier修饰的function加上一个特定的约束 ``` modifier isOwner() { if (msg.sender != owner) { throw; } _; // 继续执行余下的代码体(其实就是isOwner里的实际代码) } doSomething() isOwner { // 将会检查调用者是不是Owner // code } ``` # NEST_MiningSave的前置条件 NEST_MiningSave.sol是矿池合约。这个内容相对来说比较简单,看源码解析部分即可,最主要的内容是给挖矿函数调用转账用的。 整个合约都在NEST_MiningSave当中: 从nesttoken里面引出了ERC20,从ibmapping里面引出了IBMapping;主要内容是NEST_MiningSave,里面首先是对前面两个合约的初始化。 这里注意的是,需要在IBMapping里面设置一些对应的智能合约地址。所以安装本合约需要两个前置条件。 1, 在IBMapping里面设置nest对应的token智能合约地址 2, 在IBMapping里面设置miningCalculation对应的智能合约地址。 # NEST_MiningSave流程 1.初始化合约,默认输入是IBMapping对应的合约地址(特别注意) 2.将IBMapping里面找到nest(就是token合约)对应的合约地址 3.modifier onlyOwner()检测是否是超级用户,不是则不执行 4.modifier onlyMiningCalculation(),检测是否是挖矿计算器(mappingContract.checkAddress) 这里需要特别注意,orePoolLogic.sol对应的应该就是miningCalculation。 由于本节的初始化并不需要orePoolLogic.sol,而orePoolLogic.sol的初始化需要orePoolLogic.sol,因此,我们认为,这个挖矿存储是先编译的,而orePoolLogic.sol是后编译的。 5.changeMapping,超级用户权限才能使用。修改IBMapping合约地址,并重置token地址(这应该是用于token分叉的) 6.关于turnOut ``` function turnOut(uint256 amount, address to) public onlyMiningCalculation returns(uint256) { //先检查是否是挖矿计算器智能合约 uint256 leftNum = nestContract.balanceOf(address(this)); //获取这个合约里面还有多少币 if (leftNum >= amount) { nestContract.transfer(to, amount); return amount; } else { return 0; //如果取的值比合约里面的少,则传输,否则返回0. } } ``` 解释:首先检测是否是挖矿计算器地址。如果是是如果调用的的剩余token数量够,则往某地址转账(前提是已经通过了approve的授权) 这个函数显然是给挖矿函数调用转账用的。也是本智能合约最主要的内容。 # NESTAbonus NESTAbonus是分红合约,包含四个合约——分红nest锁仓,分红池合约,平准合约,分红逻辑合约。 NESTAbonus的结构很清晰,但源码阅读起来还是很难的,我就是尽量的说。 **分红逻辑合约**,就是NESTAbonus本身的初始化。这次初始化比较复杂,需要五个合约的前置。其中tokn,mapping在上一节已经讲完了;nestsave(分红池锁仓),abonus(分红池合约),nestleving(平准合约),这三个合约都在本文件里面。 **分红池锁仓**,也就是分红的nest池子; **分红池合约**,也就是eth的分红池子; **平准合约**,与前一个的区别是,第一个转账金额大则失败,而后面是转账金额大则一次性去除。后者是平仓,拿出所有eth用的,用于紧急情况。 总的功能就是存nest;取nest;第一次从nestleving 取eth到NESTAbonus,然后再取到用户地址(由NESTAbonus的getETH函数完成)。注意,除了token合约里面出现100亿外,这里也出现了。 **简单总结**,这四个函数有一个很有意思的特点,就是对于eth怎么存进去的没有提,我感觉是挖矿的手续费直接存入,以及其他的直接存入。 我在下面对几个合约进行更加详细的描述。 *ps1:if(msg.sender == tx.origin)如果调用者是一个账户,上面的条件永远是True。如果是合约账户,则条件就为False.* *ps2:在一个简单的调用链中,A->B->C->D,D里面的msg.sender将会是C,而tx.origin将一直是A。* # NESTSave——分红池锁仓合约 说明:将nest进行存储的合约。 ``` contract NESTSave { using SafeMath for uint256; mapping (address => uint256) baseMapping; // General ledger IBNEST nestContract; // Nest contract IBMapping mappingContract; // Mapping contract /** * @dev Initialization method * @param map Mapping contract address */ constructor(address map) public { mappingContract = IBMapping(map); //一个IBMapping的合约地址导入 nestContract = IBNEST(address(mappingContract.checkAddress("nest"))); //一个token合约的导入 } /** * @dev Change mapping contract * @param map Mapping contract address 改变映射地址 */ function changeMapping(address map) public onlyOwner{ mappingContract = IBMapping(map); nestContract = IBNEST(address(mappingContract.checkAddress("nest"))); } /** * @dev Take out nest * @param num Quantity taken out 转出 */ function takeOut(uint256 num) public onlyContract { require(isContract(address(tx.origin)) == false); require(num <= baseMapping[tx.origin]); baseMapping[address(tx.origin)] = baseMapping[address(tx.origin)].sub(num); nestContract.transfer(address(tx.origin), num); } /** * @dev Deposit in nest * @param num Deposit quantity 转入 */ function depositIn(uint256 num) public onlyContract { require(isContract(address(tx.origin)) == false); require(nestContract.balanceOf(address(tx.origin)) >= num); require(nestContract.allowance(address(tx.origin), address(this)) >= num); require(nestContract.transferFrom(address(tx.origin),address(this),num)); baseMapping[address(tx.origin)] = baseMapping[address(tx.origin)].add(num); } /** * @dev Take out all 转入者自行转出 */ function takeOutPrivate() public { require(isContract(address(msg.sender)) == false); require(baseMapping[msg.sender] > 0); nestContract.transfer(address(msg.sender), baseMapping[msg.sender]); baseMapping[address(msg.sender)] = 0; } //查询某个地址在池子里有多少nest function checkAmount(address sender) public view returns(uint256) { return baseMapping[address(sender)]; } modifier onlyOwner(){ require(mappingContract.checkOwners(msg.sender) == true); _; } modifier onlyContract(){ require(mappingContract.checkAddress("nestAbonus") == msg.sender); _; } function isContract(address addr) public view returns (bool) { uint size; assembly { size := extcodesize(addr) } return size > 0; } } ``` # Abonus——分红池合约 分红池合约,说白了就是分红。 ``` contract Abonus { using address_make_payable for address; IBMapping mappingContract; // Mapping contract /** * @dev Initialization method * @param map Mapping contract address */ constructor(address map) public { mappingContract = IBMapping(map); } /** * @dev Change mapping contract * @param map Mapping contract address 很重要的一个函数,就是更改mapping的地址 */ function changeMapping(address map) public onlyOwner{ mappingContract = IBMapping(map); } /** * @dev Draw ETH * @param num Draw amount * @param target Transfer target 提以太坊,特别注意,只有nestAbonus才能提币 */ function getETH(uint256 num, address target) public onlyContract { require(num <= getETHNum()); address payable addr = target.make_payable(); //返回一个可支付地址赋值给addr addr.transfer(num); //发送num到addr。 } //获悉本地址在这个池子里面有多少eth function getETHNum() public view returns (uint256) { return address(this).balance; } modifier onlyContract(){ require(mappingContract.checkAddress("nestAbonus") == msg.sender); _; } modifier onlyOwner(){ require(mappingContract.checkOwners(msg.sender) == true); _; } function () external payable { } } ``` # NESTLeveling——平准合约 ``` contract NESTLeveling { using address_make_payable for address; IBMapping mappingContract; // Mapping contract /** * @dev Initialization method * @param map Mapping contract address */ constructor (address map) public { mappingContract = IBMapping(map); } /** * @dev Change mapping contract * @param map Mapping contract address */ function changeMapping(address map) public onlyOwner { mappingContract = IBMapping(map); } /** * @dev Transfer ETH * @param amount Transfer quantity * @param target Transfer target 给某个地址转账eth,发送者必须是nestAbonus才行。 */ function tranEth(uint256 amount, address target) public { require(address(msg.sender) == address(mappingContract.checkAddress("nestAbonus"))); uint256 tranAmount = amount; if (amount > address(this).balance) { tranAmount = address(this).balance; } address payable addr = target.make_payable(); addr.transfer(tranAmount); } //这个this说的是NESTLeveling对应的自身地址,而eth就是存储在这里的。 function () external payable { } modifier onlyOwner(){ require(mappingContract.checkOwners(msg.sender) == true); _; } } ``` # NESTAbonus——分行逻辑合约 ``` contract NESTAbonus { using address_make_payable for address; using SafeMath for uint256; IBNEST nestContract; IBMapping mappingContract; NESTSave baseMapping; Abonus abonusContract; NESTLeveling nestLeveling; uint256 timeLimit = 168 hours; // Dividend period //分红时间段 uint256 nextTime = 1587700800; // Next dividend time //下一次分红时间 uint256 getAbonusTimeLimit = 60 hours; // Trigger calculation settlement time //获取奖金的时间限制 uint256 ethNum = 0; // ETH amount //eth的数量 uint256 nestAllValue = 0; // Nest circulation //nest的价值 uint256 times = 0; // Dividend book //分红时间 uint256 expectedIncrement = 3; // Expected dividend increment proportion //预期股利增加比例 uint256 expectedMinimum = 100 ether; // Expected minimum dividend //预期最小分红 uint256 levelingProportion = 10; // Proportion of dividends deducted //股息扣除比例 mapping(uint256 => mapping(address => bool)) getMapping; // Dividend collection record //股息搜集记录 /** * @dev Initialization method * @param map Mapping contract address */ constructor (address map) public { mappingContract = IBMapping(map); nestContract = IBNEST(address(mappingContract.checkAddress("nest"))); baseMapping = NESTSave(address(mappingContract.checkAddress("nestSave"))); address payable addr = address(mappingContract.checkAddress("abonus")).make_payable(); abonusContract = Abonus(addr); address payable levelingAddr = address(mappingContract.checkAddress("nestLeveling")).make_payable(); nestLeveling = NESTLeveling(levelingAddr); } /** * @dev Change mapping contract * @param map Mapping contract address 修改mapping及其下面的合约,算上mapping,一共更改5个合约,其中nest是token,剩下三个都是本合约里面的结构体。 */ function changeMapping(address map) public onlyOwner { mappingContract = IBMapping(map); nestContract = IBNEST(address(mappingContract.checkAddress("nest"))); baseMapping = NESTSave(address(mappingContract.checkAddress("nestSave"))); address payable addr = address(mappingContract.checkAddress("abonus")).make_payable(); abonusContract = Abonus(addr); address payable levelingAddr = address(mappingContract.checkAddress("nestLeveling")).make_payable(); nestLeveling = NESTLeveling(levelingAddr); } /** * @dev Deposit in nest 存入 * @param amount Deposit quantity */ function depositIn(uint256 amount) public { require(address(tx.origin) == address(msg.sender)); //如果调用者是一个账户,上面的条件永远是True。如果是合约账户,则条件就为False. uint256 nowTime = now; if (nowTime < nextTime) { require(!(nowTime >= nextTime.sub(timeLimit) && nowTime <= nextTime.sub(timeLimit).add(getAbonusTimeLimit))); } else { require(!(nowTime >= nextTime && nowTime <= nextTime.add(getAbonusTimeLimit))); uint256 time = (nowTime.sub(nextTime)).div(timeLimit); uint256 startTime = nextTime.add((time).mul(timeLimit)); uint256 endTime = startTime.add(getAbonusTimeLimit); require(!(nowTime >= startTime && nowTime <= endTime)); } baseMapping.depositIn(amount); //经过了一系列的时间判断后,调用NESTSave转入的命令(通过NESTAbonus身份),然后用用户的身份运行 //在一个简单的调用链中,A->B->C->D,D里面的msg.sender将会是C,而tx.origin将一直是A。 } /** * @dev Take out nest 取出nest * @param amount Quantity taken out */ function takeOut(uint256 amount) public { require(address(tx.origin) == address(msg.sender)); require(amount != 0); require(amount <= baseMapping.checkAmount(address(msg.sender))); baseMapping.takeOut(amount); } /** * @dev Receive dividend 发币减值 */ function getETH() public { require(address(tx.origin) == address(msg.sender)); reloadTimeAndMapping (); //时间校验,并提出来eth到abonusContract uint256 nowTime = now; require(nowTime >= nextTime.sub(timeLimit) && nowTime <= nextTime.sub(timeLimit).add(getAbonusTimeLimit)); require(getMapping[times.sub(1)][address(msg.sender)] != true); uint256 nestAmount = baseMapping.checkAmount(address(msg.sender)); require(nestAmount > 0); require(nestAllValue > 0); uint256 selfEth = nestAmount.mul(ethNum).div(nestAllValue); require(selfEth > 0); getMapping[times.sub(1)][address(msg.sender)] = true; abonusContract.getETH(selfEth, address(msg.sender)); //然后将上面转到abonusContract通过Abonus合约里面的getETH发送到申请分红人的地址里面。 //之所以分两步,是因为这样最安全。 } //转币,是一个私有函数,用于往分红池转账 function levelingResult() private { abonusContract.getETH(abonusContract.getETHNum().mul(levelingProportion).div(100), address(nestLeveling)); uint256 miningAmount = allValue().div(100000000 ether); uint256 minimumAbonus = expectedMinimum; for (uint256 i = 0; i < miningAmount; i++) { minimumAbonus = minimumAbonus.add(minimumAbonus.mul(expectedIncrement).div(100)); } uint256 nowEth = abonusContract.getETHNum(); if (nowEth < minimumAbonus) { nestLeveling.tranEth(minimumAbonus.sub(nowEth), address(abonusContract)); //这个表示的是从nestLeveling里面转eth币出来,到abonusContract合约地址里面 } } //证据分红池内容,具体怎么样没看懂。 function reloadTimeAndMapping() private { uint256 nowTime = now; if (nowTime >= nextTime) { levelingResult(); uint256 time = (nowTime.sub(nextTime)).div(timeLimit); uint256 startTime = nextTime.add((time).mul(timeLimit)); uint256 endTime = startTime.add(getAbonusTimeLimit); if (nowTime >= startTime && nowTime <= endTime) { nextTime = getNextTime(); times = times.add(1); ethNum = abonusContract.getETHNum(); nestAllValue = allValue(); } } } //获取池子信息 function getInfo() public view returns (uint256 _nextTime, uint256 _getAbonusTime, uint256 _ethNum, uint256 _nestValue, uint256 _myJoinNest, uint256 _getEth, uint256 _allowNum, uint256 _leftNum, bool allowAbonus) { } ``` # 放在后面的话 这方面内容一直很零散,大概写了半年多,都快忘的差不多了。我会在后面慢慢的修改和补充,让看起来更加的完整。 我们在下一节将对剩下的几个合约做介绍。

返回总章 我们上一篇文章对NESTtoken与IBMapping做了解析,本文则对NEST_MiningSave,NESTAbonus继续进行解析。

什么是modifier

首先说一下modifier在solidity中做的是什么工作。简单说就是给继承这个modifier修饰的function加上一个特定的约束

  modifier isOwner() {
     if (msg.sender != owner) {
          throw;
      }
      _; // 继续执行余下的代码体(其实就是isOwner里的实际代码)
  }

  doSomething() isOwner {
    // 将会检查调用者是不是Owner

    // code
  }

NEST_MiningSave的前置条件

NEST_MiningSave.sol是矿池合约。这个内容相对来说比较简单,看源码解析部分即可,最主要的内容是给挖矿函数调用转账用的。 整个合约都在NEST_MiningSave当中: 从nesttoken里面引出了ERC20,从ibmapping里面引出了IBMapping;主要内容是NEST_MiningSave,里面首先是对前面两个合约的初始化。 这里注意的是,需要在IBMapping里面设置一些对应的智能合约地址。所以安装本合约需要两个前置条件。 1, 在IBMapping里面设置nest对应的token智能合约地址 2, 在IBMapping里面设置miningCalculation对应的智能合约地址。

NEST_MiningSave流程

1.初始化合约,默认输入是IBMapping对应的合约地址(特别注意) 2.将IBMapping里面找到nest(就是token合约)对应的合约地址 3.modifier onlyOwner()检测是否是超级用户,不是则不执行 4.modifier onlyMiningCalculation(),检测是否是挖矿计算器(mappingContract.checkAddress) 这里需要特别注意,orePoolLogic.sol对应的应该就是miningCalculation。 由于本节的初始化并不需要orePoolLogic.sol,而orePoolLogic.sol的初始化需要orePoolLogic.sol,因此,我们认为,这个挖矿存储是先编译的,而orePoolLogic.sol是后编译的。 5.changeMapping,超级用户权限才能使用。修改IBMapping合约地址,并重置token地址(这应该是用于token分叉的) 6.关于turnOut

function turnOut(uint256 amount, address to) public onlyMiningCalculation returns(uint256) {
//先检查是否是挖矿计算器智能合约
        uint256 leftNum = nestContract.balanceOf(address(this));
//获取这个合约里面还有多少币
        if (leftNum >= amount) {
            nestContract.transfer(to, amount);
            return amount;
        } else {
            return 0;
//如果取的值比合约里面的少,则传输,否则返回0.
        }
    }

解释:首先检测是否是挖矿计算器地址。如果是是如果调用的的剩余token数量够,则往某地址转账(前提是已经通过了approve的授权) 这个函数显然是给挖矿函数调用转账用的。也是本智能合约最主要的内容。

NESTAbonus

NESTAbonus是分红合约,包含四个合约——分红nest锁仓,分红池合约,平准合约,分红逻辑合约。 NESTAbonus的结构很清晰,但源码阅读起来还是很难的,我就是尽量的说。 分红逻辑合约,就是NESTAbonus本身的初始化。这次初始化比较复杂,需要五个合约的前置。其中tokn,mapping在上一节已经讲完了;nestsave(分红池锁仓),abonus(分红池合约),nestleving(平准合约),这三个合约都在本文件里面。 分红池锁仓,也就是分红的nest池子; 分红池合约,也就是eth的分红池子; 平准合约,与前一个的区别是,第一个转账金额大则失败,而后面是转账金额大则一次性去除。后者是平仓,拿出所有eth用的,用于紧急情况。 总的功能就是存nest;取nest;第一次从nestleving 取eth到NESTAbonus,然后再取到用户地址(由NESTAbonus的getETH函数完成)。注意,除了token合约里面出现100亿外,这里也出现了。 简单总结,这四个函数有一个很有意思的特点,就是对于eth怎么存进去的没有提,我感觉是挖矿的手续费直接存入,以及其他的直接存入。 我在下面对几个合约进行更加详细的描述。 ps1:if(msg.sender == tx.origin)如果调用者是一个账户,上面的条件永远是True。如果是合约账户,则条件就为False. ps2:在一个简单的调用链中,A->B->C->D,D里面的msg.sender将会是C,而tx.origin将一直是A。

NESTSave——分红池锁仓合约

说明:将nest进行存储的合约。

contract NESTSave {
    using SafeMath for uint256;
    mapping (address => uint256) baseMapping;                   //  General ledger
    IBNEST nestContract;                                        //  Nest contract
    IBMapping mappingContract;                                  //  Mapping contract 

    /**
    * @dev Initialization method
    * @param map Mapping contract address
    */
    constructor(address map) public {
        mappingContract = IBMapping(map); 
        //一个IBMapping的合约地址导入
        nestContract = IBNEST(address(mappingContract.checkAddress("nest")));
        //一个token合约的导入
    }

    /**
    * @dev Change mapping contract
    * @param map Mapping contract address
    改变映射地址
    */
    function changeMapping(address map) public onlyOwner{
        mappingContract = IBMapping(map); 
        nestContract = IBNEST(address(mappingContract.checkAddress("nest")));
    }

    /**
    * @dev Take out nest
    * @param num Quantity taken out
    转出
    */
    function takeOut(uint256 num) public onlyContract {
        require(isContract(address(tx.origin)) == false);          
        require(num &lt;= baseMapping[tx.origin]);
        baseMapping[address(tx.origin)] = baseMapping[address(tx.origin)].sub(num);
        nestContract.transfer(address(tx.origin), num);
    }

    /**
    * @dev Deposit in nest
    * @param num Deposit quantity
    转入
    */
    function depositIn(uint256 num) public onlyContract {
        require(isContract(address(tx.origin)) == false);                               
        require(nestContract.balanceOf(address(tx.origin)) >= num);                     
        require(nestContract.allowance(address(tx.origin), address(this)) >= num);      
        require(nestContract.transferFrom(address(tx.origin),address(this),num));       
        baseMapping[address(tx.origin)] = baseMapping[address(tx.origin)].add(num);
    }

    /**
    * @dev Take out all
    转入者自行转出
    */
    function takeOutPrivate() public {
        require(isContract(address(msg.sender)) == false);          
        require(baseMapping[msg.sender] > 0);
        nestContract.transfer(address(msg.sender), baseMapping[msg.sender]);
        baseMapping[address(msg.sender)] = 0;
    }
    //查询某个地址在池子里有多少nest
    function checkAmount(address sender) public view returns(uint256) {
        return baseMapping[address(sender)];
    }

    modifier onlyOwner(){
        require(mappingContract.checkOwners(msg.sender) == true);
        _;
    }

    modifier onlyContract(){
        require(mappingContract.checkAddress("nestAbonus") == msg.sender);
        _;
    }

    function isContract(address addr) public view returns (bool) {
        uint size;
        assembly { size := extcodesize(addr) }
        return size > 0;
    }
}

Abonus——分红池合约

分红池合约,说白了就是分红。

contract Abonus {
    using address_make_payable for address;
    IBMapping mappingContract;                                  //  Mapping contract

    /**
    * @dev Initialization method
    * @param map Mapping contract address
    */
    constructor(address map) public {
        mappingContract = IBMapping(map);
    }

    /**
    * @dev Change mapping contract
    * @param map Mapping contract address
    很重要的一个函数,就是更改mapping的地址
    */
    function changeMapping(address map) public onlyOwner{
        mappingContract = IBMapping(map);
    }

    /**
    * @dev Draw ETH
    * @param num Draw amount
    * @param target Transfer target
    提以太坊,特别注意,只有nestAbonus才能提币
    */

    function getETH(uint256 num, address target) public onlyContract {
        require(num &lt;= getETHNum());
        address payable addr = target.make_payable();
        //返回一个可支付地址赋值给addr
        addr.transfer(num);
        //发送num到addr。
    }

    //获悉本地址在这个池子里面有多少eth
    function getETHNum() public view returns (uint256) {
        return address(this).balance;
    }

    modifier onlyContract(){
        require(mappingContract.checkAddress("nestAbonus") == msg.sender);
        _;
    }

    modifier onlyOwner(){
        require(mappingContract.checkOwners(msg.sender) == true);
        _;
    }

    function () external payable {

    }
}

NESTLeveling——平准合约

contract NESTLeveling {
    using address_make_payable for address;
    IBMapping mappingContract;                              //  Mapping contract

    /**
    * @dev Initialization method
    * @param map Mapping contract address
    */
    constructor (address map) public {
        mappingContract = IBMapping(map); 
    }

    /**
    * @dev Change mapping contract
    * @param map Mapping contract address
    */
    function changeMapping(address map) public onlyOwner {
        mappingContract = IBMapping(map); 
    }

    /**
    * @dev Transfer ETH
    * @param amount Transfer quantity
    * @param target Transfer target
    给某个地址转账eth,发送者必须是nestAbonus才行。
    */
    function tranEth(uint256 amount, address target) public {
        require(address(msg.sender) == address(mappingContract.checkAddress("nestAbonus")));
        uint256 tranAmount = amount;
        if (amount > address(this).balance) {
            tranAmount = address(this).balance;
        }
        address payable addr = target.make_payable();
        addr.transfer(tranAmount);
    }
    //这个this说的是NESTLeveling对应的自身地址,而eth就是存储在这里的。

    function () external payable {

    }

    modifier onlyOwner(){
        require(mappingContract.checkOwners(msg.sender) == true);
        _;
    }
}

NESTAbonus——分行逻辑合约

contract NESTAbonus {
    using address_make_payable for address;
    using SafeMath for uint256;
    IBNEST nestContract;
    IBMapping mappingContract;                  
    NESTSave baseMapping;
    Abonus abonusContract;
    NESTLeveling nestLeveling;
    uint256 timeLimit = 168 hours;                                  //  Dividend period
    //分红时间段
    uint256 nextTime = 1587700800;                                  //  Next dividend time
    //下一次分红时间
    uint256 getAbonusTimeLimit = 60 hours;                          //  Trigger calculation settlement time
    //获取奖金的时间限制
    uint256 ethNum = 0;                                             //  ETH amount
    //eth的数量
    uint256 nestAllValue = 0;                                       //  Nest circulation
    //nest的价值
    uint256 times = 0;                                              //  Dividend book
    //分红时间
    uint256 expectedIncrement = 3;                                  //  Expected dividend increment proportion
    //预期股利增加比例
    uint256 expectedMinimum = 100 ether;                            //  Expected minimum dividend
    //预期最小分红
    uint256 levelingProportion = 10;                                //  Proportion of dividends deducted
    //股息扣除比例
    mapping(uint256 => mapping(address => bool)) getMapping;        //  Dividend collection record
    //股息搜集记录
    /**
    * @dev Initialization method
    * @param map Mapping contract address
    */
    constructor (address map) public {
        mappingContract = IBMapping(map); 
        nestContract = IBNEST(address(mappingContract.checkAddress("nest")));
        baseMapping = NESTSave(address(mappingContract.checkAddress("nestSave")));
        address payable addr = address(mappingContract.checkAddress("abonus")).make_payable();
        abonusContract = Abonus(addr);
        address payable levelingAddr = address(mappingContract.checkAddress("nestLeveling")).make_payable();
        nestLeveling = NESTLeveling(levelingAddr);
    }

    /**
    * @dev Change mapping contract
    * @param map Mapping contract address
    修改mapping及其下面的合约,算上mapping,一共更改5个合约,其中nest是token,剩下三个都是本合约里面的结构体。
    */
    function changeMapping(address map) public onlyOwner {
        mappingContract = IBMapping(map); 
        nestContract = IBNEST(address(mappingContract.checkAddress("nest")));
        baseMapping = NESTSave(address(mappingContract.checkAddress("nestSave")));
        address payable addr = address(mappingContract.checkAddress("abonus")).make_payable();
        abonusContract = Abonus(addr);
        address payable levelingAddr = address(mappingContract.checkAddress("nestLeveling")).make_payable();
        nestLeveling = NESTLeveling(levelingAddr);
    }

    /**
    * @dev Deposit in nest
    存入
    * @param amount Deposit quantity

    */
    function depositIn(uint256 amount) public {
        require(address(tx.origin) == address(msg.sender));  
            //如果调用者是一个账户,上面的条件永远是True。如果是合约账户,则条件就为False.
        uint256 nowTime = now;
        if (nowTime &lt; nextTime) {
            require(!(nowTime >= nextTime.sub(timeLimit) && nowTime &lt;= nextTime.sub(timeLimit).add(getAbonusTimeLimit)));
        } else {
            require(!(nowTime >= nextTime && nowTime &lt;= nextTime.add(getAbonusTimeLimit)));
            uint256 time = (nowTime.sub(nextTime)).div(timeLimit);
            uint256 startTime = nextTime.add((time).mul(timeLimit));        
            uint256 endTime = startTime.add(getAbonusTimeLimit);        
            require(!(nowTime >= startTime && nowTime &lt;= endTime));
        }
        baseMapping.depositIn(amount);  
        //经过了一系列的时间判断后,调用NESTSave转入的命令(通过NESTAbonus身份),然后用用户的身份运行
        //在一个简单的调用链中,A->B->C->D,D里面的msg.sender将会是C,而tx.origin将一直是A。
    }

    /**
    * @dev Take out nest
    取出nest
    * @param amount Quantity taken out
    */
    function takeOut(uint256 amount) public {
        require(address(tx.origin) == address(msg.sender));          
        require(amount != 0);                                      
        require(amount &lt;= baseMapping.checkAmount(address(msg.sender)));
        baseMapping.takeOut(amount);                           
    }                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           

    /**
    * @dev Receive dividend
    发币减值
    */
    function getETH() public {
        require(address(tx.origin) == address(msg.sender));        
        reloadTimeAndMapping ();        
        //时间校验,并提出来eth到abonusContract
        uint256 nowTime = now;
        require(nowTime >= nextTime.sub(timeLimit) && nowTime &lt;= nextTime.sub(timeLimit).add(getAbonusTimeLimit));
        require(getMapping[times.sub(1)][address(msg.sender)] != true);       
        uint256 nestAmount = baseMapping.checkAmount(address(msg.sender));
        require(nestAmount > 0);
        require(nestAllValue > 0);
        uint256 selfEth = nestAmount.mul(ethNum).div(nestAllValue);
        require(selfEth > 0);
        getMapping[times.sub(1)][address(msg.sender)] = true;
        abonusContract.getETH(selfEth, address(msg.sender));     
        //然后将上面转到abonusContract通过Abonus合约里面的getETH发送到申请分红人的地址里面。
        //之所以分两步,是因为这样最安全。
    }
    //转币,是一个私有函数,用于往分红池转账
    function levelingResult() private {
        abonusContract.getETH(abonusContract.getETHNum().mul(levelingProportion).div(100), address(nestLeveling));
        uint256 miningAmount = allValue().div(100000000 ether);
        uint256 minimumAbonus = expectedMinimum;
        for (uint256 i = 0; i &lt; miningAmount; i++) {
            minimumAbonus = minimumAbonus.add(minimumAbonus.mul(expectedIncrement).div(100));
        }
        uint256 nowEth = abonusContract.getETHNum();
        if (nowEth &lt; minimumAbonus) {
            nestLeveling.tranEth(minimumAbonus.sub(nowEth), address(abonusContract));
            //这个表示的是从nestLeveling里面转eth币出来,到abonusContract合约地址里面
        }
    }

    //证据分红池内容,具体怎么样没看懂。
    function reloadTimeAndMapping() private {
        uint256 nowTime = now;
        if (nowTime >= nextTime) {                                          
            levelingResult();
            uint256 time = (nowTime.sub(nextTime)).div(timeLimit);
            uint256 startTime = nextTime.add((time).mul(timeLimit));      
            uint256 endTime = startTime.add(getAbonusTimeLimit);           
            if (nowTime >= startTime && nowTime &lt;= endTime) {
                nextTime = getNextTime();                                   
                times = times.add(1);                                   
                ethNum = abonusContract.getETHNum();                    
                nestAllValue = allValue();                              
            }
        }
    }

    //获取池子信息
    function getInfo() public view returns (uint256 _nextTime, uint256 _getAbonusTime, uint256 _ethNum, uint256 _nestValue, uint256 _myJoinNest, uint256 _getEth, uint256 _allowNum, uint256 _leftNum, bool allowAbonus)  {

}

放在后面的话

这方面内容一直很零散,大概写了半年多,都快忘的差不多了。我会在后面慢慢的修改和补充,让看起来更加的完整。 我们在下一节将对剩下的几个合约做介绍。

区块链技术网。

  • 发表于 2021-01-28 19:35
  • 阅读 ( 641 )
  • 学分 ( 9 )
  • 分类:NEST

评论