本文介绍了如何构建一个以太坊智能合约,用于质押以太币以赚取利息。文章详细讲解了合约的设计、编码、部署及测试,包括创建项目、编写合约的关键功能、在私有测试网进行部署和审核交易。最后,用户还可以邀请朋友共同参与测试,协助提升智能合约的功能和性能。
Staking 加密货币是将加密货币资产锁定或存入 DeFi 协议或智能合约以赚取利息的过程。
今天我们将构建一个智能合约,我们可以在其中质押以太币并赚取利息。如果用户尝试在解锁日期之前提取资金,将会受到惩罚。如果用户这样做,他必须放弃已获得的利息。
在本文结束时,你将学到以下内容:
让我们开始构建吧!🧑💻
1.1: 在你的命令行中使用以下命令来初始化项目。
mkdir staking-with-buildbear && cd staking-with-buildbear
1.2: 在命令行中运行命令 npx hardhat
,选择 Create a Javascript Object
;所有选项选择 yes
。
成功执行上述步骤后,如果在 VS Code 中打开此仓库,你应有一个类似于下面的目录结构:
2.1: 在 contracts
文件夹中创建一个名为 Staking.sol
的文件。
2.2: 我们将开始定义 Solidity 版本(这将决定我们在 hardhat.config.js
文件中使用的 Solidity 编译器)。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;contract Staking {
2.3: 定义我们将在合约中使用的变量:
address public owner; // 地址质押的以太币数量
struct Position {
uint positionId;
address walletAddress;
uint createdDate;
uint unlockDate;
uint percentInterest;
uint weiStaked;
uint weiInterest;
bool open;
} Position position;
uint public currentPositionId;
mapping (uint => Position) public positions;
mapping (address => uint[]) public positionIdsByAddress;
mapping (uint => uint) public tiers;
uint[] public lockPeriods; // 30天 / 90天 / 180天
2.3.1: 关键变量
2.4: 智能合约的 constructor
使用以下代码作为构造函数:
constructor () payable {
owner = msg.sender;
currentPositionId = 0;
tiers[30] = 700; // 30天 -> 7%
tiers[90] = 1000; // 90天 -> 10%
tiers[180] = 1200; // 180天 -> 12%
lockPeriods.push(30);
lockPeriods.push(90);
lockPeriods.push(180);
}
我们已经将构造函数标记为可支付,这将允许合约的部署者在部署时向其发送一些以太币。
在构造函数中,我们将 msg.sender
设置为所有者
currentPositionId
将初始化为 0tiers
lockPeriod
,也就是 30、90 和 180 天2.5: 合约的逻辑函数:
// 质押的天数
function stakeEther(uint numDays) external payable {
require(tiers[numDays] > 0, "Mapping not found");
positions[currentPositionId] = Position(
currentPositionId,
msg.sender,
block.timestamp,
block.timestamp + (numDays * 15180),
tiers[numDays],
msg.value,
calculateInterest(tiers[numDays], numDays, msg.value),
true
);
positionIdsByAddress[msg.sender].push(currentPositionId);
currentPositionId += 1;
}
function calculateInterest(uint basisPoints, uint numDays, uint weiAmount) private pure returns (uint) {
return basisPoints * weiAmount / 10000;
}
function modifyLockPeriods(uint numDays, uint basisPoints) external {
require(owner == msg.sender, "Only owner may modify staking periods");
tiers[numDays] = basisPoints;
lockPeriods.push(numDays);
}
function getLockPeriods() external view returns(uint[] memory) {
return lockPeriods;
}
function getInterestRate(uint numDays) external view returns (uint) {
return tiers[numDays];
}
function getPositionById(uint positionId) external view returns (Position memory) {
return positions[positionId];
}
function getPositionIdsForAddress(address walletAddress) external view returns (uint[] memory) {
return positionIdsByAddress[walletAddress];
}
function closePosition(uint positionId) external {
require(positions[positionId].walletAddress == msg.sender, "Only position creator can modify the position");
require(positions[positionId].open == true, "Position is closed");
positions[positionId].open = false;
if(block.timestamp > positions[positionId].unlockDate) {
uint amount = positions[positionId].weiStaked + positions[positionId].weiInterest;
payable(msg.sender).call{value: amount}("");
} else {
payable(msg.sender).call{value: positions[positionId].weiStaked}("");
}
}
让我们讨论一些关键函数:
private
函数。一个私有函数只能在定义了该函数的合约内部访问,而且不允许任何外部源访问。你的智能合约应该看起来类似于此:
3.1: 在 BuildBear 上创建一个私有测试网 🐻❄️ *(你可能会问为什么使用 BuildBear?请看这里: [Where Localhost Fails](https://medium.com/p/492f1038883d) 和 Win Web3 Hackathons, using BuildBear Testnet’s analytics )
3.1.1: 访问 BuildBear 应用。一旦你使用 GitHub 账号登录,你将看到类似以下图像的页面:
在这里,我们需要为我们的质押应用创建一个简单的节点,因此我们将点击 create an endpoint,并将被重定向到节点配置页面。对于本文,我们将使用默认配置创建节点。
所以我们将简单地单击下面所示的 create
按钮。
恭喜!你已创建了自己的私有测试网络节点!
你的页面应更新为类似下面的内容:
单击 RPC URL(复制或单击查看)以获取指向你的私有测试网的 RPC。
3.2: 为了执行交易,我们需要来自水龙头的资金。别担心!我们不需要寻找随机水龙头来获取测试以太币。
单击 Open Faucet 选项并选择你的账户。
之后,单击水龙头页面右上角的 Add to Metamask 选项。
你的 MetaMask 将立即获得 1,000 BB ETH。
3.3: 将 hardhat.config.js
更新为以下内容:
在网络中,我们创建了一个名为 buildbear 的网络,并在那里添加了我们的 RPC URL,然后添加了 MetaMask 账户的私钥(请不要将私人密钥暴露给任何人)。
现在我们的配置已经准备好了!让我们开始编写我们的智能合约。
4.1: 使用以下脚本部署你的质押合约:
const { ethers } = require("hardhat");
const hre = require("hardhat");
async function main() {
const Staking = await hre.ethers.getContractFactory("Staking");
const staking = await Staking.deploy({value: ethers.utils.parseEther('10')});
await staking.deployed();
console.log(
"Staking contract deployed to:", staking.address
);
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
打开你的命令行,运行以下命令:
npx hardhat run scripts/deploy.js --network buildbear
现在如果你返回 BuildBear Explorer(链接可从BuildBear 应用获取,当你创建私有测试网后)。你将看到已执行的交易。
打开交易哈希,你将获得与交易相关的所有细节。
如果你点击 advance 按钮,你将看到显示 unknownContract 创建的追踪。
这代表我们的质押合约已被部署。
但是 unknownContract
听起来有点令人困惑! 😥. 所以让我们来解决这个问题。
4.2: 返回你的 Dashboard, 并单击 advanced 按钮。
在这里提交你的 artifacts
文件夹。
现在,再次打开你的交易并检查 advanced 选项。
你将看到这次不是得到 unknownContract
,而是收到了质押合约。
这不是很棒吗? 😎
我们将使用 BuildBear Explorer 测试我们的合约。
5.1: 为了执行交易,请访问你在浏览器上的合约地址。将合约地址放入搜索选项中。
你的合约的样子如下:
单击与 Transactions 相邻的 Contract 选项。
在这里我们有 3 个选项:
由于我们已经使用仪表板提交了 ABI,因此我们将被重定向到读取合约选项。
你的 Read Contract 选项将具有你在合约中编写的所有函数。
5.2: 让我们在 write contract 上质押我们的以太币。
确保你连接到你的 Web3 账户。
在 write contract 选项下,你将看到 stakeEthers
函数。
我们需要传入 numDays 和 amount 的值。因此,我们将在这里将 30 作为 numDays 的值,2 以太币作为金额。
然后单击 write button 调用 stakeEthers 函数。这将触发 MetaMask,以 2 BB ETH 为值并调用智能合约的函数。
完成后,你将在查询按钮下收到一个 交易哈希,告诉你交易是否成功。
点击交易哈希,你将收到与其相关的所有信息。
我们与合约 0x73eccD6288e117cAcA738BDAD4FEC51312166C1A 进行互动,并在合约中添加了 2 ETH。
交易的追踪将展示你的活动。
在读取合约中, currentPositionId 的值等于 1,因为我们刚才质押了以太币。
通过这种方式,我们可以运行合约的所有函数并对合约进行测试。
5.3: 提取你的利息
质押的利息只有在达到 lockPeriod
时才会获得。
我们可以通过 Postman 请求进行测试。
我们将做的是,获取节点的 RPC URL 并在 Postman 上发送一个 post 请求。
将正文传递如下 JSON 主体
{
"jsonrpc": "2.0",
"id": 1,
"method": "evm_increaseTime",
"params": ["0x28DE80"]
}
这将在节点上将区块时间戳增加 31 天。因此,我们将能够关闭我们的质押并赚取利息。
因此,现在如果你运行 POST 请求,你将获得类似于此的结果。
这意味着节点的时间戳已成功增加 31 天。
现在要测试我们的质押收集,我们将返回浏览器,打开我们的合约并检查 closePosition。
现在在参数中输入 positionId 并单击 write button。
你可以看到我们的交易已成功执行。
为了了解我们刚才所做的,让我们打开在 write 按钮下方收到的交易哈希,然后打开 advanced 标签。
你将收到类似于以下内容的追踪。
让我们了解一下刚刚发生了什么:
0xd51..
是我收到资金的波动地址。 UnknownContractAndFunction
显示了发送资金的方式。现在我们刚刚学会了如何进行加密质押! 😎
这就是 BuildBear 让你部署合约并与之交互的方式。
为了更进一步,你可以邀请你的朋友在你的质押合约上质押他们的以太币并执行多个功能。我创建了私有测试网,并且质押合约在 这里 可用。
你可以从 这里 获取该测试网的水龙头。
专业提示:在创建私有测试网时,我已禁用提高时间的选项,因此你将无法提前我私有测试网的区块时间。太棒了!!!
要了解有关 BuildBear 的更多信息,请阅读这里 docs
从 这里 获取上面的 GitHub 代码。
如果你喜欢我们所做的,请在 Twitter 上关注我们,并且如果你还没有加入,Telegram 群组,请加入。
如果你喜欢我们的工作,请给我们一个掌声 👏。
作者:
Pari Tomar ( Twitter || LinkedIn),始终乐于接受反馈及学习。
顺便说一下,如果你知道任何想要与 BuildBear 一起工作的人,请查看 这里!!!
- 原文链接: medium.com/buildbear/cre...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!