hardhat 中使用 gas reporter 来优化 gas 的详细说明。
之前文章中提到了在 hardhat 中使用 gas reporter 来优化 gas,因为篇幅有限,所以另开一篇文章来详细介绍 gas reporter 的使用场景及优化策略。
Gas Reporter 是一个 Hardhat 插件,用于分析智能合约的 Gas 消耗,帮助开发者:
安装插件
npm install --save-dev hardhat-gas-reporter
配置文件 (hardhat.config.js
)
require("hardhat-gas-reporter"); // 引入插件
module.exports = {
solidity: "0.8.20",
gasReporter: {
enabled: true, // 开启报告
currency: "USD", // 费用单位(ETH/USD/EUR等)
gasPrice: 20, // Gas 单价(单位:Gwei,默认取当前网络价格)
coinmarketcap: process.env.COINMARKETCAP_KEY, // API 获取实时价格
outputFile: "gas-report.txt", // 输出到文件
noColors: true, // 文件输出时禁用颜色
excludeContracts: ["MockToken"] // 排除特定合约
}
};
执行测试时生成报告
npx hardhat test
报告会在测试完成后自动打印在控制台。
示例输出
·----------------------------|----------------------------|-------------|----------------------------·
| Solidity Contract · Method · Min (Gas) · Max (Gas) · Avg (Gas) ·
·----------------------------|----------------------------|-------------|-------------|-------------·
| MyContract · transfer · 28912 · 51234 · 43210 ·
| MyContract · approve · 2345 · 2345 · 2345 ·
·----------------------------|----------------------------|-------------|-------------|-------------·
·-------------------------|---------------------------|-------------·
| Network · Eth Price (USD) · Gas Price ·
·-------------------------|---------------------------|-------------·
| sepolia · $1,800 · 20 Gwei ·
·-------------------------|---------------------------|-------------·
核心字段
coinmarketcap
API)。关键指标
bytes
压缩数据)。// 优化前:多次修改存储变量
function updateValue(uint256 newValue) public {
value = newValue; // 第一次 SSTORE(消耗 Gas)
lastUpdate = block.timestamp; // 第二次 SSTORE(更高 Gas)
}
// 优化后:合并存储变量或使用 Memory
struct State {
uint256 value;
uint256 lastUpdate;
}
State private state;
function updateValue(uint256 newValue) public {
state = State(newValue, block.timestamp); // 单次 SSTORE
}
constant
/immutable
)// 优化前:每次读取需 SLOAD
address public owner;
// 优化后:编译时确定值,Gas 为 0
address public constant OWNER = 0x...;
// 优化前:浪费存储槽
uint128 a;
uint256 b; // 单独占用一个槽
uint128 c;
// 优化后:将 a 和 c 打包到同一槽
uint128 a;
uint128 c;
uint256 b;
unchecked
块// 优化前:安全但消耗更多 Gas
function increment(uint256 x) public pure returns (uint256) {
return x + 1;
}
// 优化后:明确无需溢出检查时节省 Gas
function increment(uint256 x) public pure returns (uint256) {
unchecked { return x + 1; }
}
// 优化前:重复计算相同值
function calculate(uint256 a, uint256 b) public pure {
uint256 sum = a + b;
require(sum > 100, "Invalid sum");
return sum * 2;
}
// 优化后:缓存中间结果
function calculate(uint256 a, uint256 b) public pure {
uint256 sum = a + b;
require(sum > 100, "Invalid sum");
uint256 result = sum * 2;
return result;
}
之前还写过一篇gas优化必须掌握的知识点 这里可以算是对 gas 优化内容的补充,需要的同学自行查阅。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!