🏗 scaffold-eth | 🏰 BuidlGuidl
🚩 Challenge 1: 🥩 Decentralized Staking App
🦸 A superpower of Ethereum is allowing you, the builder, to create a simple set of rules that an adversarial group of players can use to work together. In this challenge, you create a decentralized application where users can coordinate a group funding effort. If the users cooperate, the money is collected in a second smart contract. If they defect, the worst that can happen is everyone gets their money back. The users only have to trust the code.
🏦 Build aStaker.sol
contract that collects ETH from numerous addresses using a payablestake()
function and keeps track ofbalances
. After somedeadline
if it has at least somethreshold
of ETH, it sends it to anExampleExternalContract
and triggers thecomplete()
action sending the full balance. If not enough ETH is collected, allow users towithdraw()
.
🎛 Building the frontend to display the information and UI is just as important as writing the contract. The goal is to deploy the contract and the app to allow anyone to stake using your app. Use aStake(address,uint256)
event to all stakes.
🌟 The final deliverable is deploying a Dapp that lets users send ether to a contract and stake if the conditions are met, thenyarn build
andyarn surge
your app to a public webserver. Submit the url on SpeedRunEthereum.com!
💬 Meet other builders working on this challenge and get help in the Challenge 1 telegram!
Staker.sol
in packages/hardhat/contracts
📦 install 📚
Checkpoint 0: Want a fresh cloud environment? Click this to open a gitpod workspace, then skip to Checkpoint 1 after the tasks are complete.
git clone https://github.com/scaffold-eth/scaffold-eth-challenges.git challenge-1-decentralized-staking
cd challenge-1-decentralized-staking
git checkout challenge-1-decentralized-staking
yarn install
Staker.sol
in packages/hardhat/contracts
🔭 Environment 📺
Checkpoint 1: You'll have three terminals up for:
yarn start (react app frontend)
yarn chain (hardhat backend)
yarn deploy (to compile, deploy, and publish your contracts to the frontend)
💻 View your frontend at http://localhost:3000/
👩💻 Rerunyarn deploy --reset
whenever you want to deploy new contracts to the frontend.
🥩 Staking 💵
Checkpoint 2: You'll need to track individual balances
using a mapping:
mapping ( address => uint256 ) public balances;
And also track a constant threshold
at 1 ether
uint256 public constant threshold = 1 ether;
👩💻 Write yourstake()
function and test it with theDebug Contracts
tab in the frontend
hardhat/console.sol
to your contract, you can call console.log()
right in your Solidity code. The output will appear in your yarn chain
terminal.
🥅 Goals
- Do you see the balance of the
Staker
contract go up when youstake()
? - Is your
balance
correctly tracked? - Do you see the events in the
Staker UI
tab?
🔬 State Machine / Timing ⏱
Checkpoint 3:
⚙️ Think of your smart contract like a state machine. First, there is a stake period. Then, if you have gathered thethreshold
worth of ETH, there is a success state. Or, we go into a withdraw state to let users withdraw their funds.
Set a deadline
of block.timestamp + 30 seconds
uint256 public deadline = block.timestamp + 30 seconds;
execute()
function that anyone can call, just once, after the deadline
has expired.
👩💻 Write yourexecute()
function and test it with theDebug Contracts
tab
If the address(this).balance
of the contract is over the threshold
by the deadline
, you will want to call: exampleExternalContract.complete{value: address(this).balance}()
If the balance is less than the threshold
, you want to set a openForWithdraw
bool to true
and allow users to withdraw()
their funds.
(You'll have 30 seconds after deploying until the deadline is reached, you can adjust this in the contract.)
👩💻 Create atimeLeft()
function includingpublic view returns (uint256)
that returns how much time is left.
block.timestamp >= deadline
you want to return 0;
👩💻 You can callyarn deploy --reset
any time you want a fresh contract
🥅 Goals
- Can you see
timeLeft
counting down in theStaker UI
tab when you trigger a transaction with the faucet? - If you
stake()
enough ETH before thedeadline
, does it callcomplete()
? - If you don't
stake()
enough can youwithdraw()
your funds?
💵 Receive Function / UX 🙎
Checkpoint 4: stake()
. You will use what is called the receive()
function.
Use the receive() function in solidity to "catch" ETH sent to the contract and call
stake()
to updatebalances
.
🥅 Goals
- If you send ETH directly to the contract address does it update your
balance
?
⚔️ Side Quests
- Can execute get called more than once, and is that okay?
- Can you stake and withdraw freely after the
deadline
, and is that okay? - What are other implications of anyone being able to withdraw for someone?
🐸 It's a trap!
- Make sure funds can't get trapped in the contract! Try sending funds after you have executed! What happens?
- Try to create a modifier called
notCompleted
. It will check thatExampleExternalContract
is not completed yet. Use it to protect yourexecute
andwithdraw
functions.
⚠️ Test it!
- Now is a good time to run
yarn test
to run the automated testing function. It will test that you hit the core checkpoints. You are looking for all green checkmarks and passing tests!
🚢 Ship it 🚁
Checkpoint 5: defaultNetwork
to your choice of public EVM networks in packages/hardhat/hardhat.config.js
yarn account
to see if you have a deployer address
yarn generate
to create a mnemonic and save it locally for deploying.
📝 If you plan on submitting this challenge, be sure to set yourdeadline
to at leastblock.timestamp + 72 hours
🚀 Runyarn deploy
to deploy your smart contract to a public network (selected in hardhat.config.js)
🎚 Frontend 🧘♀️
Checkpoint 6:
📝 Edit thetargetNetwork
inApp.jsx
(inpackages/react-app/src
) to be the public network where you deployed your smart contract.
💻 View your frontend at http://localhost:3000/
yarn build
to package up your frontend.
yarn surge
(you could also yarn s3
or maybe even yarn ipfs
?)
😬 Windows users beware! You may have to change the surge code inpackages/react-app/package.json
to just"surge": "surge ./build",
yarn surge
again until you get a unique URL, or customize it in the command line.
📝 you will use this deploy URL to submit to SpeedRunEthereum.com.
constants.js
in packages/ract-app/src
.
📜 Contract Verification
Checkpoint 7: Update the api-key in packages/hardhat/package.json file. You can get your key here.
Now you are ready to run the
yarn verify --network your_network
command to verify your contracts on etherscan🛰
🏃 Head to your next challenge here.
💬 Problems, questions, comments on the stack? Post them to the🏗 scaffold-eth developers chat