智能合约一旦部署上链将无法更改,因此在上线前的安全性检查与部署流程尤为重要。安全性是智能合约开发中的核心环节,不仅关乎用户资金安全,也直接影响项目的信誉与可持续发展。
作者
经验值
阅读时间
下面是对“智能合约常见漏洞与安全检查”的简明整理,包括漏洞类型与常用审计工具简介。
slither contracts/MyContract.sol
适合人群:开发者日常自检、CI 自动化安全检查。
阶段 | 建议工具 | 目的 |
开发阶段 | Slither | 快速静态检查 |
测试阶段 | MythX(或其他如 Mythril、Certora) | 深度漏洞扫描 |
上线前 | 手动审计 + 工具结合 | 提升安全保障 |
类型 | 生命周期 | 读写成本 | 适用场景 |
memory | 函数调用期间有效 | 便宜 | 临时变量处理 |
storage | 永久存储在链上 | 昂贵(写操作尤甚) | 保存状态变量 |
优化建议:
memory
。storage
写操作能避免就避免,如需多次写入,合并操作再写回。示例:
// ❌ 两个函数重复逻辑
function setA(uint val) public { a = val; }
function setB(uint val) public { b = val; }
// ✅ 合并优化
function setValue(string memory key, uint val) public {
if (keccak256(bytes(key)) == keccak256("a")) {
a = val;
} else if (keccak256(bytes(key)) == keccak256("b")) {
b = val;
}
}
internal
或 private
,可以减少一些安全性检查的开销。mapping
替代大部分数组。
// ❌ 低效写法
for (uint i = 0; i < array.length; i++) {
doSomething(array.length); // 重复计算
}
// ✅ 优化写法
uint len = array.length;
for (uint i = 0; i < len; i++) {
doSomething(len);
}
for (uint i = arr.length; i > 0; i--) {
// 比 i++ 更节省 Gas,因为 i 不需要与上限比较
}
技巧 | 描述 |
✅ 减少 storage 写操作 | 可改为一次性写入 |
✅ 使用 uint256 统一变量类型 | 避免类型转换消耗 |
✅ 状态变量顺序优化 | 相同类型变量可紧挨压缩存储 |
✅ 事件记录替代部分 storage 保存 | 节省存储成本,适用于只读历史 |
✅ 使用 immutable 或 constant | 编译期固定的变量节省 Gas |
类型 | 节省目标 | 示例技巧 |
数据存储 | 降低 storage 成本 | memory 处理、合并写入 |
函数调用 | 降低调用开销 | 函数合并、内部函数 |
循环效率 | 降低重复操作 | 常量缓存、mapping 替代 |
编译优化 | 编译器自动优化 | unchecked、immutable |
.env
文件保存私钥与 RPC(注意保密)
// hardhat.config.js
networks: {
sepolia: {
url: "https://sepolia.infura.io/v3/your_project_id",
accounts: [`0x${process.env.PRIVATE_KEY}`]
}
}
npx hardhat run scripts/deploy.js --network sepolia
✅ 上线前检查清单:
项目 | 描述 |
✅ 安全审计 | 使用 Slither、MythX 或手动审计 |
✅ Gas 优化 | 检查 storage 使用、函数调用等优化点 |
✅ 权限控制 | 确保 onlyOwner、reentrancyGuard 等安全设置正确 |
✅ 非测试代码 | 删除调试代码、确认 constructor 参数 |
✅ 合约不可变性 | 若使用 upgradeable 合约,需小心代理合约设计 |
⚠️ 注意事项:
npm install --save-dev @nomicfoundation/hardhat-verify
etherscan: {
apiKey: process.env.ETHERSCAN_API_KEY
}
npx hardhat verify --network sepolia YOUR_CONTRACT_ADDRESS "构造函数参数1" "参数2"
编译器版本(需与本地一致)
合约类型(单文件或多文件 Flattened)
构造函数参数(ABI 编码)
📦 使用 OpenZeppelin 合约库可减少重复代码并增强安全性。
🧪 测试合约时建议使用 forge test
或 Hardhat 的 npx hardhat test
,确保核心逻辑无误。
📄 验证合约后,可以在区块浏览器直接交互,非常利于用户或团队后续维护。