# 智能合约安全 ## 问题 1. 智能合约安全有哪些常见漏洞? 2. 什么是重入攻击(Reentrancy)?如何防范? 3. 什么是整数溢出/下溢?Solidity 0.8+如何处理? 4. 什么是访问控制漏洞?如何设计权限管理? 5. 什么是前置交易(Front-running)?如何防范? 6. 什么是闪电贷攻击?如何防范? 7. 什么是跨链桥安全风险? 8. 智能合约如何进行安全审计? 9. 使用哪些工具进行安全检测? 10. 智能合约有哪些最佳实践? --- ## 标准答案 ### 1. 常见智能合约漏洞 #### **OWASP Top 10 - Smart Contract** ``` 1. 重入攻击(Reentrancy) 2. 整数溢出/下溢(Arithmetic Issues) 3. 访问控制失败(Access Control) 4. 未检查的低级调用(Unchecked Low-Level Calls) 5. 前置交易(Front-running / TX Origin) 6. 时间戳依赖(Timestamp Manipulation) 7. 逻辑错误(Logic Errors) 8. Gas限制和循环(Gas Limit and Loops) 9. 默认可见性(Default Visibility) 10. 竞态条件(Race Conditions) ``` --- ### 2. 重入攻击(Reentrancy) #### **原理** 攻击者在合约更新状态之前,递归调用提款函数,多次提取资金。 #### **经典案例:The DAO攻击(2016)** ``` 1. 攻击者存入ETH到DAO合约 2. 攻击者调用withdraw() 3. DAO合约发送ETH给攻击者 4. 攻击者的fallback函数再次调用withdraw() 5. DAO合约未更新余额,再次发送ETH 6. 重复步骤3-5多次 7. 最终提取远超存款的ETH 损失:360万 ETH(当时价值约$7000万) ``` #### **漏洞代码** ```solidity // ❌ 易受攻击的合约 contract VulnerableBank { mapping(address => uint256) public balances; function deposit() public payable { balances[msg.sender] += msg.value; } function withdraw(uint256 amount) public { require(balances[msg.sender] >= amount, "Insufficient balance"); // ❌ 先转账,后更新状态(漏洞!) (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed"); // 更新状态(太晚了!) balances[msg.sender] -= amount; } } // 攻击合约 contract Attack { VulnerableBank public bank; constructor(address _bank) { bank = VulnerableBank(_bank); } // 存入ETH function attack() public payable { bank.deposit{value: msg.value}(); bank.withdraw(msg.value); } // fallback函数递归调用 fallback() external payable { if (address(bank).balance >= 1 ether) { bank.withdraw(1 ether); } } } ``` **攻击流程**: ``` 1. 攻击者调用attack(),存入1 ETH 2. 调用withdraw(1 ether) 3. 合约检查:balances[msg.sender] >= 1 ether ✓ 4. 合约发送1 ETH给攻击者 5. 攻击者合约的fallback()被触发 6. fallback()再次调用withdraw(1 ether) 7. 合约检查:balances[msg.sender]还是1 ether(未更新!)✓ 8. 合约再次发送1 ETH 9. 重复步骤5-8,直到合约余额不足 ``` --- #### **修复方案1:检查-生效-交互模式(CEI)** ```solidity // ✅ 安全的合约 contract SecureBank { mapping(address => uint256) public balances; function withdraw(uint256 amount) public { require(balances[msg.sender] >= amount, "Insufficient balance"); // ✅ 先更新状态 balances[msg.sender] -= amount; // ✅ 后交互(转账) (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed"); } } ``` --- #### **修复方案2:重入锁(ReentrancyGuard)** ```solidity // OpenZeppelin ReentrancyGuard abstract contract ReentrancyGuard { uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } modifier nonReentrant() { require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); _status = _ENTERED; _; _status = _NOT_ENTERED; } } // 使用ReentrancyGuard contract SecureBankWithGuard is ReentrancyGuard { mapping(address => uint256) public balances; function withdraw(uint256 amount) public nonReentrant { require(balances[msg.sender] >= amount, "Insufficient balance"); balances[msg.sender] -= amount; (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed"); } } ``` --- #### **修复方案3:Pull over Push模式** ```solidity // ✅ 使用Pull模式 contract PullOverPush { mapping(address => uint256) public balances; mapping(address => uint256) public withdrawals; function requestWithdraw(uint256 amount) public { require(balances[msg.sender] >= amount, "Insufficient balance"); balances[msg.sender] -= amount; withdrawals[msg.sender] += amount; } // 用户主动提取 function withdraw() public { uint256 amount = withdrawals[msg.sender]; require(amount > 0, "Nothing to withdraw"); withdrawals[msg.sender] = 0; (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed"); } } ``` --- ### 3. 整数溢出/下溢 #### **原理** ``` uint8 最大值:255 uint8 最小值:0 溢出: 255 + 1 = 0(回绕) 下溢: 0 - 1 = 255(回绕) Solidity 0.8+ 自动检查溢出/下溢 旧版本需要使用SafeMath库 ``` #### **漏洞代码** ```solidity // ❌ Solidity 0.8之前 contract VulnerableToken { uint8 public totalSupply = 255; function mint(uint8 amount) public { // 溢出:255 + 1 = 0 totalSupply += amount; } } // 攻击 // mint(1) → totalSupply = 0(溢出!) ``` #### **修复方案** **Solidity 0.8+**(自动检查): ```solidity // ✅ Solidity 0.8+ contract SecureToken { uint256 public totalSupply; function mint(uint256 amount) public { // ✅ 自动检查溢出,失败会revert totalSupply += amount; } } ``` **SafeMath库**(旧版本): ```solidity library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } } contract SecureTokenWithSafeMath { using SafeMath for uint256; uint256 public totalSupply; function mint(uint256 amount) public { // ✅ 使用SafeMath检查溢出 totalSupply = totalSupply.add(amount); } } ``` --- ### 4. 访问控制漏洞 #### **常见问题** ``` 1. 函数未设置访问控制 2. 使用tx.origin认证(中间人攻击) 3. 权限提升漏洞 ``` #### **漏洞代码1:未保护的函数** ```solidity // ❌ 任何人都可以调用 contract Vulnerable { address public owner; uint256 public price = 100; function setPrice(uint256 _price) public { // ❌ 没有权限检查 price = _price; } } ``` **修复**: ```solidity // ✅ 使用onlyOwner修饰符 contract Secure { address public owner; uint256 public price = 100; constructor() { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "Not owner"); _; } function setPrice(uint256 _price) public onlyOwner { // ✅ 只有owner可以调用 price = _price; } } ``` --- #### **漏洞代码2:tx.origin认证(钓鱼攻击)** ```solidity // ❌ 易受钓鱼攻击 contract Wallet { address public owner; constructor() { owner = msg.sender; } function withdraw() public { // ❌ 使用tx.origin(不安全!) require(tx.origin == owner, "Not owner"); payable(msg.sender).transfer(address(this).balance); } } // 攻击合约 contract AttackWallet { Wallet public wallet; constructor(address _wallet) { wallet = Wallet(_wallet); } function attack() public { // 诱导owner调用这个函数 wallet.withdraw(); } fallback() external payable { // 转账给攻击者 payable(msg.sender).transfer(msg.value); } } ``` **攻击流程**: ``` 1. 攻击者创建AttackWallet合约 2. 攻击者诱导owner调用AttackWallet.attack() 3. attack()调用Wallet.withdraw() 4. Wallet检查:tx.origin == owner ✓(owner是调用者) 5. msg.sender是AttackWallet合约 6. 资金转给AttackWallet合约 7. AttackWallet的fallback()把资金转给攻击者 ``` **修复**: ```solidity // ✅ 使用msg.sender contract SecureWallet { address public owner; constructor() { owner = msg.sender; } modifier onlyOwner() { require(msg.sender == owner, "Not owner"); _; } function withdraw() public onlyOwner { // ✅ 使用msg.sender payable(msg.sender).transfer(address(this).balance); } } ``` --- #### **漏洞代码3:权限提升** ```solidity // ❌ 可以提升自己为管理员 contract AccessControl { mapping(address => bool) public admins; address public owner; constructor() { owner = msg.sender; admins[owner] = true; } function addToAdmin(address _user) public { // ❌ 没有检查调用者是否是admin admins[_user] = true; } } // 攻击 // 攻击者调用addToAdmin(攻击者地址) // 攻击者成为管理员 ``` **修复**: ```solidity // ✅ 检查调用者权限 contract SecureAccessControl { mapping(address => bool) public admins; address public owner; constructor() { owner = msg.sender; admins[owner] = true; } modifier onlyAdmin() { require(admins[msg.sender], "Not admin"); _; } function addToAdmin(address _user) public onlyAdmin { // ✅ 只有admin可以添加新admin admins[_user] = true; } } ``` --- ### 5. 前置交易(Front-running) #### **原理** 攻击者看到交易在内存池(Mempool)中,复制交易并设置更高的Gas Price,让自己的交易先执行。 #### **示例场景** ``` 1. 用户在DEX上用1 ETH买UNI(价格$10) 2. 攻击者看到这笔交易 3. 攻击者设置更高Gas Price,抢先买入 4. 用户交易执行,价格被推高到$11 5. 攻击者立即卖出,获利 用户损失:原本应该花$10,实际花了$11 攻击者获利:$1/UNI × 交易数量 ``` #### **代码示例** ```solidity // ❌ 易受前置交易攻击 contract VulnerableDEX { mapping(address => uint256) public prices; function setPrice(address token, uint256 price) public { // ❌ 可以被抢先交易 prices[token] = price; } function trade(address token, uint256 amount) public { uint256 price = prices[token]; // 使用price交易 } } ``` #### **修复方案1:提交-揭示模式(Commit-Reveal)** ```solidity // ✅ 使用Commit-Reveal contract CommitReveal { struct Commitment { bytes32 commitHash; uint256 revealTime; bool revealed; } mapping(address => Commitment) public commitments; mapping(address => uint256) public revealedValues; // 1. 提交哈希(隐藏真实值) function commit(bytes32 commitHash) public { commitments[msg.sender] = Commitment({ commitHash: commitHash, revealTime: block.timestamp + 1 days, revealed: false }); } // 2. 揭示真实值(1天后) function reveal(uint256 value, uint256 salt) public { Commitment storage c = commitments[msg.sender]; require(!c.revealed, "Already revealed"); require(block.timestamp >= c.revealTime, "Too early"); // 验证哈希 bytes32 computedHash = keccak256(abi.encodePacked(value, salt)); require(computedHash == c.commitHash, "Invalid reveal"); c.revealed = true; revealedValues[msg.sender] = value; } } ``` --- #### **修复方案2:批量交易** ```solidity // ✅ 批量执行交易,减少前置交易 contract BatchTrade { struct Trade { address user; address token; uint256 amount; uint256 price; } Trade[] public pendingTrades; function submitTrade(address token, uint256 amount) public { pendingTrades.push(Trade({ user: msg.sender, token: token, amount: amount, price: 0 // 后续设置 })); } // 批量执行所有交易 function executeBatch() public { for (uint256 i = 0; i < pendingTrades.length; i++) { Trade memory t = pendingTrades[i]; // 使用平均价格执行所有交易 executeTrade(t); } delete pendingTrades; } } ``` --- ### 6. 闪电贷攻击 #### **原理** ``` 1. 攻击者闪电贷借入大量资金 2. 使用资金操纵市场(如DEX价格) 3. 利用被操纵的价格获利(如套利、清算) 4. 还款 + 手续费 5. 如果失败,交易回滚(无风险) ``` #### **攻击示例** ```solidity // 闪电贷攻击DEX contract FlashLoanAttack { IUniswapV2Router public router; IUniswapV2Pair public pair; function attack() external { // 1. 闪电贷借入10,000 ETH flashLoan(10000 ether); // 2. 在DEX上用10,000 ETH卖出代币 // → 价格被砸到极低 // 3. 在另一个DEX用低价买回代币 // → 赚取差价 // 4. 还款 10,000 ETH + 手续费 repayFlashLoan(10000 ether); } } ``` #### **防范措施** ``` 1. 使用时间加权平均价格(TWAP) - 链下预言机(Chainlink) - 多个价格源聚合 2. 限制单笔交易规模 - 最大交易量限制 - 滑点保护 3. 闪电贷检测 - 单个区块内大额交易 - 可疑价格波动告警 4. 暂停机制 - 检测到攻击时暂停合约 - 多重签名恢复 ``` **代码示例:TWAP预言机**: ```solidity // ✅ 使用TWAP预言机 contract TWAPOracle { uint256 public price; uint256 public lastUpdateTime; uint256 public constant PERIOD = 1 hours; function updatePrice(uint256 newPrice) external { if (block.timestamp >= lastUpdateTime + PERIOD) { // 时间到了,可以更新 price = newPrice; lastUpdateTime = block.timestamp; } else { // 未到期,使用加权平均 uint256 timeElapsed = block.timestamp - lastUpdateTime; uint256 weight = timeElapsed * 100 / PERIOD; price = (price * (100 - weight) + newPrice * weight) / 100; } } } ``` --- ### 7. 跨链桥安全风险 #### **常见攻击** ``` 1. 验证节点私钥泄露 - Ronin Bridge:$6.25亿被盗 - 攻击者控制了5/9个验证节点 2. 伪造签名 - Wormhole:$3.2亿被盗 - 攻击者伪造了验证者签名 3. 智能合约漏洞 - Harmony Bridge:$1亿被盗 - 漏洞允许绕过验证 4. 逻辑漏洞 - Nomad Bridge:$1.9亿被盗 - 漏洞允许任何人伪造消息 ``` #### **安全设计原则** ```solidity // ✅ 安全的跨链桥设计 contract SecureBridge { // 1. 多重签名验证 mapping(bytes32 => bool) public usedSignatures; address[] public validators; modifier validateSignature(bytes32 message, bytes memory signature) { require(verifySignature(message, signature), "Invalid signature"); require(!usedSignatures[keccak256(signature)], "Signature used"); _; } // 2. 延迟提款(给用户时间取消) mapping(address => uint256) public pendingWithdrawals; uint256 public constant DELAY = 24 hours; function requestWithdraw(address token, uint256 amount) public { pendingWithdrawals[msg.sender] = block.timestamp; emit WithdrawRequested(msg.sender, token, amount); } function executeWithdraw(address token, uint256 amount) public { require( block.timestamp >= pendingWithdrawals[msg.sender] + DELAY, "Delay not met" ); // 执行提款 } // 3. 暂停机制 bool public paused; modifier whenNotPaused() { require(!paused, "Paused"); _; } function pause() public { // 多重签名 paused = true; } } ``` --- ### 8. 智能合约安全审计 #### **审计流程** ``` 1. 文档审查 - 白皮书 - 技术文档 - 经济模型 2. 代码审查 - 手动代码审查 - 自动化工具扫描 - 测试覆盖率检查 3. 测试 - 单元测试 - 集成测试 - 模糊测试(Fuzzing) 4. 形式化验证 - 数学证明 - 不变量检查 5. 渗透测试 - 模拟攻击 - 红队演练 ``` --- #### **审计清单** ``` ✅ 访问控制 - 所有敏感函数都有访问控制 - 使用OpenZeppelin的AccessControl ✅ 重入保护 - 外部调用在状态更新之后 - 使用ReentrancyGuard ✅ 整数溢出 - 使用Solidity 0.8+ - 或使用SafeMath ✅ 外部调用 - 检查返回值 - 使用try-catch ✅ Gas优化 - 循环有限制 - 避免动态数组 ✅ 测试 - 单元测试覆盖率 > 90% - 集成测试 - 边界条件测试 ✅ 文档 - NatSpec注释 - 清晰的函数说明 - 使用示例 ``` --- ### 9. 安全检测工具 #### **静态分析工具** ``` 1. Slither - Python开发 - 快速扫描 - 检测常见漏洞 安装: pip install slither-analyzer 使用: slither contract.sol ``` ```bash # Slither扫描示例 $ slither token.sol ... INFO:Detectors: Reentrancy in Token.withdraw(uint256) (token.sol#45-50): External calls: - msg.sender.call{value: amount}(gas()) (token.sol#48) State variables written after the call(s): - balances[msg.sender] -= amount (token.sol#49) ``` --- ``` 2. MythX - 商业工具 - 深度分析 - 支持多种漏洞检测 使用: mythx analyze contract.sol ``` --- ``` 3. Echidna - 模糊测试工具 - 基于属性的测试 - 发现边缘情况 安装: cargo install echidna 使用: echidna-test contract.sol ``` **Echidna示例**: ```solidity // 测试不变量:总供应量 = 所有人余额之和 contract Token { mapping(address => uint256) public balanceOf; uint256 public totalSupply; function transfer(address to, uint256 amount) public { balanceOf[msg.sender] -= amount; balanceOf[to] += amount; } } // Echidna测试 contract TestToken is Token, Test { function check_total_supply() public { uint256 sum = 0; // 计算所有余额(需要手动添加) assert(totalSupply == sum); } } ``` --- ``` 4. Mythril - 符号执行引擎 - 深度漏洞检测 - 支持攻击路径分析 安装: pip install mythril 使用: myth contract.sol ``` --- #### **动态分析工具** ``` 1. Hardhat + Tenderly - 交易模拟 - Gas分析 - 调试工具 2. Ganache - 本地测试网络 - 快速部署测试 3. Fork测试 - Fork主网状态 - 在真实环境测试 ``` **Fork测试示例**: ```javascript // hardhat.config.js module.exports = { networks: { hardhat: { forking: { url: "https://eth-mainnet.alchemyapi.io/v2/YOUR-API-KEY", blockNumber: 15000000, // Fork特定区块 }, }, }, }; // 测试 describe("Uniswap Fork Test", function () { it("should swap on real Uniswap", async function () { // 在主网Uniswap上交易(不花真钱) const uniswap = await ethers.getContractAt("IUniswapV2Router", UNISWAP_ROUTER); await uniswap.swapExactETHForTokens(...); }); }); ``` --- ### 10. 智能合约最佳实践 #### **1. 使用OpenZeppelin库** ```solidity // ✅ 不要重复造轮子 import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; contract MyToken is ERC20, Ownable, ReentrancyGuard { constructor() ERC20("My Token", "MTK") {} function mint(address to, uint256 amount) public onlyOwner { _mint(to, amount); } } ``` --- #### **2. 检查-生效-交互模式** ```solidity // ✅ CEI模式 function withdraw(uint256 amount) public { // 1. 检查(Checks) require(balances[msg.sender] >= amount, "Insufficient"); // 2. 生效(Effects) balances[msg.sender] -= amount; // 3. 交互(Interactions) (bool success, ) = msg.sender.call{value: amount}(""); require(success, "Transfer failed"); } ``` --- #### **3. 使用SafeERC20** ```solidity import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; contract SafeTransfer { using SafeERC20 for IERC20; function transferToken(address token, address to, uint256 amount) public { // ✅ 自动处理返回值 IERC20(token).safeTransfer(to, amount); } } ``` --- #### **4. 停止机制(Emergency Pause)** ```solidity import "@openzeppelin/contracts/security/Pausable.sol"; contract PausableContract is Pausable, Ownable { function deposit() public payable whenNotPaused { // 正常逻辑 } function pause() public onlyOwner { _pause(); } function unpause() public onlyOwner { _unpause(); } } ``` --- #### **5. 事件日志** ```solidity contract LogEvents { event Withdrawal(address indexed user, uint256 amount, uint256 timestamp); function withdraw(uint256 amount) public { // ✅ 记录所有重要操作 emit Withdrawal(msg.sender, amount, block.timestamp); // 执行提款 payable(msg.sender).transfer(amount); } } ``` --- #### **6. 限流机制** ```solidity contract RateLimiter { mapping(address => uint256) public lastCallTime; uint256 public constant COOLDOWN = 1 minutes; modifier rateLimit() { require( block.timestamp >= lastCallTime[msg.sender] + COOLDOWN, "Cooldown not met" ); _; lastCallTime[msg.sender] = block.timestamp; } function sensitiveOperation() public rateLimit { // 限制每个用户每分钟只能调用一次 } } ``` --- #### **7. 多重签名钱包** ```solidity // ✅ 关键操作使用多签 contract MultiSigWallet { address[] public owners; uint256 public required; mapping(uint256 => Transaction) public transactions; mapping(uint256 => mapping(address => bool)) public confirmations; struct Transaction { address to; uint256 value; bytes data; bool executed; } function submitTransaction(address to, uint256 value, bytes memory data) public { uint256 txIndex = transactions.length; transactions[txIndex] = Transaction({ to: to, value: value, data: data, executed: false }); confirmTransaction(txIndex); } function confirmTransaction(uint256 txIndex) public { // 需要多个所有者确认 confirmations[txIndex][msg.sender] = true; if (isConfirmed(txIndex)) { executeTransaction(txIndex); } } function isConfirmed(uint256 txIndex) public view returns (bool) { uint256 count = 0; for (uint256 i = 0; i < owners.length; i++) { if (confirmations[txIndex][owners[i]]) { count += 1; } } return count >= required; } } ``` --- #### **8. 升级模式** ```solidity // ✅ 使用代理模式升级 contract LogicV1 { uint256 public value; function setValue(uint256 _value) public { value = _value; } } contract LogicV2 { uint256 public value; uint256 public newValue; function setValue(uint256 _value) public { value = _value; newValue = _value * 2; } } // 使用OpenZeppelin Transparent Proxy import "@openzeppelin/contracts/proxy/transparent/TransparentUpgradeableProxy.sol"; // 部署 // 1. 部署LogicV1 // 2. 部署Proxy,指向LogicV1 // 3. 用户通过Proxy交互 // 4. 升级:部署LogicV2,调用Proxy.upgradeTo(LogicV2) ``` --- ## 结合简历的面试题 ### 1. 电商风控 vs DeFi安全 **面试官会问**: > "你在电商做过风控系统,DeFi安全有什么异同?" **参考回答**: ``` 电商风控: - 反欺诈:识别虚假订单、刷单 - 信用评估:用户信用评分 - 异常检测:异常交易行为 DeFi安全: - 智能合约审计:代码漏洞检测 - 链上监控:异常交易监控 - 价格预言机:防止价格操纵 - MEV保护:防止三明治攻击 共同点: - 需要实时监控系统 - 需要异常检测机制 - 需要快速响应机制 差异: - 电商:中心化,可以人工介入 - DeFi:去中心化,只能通过智能合约 ``` --- ### 2. 高并发与Gas优化 **面试官会问**: > "你做过高并发系统,智能合约如何优化Gas?" **参考回答**: ``` Web2高并发: - 缓存热点数据 - 异步处理 - 数据库优化 Web3 Gas优化: 1. 存储优化 - 使用打包类型(uint256 vs uint8) - 使用短字符串 - 删除不需要的数据(refund gas) 2. 循环优化 - 限制循环次数 - 使用mapping代替array查找 3. 批量操作 - 批量转账 - 批量Mint 4. 链下计算 - Merkle Tree - 零知识证明 示例: // ❌ 高Gas for (uint256 i = 0; i < 1000; i++) { users[i].reward = calculateReward(i); } // ✅ 低Gas(链下计算 + Merkle Proof) bytes32 public merkleRoot; function claimReward(uint256 amount, bytes32[] memory proof) public { require(verifyMerkleProof(msg.sender, amount, proof), "Invalid proof"); payable(msg.sender).transfer(amount); } ``` --- ## 智能合约安全面试加分项 ### 1. 实战经验 - 参与过智能合约审计 - 发现过真实漏洞 - 有漏洞修复经验 - 熟悉常见攻击手法 ### 2. 技术深度 - 理解EVM底层机制 - 熟悉汇编语言(Yul) - 了解形式化验证 - 掌握Gas优化技巧 ### 3. 工具使用 - 熟练使用Slither、MythX - 会使用Foundry测试框架 - 会使用Tenderly调试 - 了解Fuzzing测试 ### 4. 安全意识 - 防御性编程思维 - 最小权限原则 - 深度防御策略 - 持续学习最新漏洞