Solidity
文章目录
结构
- 状态变量:永久存储在合约账户存储的值
- 函数:合约代码的执行单位,相互调用共同组成合约的工作逻辑
- 函数修改器:用于改变函数的行为,在函数执行前或执行后插入其他逻辑
- 事件:以太坊日志协议的高层次抽象,记录合约执行过程中发生的各种事件和状态变化
变量类型
值类型
- 布尔类型bool
- 整数类型int/uint
- 定长浮点型fixed/ufixed
- 枚举类型enum
- 地址类型address
-
转换
-
合约通过显示转换为地址类型,不再由地址类型派生
-
<address payable>可通过隐式转换为<address>,<address>使用uint160中间转换为<address payable>
-
-
成员变量
-
<address payable>.send
- 执行失败,返回false,代码继续执行
-
<address payable>.transfer
- 执行失败时,抛出异常并终止代码
-
<address>.call
-
<address>.delegatecall
-
<address>.staticcall
-
- 固定长度字节数组
引用类型
- 数组array
-
长度是否变化
- 定长数组
- 动态数组/变长数组
-
存储位置
-
账户存储的数组 storage
- 元素可以是任何类型
-
内存中的数组 memory
- 元素不可以是映射
-
-
成员变量和函数
- length:账户存储的数组可以动态改变
- push():账户存储的动态数组和bytes类型的变量
- 结构体struct
-
可在映射和数组中使用
-
contract Struct { struct Donator { address add; uint amount; } }
- 映射mapping
mapping(keyType => valueType)
类型转换
运算符
类型推断
内置单位、全局变量和函数
货币单位
时间单位
区块和交易属性
- msg.sender
- msg.value
异常处理
- assert(bool)
- require(bool)
- revert(bool)
数学和加密函数
与合约相关的变量和函数
控制结构语句
函数
可见性
- external:用于修饰函数,表示外部函数
- public:表示函数/变量可在合约内外部访问
- internal:内部函数/变量,表示只能在合约内部或子类访问
- private:表示只能在合约内部访问
状态可变性
- pure:不允许修改和访问状态
- view:不允许修改
- payable:允许接收以太
- constant:同view
fallback函数
当合约收到无法匹配的函数调用或仅用于转账的交易时,自动执行
contract Test {
uint x;
fallback() external{
x = 1;
}
}
contract Caller {
function callTest(Test test) public{
// 对应的函数不存在,触发回退函数,x = 1
test.call(0x12345);
// 发送以太币产生交易,触发异常并退回以太币
test.send(2 ether);
}
}
函数修改器
contract Modifier {
address public creater;
constructor() {
creater = msg.sender;
}
// 函数修改器
modifier onlyCreater() {
require(msg.sender == creater);
_; //使用下划线指代原函数代码
}
// 使用函数修改器
function abort() onlyCreater public{
}
}
异常处理
- assert():检查变量和内部错误
- require():用于确保程序执行的必要条件成立
- revert()/throw:标识错误,回退
contract Exception {
function sendHalf(address payable addr) payable public returns(uint balance) {
require(msg.value % 2 == 0);
uint balanceA = balance;
addr.transfer(msg.value/2);
assert(balance == balanceA-msg.value/2);
return balance;
}
事件和日志
contract Event {
// 事件
event Deposit(address _from, uint _amount);
function donate() payable public{
// 触发事件
emit Deposit(msg.sender, msg.value);
}
}