主页 > 苹果手机imtoken怎么下载 > 如何编写智能合约来优化以太坊gas的消耗
如何编写智能合约来优化以太坊gas的消耗
在以太坊区块链上,gas 是一种执行费用,用于补偿矿工为智能合约提供计算能力所需的计算资源。网络的使用逐渐增加,目前的gas费用在每天数百万美元。随着生态系统的不断发展,gas 优化的价值也会不断增长。下面介绍了一些常见的气体优化模式。
省油模式
您可以在代码中使用以下模式来减少 gas 消耗。
短路
短路是操作使用 || 时的一种策略或者 &&。这种模式的工作原理是首先对低成本操作进行排序,以便在第一个操作评估为真时跳过高成本操作(短路)。
// f(x) 成本低
// g(y) 很昂贵
// 顺序如下
f(x) || g(y)
f(x) && g(y)
不必要的库
库(libraries)通常仅用于少数用途,这意味着它们可能包含大量对您的智能合约来说是多余的代码。如果您可以在智能合约中安全高效地实现从库中导入的功能,那么最好这样做。
将 './SafeMath.sol' 导入为 SafeMath;
合约 SafeAddition {
function safeAdd(uint a, uint b) public pure returns(uint) {
return SafeMath.add(a, b);
}
}
合约 SafeAddition {
function safeAdd(uint a, uint b) public pure returns(uint) {
uint c = a + b;
require(c >= a, "加法溢出") ;
返回 c;
}
}
显式函数可见性
明确的功能可见性 安全性通常可以在智能合约安全性和 gas 优化方面带来好处。
显式标记一个外部函数数字货币合约计算器,例如强制将函数参数存储位置设置为calldata,这样每次执行函数都可以节省gas。
正确的数据类型
在 Solidity 中,某些数据类型比其他数据类型更昂贵。了解可以使用的最有效类型很重要。以下是有关数据类型的一些规则。
· 尽可能使用 uint 类型而不是字符串类型。
· 与 uint8 相比,uint256 类型存储的 gas 更少。
· 类型 byte 应该在 byte[] 上使用。
· 如果可以限制字节长度数字货币合约计算器,请使用字节 1 到字节 32 中最小的数字。
· 使用 bytes32 类型比使用 string 类型便宜。
用气方式
以下模式会增加gas成本,应避免。
死代码
死代码是永远不会运行的代码,因为它的计算基于始终返回 false 的条件。
function deadCode(uint x) public pure {
如果(x < 1) {
如果(x > 2) {
返回 x;
}
}
}
不透明谓词
有些条件的结果不执行就知道,所以不需要计算。
function opaquePredicate(uint x) public pure {
如果(x> 1) {
如果(x > 0) {
返回 x;
}
}
}
循环中的昂贵操作
在存储中管理变量比在内存中管理变量更好,因为 SLOAD 和 SSTORE 操作码变量更昂贵。因此,存储变量不应该在循环中使用。
uint num = 0;
函数昂贵循环(uint x)公共{
for(uint i = 0; i < x; i++) {
num += 1;
}
}
这种模式的解决方案是创建一个临时变量,代表全局变量,循环完成后,将临时变量的值重新赋值给全局变量。
uint num = 0;
function lessExpensiveLoop(uint x) public {
uint temp = num;
for(uint i = 0; i < x; i++) {
温度 += 1;
}
num = 温度;
}
循环的恒定结果
如果循环的结果是一个可以在编译时推断的常量,则不应使用它。
function constantOutcome() public pure returns(uint) {
uint num = 0;
for(uint i = 0; i < 100; i++) {
num += 1;
}
返回数字;
}
循环融合
有时在智能合约中,你可能会发现有两个循环。当循环参数相同时,没有理由使用单独的循环。
function loopFusion(uint x, uint y) 公共纯返回(uint) {
for(uint i = 0; i < 100; i++) {
x += 1;
}
for(uint i = 0; i < 100; i++) {
y += 1;
}
返回 x + y;
}
循环重复计算
如果循环中的表达式在下一次迭代中产生相同的结果,您可以将其移出循环。当表达式中使用的变量存储在内存中时,这一点尤其重要。
uint a = 4;
uint b = 5;
函数重复计算(uint x)公共返回(uint){
uint sum = 0;
for(uint i = 0; i