42 lines
1.4 KiB
Markdown
42 lines
1.4 KiB
Markdown
---
|
||
title: "ChecksEffectsInteractions"
|
||
type: concept
|
||
tags: []
|
||
last_updated: 2026-05-01
|
||
---
|
||
|
||
## Definition
|
||
_checks-effects-interactions_ 是 Solidity 智能合约开发的核心安全原则,规定函数内操作必须按以下顺序执行:
|
||
|
||
1. **Checks**:验证前置条件(require/assert 语句)
|
||
2. **Effects**:更新合约内部状态(状态变量修改)
|
||
3. **Interactions**:执行外部调用(token transfer、合约调用等)
|
||
|
||
## Why It Matters
|
||
违反此顺序会导致 **重入攻击(Reentrancy Attack)**。如果外部调用在状态更新之前执行,攻击者的恶意合约可以在状态仍然显示"资金未提取"的情况下递归调用 withdraw(),反复提取资金。
|
||
|
||
### Vulnerable Pattern (违反 CEI)
|
||
```solidity
|
||
function withdraw(uint256 amount) external {
|
||
require(balances[msg.sender] >= amount);
|
||
// ❌ 外部调用在状态更新之前
|
||
msg.sender.call{value: amount}("");
|
||
balances[msg.sender] -= amount; // 太晚了
|
||
}
|
||
```
|
||
|
||
### Secure Pattern (遵循 CEI)
|
||
```solidity
|
||
function withdraw(uint256 amount) external {
|
||
require(balances[msg.sender] >= amount);
|
||
balances[msg.sender] -= amount; // ✅ 先更新状态
|
||
emit Withdrawal(msg.sender, amount);
|
||
msg.sender.call{value: amount}(""); // ✅ 最后外部调用
|
||
}
|
||
```
|
||
|
||
## Sources
|
||
- [[engineering-solidity-smart-contract-engineer]]
|
||
- [[The-DAO]]
|
||
- [[blockchain-security-auditor]]
|