常见区别点
[TOC]
常见区别点
函数可视范围: private、internal、public、external
- private: 只在合约内部可见
- internal:在合约内部和被继承的子合约都可见
- public: 内部、被继承的子合约、外部均可见
- external: 仅在合约外部可见,合约内部不可见
状态变量的可见性: private、public、internal(默认的)
- 对于 public 的状态变量,会默认生成一个 getter 函数
pure、view
- pure: 读取了状态变量
- view: 不读取任何状态变量
memory、storage、calldata
- memory: 局部变量,只在函数内临时使用,
- storage: 状态变量,会持久化的保存到区块链上
- calldata: 也是局部变量,但是只能用于输入参数中
constant 和 immutable
constant
- 编译阶段确定值
- 可以在文件层面定义
- 编译器不会为这些变量保留
storage slot
,而是每次出现这些变量的时候就会被编译器替换为对应的值 - 如果
constant
变量是一个表达式,每次使用这个变量时都会执行这个表达式重新求值
- immutable: 在合约部署前不知道,合约初始化时赋值。以后就不再可变
- 在构造方法中赋值,只能赋值一次。
- 编译器会将这个值赋值到所有使用这个变量的地方,给这些值预留 32 个字节的
storage slot
(这也是为什么constant
比immutable
更便宜) - 目前
0.8.0
只实现了将string
和值类型才能设置为常量
使用常量可以节省 gas 费
参考: constant 和 immutable 有什么区别
发送 ETH 的三种方法: transfer、send、call
- transfer: 带有 2300gas,如果失败会 revert
- send: 带有 2300gas,会返回一个 bool 值标志成功/失败
- call: 会发送所有剩余的 gas,返回
(bool success,bytes memoy data)
,如果调用的是一个合约,合约的返回值会在data
中提现
abstract
tx.origin、msg.sender
msg.sender
: 指直接调用智能合约功能的帐户或智能合约的地址tx.origin
: 指调用智能合约功能的账户地址,只有账户地址可以是 tx.origin
call、callcode、delegatecal、staticcall 的区别
call 与 callcode
- call:修改的是
被调用者
的 storage - callcode:修改的是
调用者
的 storage
callcode 与 delegatecall
delegatecall
可以认为delegatecall
是callcode
的 bugfix 版本,官方已经不建议使用callcode
了
区别点是: msg.sender
不同
- delegatecall:
msg.sender
是原始调用者 - callcode:
msg.sender
是直接调用者
staticcall
staticcall
是一种静态调用,用于在运行时保证只读方法。
现在通过view
或pure
来声明只读方法,而且是在编译阶段确定。通过staticcall
可以在运行时确定是只读方法