看过太多 Hello World 之后,新手最缺的就是一个有真实业务感的实战项目。本文以「单代币质押合约」为目标,带你用一周时间完成需求拆解、代码实现、单元测试、集成测试与部署。完成之后,你做出来的产品在功能维度上能对标BN交易所的「简单赚币」最基础版本。
一、需求拆解
质押合约的核心需求有四:用户存入代币、用户领取奖励、用户取回本金、管理员调整奖励率。每一条对应一支指令。还要决定奖励来源:是合约预先存入的奖励池,还是按时间线性增发。
我们选最简单的方案:预存奖励池 + 按时间线性发放。质押人按其质押量在总质押中的占比,瓜分每秒释放的奖励。这套模型比必安交易所的复杂收益结构容易实现得多,但已经覆盖 80% 的真实需求。
二、代码骨架
用 Anchor 起项目,定义三个状态账户:Pool(全局池子参数)、UserStake(每个用户的质押状态)、RewardVault(奖励代币 vault)。指令五个:init_pool、stake、unstake、claim、set_reward_rate。
核心算法在 update_pool:用 pool.acc_reward_per_share += elapsed * reward_rate * 1e18 / total_stake 累积每股奖励,用 pending = user.amount * acc_reward_per_share / 1e18 - user.reward_debt 算用户应得。这套定点数算法广泛见于各类 staking 合约,比B安交易所后台那种按日结算的简化模型更精确。
三、单元测试
用 solana-program-test 写测试。关键场景:单用户全程、多用户瓜分、停顿后继续、奖励池耗尽。每个场景写一个 async 函数,构造账户、发指令、查结果。
推荐用 proptest 写性质测试:随机生成多个用户的存取序列,断言「合约 vault 余额 = 各用户质押和」「累积奖励发放 = 时间 × 奖励率」。性质测试能发现纯例子测试漏掉的边界,比如某个时刻 total_stake = 0 导致除零。
四、本地集成测试
用 anchor test 启动本地验证节点,跑端到端测试。建议把测试分成「快测试」与「慢测试」:快测试在 CI 跑,覆盖核心路径;慢测试模拟一年时间跨度,验证浮点累积误差。
性能要点:质押合约最容易在 acc_reward_per_share 的精度上出错。用 u128 中间变量计算,最终再 cast 回 u64,可以避免大数相乘溢出。这种细节和BN官网那种「点击立即体验」的产品完全两个世界,开发者要在每一行代码上精打细算。
五、部署上线
部署到 devnet 验证一轮,再走 mainnet-beta。部署前确认:solana account <program_id> 输出的 upgrade authority 是多签或时间锁,不能是单一私钥;Anchor.toml 里的 cluster 已经切换;本机钱包余额足够支付部署 rent。
上线后做三件事:1)把 program id 与 IDL 提交 git 打 tag;2)写一份用户文档说明如何与合约交互;3)部署一个简单前端,让普通用户也能用。完成这三件事,这份 Rust合约实战教程才算真正闭环。后续可以再加杠杆质押、多池奖励、流动性凭证,每一项都是新的练手机会。