先说结论:别急着问哪个链快,先问升级权限在谁手里
去年帮朋友看一个 NFT 小项目,本来只想改白名单,结果在 Arbiscan 上点开代理合约,发现 implementation 地址指向一个没验证的合约,owner 还是个单签 EOA。那天凌晨 2 点,我盯着屏幕想:这玩意要是被钓鱼,白名单没改完,整个系列先没了。后来我花了 30 天,用 Foundry + Slither + Tenderly 把 ERC-20、ERC-721 和一个简单订单簿在 Ethereum Sepolia、Arbitrum Sepolia、Base Sepolia、Solana Devnet 各跑了一遍。不是专家,踩的坑倒是很具体,下面这些数字和参数你可以自己查。
语言和链的对比:Solidity、Rust、Move 不是同一道题
Solidity 0.8.24 + Foundry,默认 optimizer runs 200,我测 ERC-20 transfer 大约 51,234 gas;开 viaIR 后降到 47,891 gas,省了约 6.5%,但编译时间翻倍,CI 里等得想砸键盘。Solana Anchor 0.29 + Rust 1.75,SPL Token transfer 通常 5,000 lamports 左右,按 SOL 150 美元算不到 0.001 美元;可账户模型要传一堆 AccountMeta,我漏传 associated token account,直接报 AccountNotInitialized,卡了 6 小时。Move 在 Aptos 上资源模型很舒服,但工具链和文档少,测试网水龙头经常要等。我的独立观点:选语言不如选你半夜 3 点能找到人修的那条链。
重入和 Gas 优化:我固定下来的 7 步土办法
重入不是只发生在 withdraw。我写了个简化金库,先用 call{value: 1 ether} 再改余额,Slither 直接报 reentrancy-eth。加 OpenZeppelin ReentrancyGuard 的 nonReentrant 后,攻击合约再调就 revert。后来我固定成 7 步:1) forge init 或自己搭;2) 继承 ERC20、Ownable2Step、Pausable;3) 所有外部调用前先改状态,checks-effects-interactions;4) forge test --gas-report,看 SSTORE 次数;5) slither . --detect reentrancy-eth,suicidal,arbitrary-send;6) Tenderly 模拟主网分叉,设置 block number 和 from;7) 上线加 48 小时时间锁 + 3/5 多签。具体参数:合约大小别超 24,576 字节,这是 EIP-170 硬限制;Arbitrum 上 L1 数据费有时比 L2 执行费还贵,别只盯 execution gas。
升级权限才是大多数项目的暗门
很多人吹不可篡改,但我手上 20 个开源项目里,15 个用了代理,其中 9 个 admin 是单个 EOA。EIP-1967 实现槽是 bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1),你在区块浏览器读这个槽,就能看到真实实现。Transparent 代理和 UUPS 的差别不在 gas,而在升级逻辑放哪:UUPS 把 upgradeTo 放实现合约,忘了加 _authorizeUpgrade,等于把钥匙插门上。我的全新观点:智能合约最大的创新不是自动执行,是把“谁有权改规则”写进代码并留下痕迹;但多数项目只做了前半句。选链时别只看 TPS,看故障时谁能暂停、谁能回滚、多签分布在哪。
审计报价和用户真问题:先做便宜的三件事
你搜智能合约审计多少钱,我收到的报价从 8 千美元到 8 万美元不等,差别是代码行数、链数量、是否含经济模型。小项目别一上来买全套审计,先做三件事:1) 用 Foundry fuzz 跑 10,000 次,找边界;2) 用 Tenderly 模拟 0x 攻击交易;3) 把 owner 私钥放进硬件钱包,别放浏览器插件。我犯过的错:把 API key 写进 .env 又提交到 GitHub,幸好是测试网;还有 nonce 卡住,MetaMask 里用自定义 nonce 覆盖,或者发 0 ETH 给自己。最后说句可能不讨喜的:智能合约不是把信任消灭了,是把信任换成了可读的代码、可查的地址和可追的治理记录。你能读多少,就能少信多少。