nest3.0从架构解析到克隆二(从token到mapping)

nest3.0相对于2.0做了全新的开发,尽管里面的很多源码都是复用的,但结构发生了翻天覆地的变化。其中一共非常关键的内容就是mapping的变化。本文将从token讲到mapping,并对其源码进行中文注释。帮助阅读者从框架上掌握更多的内容。

返回总章 我们在上篇文章对nest3.0的架构做了一下解析,我们在本文继续讲解。 nest3.0相对于2.0做了全新的开发,尽管里面的很多源码都是复用的,但结构发生了翻天覆地的变化。其中一共非常关键的内容就是mapping的变化。

IBNEST与token设计

NEST的token是在2019年就设计完毕了。其宣传的是报价挖矿得币,猛一看有点像比特币,但其实区别非常的大。NEST的token在早期就一次性都出来了,只不过是存在一个专门的地址,而每一次的报价就通过函数调用而获得一次打款。 这种灵活的方式其实非常值得借鉴,就是我们在做很多token的时候,不一定太依赖于某种新的方案。我们往往采用的是成熟的方案,与折中的行为来完成。

Nest_3_VoteFactory与mapping

预言机是一套非常复杂的智能合约,如何来进行相关合约的升级呢?在nest2.0当中有一个专门的mapping来存储这些合约的地址。简单说就是,当某一个合约升级后,将其对应的合约地址更新一下就可以了。 但在nest3.0里面却找不到这个mapping了。其实这只是层窗户纸罢了,我在这里告诉大家,只是换了个地方,改了一个名字而已。 现在合约名称叫Nest_3_VoteFactory,位于VoteContract里面的Nest_3_VoteFactory.sol文件。

Nest_3_VoteFactory的结构

主要分四部分: 第一部分是基本定义,对需要的相关变量进行定义; 第二部分是做智能合约的映射,以及各种权限的修改; 第三部分是进行投票的设定和使用; 第四部分是紧急事件处理;

Nest_3_VoteFactory的变量定义

   using SafeMath for uint256;

    uint256 _limitTime = 7 days;                                    //  Vote duration投票持续时间
    uint256 _NNLimitTime = 1 days;                                  //  NestNode raising time NestNode筹集时间
    uint256 _circulationProportion = 51;                            //  Proportion of votes to pass 通过票数比例
    uint256 _NNUsedCreate = 10;                                     //  The minimum number of NNs to create a voting contract创建投票合约最小 NN 数量
    uint256 _NNCreateLimit = 100;                                   //  The minimum number of NNs needed to start voting开启投票需要筹集 NN 最小数量
    uint256 _emergencyTime = 0;                                     //  The emergency state start time紧急状态启动时间
    uint256 _emergencyTimeLimit = 3 days;                           //  The emergency state duration紧急状态持续时间
    uint256 _emergencyNNAmount = 1000;                              //  The number of NNs required to switch the emergency state切换紧急状态需要nn数量
    ERC20 _NNToken;                                                 //  NestNode Token守护者节点Token(NestNode)
    ERC20 _nestToken;                                               //  NestToken
    mapping(string => address) _contractAddress;                    //  Voting contract mapping投票合约映射
    mapping(address => bool) _modifyAuthority;                      //  Modify permissions修改权限
    mapping(address => address) _myVote;                            //  Personal voting address我的投票
    mapping(address => uint256) _emergencyPerson;                   //  Emergency state personal voting number紧急状态个人存储量
    mapping(address => bool) _contractData;                         //  Voting contract data投票合约集合
    bool _stateOfEmergency = false;                                 //  Emergency state紧急状态
    address _destructionAddress;                                    //  Destroy contract address销毁合约地址

Nest_3_VoteFactory的合约映射

这个里面主要是3个内容。 第一个是修改超级用户; 第二个是增加智能合约地址与name的对应; 第三个是将相关的智能合约进行刷新。

    constructor () public {
        _modifyAuthority[address(msg.sender)] = true;
        //将修改权限者(也叫超级用户)。
    }
    /** nest
    * @dev Reset contract
    重置合约
    */
    function changeMapping() public onlyOwner {
        _NNToken = ERC20(checkAddress("nestNode"));
        _destructionAddress = address(checkAddress("nest.v3.destruction"));
        _nestToken = ERC20(address(checkAddress("nest")));
    }
    //这个地方刷新nestnode,nest.v3.destruction,以及nestnode
   //  Check address
    function checkAddress(string memory name) public view returns (address contractAddress) {
        return _contractAddress[name];
    }
    //查看合约地址

    //  Add contract mapping address
    function addContractAddress(string memory name, address contractAddress) public onlyOwner {
        _contractAddress[name] = contractAddress;
    }
    //将合约名称与地址对应

    //  Add administrator address 
    function addSuperMan(address superMan) public onlyOwner {
        _modifyAuthority[superMan] = true;
    }
    //增加管理地址

    function addSuperManPrivate(address superMan) private {
        _modifyAuthority[superMan] = true;
    }

    //  Delete administrator address
    //删除管理地址
    function deleteSuperMan(address superMan) public onlyOwner {
        _modifyAuthority[superMan] = false;
    }
    function deleteSuperManPrivate(address superMan) private {
        _modifyAuthority[superMan] = false;
    }
    //解除合约管理员权限

    //  Delete voting contract data
    //删除投票合约集合
    function deleteContractData(address contractAddress) public onlyOwner {
        _contractData[contractAddress] = false;
    }

    //  Check whether the administrator
    //查看是否管理员
    function checkOwners(address man) public view returns (bool) {
        return _modifyAuthority[man];
    }

    //  Administrator only
    //仅管理员操作
    modifier onlyOwner() {
        require(checkOwners(msg.sender), "No authority");
        _;
    }

Nest_3_VoteFactory的投票管理

主要是三个内容: 1.创建普通投票 2.创建NN投票 3.查看投票

   /**
    * @dev Create voting contract
    创建投票合约
    * @param implementContract The executable contract address for voting
    投票可执行合约地址
    * @param nestNodeAmount Number of NNs to pledge
    质押 NN 数量
    */
    function createVote(address implementContract, uint256 nestNodeAmount) public {
        require(address(tx.origin) == address(msg.sender), "It can't be a contract");
        require(nestNodeAmount >= _NNUsedCreate);
        Nest_3_VoteContract newContract = new Nest_3_VoteContract(implementContract, _stateOfEmergency, nestNodeAmount);
        //建立一个新的投票,这里主要是初始化一个Nest_3_VoteContract结构体
        require(_NNToken.transferFrom(address(tx.origin), address(newContract), nestNodeAmount), "Authorization transfer failed");
        //传输nn数量
        _contractData[address(newContract)] = true;
        //新投票成立
        emit ContractAddress(address(newContract));
        //监听新合约地址事件
    }

    /**
    * @dev Use NEST to vote
    使用nest投票
    * @param contractAddress Vote contract address
    投票合约地址
    */
    function nestVote(address contractAddress) public {
        require(address(msg.sender) == address(tx.origin), "It can't be a contract");
        require(_contractData[contractAddress], "It's not a voting contract");
        //先检测地址是否合法
        require(!checkVoteNow(address(msg.sender)));
        //如果投票未结束,或者发送者投票为0则继续
        //检查投票者
        Nest_3_VoteContract newContract = Nest_3_VoteContract(contractAddress);
        //建立一个用于投票的合约
        newContract.nestVote();
        //投票
        _myVote[address(tx.origin)] = contractAddress;
        //我的投票地址为contractAddress
    }

    /**
    * @dev Vote using NestNode Token
    使用 nestNode 投票
    * @param contractAddress Vote contract address
    投票合约地址
    * @param NNAmount Amount of NNs to pledge
    质押 NN 数量
    */
    function nestNodeVote(address contractAddress, uint256 NNAmount) public {
        require(address(msg.sender) == address(tx.origin), "It can't be a contract");
        require(_contractData[contractAddress], "It's not a voting contract");
        Nest_3_VoteContract newContract = Nest_3_VoteContract(contractAddress);
        //建立一个用于投票的合约
        require(_NNToken.transferFrom(address(tx.origin), address(newContract), NNAmount), "Authorization transfer failed");
        //将币传输到合约地址
        newContract.nestNodeVote(NNAmount);
    }

    /**
    * @dev Excecute contract
    执行投票
    * @param contractAddress Vote contract address
    投票合约地址
    */
    function startChange(address contractAddress) public {
        require(address(msg.sender) == address(tx.origin), "It can't be a contract");
        require(_contractData[contractAddress], "It's not a voting contract");
        Nest_3_VoteContract newContract = Nest_3_VoteContract(contractAddress);
        //获得这个地址的智能合约
        require(_stateOfEmergency == newContract.checkStateOfEmergency());
        //检测是不是状态一致
        addSuperManPrivate(address(newContract));
        //使得这个地址获取超级用户权力
        newContract.startChange();
        //运行(但目前没有这个接口文件)
        deleteSuperManPrivate(address(newContract));
        //解除超级用户权限
    }
    /**
    * @dev Check my voting
    查看我的投票
    * @param user Address to check
    参与投票地址
    * @return address Address recently participated in the voting contract address
    是否正在参与投票
    */
    function checkMyVote(address user) public view returns (address) {
        return _myVote[user];
    }

    //  Check the voting time
    //检查投票时间
    function checkLimitTime() public view returns (uint256) {
        return _limitTime;
    }

Nest_3_VoteFactory紧急事件处理

一般出现了严重的问题,比如token出现严重bug,或者有大量的币被盗,才启用。 一般来说,需要守护者节点2/3以上的同意才行。 基本原则就是快速完成映射,然后锁死合约。

    /**
    * @dev Switch emergency state-transfer in NestNode Token
    切换紧急状态-转入NestNode
    * @param amount Amount of NNs to transfer
    转入 NestNode 数量
    */
    function sendNestNodeForStateOfEmergency(uint256 amount) public {
        //单独调用的函数
        require(_NNToken.transferFrom(address(tx.origin), address(this), amount));
        //用户将自己的nn转入到这个合约地址里面
        _emergencyPerson[address(tx.origin)] = _emergencyPerson[address(tx.origin)].add(amount);
        //_emergencyPerson数组里面的该地址的nn增加。
    }

    /**
    * @dev Switch emergency state-transfer out NestNode Token
    切换紧急状态-取出NestNode
    */
    function turnOutNestNodeForStateOfEmergency() public {
        require(_emergencyPerson[address(tx.origin)] > 0);
        require(_NNToken.transfer(address(tx.origin), _emergencyPerson[address(tx.origin)]));
        //检测本地址是否应该有币要转移,然后把nn转移到本地址
        _emergencyPerson[address(tx.origin)] = 0;
        uint256 nestAmount = _nestToken.balanceOf(address(this));
        //检测本地址有多少nest
        require(_nestToken.transfer(address(_destructionAddress), nestAmount));
        //一并销毁
    }

    /**
    * @dev Modify emergency state
    修改紧急状态
    */
    function changeStateOfEmergency() public {
        if (_stateOfEmergency) {
            require(now > _emergencyTime.add(_emergencyTimeLimit));
            //now为当前时间戳
            _stateOfEmergency = false;
            _emergencyTime = 0;
            //如果为紧急状态,看是否结束,结束则赋值为false
        } else {
            require(_emergencyPerson[address(msg.sender)] > 0);
            //本人是否为注册
            require(_NNToken.balanceOf(address(this)) >= _emergencyNNAmount);
            //总量是否达标,
            _stateOfEmergency = true;
            //然后就执行
            _emergencyTime = now;
            //
        }
    }
   //  Check the NestNode raising time
    //查看NestNode筹集时间
    function checkNNLimitTime() public view returns (uint256) {
        return _NNLimitTime;
    }

    //  Check the voting proportion to pass
    //查看通过投票比例
    function checkCirculationProportion() public view returns (uint256) {
        return _circulationProportion;
    }

    //  Check the minimum number of NNs to create a voting contract
    //查看创建投票合约最小 NN 数量
    function checkNNUsedCreate() public view returns (uint256) {
        return _NNUsedCreate;
    }

    //  Check the minimum number of NNs raised to start a vote
    //查看创建投票筹集 NN 最小数量
    function checkNNCreateLimit() public view returns (uint256) {
        return _NNCreateLimit;
    }

    //  Check whether in emergency state
    //查看是否是紧急状态
    function checkStateOfEmergency() public view returns (bool) {
        return _stateOfEmergency;
    }

    //  Check the start time of the emergency state
    //查看紧急状态启动时间
    function checkEmergencyTime() public view returns (uint256) {
        return _emergencyTime;
    }

    //  Check the duration of the emergency state
    //查看紧急状态持续时间
    function checkEmergencyTimeLimit() public view returns (uint256) {
        return _emergencyTimeLimit;
    }

    //  Check the amount of personal pledged NNs
    //查看个人 NN 存储量
    function checkEmergencyPerson(address user) public view returns (uint256) {
        return _emergencyPerson[user];
    }

    //  Check the number of NNs required for the emergency
    // 查看紧急状态需要 NN 数量
    function checkEmergencyNNAmount() public view returns (uint256) {
        return _emergencyNNAmount;
    }

    //  Verify voting contract data
    //验证投票合约
    function checkContractData(address contractAddress) public view returns (bool) {
        return _contractData[contractAddress];
    }

    //  Modify voting time
    //修改投票时间
    function changeLimitTime(uint256 num) public onlyOwner {
        require(num > 0, "Parameter needs to be greater than 0");
        _limitTime = num;
    }

    //  Modify the NestNode raising time
    //修改NestNode筹集时间
    function changeNNLimitTime(uint256 num) public onlyOwner {
        require(num > 0, "Parameter needs to be greater than 0");
        _NNLimitTime = num;
    }

    //  Modify the voting proportion
    //修改通过投票比例
    function changeCirculationProportion(uint256 num) public onlyOwner {
        require(num > 0, "Parameter needs to be greater than 0");
        _circulationProportion = num;
    }

    //  Modify the minimum number of NNs to create a voting contract
    //修改创建投票合约最小 NN 数量
    function changeNNUsedCreate(uint256 num) public onlyOwner {
        _NNUsedCreate = num;
    }

    //  Modify the minimum number of NNs to raised to start a voting
    //修改创建投票筹集 NN 最小数量
    function checkNNCreateLimit(uint256 num) public onlyOwner {
        _NNCreateLimit = num;
    }

    //  Modify the emergency state duration
    //修改紧急状态持续时间
    function changeEmergencyTimeLimit(uint256 num) public onlyOwner {
        require(num > 0);
        _emergencyTimeLimit = num.mul(1 days);
    }

    //  Modify the number of NNs required for emergency state
    //修改紧急状态需要 NN 数量
    function changeEmergencyNNAmount(uint256 num) public onlyOwner {
        require(num > 0);
        _emergencyNNAmount = num;
    }

简单总结

Nest_3_VoteFactory是除了报价部分外最重要的部分,他将token,公投,以及合约映射无缝连接到了一起。 我曾经一度奇怪为什么要这么做,把mapping分开单独不可以吗? 后来大概有点明白开发小组的意思了,他们的目的是将紧急处理部分与mapping合在一起,以免最糟糕的情况发生,就是mapping也被黑客掌握了。 而目前的这种情况的,随着后期将所有权限都转交给投票系统后,整个系统将变得更加的安全。

点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

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