Solidity v0.7.0 突破性变化
本节强调了 Solidity 0.7.0 版本中引入的主要突破性变化, 以及这些变化背后的原因和如何更新受影响的代码。 对于完整的列表,请查看 版本更新日志。
语义的微小变化
用非字符量进行指数和移位(例如:
1 << x
或2 ** x
) 将总是使用uint256
类型(对于非负数)或int256
类型(对于负数)来执行操作。 在此之前,该操作是在移位量/指数的类型中进行的,这可能会产生误导。
语法的变化
在外部函数和合约创建调用中,现在使用新的语法指定以太和gas:
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
现在是一个关键词(用于指定,例如2 gwei
作为一个数字),不能作为一个标识符使用。字符串现在只能包含可打印的ASCII字符,这也包括各种转义序列, 如十六进制(
\xff
)和unicode转义(\u20ac
)。现在支持Unicode字符串文本来容纳有效的UTF-8序列。 它们用
unicode
前缀来标识:unicode"Hello 😃"
。状态可变性:现在可以在继承过程中限制函数的状态可变性。 具有默认状态可变性的函数可以被
pure
和view
函数所覆盖, 而view
函数可以被pure
函数所覆盖。 同时,公共状态变量被认为是view
,甚至是pure
,如果它们是常量。
内联汇编
在用户定义的函数和变量名称中,不允许在内联汇编中使用
.
。 如果您在“仅Yul”模式下使用Solidity,它仍然有效。存储指针变量
x
的槽和偏移量通过x.slot
和x.offset
访问, 而不是x_slot
和x_offset
。
移除未使用或不安全的功能
存储之外的映射关系
如果一个结构或数组包含一个映射,它只能在存储中使用。 以前,映射成员在内存中被默默地跳过,这让人困惑,也容易出错。
如果存储中的结构或数组包含映射,则对其进行赋值是不可行的。 以前,在复制操作过程中,映射会被默默地跳过,这是一种误导,而且容易出错。
函数和事件
构造函数不再需要可见性(
public
/internal
)了。 为了防止合约被创建,可以将其标记为abstract
。 这使得构造函数的可见性概念变得过时了。类型检查器:不允许库函数为
virtual
: 由于库合约不能被继承,库函数不应该被标记为 virtual。不允许在同一继承层次中具有相同名称和参数类型的多个事件。
using A for B
只影响到它所提到的合约。以前,这种影响是继承的。 现在,您必须在所有使用该特性的派生合约中重复using
语句。
表达式
有符号类型的移位是不允许的。以前,允许负数的移位,但它在运行时会被还原。
finney
和szabo
的面额被删除。它们很少被使用,并且不能使实际的金额清晰可见。 相反,可以使用明确的数值,如1e20
或非常常见的gwei
。
声明
关键字
var
不能再使用了。 以前,这个关键词可以解析,但会导致一个类型错误, 并建议使用哪种类型。现在,它导致一个解析器错误。
接口变化
JSON AST:用
kind: "hexString"
来标记十六进制字符串文本。JSON AST:值为
null
的成员将从JSON输出中删除。NatSpec:构造器和函数有一致的用户文档输出。
如何更新您的代码
本节详细说明了如何为每一个突破性变化更新先前的代码。
将
x.f.value(...)()
改为x.f{value: ...}()
。类似地,(new C).value(...)()
改为new C{value: ...}()
,x.f.gas(...).value(...)()
改为x.f{gas: ..., value: ...}()
。将
now
改为block.timestamp
.将移位运算符中的右操作数的类型改为无符号类型。 例如,将
x >> (256 - y)
改为x >> uint(256 - y)
。如果需要,在所有派生合约中重复
using A for B
的语句。从每个构造函数中删除
public
关键字。从每个构造函数中删除
internal
关键字,并在合约中添加abstract
(如果还没有存在)。将内联汇编中的
_slot
和_offset
后缀分别改为.slot
和.offset
。