Solidity v0.7.1 添加了文件级函数并修复了一些小错误。
值得注意的新功能
文件级函数
现在可以在文件级别定义函数。此类函数称为“自由函数”(与绑定到特定合约的函数相反)。
自由函数始终是内部函数,旨在替代内部库函数及其非常特殊的行为。
自由函数的行为类似于调用它的合约的内部函数。主要区别在于自由函数不能直接访问合约的状态变量和内部函数。自由函数可以调用其他合约、发出事件和发送 Ether,在这种情况下,msg.sender 将是调用自由函数的合约。
只有在将存储指针传递给函数(参见下面的示例)或使用内联汇编时,才能从自由函数访问合约的存储。状态可变性将被检查,这意味着pure 自由函数不能访问存储或发送 Ether。
自由函数的代码仅包含在使用它的合约中。
/// @dev returns the smaller of the two values. function min(uint x, uint y) pure returns (uint) { return x < y ? x : y; } /// @dev returns the sum of the elements of the storage array function sum(uint[] storage items) view returns (uint s) { for (uint i = 0; i < items.length; i++) s += items[i]; }
如果从另一个文件导入自由函数,建议使用生成新对象的 import 语句,以便不必要地污染文件的范围。
helper.sol
function f() returns (uint) { /* ... */ }
main.sol
import "helper.sol" as Helper; contract C { function g() public returns (uint) { return Helper.f(); } }
计划在未来版本中添加对自由函数使用using A for B 的支持。
完整变更日志
语言功能
- 允许在合约外部定义函数,其行为类似于内部库函数。
- 代码生成器:实现了将结构体从 calldata 复制到存储。
编译器功能
- SMTChecker:在 CHC 引擎中添加下溢出和上溢出作为验证条件。
- SMTChecker:支持按位或、异或和非运算符。
- SMTChecker:支持条件运算符。
- 标准 JSON 接口:如果只请求 Yul IR 或 EWasm 输出,则不运行 EVM 字节码代码生成。
- Yul 优化器:LoopInvariantCodeMotion 可以将读取操作移出 for 循环,只要受影响的区域在循环内没有被修改。
- Yul:当对datasize()、dataoffset()、linkersymbol()、loadimmutable()、setimmutable() 使用非字符串字面量时报告错误。
错误修复
- AST:当编译器在 standard-json-mode 模式下使用时,也删除null 成员值。
- 常规:允许type(Contract).name 用于抽象合约和接口。
- 不可变变量:禁止在声明期间多次为不可变变量赋值。
- 不可变变量:正确地将复杂赋值和递增/递减视为读写操作,因此禁止在不可变变量中使用它们。
- 优化器:在byte(a, shr(b, x)) 中保留x 的副作用,即使常量a 和b 无条件地使表达式为零。虽然这个优化规则很难(甚至不可能)触发,但它可能导致无效的代码。
- 引用解析器:修复使用库构造函数时的内部错误。
- 扫描器:修复在-> 令牌中允许出现空白字符的错误(例如,function f() - > x {} 在内联汇编和 Yul 中变为无效)。
- SMTChecker:修复 BMC 函数内联中的内部错误。
- SMTChecker:修复数组隐式转换中的内部错误。
- SMTChecker:修复固定字节索引访问中的内部错误。
- SMTChecker:修复带有元组的左值一元运算符的内部错误。
- SMTChecker:修复数组pop 的健全性。
- 类型检查器:禁止在接口中使用using for 指令。
- 类型检查器:禁止带符号字面量作为指数运算符中的指数。
- 类型检查器:禁止将包含内存中嵌套映射的结构体作为库函数的参数。
- Yul 优化器:确保 NameDispenser 和 VarNameCleaners 不错误地使用 Yul 关键字。此错误会导致无法编译的代码。
- Yul 优化器:使函数内联顺序对是否存在无关源文件更具弹性。
非常感谢所有为此次发布做出贡献的人!
在此下载 Solidity 的新版本here。