一、区块和交易属性(Block and Transaction Properties)
- block.blockhash(uint blockNumber) returns (bytes32): 给定区块的哈希值 - 仅适用于最新的256个区块,不包括当前区块
- block.coinbase (address):当前区块的矿工的地址
- block.difficulty (uint):当前区块的难度系数
- block.gaslimit (uint):当前区块gas限制
- block.number (uint):当前区块编号
- block.timestamp (uint):当前块的时间戳
- msg.data (bytes):完整的calldata
- msg.gas (uint):剩余的gas
- msg.sender (address):消息的发送方(当前调用)
- msg.sig (bytes4):calldata的前四个字节(即函数标识符)
- msg.value (uint):所发送的消息中wei的数量
- now (uint):当前块时间戳(block.timestamp的别名)
- tx.gasprice (uint):交易的gas价格
- tx.origin (address):交易发送方(完整的调用链)
-
二、重要语法
基本语法可参考如下博文:https://blog.csdn.net/super_lixiang/article/details/83049719
- require(
(msg.sender == chairPerson)
&& !voters[voter].voted
&& (voters[voter].weight == 0)
);
若 `require` 的入参判定为 `false`, 则终止函数,恢复所有对状态和以太币账户的变动,并且也不会消耗 gas 。
2、函数可见性分析----
- public - 任意访问
- private - 仅当前合约内
- internal - 仅当前合约及所继承的合约
- external - 仅外部访问(在内部也只能用外部访问方式访问)
- 和java一样,适用于全局变量
3、函数的限制访问----
- 在Solidity中constant、view、pure三个函数修饰词的作用是告诉编译器,函数不改变/不读取状态变量,这样函数执行就可以不消耗gas了,因为不需要矿工来验证。在Solidity v4.17之前,只有constant,后续版本将constant拆成了view和pure。view的作用和constant一模一样,可以读取状态变量但是不能改;pure则更为严格,pure修饰的函数不能改也不能读状态变量,智能操作函数内部变量,否则编译通不过。
- Solidity中的存储区
参见解决:这里就要说一下Solidity中的存储区了,详解了解亲参阅博客
memery与storage实例图
memery与storage错误实例
memery与storage解决错误实例
- modifier的强大功能(重点)
代码重用性(一个modifier方法可以被多处调用),多重modifier的执行顺序,很重要!!!
modifier用法实例
- 面向对象——合约的继承
当一个合约继承自多个合约时,只会在区块链上创建单个合约,并将所有父合约中的代码复制到创建的合约中。
使用`is`继承另一个合约。 子合约可以访问所有非私有成员,包括内部函数和状态变量。不过,不能通过`this`来外部访问这些。
用public、internal、external(调用用this)的函数可被继承,private修饰的不能被继承。
多重继承,同时继承多个合约的时候,如果被继承的多个合约都有相同属性或者方法的时候,写在后面(father合约)的会覆盖前面的(mother合约),如多重继承图
多重继承图
权限修饰符图示
继承的重载
- 元组:解构赋值和返回多个结果
Solidity内置支持元组(tuple),也就是说支持一个可能的完全不同类型组成的一个列表,数量上是固定的(Tuple一般指两个,还有个Triple一般指三个)。
元组实例<一>
元组实例<二>
三、报错解决汇总
- TypeError: "send" and "transfer" are only available for objects of type "address payable", not "address".
解决:必须要有一个供外部调用的函数,如下
function () payable external{ }
2、
TypeError: Member "transfer" not found or not visible after argument-dependent lookup in contract addressBalance. Use "address(this).transfer" to access this address member.
解决:在新版本中,对地址的使用,不能用只this指代,修改如下:
3、TypeError: Data location must be "memory" for return parameter in function, but none was given.
解决:这里就要说一下Solidity中的存储区了,详解了解亲参阅博客
https://blog.csdn.net/yjhzxhyzq123/article/details/80598220
不同数据类型的变量会有各自默认的存储位置,
-状态变量总是会存储在storage 中
-函数参数和返回值默认存放在 内存memory 中
-结构、数组或映射类型的局部变量,默认会放在 存储storage 中
-除结构、数组及映射类型之外的简单局部值变量,会储存在栈中
这里需要给返回值加上存储位置,修改如下:
转账时调用transfer2方法,如果日志提示转账失败信息:VM error: revert. revert The transaction has been reverted to the initial state. Note: The constructor should be payable if you send value
解决:添加一个方法即可外部可调用的payable方法即可
- 底层send()的使用:
- 调动递归深度不能超过1024。
- 如果gas不够,执行会失败。
- send()方法要检查成功与否。
- transfer()相对send()更安全。
Transact to mappingtest.regiter errored:Error encoding arguments:SyntaxError:Unexpected token s in json at position address(this).send(10 ether);
解决:这个错误是因为调用方法传递参数是没有给参数加上双引号,或者双引号不是英文的
7、
承接区块链业务:
1.区块链服务器搭建(包含主链数据同步)
2.eth及erc20代币充提
3.btc及usdt充提