第22讲 智能合约
Solidity例子
外部账户调用智能合约
一个合约如何调用另一个合约中的函数
第一种 直接调用
第二种 address中的call方法
这两种方式的区别在于:对于错误处理的不同。直接调用中被调用的那个合约执行中如果出现错误,那么会导致调用的那个合约一起发生回滚,例如图中A出现异常,那么会导致B跟着一起抛出异常;而对于第二种方式,如果被调用的合约出现了异常,那么调用的合约中只会返回一个false,发起调用的函数并不会抛出异常,而是可以继续执行。
第三种:delegatecall
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UDYJUuFQ-1601776811312)(http://xwjpics.gumptlu.work/qiniu_picGo/20200715221444.png)]
payable
加上payable指的是该函数需要接受外部转账
fallback函数
其中造成没有任何资金输入时,一旦有人调用此合约且data域为空,那么就会引发异常,所以一般fallback函数都会写上payable
fallback函数在合约设计时不是必须定义的,如果该合约没定义那么如果调用时data域为空那么也会抛出异常。
智能合约的创建和运行
汽油费:
错误处理:
错误处理实例:
收据的数据结构
汽油费
智能合约中能够得到的一些环境状态信息
区块信息:
调用信息:
地址类型
从一个实例开始
拍卖实例:拍卖过程中每个人都可以出价,但是出的价格就需要将相应的以太币转到拍卖合约中锁起来才算有效。当最终出现最高出价后,最高出价会转给拍卖的发起者即受益人,其他竞价都会返还给对应的出价人。
在拍卖竞价的过程中,每次加价只需要补差价即可,将对应的差价转到拍卖合约中。例如第一次出100,转入100ETH,第二次出110,只需要把10ETH转入合约即可。
注意,其他账户每次竞价(调用bid)都是交易,都要发布然后写到区块链里面。
这样有什么问题?
谁来使最终的拍卖结束不知道,Solidity不存在自动执行的函数。
黑客可以利用fallback实现整个拍卖的失败。
**!!!注意:这里的回滚,是回顾到这个拍卖结束函数未执行之前,而不是整个拍卖过程之前(也就是说整个拍卖都没进行过)。**在这个例子中,回滚会导致所有人都拿不到钱。
比如你发布这样的一个拍卖吸引大家来参与,很多人参与竞价,钱都投进去了,但是发布后发现有这样的黑客合约攻击出现,怎么办?
没有办法。code is law,有漏洞也是无法修改的。
改进:
这样就可以吗?
不行,会造成重入攻击
攻击者除第一次是收回自己的出价以外,其他的转回钱都是从合约账户中多转回的别的账户的钱。
递归转钱会一直进行吗?不,结束的条件是:
修改的方法:
send和transfer方式的汽油费2300个单位,只够被调用的合约写一个log。
智能合约中的经典编程模式:
先判断条件 -> 再改变条件 -> 最后与其他账户发生交互