就是要学社区 QQ群组:646854445
你并非已无懈可击,所以你不能逃避问题,拒绝学习!

036孤荷凌寒从零开始学区块链第36天以太坊智能合约015

|阅读量:51 |发布于2020-08-30 20:54:38


正文内容

【主要内容】

今天继续使用erc20标准规范按一篇网络博文的教程进行亲自敲打代码来写一个可以发行token的智能合约。学习共用时44分钟。

(此外整理作笔记花费了约53分钟)

详细学习过程见文末学习过程屏幕录像。


【学习笔记】

一、尝试理解approveAndCall()函数内部的操作

https://mp.weixin.qq.com/s/foM1QWvsqGTdHxHTmjczsw

继续按以上博文的指导为主,结合官方中文文档的解释来理解:

(官方中文文档:

https://solidity-cn.readthedocs.io/zh/develop/units-and-global-variables.html?highlight=%20keccak256#id3)

       if(!_spender.call(bytes4(bytes32(sha3("receiveApproval(address,uint256,address,bytes)"))), msg.sender, _value, this, _extraData)) { throw; }

(一)solidity中计算一个对象的哈希值(散列值)的几个函数

1.

keccak256(...) returns (bytes32)

计算参数的Ethereum-SHA-3(Keccak-256)的散列

2.

sha256(...) returns (bytes32)

计算参数的SHA-256散列

3.

sha3(...) returns (bytes32)

keccak256的别名

4.

ripemd160(...) returns (bytes20)

计算参数的RIPEMD-160哈希值


(二)调用一个合约地址所在的智能合约的函数的call方法

在上面的式子中,【_spender】代表的是提供服务的服务合约据的地址,通过调用此地址的call方法,可以调用此节点上的智能合约中的函数。上面式子进行了多次数据类型转换(我的理解是这实际上应当就是编码转换),进而调用了服务智能合约中的用于接受授权的函数【receiveApproval】。

而此函数需要的参数,则在call方法的后面的实参中一一给出。

http://www.chidaolian.com/article-6311-1

这篇博文对call方法的安全问题作了阐述。


(三)我发现其它一些范例,不是使用的通过调用智能合约地址所在的call方法来进行跨智能合约函数调用与交互的。

如:https://mp.weixin.qq.com/s/foM1QWvsqGTdHxHTmjczsw

讲到approveAndCall()方法时的示例如下:

```

function approveAndCall(address _recipient,

                       uint256 _value,

                       bytes _extraData) {

 approve(_recipient, _value);

 TokenRecipient(_recipient).receiveApproval(msg.sender,

                                            _value,

                                            address(this),

                                            _extraData);

}


```

在上面的代码中,对象:

TokenRecipient

其实是一个作为基础合约的抽象合约(即是说,合约的具体函数内部没有可执行代码,只是个空壳,这样的合约只能作为别的合约的基础合约,供其它合约继承使用)

不过声明这个抽象合约时,使用的是interface关键词定义的,而不是通常使用的contract.

通过直接使用

这个抽象合约名(实际的地址)

的方法就可以直接引用到实际地址所在节点上的智能合约

然后就可以直接使用这个智能合约对象.其中的函数()

如上例中的代码所写的那样。

我个人感觉这个写法更好理解一些,不过不知道这是否意味着使用call()方法所产生的安全问题,也被消除了。

博文:https://blog.csdn.net/weixin_34291004/article/details/91902209

对这种写法进行了详细说明。

特别发现:

这个抽象合约的名称可以作为定义一个对象变量的类型来使用,如下面的例子,就来自于上面的博文:

这是一个智能合约的完整内容(虽然很简单,但为了说明问题):

```

//这个合约,作为一个提供服务的智能合约而存在,部署时,只部署InterfaceImplContract这个合约即可。

pragma solidity ^0.4.16;


//下面使用了interface关键词定义了一个抽象合约

interface interfaceContract {

   function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData);

}

//下面使用contract关键词定义了一个智能合约,就继承自抽象合约interfaceContract

contract InterfaceImplContract is interfaceContract {

   event Receive(address from, uint256 value, address token, bytes extraData);

   function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData) {

       Receive(_from,_value,_token,_extraData);

   }

}


```

然后,另一个合约中要和上面的这个合约交互,这个合约的代码如下:

```

pragma solidity ^0.4.16;


//下面使用了interface关键词定义了一个抽象合约

//此抽象合约与上面定义过另一个智能合约(提供服务的服务合约)的声明完全一样,但此时不是用于被别的合约继承,此处它的作用作为一个跨合约的接口而存在。

interface interfaceContract {

   function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData);

}

contract RemoteContract {

   function func(address _addr, uint _value) {

       //注意这里的_addr参数,需要填写tokenRecipient合约的地址。这里加载已经存在的智能合约。如何合约不存在会报错回滚。

       interfaceContract _interfaceContract = interfaceContract(_addr);

       //上面的代码中,作为接口抽象合约的合约名interfaceContract 被作为定义的类型来使用,定义了一个具体的对象_interfaceContract

       //真正直到指明要调用哪个服务合约的定位作用的是实参【_addr】

       //通过给接口合约(就是抽象合约interfaceContract)传递真正的上面的定义过的合约【tokenRecipient】部署后的地址【_addr】

       //就实现了引用合约【tokenRecipient】,然后此时对象【_interfaceContract】就已经代表的是合约【tokenRecipient】了。

       //此时,就可以通过对象【_interfaceContract】来调用合约其中可用的函数了。

       //下一句代码,就调用了合约【tokenRecipient】的方法函数【receiveApproval】

       _interfaceContract.receiveApproval(msg.sender, _value, address(this), "这是一些信息");

   }

}


```


二、今天真正确认solidity语言的一个特别之处:函数可以指定多个返回对象

今天正式确认已了解到,solidity语言的函数定义时,使用的函数返回定义使用的是:

returns

是复数形式,则证实是可以在同一个函数中返回多个返回对象,这在之前学习的其它编程语言中是没有明确注意到的新特性,我个人认为这是非常了不起的创举,很多编程语言不支持同一函数返回多个计算结果给外部调用者,而有的时候,又急切地想要使用这样的效果,没有想到solidity语言真正的直接支持这一特性,非常意外的惊喜。


【今天的自学感悟分享】

随着自学了越来越多的跨界的领域,我发现,这世界上的工作大概分为两种——

有一种是,干得越辛苦,干得越卖力,就会在这条道上陷得越深,然后再没有看到的领域,一旦这个领域消失,就再也无法适应别的道路。

另一种是,在做的过程中,可以不断地升级自己的认知和大脑,使自己见识越来越多的领域,可以在有限的人生中经历更多的可能,有更多的选择。

然而不幸的是,90%的工作是属于第一种的,我也不例外,我看到这可怕的结局,于是我要逃出生天。

这就是我始终在坚持自学的原动力所在,当一个人有了这样的动力的时候,就好像走在一条满是繁花美景的大路向着似乎遥不可及的目标走过去,因为有了这样的动力,所以这些年来,我从来没有停下来留恋于任何一个已经熟悉的生活状态,留恋于路旁也许美丽的风景;因为有了这样的动力,我就知道我不能停下来,不敢停下来。

这就是自学原动力的重大作用,就好像一辆车开始在强大原动力的驱动下开始风驰电掣,哪还可能会被别的什么所拦住而停止下来呢?


【就是要学】社区
一个平等,纯粹的社群
本社群旨在为真正愿意不断学习,终身成长的朋友提供一个平等互助互相鼓励的清洁纯粹的学习交流的平台。
加入社群将获得
1、与真正终身学习者为伍
2、在榜样带领下坚持每天学习,终身成长
3、养成记录时间日志,成功日记的习惯


【就是要学】社区QQ群:646854445





【返回首页】