语法摘要:Contact,数据类型,异常处理
类似 class,可以:abstract、继承和被其他 contract 调用。
典型使用:
new MyContract(...)
MyContract($address)
可见性 | 类似 | 应用于 | 外部可访问 | 子合约可访问 |
---|---|---|---|---|
external | 函数 | √ | ||
public | public | 函数 + 状态变量 | √ | √ |
internal | protected | 函数 + 状态变量 | √ | |
private | private | 函数 + 状态变量 |
注:对于 public 变量,会自动生成对应的 getter(详见:Ethers.js 非权威开发指南(续))。
要素 | 说明 | 示例 |
---|---|---|
状态变量 | 永久存储于链上,需耗费 gas | uint data; |
函数 | 读/写两类,写方法需耗费 gas;可存在于合约内部和外部 | function func() public {...} |
fallback() | 无法直接被外部调用,当请求合约中不存在函数时执行 | fallback() external { ... } |
receive() | 无法直接被外部调用,当接收 eth 时执行 | receive() external payable {...} |
modifier | 可复用的声明性约束,函数调用前执行。 | 声明:modifier onlyOwner(){...} 使用:function func() public onlyOwner {...} |
事件 | 链上执行日志,可供日后查询。 | emit Event1(data); |
structure | 自定义类型 | struct MyType { uint item1; bool item2; } |
error | 自定义异常 | 声明:error MyError(unit reason); 使用:revert MyError(200); |
枚举 | 有限常数值最佳选择 | enum State { Created, Locked, Inactive } |
注:
fallback 和 receive 函数
function
关键字。external
关于在 dapp 中如何使用事件和查询日志,详见:Ethers.js 非权威开发指南(下)
类似其他语言中的 interface,可以:
类似 contract,但:
两者关系类似:contract,可执行文件;library,动态链接库
类似 | |
---|---|
值类型 | bool、uint / int、address、byte、enum |
引用类型 | 数组(如 bytes / string)、structure、mapping |
注:
字节数组和字符串
keccak256(abi.encodePacked(s1)) == keccak256(abi.encodePacked(s2))
bytes bs = 'bytes';
string str = 'string';
byte1 b1 = 'a';
byte2 b2 = 256;
,256 超出了单字节大小int[] age = [10, 20, 30, 40, 50];
int[] age = new int[](5);
int[5] age = [10, 20, 30, 40, 50];
address
和 address payable
,相比前者,后者多了转账功能。类似 | 举例 | |
---|---|---|
storage | 持久化,合约内全局内存 | 状态变量 |
memory | 函数的本地内存,非持久化 | 函数入参 |
calldata | 函数入参,非持久化 | 函数入参 |
stack | EVM 调用栈 |
相关规则:
函数局部变量:
mapping (uint => address) storage localNames = names;
names
是定义在合约中的状态变量,类型也是 mapping。说明 | 举例 | |
---|---|---|
eth 单位 | wei、gwei、ether | 1 gwei |
时间单位 | seconds、minutes、hours、days、weeks | 1 minutes |
block | block 对象 | |
blockhash() | 若入参为最近 256 个 block 之一,则为其 hash。否则,0。 | |
msg | msg 对象 | |
tx | tx 对象 | |
gasleft() | 剩余 gas | |
abi | abi 对象 | |
address | address 对象 | |
this | 当前合约对象,可显式转换成 address | address(this).balance |
type() | 类型信息 | |
addmod | (a + b) % k | |
mulmod | (a * b) % k | |
哈希函数 | keccak256、sha256、ripemd160 | |
ecrecover | 从签名恢复地址 |
详见:https://docs.soliditylang.org/en/latest/units-and-global-variables.html
注:
tx.orgin 和 msg.sender 区别
address.transfer
,在失败时,transfer
抛出异常,而 sender
则返回 false
。bytes memory payload = abi.encodeWithSignature("register(string)", "MyName");
(bool success, bytes memory returnData) = address(nameReg).call(payload);
require(success);
address(nameReg).call{gas: 1000000, value: 1 ether}(abi.encodeWithSignature("register(string)", "MyName"));
异常类型:
合约抛出异常之后,状态回滚,当前有 3 种方式:
require(表达式),若表达式为 false,则抛出异常,未使用的 gas 退回
try...catch 语句示例:
try feed.getData(token) returns (uint v) {
return (v, true);
} catch Error(string memory /*reason*/) {
// require 导致
errorCount++;
return (0, false);
} catch Panic(uint /*errorCode*/) {
// assert 导致
errorCount++;
return (0, false);
} catch (bytes memory /*lowLevelData*/) {
// revert 导致
errorCount++;
return (0, false);
}
相关文章:
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!