Skip to main content

常见区别点

[TOC]

常见区别点

函数可视范围: private、internal、public、external

  1. private: 只在合约内部可见
  2. internal:在合约内部和被继承的子合约都可见
  3. public: 内部、被继承的子合约、外部均可见
  4. external: 仅在合约外部可见,合约内部不可见

状态变量的可见性: private、public、internal(默认的)

  • 对于 public 的状态变量,会默认生成一个 getter 函数

pure、view

  • pure: 读取了状态变量
  • view: 不读取任何状态变量

memory、storage、calldata

  • memory: 局部变量,只在函数内临时使用,
  • storage: 状态变量,会持久化的保存到区块链上
  • calldata: 也是局部变量,但是只能用于输入参数中

constant 和 immutable

  • constant
    1. 编译阶段确定值
    2. 可以在文件层面定义
    3. 编译器不会为这些变量保留storage slot,而是每次出现这些变量的时候就会被编译器替换为对应的值
    4. 如果constant变量是一个表达式,每次使用这个变量时都会执行这个表达式重新求值
  • immutable: 在合约部署前不知道,合约初始化时赋值。以后就不再可变
    1. 在构造方法中赋值,只能赋值一次。
    2. 编译器会将这个值赋值到所有使用这个变量的地方,给这些值预留 32 个字节的storage slot(这也是为什么constantimmutable更便宜)
    3. 目前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

可以认为delegatecallcallcode的 bugfix 版本,官方已经不建议使用callcode

区别点是: msg.sender不同

  • delegatecall: msg.sender是原始调用者
  • callcode: msg.sender是直接调用者

staticcall

staticcall是一种静态调用,用于在运行时保证只读方法。 现在通过viewpure来声明只读方法,而且是在编译阶段确定。通过staticcall可以在运行时确定是只读方法