dApp开发最重要的就是编写智能合约,我们先来分析一下Staking合约的基本格式。
在一定时间(deadline)内,质押(stake)一定数量(threshold)的代币。到期之后可以将代币转入(execute)到另一个合约,也可以将代币提取出来(withdraw)。
所以我们抽像出来了三个关键函数:
stake()
execute()
withdraw()
scaffold-eth也为我们提供了这样的一个脚手架,只需要把代码拉下来,我们本次就在这个基础上逐步来实现。
https://github.com/scaffold-eth/scaffold-eth-challenges
git clone https://github.com/scaffold-eth/scaffold-eth-challenges.git
cd scaffold-eth-challenges
git checkout challenge-1-decentralized-staking
yarn install
然后开三个终端窗口,执行如下三个命令:
yarn chain
yarn start
yarn deploy --reset
pragma solidity 0.8.4;
import "hardhat/console.sol";
import "./ExampleExternalContract.sol";
contract Staker {
mapping(address => uint256) public balances;
event Stake(address indexed staker, uint256 amount);
function stake() public payable {
balances[msg.sender] += msg.value;
emit Stake(msg.sender, msg.value);
}
}
// deploy/01_deploy_staker.js
// ....
await deploy("Staker", {
// Learn more about args here: https://www.npmjs.com/package/hardhat-deploy#deploymentsdeploy
from: deployer,
// args: [exampleExternalContract.address],
log: true,
});
//...
yarn deploy --reset
筹集到的资金,在满足一定条件之后,转移给另一个合约中。
contract ExampleExternalContract {
bool public completed;
function complete() public payable {
completed = true;
}
}
很简单,有一个flag代表是否已经结束了。
在stake合约中,要把这个合约引入进来,同时要有一个构造函数
ExampleExternalContract public exampleExternalContract;
constructor(address exampleExternalContractAddress) public {
exampleExternalContract = ExampleExternalContract(
exampleExternalContractAddress
);
}
// deploy/01_deploy_staker.js
// ....
await deploy("Staker", {
// Learn more about args here: https://www.npmjs.com/package/hardhat-deploy#deploymentsdeploy
from: deployer,
args: [exampleExternalContract.address],
log: true,
});
//...
uint256 public constant threshold = 1 ether;
function execute() public {
uint256 contractBalance = address(this).balance;
// check the contract has enough ETH to reach the treshold
require(contractBalance >= threshold, "Threshold not reached");
// Execute the external contract, transfer all the balance to the contract
// (bool sent, bytes memory data) = exampleExternalContract.complete{value: contractBalance}();
(bool sent, ) = address(exampleExternalContract).call{
value: contractBalance
}(abi.encodeWithSignature("complete()"));
require(sent, "exampleExternalContract.complete failed");
}
// SPDX-License-Identifier: MIT
pragma solidity 0.8.4;
import "hardhat/console.sol";
import "./ExampleExternalContract.sol";
contract Staker {
ExampleExternalContract public exampleExternalContract;
mapping(address => uint256) public balances;
uint256 public constant threshold = 1 ether;
event Stake(address indexed staker, uint256 amount);
constructor(address exampleExternalContractAddress) public {
exampleExternalContract = ExampleExternalContract(
exampleExternalContractAddress
);
}
function stake() public payable {
balances[msg.sender] += msg.value;
emit Stake(msg.sender, msg.value);
}
function execute() public {
uint256 contractBalance = address(this).balance;
require(contractBalance >= threshold, "Threshold not reached");
(bool sent, ) = address(exampleExternalContract).call{
value: contractBalance
}(abi.encodeWithSignature("complete()"));
require(sent, "exampleExternalContract.complete() failed");
}
}
yarn deploy --reset
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。