Solidity v0.6.10修复了先前版本引入的一个重要错误,并添加了错误代码。
如果您正在使用带有 calldata 参数的内部库函数,并结合using for.
重要错误修复
内部库函数中 calldata 参数的无效访问
问题:先前版本,Solidity 0.6.9,引入了在内部函数中使用 calldata 类型,而不是像以前那样仅在外部函数中使用。这导致了一个与通过 using for 调用带有 calldata 参数的库函数相关的错误。更具体地说,编译器会先将所有 calldata 参数复制到内存中 - 就像对公共库函数的调用一样。然后,内部库函数将接收内存指针,但将其解释为 calldata 指针,导致在错误的位置读取 calldata,并可能导致堆栈损坏。堆栈损坏是由 calldata 指针可以使用两个堆栈槽,而内存指针始终仅使用一个堆栈槽这一事实造成的。这反过来会导致其他变量出现问题,并在函数返回时发生错误跳转。
我们将其严重性评定为“非常低”,因为该错误是在一周前才引入的,并且很容易通过测试检测到。
解决方案:升级到 Solidity 0.6.10,该版本不会执行复制到内存的操作。
受影响代码示例
library L { function helper(bytes calldata _x) internal pure returns (byte) { return _x[0]; } } contract C { using L for bytes; function fun(bytes calldata _x) public pure returns (byte) { // This would incorrectly copy ``_x`` from calldata // to memory and then call L.helper with this memory array, // but the function expects a calldata array and thus // reads the data from the wrong calldata offset. return _x.helper(); } }
感谢 Gelato 的 Luis (@gitpusha) 报告了此错误!
值得注意的新功能
错误代码
一个值得注意的新功能是引入了错误代码。在标准 JSON 输入/输出模式(--standard-json)下,错误代码将始终在 "errorCode" 属性下可用。在命令行界面中,您可以通过开关 --error-codes 启用错误代码。
本质上是关于同一件事但包含不同错误消息的两个错误,例如,当错误涉及两种不同类型时,将使用相同的错误代码。
错误代码旨在在不同版本之间保持合理的稳定性。
我们希望这能够改进智能合约的分析,而无需对错误消息进行复杂且脆弱的检查。
示例
以下源代码生成三个错误消息
// SPDX-License-Identifier: MIT pragma solidity ^0.6.10; contract C { uint8 x = 1000; function f(uint _y) public { x = _y; x.g(); } }
# solc --error-codes c.sol Error (7407): Type int_const 1000 is not implicitly convertible to expected type uint8. --> c.sol:5:13: | 5 | uint8 x = 1000; | ^^^^ Error (7407): Type uint256 is not implicitly convertible to expected type uint8. --> c.sol:7:9: | 7 | x = _y; | ^^ Error (9582): Member "g" not found or not visible after argument-dependent lookup in uint8. --> c.sol:8:5: | 8 | x.g(); | ^^^
请注意,关于无效类型转换的错误使用相同的代码,即使文本不同。关于缺少成员的错误使用不同的代码。
我们目前不打算创建所有错误代码的完整列表。如果您想查找它们,请查看编译器的源代码。
错误代码目前始终是四位数的十进制数,在数字分配中没有结构。
完整变更日志
新功能
- 命令行界面:重新分组帮助屏幕。
- 在标准 JSON 中以及使用 --error-codes 时输出编译错误代码。
- Yul:对于仅具有默认值且没有其他情况的 switch 语句发出警告。
错误修复
- SMTChecker:修复编码元组的元组时的内部错误。
- SMTChecker:修复推送到数组指针后的别名安全性。
- 类型系统:修复在外部调用返回具有 calldata 位置的变量的函数时的内部编译器错误。
- 类型系统:修复当 using for 应用于显式引用类型时找不到绑定函数的错误。
非常感谢所有帮助使此版本成为可能的贡献者!
在此处下载 Solidity 的新版本 此处。