nest3.0相对于2.0做了全新的开发,尽管里面的很多源码都是复用的,但结构发生了翻天覆地的变化。其中一共非常关键的内容就是mapping的变化。本文将从token讲到mapping,并对其源码进行中文注释。帮助阅读者从框架上掌握更多的内容。
返回总章 我们在上篇文章对nest3.0的架构做了一下解析,我们在本文继续讲解。 nest3.0相对于2.0做了全新的开发,尽管里面的很多源码都是复用的,但结构发生了翻天覆地的变化。其中一共非常关键的内容就是mapping的变化。
NEST的token是在2019年就设计完毕了。其宣传的是报价挖矿得币,猛一看有点像比特币,但其实区别非常的大。NEST的token在早期就一次性都出来了,只不过是存在一个专门的地址,而每一次的报价就通过函数调用而获得一次打款。 这种灵活的方式其实非常值得借鉴,就是我们在做很多token的时候,不一定太依赖于某种新的方案。我们往往采用的是成熟的方案,与折中的行为来完成。
预言机是一套非常复杂的智能合约,如何来进行相关合约的升级呢?在nest2.0当中有一个专门的mapping来存储这些合约的地址。简单说就是,当某一个合约升级后,将其对应的合约地址更新一下就可以了。 但在nest3.0里面却找不到这个mapping了。其实这只是层窗户纸罢了,我在这里告诉大家,只是换了个地方,改了一个名字而已。 现在合约名称叫Nest_3_VoteFactory,位于VoteContract里面的Nest_3_VoteFactory.sol文件。
主要分四部分: 第一部分是基本定义,对需要的相关变量进行定义; 第二部分是做智能合约的映射,以及各种权限的修改; 第三部分是进行投票的设定和使用; 第四部分是紧急事件处理;
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销毁合约地址
这个里面主要是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");
_;
}
主要是三个内容: 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;
}
一般出现了严重的问题,比如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也被黑客掌握了。 而目前的这种情况的,随着后期将所有权限都转交给投票系统后,整个系统将变得更加的安全。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!