🔐 6.1 如何防范重放攻击、私钥泄露、钓鱼签名?
✅ 重放攻击(Replay Attack)防范:
引入 nonce:每次登录或交易签名都携带唯一 nonce;
链 ID 检查:在签名中加入特定链 ID,防止跨链重放;
使用 EIP-712 签名结构:结构化签名防止签名滥用。
✅ 私钥泄露防范:
从不把私钥写入前端代码或硬盘明文保存;
后端钱包使用冷钱包或 HSM 服务(如 AWS KMS, Fireblocks);
使用环境变量加密存储助记词或私钥,部署中使用
.env + vault
;限制私钥操作权限,冷热钱包分离;
✅ 钓鱼签名防范:
签名前显示明确信息说明(如“登录授权而非转账”);
使用 EIP-712 结构化数据签名,避免用户签不明数据;
前端签名提示加上网站来源(如
yourapp.com
)+ 描述;
⚡ 6.2 什么是“前置运行攻击”(Front-running)?怎么防御?
✅ 定义:
Front-running 是攻击者监听 mempool,抢在用户交易之前提交相同或对其有利的交易(如抢先购买 NFT、调整价格、抢矿);
🛡️ 防御方式:
使用 commit-reveal 策略:
用户先提交加密数据(commit),后提交明文(reveal);
延迟执行 + 随机性机制:
引入链上随机数,避免固定执行顺序;
Flashbots:
将交易发送至 Flashbots 私有池,避免泄露到公共 mempool;
签名授权后端执行:
用户授权后由后端发送交易,缩短暴露时间窗口;
🎁 6.3 如果要做代币空投(Airdrop),你如何设计安全的分发策略?
✅ 目标:确保代币安全发放、避免滥领、节省 Gas。
📌 安全空投策略设计:
Merkle Tree 空投(常用):
构造用户地址+数量的 Merkle Root,存入合约;
用户自行调用
claim()
提供 Merkle proof;✅ 优点:一次部署即可支持大规模空投,节省 Gas;
✅ 防止重复领取,通过记录
claimed[address] = true
;
签名式空投:
后端为每个地址签名分发信息;
用户提交签名至合约,合约验证签名;
适合灵活分发、动态设置领取者;
Batch Transfer + 权限限制:
批量发送空投(
transferBatch()
);控制可操作账户,避免私钥被盗后滥发;
✅ 安全建议:
空投逻辑使用开源库(如 OpenZeppelin MerkleDistributor);
空投合约部署后不可修改 Merkle Root;
添加空投截止时间、防多次领取、防重入等措施;
🔁 6.4 合约升级有几种方式?各自的优缺点?
✅ 1. 代理合约(Proxy Pattern):
实现方式:使用
delegatecall
将调用转发至逻辑合约;典型模式:
Transparent Proxy(OpenZeppelin)
UUPS Proxy(更轻量,推荐)
模式 | 优点 | 缺点 |
---|---|---|
Transparent | 稳定,OpenZeppelin支持 | 存储布局要求严格,结构复杂 |
UUPS | 更节省 Gas,可自定义升级逻辑 | 升级函数自身易被攻击,需审慎授权 |
✅ 2. 数据迁移升级:
新部署一个合约,人工迁移数据;
✅ 优点:无 delegatecall 安全风险;
❌ 缺点:迁移成本高、用户需重新授权;
✅ 3. Eternal Storage 模式:
将状态变量独立放在一个固定合约;
易维护,但结构复杂、不推荐新项目使用;
🧨 6.5 哪些 Solidity 编码模式容易出安全漏洞?
🚨 常见风险编码模式:
漏洞类型 | 示例代码 / 描述 | 防御方式 |
---|---|---|
重入攻击 | 调用外部合约前修改状态(如提现) | Checks-Effects-Interactions;使用 ReentrancyGuard |
整数溢出/下溢 | uint256 a = b - c(未判断 b > c) | 使用 SafeMath 或启用 Solidity ≥0.8 自动检查 |
无访问控制 | 没有限制 setOwner() |
添加 onlyOwner 或 AccessControl |
调用未初始化合约地址 | 外部合约地址为空调用 | require 地址非 0 且合约存在 |
delegatecall 滥用 | 调用非可信合约逻辑代码 | 限制 delegatecall 使用,仅可信模块 |
Gas limit 不足 | 数组遍历转账 gas 用尽,状态不变 | 加限制、使用 pull 模式而非 push |
tx.origin 验证身份 | require(tx.origin == owner) 易被 phishing |
用 msg.sender 替代 tx.origin |
📌 总结建议:
使用 OpenZeppelin 工具、Hardhat 插件审计合约;
引入 CI 检查(如
slither
、mythx
);所有用户交互都应防御重入、钓鱼、溢出、权限越权;
升级合约需严格测试、控制 upgrade 权限;
尽量使用 audited 合约库,避免“自己写轮子”;