scaffold-eth 挑战1:实现质押 dApp
接下来,我将介绍第一个 scaffold-eth 学习项目:创建一个质押 dApp。
这个项目的最终目标是模仿以太坊2.0的质押合约,需求非常简单:
你可以把这看作是我们开发旅程的第一步。
首先,我们需要设置克隆 scaffold-eth 库,切换到 challenge 1 分支,并安装所有需要的依赖:
git clone https://github.com/austintgriffith/scaffold-eth.git challenge-1-decentralized-staking
cd challenge-1-decentralized-staking
git checkout challenge-1-decentralized-staking
yarn install
这些命令并不是只适用于本次挑战,而是适用于每个 scaffold-eth 项目:
yarn chain
这个命令会启动本地 Hardhat 网络并配置好地址http://localhost:8545
yarn start
这个命令会启动你的本地 react 网站,地址为http://localhost:3000/
yarn deploy
这个命令会部署所有合约并刷新 react 程序。准确地说,这个命令会运行两个 javascript 脚本(部署和发布)。
打开三个不同的终端,执行这些命令。每次修改合约,你只需要重新执行deploy命令。
在这部分练习中,我们想做到用户可以在合约中质押 ETH,并可以随时查看余额变动。
stake()
,用来更新质押者的余额。// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;
import "hardhat/console.sol";
import "./ExampleExternalContract.sol";
/**
* @title Stacker Contract
* @author scaffold-eth
* @notice A contract that allow users to stack ETH
*/
contract Staker {
// External contract that will old stacked funds
ExampleExternalContract public exampleExternalContract;
// Balances of the user's stacked funds
mapping(address => uint256) public balances;
// Staking threshold
uint256 public constant threshold = 1 ether;
// 合约事件
event Stake(address indexed sender, uint256 amount);
/**
* @notice Contract Constructor
* @param exampleExternalContractAddress Address of the external contract that will hold stacked funds
*/
constructor(address exampleExternalContractAddress) public {
exampleExternalContract = ExampleExternalContract(exampleExternalContractAddress);
}
/**
* @notice Stake method that update the user's balance
*/
function stake() public payable {
// update the user's balance
balances[msg.sender] += msg.value;
// emit the event to notify the blockchain that we have correctly Staked some fund for the user
emit Stake(msg.sender, msg.value);
}
}
一些注意事项:
uint
和uint256
是一样的(它只是别名)yourVariableName()
方法可调用回顾一下:
balances
,可以保存每个用户的地址和其质押金额Stake
事件,当某用户质押了一定数量 ETH ,它会向区块链发出通知Stake
函数,它会更新用户的余额,并发出 Stake 事件。你也许会有点奇怪,我们只是简单地更新质押金额,而没有初始化balances[msg.sender]
的值。这是可行的,因为当声明变量时没有初始化,Solidity 会自动初始化为其类型的默认值,这里类型是uint256
,所以默认值是 0。
现在部署合约,从水龙头(Faucet)获取 ETH ,并尝试质押一些给合约。
检查下你是否完成下面所有项目,以便继续进行第二部分的练习:
以下是本次视频的演示:
https://www.youtube.com/watch?v=KfoNrlYxBKY
本翻译由 CellETF 赞助支持。
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!