待字闺中开发了一门区块链方面的课程:《深入浅出ETH原理与智能合约开发》,马良老师讲授。此简书文集记录我的学习笔记。
课程共8节课。其中,前四课讲ETH原理,后四课讲智能合约。
第六课分为三部分:
- Solidity语法之数组
- Solidity语法之合约
- Truffle简介与使用
这篇文章是第六课第二部分的学习笔记:Solidity语法之合约。
第5课第3小节简要介绍了 Solidity 的基础语法。还有两部分重要的内容要重点讲解一下,分别是数组和合约。
这节课主要讲解Solidity合约相关知识,并有若干实例辅助理解。
1、合约相关知识点
合约相关知识点1.1 合约调用
- 合约间接口相互调用
□ address.function(para)
□ address.call(func_signature, para) - 合约之间转账
□ address.transfer()
□ address.send()
□ address.call()
□ - address.call.gas(num).value(num)() 缺省的是使用所有可用的Gas - 调用深度是1024。一般正常情况不会这么多,除非发生递归。
- delegatecode(),主要是调用库函数,但还是在当前函数的上下文环境。(第四课出现过)
1.1 转账需要注意的问题
- 可以收钱的接口需要payable。
- 转账会触发接收账户的fallback函数(payable)。fallback函数,一个匿名函数。
- transfer 仅仅转发2300 gas, 失败会抛出异常。fallback 要非常简单。
- send 仅仅转发2300 gas, 失败只会返回false。fallback 要非常简单。
- call.value(amount)() 会转发全部的可用的gas,失败只会返回false,容易引起重入型攻击。
2、合约相关实例
1、合约间接口调用实例
代码见git仓库,或见下图。
合约间接口调用实例- 打开文件 example_2.sol ,编译。
-
在 run 页面,选择 B_caller ,点击 Deploy 。下面出现三个接口。
B合约的三个接口 - 在调用合约前,先显示一下A的状态值,点 Getstate_A,显示为0。
- 显式调用,点击Invocate_A,再点击 Getstate_A,结果为15,正确。
- call调用。点击 Call_A ,返回值为真。再点击 Getstate_A,结果为23,正确。
特别注意:代码第45行。keccak256在计算签名时,函数的参数要写全称uint256,不要写简称uint,否则会出现问题。因为签名算法是根据字符串算的,它不会自动把简称替换成全称。
1、合约间接口调用实例
合约转账实例- 关闭example_2.sol,打开example_3.sol,(有时需要刷新一下浏览器)
- 编译,或勾上自动编译。
-
在 run 页面,选择 B_caller ,点击 Deploy 。下面出现四个接口。
B合约的三个接口 - 在调用合约前,先显示一下A的状态值,点 Getbalance_A,显示为0。
- Value值输入6666,点击 Transfer_A,再点击 Getbalance_A,结果为6666,正确。
- Value值输入8888,点击 Sender_A ,返回值为真。再点击 Getbalance_A,结果为15554,正确。
- Value值输入1,点击Call_A,返回值为真。再点击 Getbalance_A,结果为15555,正确。
以上是将9~11行注释掉的情况。现在去掉这三行的注释,再操作一遍。
Transfer_A、Sender_A 操作均失败, Call_A 成功。而把49行代码换成第48行代码时,又会转账失败。
其中,9~11的三行代码会消耗6万个Gas 。transfer、send 仅仅转发2300个Gas,所以会失败。而Call调用方法,缺省是支付所有Gas,在本例中若限制5万个Gas,则转账失败。
小结一下,本小节主要讲解了 Solidity 合约相关知识,并有两个实例辅助理解。
不足之处,请批评指正。
网友评论