Xinmin's Blog
AdminRSS
全部AIDeFiSolidity以太坊公链实战区块链行业观察
Admin
RSS

【以太坊】从0到1打造安全智能合约:我的开发经验

以太坊·2025年3月18日·1 次阅读·约 10 分钟
© 2026·

关注我,带你转型Web3开发,分享我从2018年入行区块链以来的开发经验(DeFi/GameFi/NFT/DAO/OTC/钱包/Trading Bot/MEME Launch)

[公众号名片占位]

智能合约上了链就基本没法改,所以安全必须放第一位。 以下是我在开发智能合约时总结的一些安全经验,分享给你,希望能帮助你写出更安全、更靠谱的智能合约。

智能合约安全系列回放:【以太坊】聊聊智能合约的重入攻击【以太坊】聊聊智能合约的溢出攻击【以太坊】聊聊智能合约的未授权访问攻击【以太坊】聊聊智能合约的Permit2钓鱼攻击【以太坊】聊聊智能合约的闪电贷攻击【以太坊】聊聊智能合约的0转账钓鱼攻击【以太坊】聊聊智能合约的时间戳依赖攻击

合约得支持升级

除了资产类合约(像 ERC20、ERC721、ERC1155),业务类合约最好用代理模式支持升级,推荐 UUPS(比 Transparent 或 Beacon 更省 gas)。万一出了漏洞,能及时修补,减少项目损失。升级时记住:状态变量只加不删、顺序别动、类型别变,继承顺序也别乱。不过别慌,Hardhat这类工具会提醒你。

单元测试不偷懒

单元测试是合约安全第一关。每个方法都写详细测试用例,各种输入都试试,尤其是边缘情况和跟钱相关的逻辑,尽早挖出问题。推荐Foundry(编译快,能用Solidity写测试)或Hardhat,效率高又方便。

安全审计少不了

安全审计是合约安全第二关,DeFi项目尤其得重视。专业团队会审查代码、模拟攻击,找出隐藏风险。部署前至少审一次,按报告修Bug。高价值项目多审几次,或者找几家交叉验证。小项目可以找小审计公司,便宜也能干好安全工作;大牌公司贵点,但能背书口碑。

我在厦门做的Pump404项目是找慢雾科技审的(1000U/合约),去过他们公司,挺专业。

编译器用最新稳定版

最新稳定版编译器能少踩坑,比如Solidity 0.8.0默认开了溢出检查。

常去官网看更新日志,了解新功能和安全改进,及时升级,别让已知漏洞钻空子。

第三方库省时又安全

OpenZeppelin的模板(ERC20、ERC721等)经过社区和实战验证,安全又省心,不用自己审基础代码,专注业务逻辑就好。但得用最新版,看好文档,别用错。

使用send和call小心点

  • send:发以太币用它,但不抛异常,只返回布尔值。老版本中栈深度超1024会失败(Solidity 0.8.0及以后版本已无此限制),批量转账得检查返回值,确保转账成功。
  • call:调外部合约灵活,但默认把所有gas给出去,容易被恶意合约搞乱(参考我的文章:)。建议限gas(像call{gas: 100000}),检查返回值,确保转账成功。

支付用 pull 模式

别用 push 模式批量支付,推荐 pull 模式——用户自己调claim领。这样就算某个地址出问题也不会拖垮全局,还省gas。

BEC代币被攻击就是用 push 模式的教训,pull 能避免这档子事。

防重入攻击

重入攻击通过外部调用反复搞乱合约,偷钱。得按“检查-修改-交互”(checks-effects-interactions)顺序写:先查条件、再改状态、最后调外部。用OpenZeppelin的nonReentrant修饰符(@openzeppelin/contracts/utils/ReentrancyGuard.sol)更稳。The DAO被重入搞垮就是前车之鉴(参考我的文章:)。

SafeMath 防溢出

Solidity 0.8.0 自带溢出检查,老版本得用 SafeMath。加减乘除溢出可能算错钱,SafeMath 能拦住异常,确保安全。尤其跟代币或ETH相关的计算,别省这步。

BEC 代币项目的溢出攻击就是没用SafeMath的教训(参考我的文章:)。

权限别乱给

合约权限管理得严,别随便给大权。明确角色(管理员、操作员啥的),限制好范围。别用 tx.origin 验身份,容易被钓鱼,改用 msg.sender。推荐使用 OpenZeppelin 的 AccessControl(@openzeppelin/contracts/access/AccessControl.sol), 能帮我们管好权限,清晰又安全。

日志记清楚

关键操作(转账、改权限)用事件(event)记下来,方便查。调试、审计时能快速定位问题。日志别太啰嗦,省点 gas,但关键信息得全。日志做好了,合约透明又好维护。

代码尽量简洁优雅

代码简洁好懂,出错少。别重复写,用函数封装。变量名、函数名起清楚,简洁不糊弄。还能省 gas,效率更高。

文档和注释得全

每个函数写好文档和注释,说清干啥用的、参数啥意思。方便自己(日后翻阅),也方便团队合作、外部审计。 我遇到过这样的“神棍”:一行代码注释都没有,变量命名只有他自己看得懂,是要遭唾骂的。

测试网上先跑

上线前在测试网(比如 Sepolia)试试,模拟真实环境,找问题。测功能、测安全,确保没毛病。测试网跑好了,主网风险就小很多。

紧急刹车得有

合约加个紧急停止开关,发现问题时让管理员暂停关键功能(像转账、铸币)。争取时间修漏洞,减少亏损。得限制谁能按开关,还得能安全恢复。

delegatecall少碰

delegatecall 风险大,存储容易乱,权限也可能被滥用。除非非用不可(比如代理模式),尽量别碰。用的话,确认被调合约安全,测试到位。 Parity多签钱包被攻击事件,delegatecall就是祸源(参考我的文章:)。

少靠外部调用

别太依赖外部合约或数据,风险不好控。真要调,确认对方安全,最好是审过的。调用时加点防护,比如用 try-catch 或日志,防外部出问题波及自己。

gas 上限定好

函数设个合理 gas 上限,别让交易失败或太贵。估好消耗,优化代码,少用计算和存储,用户体验也好。

时间戳别乱玩

block.timestamp 别拿来做关键判断,矿工能操控。不适合当随机数种子或定顺序,用预言机拿靠谱时间吧。

随机数得靠谱

链上随机数容易被猜,别用 blockhash 或 block.timestamp。Chainlink VRF (参考我的后续文章)这种服务才安全,游戏、抽奖才公平。

防 DoS 攻击

别循环处理外部输入,容易被搞成拒绝服务。限制规模(如下例)或分批干,异常也能跑:

function batchTransfer(address[] calldata recipients) external {
    require(recipients.length <= 50, "一次处理太多了"); // 防超长数组或恶意地址耗尽gas
    for (uint256 i = 0; i < recipients.length; i++) {
        (bool success, ) = recipients[i].call{value: 1e15}("");
        require(success, "转账失败"); // 检查返回值,失败时终止
    }
}

资金分开管

核心资金(如平台抽取的交易手续费)别跟业务逻辑混一块,用多签钱包或独立账户管。隔离更安全,适合大项目。

代码版本控制好

用 Git 管代码,能回溯。部署前备好回滚方案,上线修Bug也方便。

学习不偷懒

区块链和合约技术得一直学,看看 Solidity 更新和新攻击案例。有机会多参加行业活动,长长安全见识。学好了,合约才能跟上变化。

总结

智能合约安全不能含糊,项目好坏全指望它。照着这些实践来——认真测代码、找人审一审、支持升级别偷懒、用库小心点——漏洞就能少不少,用户资金安全有保障,项目口碑自然也上去了。安全这块得重视,开发者要多学新东西,跟上技术变化,让合约稳稳跑下去。


sunny_yang.png

我的产品体系: 《Web3开发转型陪跑计划》 《AI编程教学》 本人技术栈: Solidity/Golang/Rust/NodeJS/Python/AI编程 项目合作,欢迎你来链接我! 都看到这里了,不关注一下嘛👇

[公众号名片占位]

继续阅读

基于全文检索与主题相似度

以太坊2025年3月15日

【以太坊】聊聊智能合约的时间戳依赖攻击

说在前面 生活中,我们习惯了依赖时间来安排一切。闹钟提醒我们起床,高铁准点发车,考试到点交卷,股票交易精确到毫秒撮合…… 在 Web2 世界里,软件系统同样靠精准的时间戳来自动执行任务,比如定时扣款、会员到期、订单结算,这一切都建立在可信的时间基础上。但到了 Web3 世界里,时间居然能被“调表”!

以太坊2025年3月14日

【以太坊】聊聊智能合约的0转账钓鱼攻击

0转账钓鱼攻击是个啥? 0转账钓鱼攻击(Zero Transfer Phishing Attack)是一种简单却阴险的骗术,虽然技术含量不高,但在币圈屡屡得手,甚至酿成过惊天大案(见下文)。 每次听说这种攻击得逞,连我都忍不住暗想:这黑客咋不是我呢? 先打个生活中的比方: 假设你和好友张三经常通过银

以太坊2025年3月14日

【以太坊】聊聊智能合约的Permit2钓鱼攻击

说在前面 玩过币的人都知道,ERC20是以太坊上一个常见的代币标准(支持钱包交易交互),里面有个类似开支票的功能——approve授权和transferFrom转账兑现。 如同现实生活中你给人开了一张支票,写上金额,对方拿着支票去银行就能把钱取走。你账户里的钱少了,他的账户里钱多了。 在智能合约里,