区块链开发选型别只看 TPS:我拿 4 条链跑了 30 天,记下这些真实成本和坑
2024 年 2 月,我接了个小活:给一个线下桌游店做 2000 张 NFT 会员卡,定价 0.03 ETH,权益是周末免费占座和一杯美式。 Sepolia 测试网一路顺利,mint、白名单、退费都跑通,我甚至觉得这项目一周就能收工。 结果第 3 天晚上,用户从交易所提 USDC 到 Polygon PoS,等了 11 分钟没到账,群里开始刷“是不是跑路了”。 我盯着 Polygonscan,才发现 Polygon PoS 出块是 2 秒,但跨链桥和交易所入账要等检查点,有时候 30 分钟起步。 那晚我学到第一件事:TPS 是给技术人看的,用户只关心“我点完,钱多久到,失败谁赔”。
后面 30 天我把同一个 ERC-721 合约部署到以太坊主网、Polygon PoS、Arbitrum One、Base 和 zkSync Era,记了一本流水账。 表格里的费用不是理论值,是我在 2024 年 3 月某一周、ETH 约 3500 美元、MATIC 约 1.2 美元时实际看到的区间,Gas 会跳,别当报价单。 主网 ERC-20 转账 45000-65000 gas,base fee 25 gwei 时约 0.0011-0.0016 ETH,也就是 3.8-5.6 美元;简单 ETH 转账 21000 gas 约 1.8 美元。 Arbitrum One 同笔 ERC-20 转账我付过 0.000018 ETH,约 0.06 美元;Base 付过 0.000006 ETH,约 0.02 美元;zkSync Era 约 0.000012 ETH,约 0.04 美元。 Polygon PoS 最便宜,50000 gas 按 30 gwei 算只要 0.0015 MATIC,约 0.002 美元,但用户从主网桥过去要花 1-5 美元,还要等。 所以别只比执行费,要把“入金路径”算进去:用户从交易所提现、从主网桥、还是信用卡买币,成本差 10 倍都不止。
工具链我先说结论:新项目别再用 Truffle 了,Hardhat 2.22.10 和 Foundry 二选一,或者像我一样用 Foundry 写测试、Hardhat 做部署脚本。 Solidity 我锁 0.8.24,OpenZeppelin 5.0.2,Foundry 默认 evm_version 是 cancun,但有些链还没跟上。 我踩过最蠢的坑:Solidity 0.8.20 编译默认带 PUSH0,部署到某个没升级的 L2 测试网,直接 invalid opcode,交易失败还扣了 gas。 解决方式是在 foundry.toml 里写 evm_version = 'paris' 或 'shanghai',重新 forge build,别偷懒用默认。 合约大小也要盯:EIP-170 限制 24576 字节,我第一版带白名单和退款逻辑,编译出来 26112 字节,Arbitrum 能部署,主网直接报 code size limit。 用 forge build --sizes 看,优化器 runs 从 200 调到 1 能省一点,但 gas 会涨;如果是复杂逻辑,拆库或代理,但代理又引入存储槽和升级权限的坑。
并发 nonce 是我亏过真金白银的地方。用户同时点 mint,前端用 ethers.js 自动发交易,两个请求拿到同一个 nonce。 一个成功,另一个报 replacement transaction underpriced,用户以为没 mint 成功,又点了一次,最后多买了 3 张。 后来我改成后端队列:一个热钱包一个队列,按 pending nonce 串行,每发一笔 nonce+1,或者用 ethers 的 NonceManager。 Gas 估算也别信 estimateGas 的返回值,我一般乘 1.2;EIP-1559 参数用 maxPriorityFeePerGas = 1.5 gwei,maxFeePerGas = baseFee * 2 + 1.5 gwei。 L2 还要算 L1 data fee:Arbitrum 用 @arbitrum/sdk 或 NodeInterface,OP 系调用 0x420000000000000000000000000000000000000F 的 getL1Fee,zkSync 要设 gasPerPubdataByte。 RPC 也别只用一个,Infura、Alchemy、QuickNode 我都会配 fallback,主网拥堵时单 RPC 限流会让你以为交易丢了。
安全这块,我水平一般,但有几个底线:重入用 Checks-Effects-Interactions + ReentrancyGuard,权限用 Ownable(msg.sender) 别再用无参数 Ownable。 随机数绝对别用 block.timestamp、blockhash 或 block.prevrandao,链上全公开,用 Chainlink VRF v2.5,订阅 ID、gas lane 500000、确认块数 3。 价格预言机用 Chainlink ETH/USD 主网喂价,检查 updatedAt 和 answeredInRound,heartbeat 3600 秒,deviation 0.5%,别把 stale price 当现价。 升级合约我现在的观点可能反常识:大多数小项目不需要 UUPS 或 Transparent 代理,不可变合约加迁移合约更省心。 我见过代理因为 __gap 少写、初始化函数没锁、实现合约被初始化,直接被人拿走 owner。不可变合约出 bug 要迁移,但至少不会被升级权限一锅端。 多签用 Gnosis Safe 3/5,时间锁 TimelockController 最小延迟 48 小时,别把 owner 放在个人热钱包。
跨链和 L2 选择,我的独立观点是:先看用户资产在哪,再看开发者体验,最后才看 TPS。 如果用户从 Binance 来,就选交易所支持的 L2,Arbitrum、Optimism、Base、Polygon 都行;从 Coinbase 来,Base 入金摩擦最小。 从主网桥到 Arbitrum 用 Across 我实测 2-10 分钟,费用 1-5 美元;Stargate 流动性费约 0.1%,大额更划算,小额不如直接交易所提现。 0.03 ETH 的 mint,如果桥费 3 美元,用户实际成本多 10%,所以我在 Base 上做了个“从 Coinbase 直接提 Base”的引导页,转化率比教程高。 Arbitrum 生态大、TVL 高、工具成熟;Base 有 Coinbase 法币入口和社交传播;Optimism 有 OP Stack 超级链叙事;zkSync Era 的 zk 证明很酷,但 zksolc 编译和调试会多花我至少 30% 时间。 如果你做游戏高频交互,Solana 的 400ms slot 很香,但 Rust、Anchor、账户模型和 EVM 完全两套,团队没有积累别硬上。
最后给一套我现在还在用的 Foundry 步骤,能少踩几个坑。 第 1 步:curl -L https://foundry.paradigm.xyz | bash,然后 foundryup,forge --version 确认。 第 2 步:forge init nft-membership,cd nft-membership,forge install OpenZeppelin/openzeppelin-contracts@v5.0.2。 第 3 步:在 foundry.toml 写 solc = '0.8.24',optimizer = true,optimizer_runs = 200,evm_version = 'cancun',rpc_endpoints 配好主网和 Arbitrum。 第 4 步:写合约,先写失败测试:白名单没开、重复 mint、超发、退款重入,再写正常路径。 第 5 步:forge test --fork-url $MAINNET_RPC --fork-block-number 19500000 -vvv,分叉测试比本地模拟更接近真实状态。 第 6 步:forge script script/Deploy.s.sol --rpc-url $ARBITRUM_RPC --broadcast --verify --slow,--slow 会等上一笔确认,减少 nonce 爆炸。 第 7 步:先 mint 50 个灰度,观察 24 小时,再开 500 个,最后全量;监控用 Tenderly alert、OpenZeppelin Defender Sentinel、Blocknative。 第 8 步:出问题先暂停,Pausable 可以救命,但别把暂停权当日常运营;退款逻辑提前写好,别等用户骂了才写。
如果让我重来一次,我会把主网当结算层,Arbitrum 或 Base 当交互层,再加 ERC-4337 做免 gas mint。 EntryPoint v0.7 地址是 0x0000000071727De22E5E9d8BAf0edAc6f37da032,v0.6 是 0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789,Paymaster 每笔补贴大概 0.05-0.2 美元,预算要算清楚。 用户不关心你用的 Rollup 还是 Validium,也不关心 DA 层是 blob 还是 calldata,他们只关心点一下之后多久成功、花多少钱、失败了能不能退。 我现在选链的顺口溜是:先看用户从哪来,再看失败怎么赔,最后才看 TPS 和 Gas。这个顺序反过来,项目大概率会在群里被骂。