1. 未校验的外部输入
漏洞描述:
合约未对外部输入进行正确的验证,可能导致漏洞。
修改前的例子:
solidityCopy codecontract Vulnerable {
function setAdmin(address _newAdmin) public {
admin = _newAdmin;
}
}
修改建议:
对所有外部输入进行正确的验证,确保它们满足预期的条件。
修改后的例子:
solidityCopy codecontract Secure {
function setAdmin(address _newAdmin) public {
// 添加输入验证
require(_newAdmin != address(0), "Invalid address");
admin = _newAdmin;
}
}
2. 合约破产(Contract Bankruptcy)
漏洞描述:
当合约的余额耗尽时,合约可能无法继续执行操作。
修改前的例子:
solidityCopy codecontract Vulnerable {
function withdrawAll() public {
msg.sender.transfer(address(this).balance);
}
}
修改建议:
在涉及余额的操作之前检查余额是否足够,以防止合约破产。
修改后的例子:
solidityCopy codecontract Secure {
function withdrawAll() public {
// 添加余额检查
require(address(this).balance > 0, "Insufficient balance");
msg.sender.transfer(address(this).balance);
}
}
3. 随机数不可信
漏洞描述:
区块链上的随机数是不可信的,因此依赖于它们可能导致不安全的实现。
修改前的例子:
solidityCopy codecontract Vulnerable {
function generateRandomNumber() public view returns (uint) {
// 不可预测的随机数
return uint(keccak256(abi.encodePacked(blockhash(block.number))));
}
}
修改建议:
避免在合约中依赖区块链上的随机数,考虑使用链外的随机数服务。
修改后的例子:
solidityCopy codecontract Secure {
function generateRandomNumber() public view returns (uint) {
// 不可预测的随机数
return uint(keccak256(abi.encodePacked(blockhash(block.number))));
}
}
4. Gas 竞拍(Gas Auction)
漏洞描述:
合约中使用复杂的计算或循环可能导致 Gas 竞拍,使攻击者能够调整 Gas 费用。
修改前的例子:
solidityCopy codecontract Vulnerable {
function consumeGas() public {
for (uint i = 0; i < 1e18; i++) {
// ...
}
}
}
修改建议:
避免在合约中使用复杂的计算或循环,使用 Gas 限制来限制计算的复杂性。
修改后的例子:
solidityCopy codecontract Secure {
function consumeGas() public {
// 添加 Gas 限制
require(gasleft() > 10000, "Not enough gas");
for (uint i = 0; i < 1e18; i++) {
// ...
}
}
}