Solidity v0.7.0中断更改

本节重点介绍Solidity版本0.7.0中引入的主要突破性更改,以及更改背后的推理以及如何更新受影响的代码。对于完整列表检查 the release changelog .

语义的无声变化

  • 非文字的指数和位移(例如。 1 << x2 ** x )将始终使用 uint256 (对于非负数字面值)或 int256 (对于负数字面值)执行操作。以前,操作是以移位量/指数的类型执行的,这可能会造成误导。

语法的更改

  • 在外部函数和协定创建调用中,现在使用新语法指定乙醚和气体: x.f{{gas: 10000, value: 2 ether}}(arg1, arg2) . 旧的语法-- x.f.gas(10000).value(2 ether)(arg1, arg2) --将导致错误。

  • 全局变量 now 已弃用, block.timestamp 应该改为使用。单一标识符 now 对于全局变量来说太泛型了,可能会给人一种在事务处理过程中发生更改的印象,而 block.timestamp 正确地反映了它只是块的一个属性。

  • 变量上的NatSpec注释只允许用于公共状态变量,而不允许用于局部或内部变量。

  • 代币 gwei 是一个关键字now(用于指定,例如。 2 gwei 作为数字),不能用作标识符。

  • 字符串文字现在只能包含可打印的ASCII字符,这还包括各种转义序列,如十六进制 (\xff )unicode转义 (\u20ac

  • 现在支持Unicode字符串文本来容纳有效的UTF-8序列。它们与 unicode 前缀: unicode"Hello 😃" .

  • 状态可变性:现在可以在继承期间限制函数的状态可变性:具有默认状态可变性的函数可以被重写 pureview 函数while view 函数可以被重写 pure 功能。同时考虑了公共状态变量 view 甚至 pure 如果它们是常数。

内联程序集

  • 不允许的 . 在内联程序集中的用户定义函数和变量名中。如果在“仅Yul”模式下使用Solidity,则它仍然有效。

  • 存储指针变量的槽和偏移量 x 通过访问 x.slotx.offset 而不是 x_slotx_offset .

移除未使用的或不安全的特征

存储外部映射

  • 如果结构或数组包含映射,则只能在存储中使用。以前,映射成员在内存中被无提示地跳过,这是令人困惑和容易出错的。

  • 如果存储中的结构或数组包含映射,则对它们的分配将不起作用。以前,在复制操作过程中,映射会被无提示地跳过,这很容易产生误导和错误。

功能和事件

  • 可见性 (public / internal 构造函数不再需要):要防止创建合同,可以将其标记为 abstract 。这使得构造函数的可见性概念过时了。

  • 类型检查器:不允许 virtual 对于库函数:由于库不能从继承,因此库函数不应是虚拟的。

  • 不允许在同一继承层次结构中具有相同名称和参数类型的多个事件。

  • using A for B 仅影响中提到的合同。以前,这种影响是遗传的。现在,你必须重复 using 所有使用该功能的派生契约中的语句。

表达

  • 不允许按有符号类型的移位。以前,允许负数的移位,但在运行时恢复。

  • 这个 finneyszabo 面额被删除。它们很少被使用,而且不容易看到实际的用量。相反,显式值 1e20 或者很普通的 gwei 可以使用。

声明

  • 关键词 var 不能再使用了。以前,此关键字将进行解析,但会导致类型错误和有关使用哪种类型的建议。现在,它会导致解析器错误。

接口更改

  • JSON AST:用标记十六进制字符串文本 kind: "hexString" .

  • JSON AST:具有值的成员 null 从JSON输出中移除。

  • NatSpec:构造函数和函数具有一致的userdoc输出。

如何更新代码

本节详细说明了如何为每次中断更改更新先前的代码。

  • 变化 x.f.value(...)()x.f{{value: ...}}() . 同样地 (new C).value(...)()new C{{value: ...}}()x.f.gas(...).value(...)()x.f{{gas: ..., value: ...}}() .

  • 变化 nowblock.timestamp .

  • 将移位运算符中右操作数的类型更改为无符号类型。例如变更 x >> (256 - y)x >> uint(256 - y) .

  • 重复 using A for B 所有派生合同中的语句(如果需要)。

  • 移除 public 来自每个构造函数的关键字。

  • 移除 internal 关键字从每个构造函数和添加 abstract 合同(如果尚未提交)。

  • 变化 _slot_offset 内联程序集中的后缀 .slot.offset ,分别。