CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
区块链入门/课时/安全与测试
RawBlame
课时目录12 节

区块链入门

  1. 01区块链是什么
  2. 02结构与共识
  3. 03链类型与扩容
  4. 04EVM 生态
  5. 05智能合约与 Solidity
  6. 06开发工具链
  7. 07DApp 与 Web3 前端
  8. 08DeFi 与应用场景
  9. 09预言机
  10. 10安全与测试
  11. 11部署与节点运维
  12. 12综合练习

安全与测试

fuzz、威胁向量、随机数攻击、Echidna。

35 分钟

安全与测试

智能合约部署后难以修补,安全与测试必须前置。本课覆盖常见威胁向量、模糊测试(Fuzz)、随机数陷阱与 Echidna 等工具。见 /roadmaps/blockchain。

学习目标

  • 识别重入、权限绕过、整数精度等高频漏洞
  • 用 Hardhat/Foundry 编写单元测试与 Fuzz 测试
  • 了解 Echidna 属性测试的基本思路

威胁向量

攻击机制防御
重入外部调用回调再次进入Checks-Effects-Interactions;ReentrancyGuard
权限提升缺少 onlyOwnerOpenZeppelin AccessControl
前端运行用户交易被抢跑commit-reveal;私有 mempool
预言机操纵瞬时价格失真多源喂价、TWAP
错误随机数用 block.timestamp 当随机Chainlink VRF

重入示例与修复

// 脆弱:先转账后改余额
function withdraw(uint256 amount) external {
    require(balances[msg.sender] >= amount);
    (bool ok,) = msg.sender.call{value: amount}("");
    require(ok);
    balances[msg.sender] -= amount; // 太晚了
}

// 修复:先改状态
function withdrawSafe(uint256 amount) external nonReentrant {
    require(balances[msg.sender] >= amount);
    balances[msg.sender] -= amount;
    (bool ok,) = msg.sender.call{value: amount}("");
    require(ok);
}

Fuzz 与属性测试

Foundry 内置 fuzz:随机 amount 不应破坏总供应量不变量。

function testFuzz_transfer(uint256 amount) public {
    amount = bound(amount, 0, token.balanceOf(address(this)));
    token.transfer(recipient, amount);
    assertGe(token.balanceOf(recipient), 0);
}

Echidna 用 echidna_* 函数声明应始终成立的全局属性,例如「任意地址余额 ≤ totalSupply」,适合发现边界组合漏洞。

练习

  • 故意写一个带重入漏洞的 withdraw,用测试证明可被攻击
  • 为 ERC-20 添加一条 Foundry fuzz 测试
  • 运行 Slither,修复至少一条 medium 以上告警

小结

链上无 hotfix,测试与审计就是发布流程的一部分。 下一课讲解部署、RPC 节点与运维监控。

加载本节练习…
← 上一课预言机下一课 →部署与节点运维