我们再次引入了一些计划在 0.5.0 版本中发布的变更,可以使用pragma experimental "v0.5.0"; 来激活这些变更。在这个版本中,这个 pragma 不会再生成警告,所以您可以在生产代码中使用它(也应该使用它)。
除此之外,您现在可以指定合约应该编译到的 EVM 版本。有效的值是 "homestead"、"tangerineWhistle"、"spuriousDragon"、"byzantium"(默认值)和 "constantinople"。根据此设置,某些情况下将使用不同的操作码。目前,默认情况下,唯一使用此设置的地方是,从 "tangerineWhistle" 开始,所有 gas 都将通过调用转发(在 homestead 中,需要保留一些 gas 用于 call 操作码本身)。此外,gas 估计器会根据版本报告不同的操作码成本,因此优化器可能会生成不同的代码。
新 "0.5.0" 功能将在功能和错误修复列表下方更详细地解释。
功能
- 代码生成器:断言 k != 0 对于 mulmod(a, b, k) 和 addmod(a, b, k),作为实验性 0.5.0 功能。
- 代码生成器:在调用中不保留任何 gas(除非 EVM 版本设置为 homestead)。
- 代码生成器:对调用 view 和 pure 函数使用 STATICCALL 操作码,作为实验性 0.5.0 功能。
- 通用:C99/C++ 风格的范围规则(而不是 JavaScript 函数范围)生效,作为实验性 v0.5.0 功能。
- 通用:当错误跨越源文件多行时改进消息传递。
- 通用:支持并建议使用 emit EventName(); 显式调用事件。
- 内联汇编:作为实验性 0.5.0 功能,强制执行严格模式。
- 接口:提供选择目标 EVM 版本(homestead 或 byzantium,默认值为 byzantium)的能力。
- 标准 JSON:拒绝格式错误的无效 JSON 输入。
- 类型检查器:禁止未初始化的存储指针,作为实验性 0.5.0 功能。
- 语法分析器:如果实验性功能不涉及代码生成,则不会发出警告。
- 语法分析器:不会发出关于 pragma experimental "v0.5.0" 的警告,并且不会为此设置字节码中的实验性标志。
- 语法检查器:将 throw 标记为错误,作为实验性 0.5.0 功能。
- 语法检查器:如果在合约函数上未指定可见性,则发出错误,作为实验性 0.5.0 功能。
- 语法检查器:在合约实例上使用 address 的重载时发出警告。
- 类型检查器:禁止将十六进制数字和单位标识组合在一起,作为实验性 0.5.0 功能。
错误修复
- 汇编:在汇编中对超大数字字面量引发错误。
- JSON-AST:在函数、事件和修饰符定义中添加 "documentation" 属性。
- 解析器:为使用别名的导入正确确定阴影。
- 独立汇编:不要忽略顶级块的闭合大括号后的输入。
- 标准 JSON:在传递无效 "sources" 时正确捕获错误。
- 标准 JSON:确保提供的库地址长度正确且以十六进制前缀开头。
- 类型检查器:正确检测旧的 ABI 编码器不支持哪些数组和结构类型。
- 类型检查器:在内联汇编中使用 _offset 和 _slot 用于常量时正确发出警告。
- 命令行界面:如果选项未知,则抛出错误。
详情
- 代码生成器:对调用 view 和 pure 函数使用 STATICCALL 操作码,作为实验性 0.5.0 功能。
这确保标记为 view 或 pure(以前为 constant)的函数不能修改状态。如果您通过通用接口调用未知代码,并且无法确定该函数是否修改状态,这一点尤其重要。这样,view 和 pure 函数不会产生重入效应。
- 通用:C99/C++ 风格的范围规则(而不是 JavaScript 函数范围)生效,作为实验性 v0.5.0 功能。
变量不再在整个函数中都有效,甚至在 JavaScript 中声明之前也不有效,而是在声明它们的 {/} 包围的块中有效,并且仅在声明之后有效。这些是 C++ 或 Java 也使用的规则。有一个常见的例外,即在 for 头部的初始化部分声明的变量在 for 循环构造的其余部分也有效,我们也在 Solidity 中使用此规则。目前,为变量保留的堆栈槽位仍然跨越整个函数,但这计划在下一个版本中进行改进。
- 通用:支持并建议使用 emit EventName(); 显式调用事件。
为了使事件在常规函数调用中脱颖而出,现在应使用 emit EventName() 而不是 EventName() 来 "调用" 事件。
- 内联汇编:作为实验性 0.5.0 功能,强制执行严格模式。
严格模式禁止标签、跳转和直接修改堆栈的操作码。它比非严格模式安全得多,因为您不必跟踪堆栈的当前状态。此外,它允许更容易地创建优化阶段(即将完成)。因此,优化器将拒绝处理非严格汇编。
- 类型检查器:禁止未初始化的存储指针,作为实验性 0.5.0 功能。
存储指针(例如 StructType storage x;)如果在未分配的情况下使用,会导致严重的存储损坏。在 0.5.0 中,在未直接初始化的情况下声明存储指针将是非法的。
- 语法检查器:将 throw 标记为错误,作为实验性 0.5.0 功能。
throw 关键字让人觉得异常是 Solidity 的一项功能,而实际上,它只支持状态回滚,这种回滚很快也能包含错误数据。因此,throw 已被弃用。
- 语法检查器:如果在合约函数上未指定可见性,则发出错误,作为实验性 0.5.0 功能。
由于存在一些错误,人们没有意识到函数的默认可见性是 public,因此规定必须指定可见性。
- 语法检查器:在合约实例上使用 address 的重载时发出警告。
address 类型的原生成员与合约的自定义成员之间的冲突很容易欺骗用户。因此,地址成员不再在合约中可用。如果您想使用地址成员(transfer 是其中之一!),请将其转换为地址:address(contractInstance).transfer(2 wei)。
- 类型检查器:禁止将十六进制数字和单位标识组合在一起,作为实验性 0.5.0 功能。
我们无法想到任何情况,其中单位标识(如 seconds 或 ether)与十六进制字面量相结合会有意义(0x1234 ether 或 0x20 minutes),因此弃用了这种组合。
非常感谢所有帮助实现这个版本的发布的贡献者!
下载新版本的 Solidity这里.