关于nest2.0智能合约的架构解析二(NESTtoken与IBMapping)

我们上一篇文章对nest2.0整体架构做了一个说明,本文则对每个文件进行进一步的解释。

返回总章 我们上一篇文章对nest2.0整体架构做了一个说明,本文则对每个文件进行进一步的解释。

前言

nest2.0一共七个文件在上一篇文章里面已经说过了。其中最重要的两个文件是token部分和合约映射部分。前者是nest的token基石,而后者则为了nest合约的灵活升级做了准备。我们在本文对这两个合约做简要的解释。 我们通过对合约地址的查询可以看到。最早的NESTtoken,也就是IBNEST,这个合约是2019年5月份部署的;而后面的几个合约都是2020年上半年部署的;这就是为什么整个nest2.0看起来似乎很不太协调,因为整个项目的跨度达到了一年左右

1.基本概念——mapping

先特别说明一下,在nest2.0里面的很多地方都用到了mapping。我在这里简单的讲一下。 solidity里的映射可以理解为python里的字典,建立键-值的对应关系,可以通过键来查找值,键必须是唯一的,但值可以重复。

定义方式为:mapping(键类型=>值类型),例如mapping(address=>uint) public balances,这个映射的名字是balances,权限类型为public,键的类型是地址address,值的类型是整型uint,在solidity中这个映射的作用一般是通过地址查询余额。键的类型允许除映射外的所有类型。 maping是根据定义的类型确定名次mapping(a=>b) mmm。表示mmm是一个数组名字,其数组类型是a,赋值的类型是b。

例如:映射balances中包括三个键值对(user1:100,user2:145,user3:195),输入user2即可得到145

下面来看一个例子:

contract MappingExample{
    mapping(address => uint) public balances;
    function update(uint amount) returns (address addr){
        balances[msg.sender] = amount;
        return msg.sender;
    }
}

说明:定义balances为一个映射,msg.sender是合约创建者的地址,函数update有一个整型参数amount(数量), balances[msg.sender]=amount的意思是将参数amount的值和msg.sender这个地址对应起来。 好了,接下来我们说两个合约,NESTtoken和IBMapping。

2. NESTtoken

NESTtoken基于的是IBNEST.sol 基本上就是一个erc20,没有什么特别额外的功能。这个里面唯一值得注意的是library IterableMapping 。 library IterableMapping 在这里起到了一个顺序可查询与删除的功能。

3. IBMapping

然后是IBMapping。主要是三个功能: 第一个功能是制作一个智能合约映射图; 第二个功能是在初始化中,将创建者的地址设置为管理员用户,并提供修改和查询功能; 第三个功能是提供智能合约映射的修改和查询。 我们一个个说。

3.1 Superman

我们注意到的第一个内容就是Superman(超级管理者)。

mapping (address => bool) owners;                                       //  Superman address
    /**
    * @dev Initialization method
    */
    constructor () public {
        owners[msg.sender] = true;
    }

所有者是一个数组。智能合约的构造者就是所有者里面的真。

3.2 地址对应

function addContractAddress(string memory name, address contractAddress) public {
        require(checkOwners(msg.sender) == true);
        ContractAddress[name] = contractAddress;
    }

这个表示的是,发送者的所有者权限有效,那么将ContractAddress里面name赋值为contractAddress) ,说白了就是将两者对应起来。 这是一个非常关键的内容,应该学习。

3.3 合约引用

首先添加在要引用的合约里面结构体和函数

contract IBMapping {
    function checkAddress(string memory name) public view returns (address contractAddress);
    function checkOwners(address man) public view returns (bool);
}

在要执行的结构体里面定义这个结构体

IBMapping mappingContract; 

然后在要执行的结构体里面初始化

 constructor(address map) public {
        mappingContract = IBMapping(map); 
                //这句是对外部地址map进行结构体定义,这里定义的是IBMapping.sol的合约地址。

并将map里面的IBMapping与mappingContract 对接,也就是找到智能合约对接表。

        nestContract = IBNEST(address(mappingContract.checkAddress("nest")));
    mappingContract.checkAddress("nest")=addrnest
//这个获取的是nest对应的合约地址

3.4 关于合约映射与引用的说明

关于合约映射与引用源码部分还有三个说明。 首先之所以做成这样是,是为了可以随时升级合约地址的位置。 其次,为了便于管理,将检测到的合约地址对接如下: address(addrnest)表示显式转换,因此就是nestContract 获得的是token的合约地址。 最后,一个addr不用转换因为默认就是addr,第二个因为是从列表里读的,所以从address payable转换为address。区别在于,前者地址可用.transfer()和.send()方法,后者不可以,防止越权。但不不意味着mappingContract 和nestContract 不是payable类型。

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

0 条评论

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