# solidity教程:从零开始写质押挖矿合约(一):需求整理 **Published by:** [daxiong](https://paragraph.com/@daxiong/) **Published on:** 2022-02-12 **URL:** https://paragraph.com/@daxiong/solidity-3 ## Content 质押合约的算法,之前的文章已经推到过,本文在此基础上进行开发。 本文使用truffle框架进行开发,truffle的基础用法不再赘述,可以查阅官方文档。在着手开始编写一个智能合约之前,首先要了解需求,进行合约开发设计。Step1:了解需求,明白该合约要实现哪些功能。1、将token转入合约进行质押; 2、解除质押并且token转出合约; 3、计算挖矿收益,挖矿算法是:没分钟产出10个奖励; 4、奖励提现; 5、查看某个地址的质押份额; 所以梳理出以下方法: 1、stake(uint256 _amount):质押,【外部调用/所有人/不需要支付/读写状态】 2、unStake(uint256 _amount):解除质押,提取token,【外部调用/所有人/不需要支付/读写状态】 3、getReward():获取挖矿收益,【内部调用/合约创建者/不需要支付/只读】 4、withdraw(uint256 _amount):提现收益,【外部调用/所有人/不需要支付/读写】 5、getShare(address _addr):获取某地址质押份额,【外部调用/所有人/不需要支付/只读】Step2:根据合约和方法的业务逻辑梳理出属性:1、质押合约基础属性:质押代币地址、质押奖励token的地址、每分钟产出奖励数量 2、getShare方法,需要获取每个地址的质押份额 3、withdraw方法,需要存储每个地址已经提现的奖励 4、挖矿算法,需要记录每个地址最近一次的每份额累计奖励 以及 每个地址最近一次的累计收益 以及 每份额累计总奖励 5、总挖矿奖励数量 所以梳理出以下属性: 质押代币地址:address stakeTokenAddr 【公共】 质押奖励token地址:address rewardTokenAddr 【公共】 每分钟产出奖励数量:uint256 rewardPerMin 【公共】 每个地址的质押份额:mapping(address => uint256) shares【私有】 每个地址已经提现的奖励:mapping(address => uint256) withdrawdReward【私有】 每个地址最近一次的每份额累计奖励:mapping(address => uint256) lastAddUpRewardPerShare【私有】 每个地址最近一次的累计总奖励:mapping(address => uint256) lastAddUpReward【私有】 每份额累计奖励:uint256 addUpRewardPerShare【公共】 总挖矿奖励数量:totalReward【公共】Step3:综上所属,当前合约代码为:// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable.sol"; contract Pool is Ownable { //质押代币地址 address stakeTokenAddr; //质押奖励token地址 address rewardTokenAddr; //每分钟产出奖励数量 uint256 rewardPerMin; //每个地址的质押份额 mapping(address => uint256) private shares; //每个地址已经提现的奖励 mapping(address => uint256) private withdrawdReward; //每个地址最近一次的每份额累计奖励 mapping(address => uint256) private lastAddUpRewardPerShare; //每个地址最近一次的累计总奖励 mapping(address => uint256) private lastAddUpReward; //每份额累计奖励 uint256 addUpRewardPerShare; //总挖矿奖励数量 uint256 totalReward; //质押,【外部调用/所有人/不需要支付/读写状态】 function stake(uint256 _amount) external {} //解除质押,提取token,【外部调用/所有人/不需要支付/读写状态】 function unStake(uint256 _amount) external {} //获取挖矿收益,【内部调用/合约创建者/不需要支付/只读】 function getReward() internal view onlyOwner {} //提现收益,【外部调用/所有人/不需要支付/读写】 function withdraw(uint256 _amount) external {} //获取某地址质押份额,【外部调用/所有人/不需要支付/只读】 function getShare(address _addr) external view {} } ## Publication Information - [daxiong](https://paragraph.com/@daxiong/): Publication homepage - [All Posts](https://paragraph.com/@daxiong/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@daxiong): Subscribe to updates - [Twitter](https://twitter.com/soliditier): Follow on Twitter