Shows you how to use Chainlink VRF to randomly reveal a dice roll.
is everything you need to get started building decentralized applications powered by smart contracts.
This tutorial is PART 1 of a series on how to integrate Chainlink technology with Scaffold-ETH.
For some more advanced VRF handling, check out PART 2.
To learn about public APIs / Data feeds, check out PART 3.
In this tutorial you learn how to use Chainlink VRF (verifiable randomness) ๐ฒ
There are 3 example contracts (simple to advanced) for you to ape into! ๐ฆ
๐งช Quickly experiment with Solidity using a frontend that adapts to your smart contract:
git clone -b chainlink-tutorial-1 https://github.com/scaffold-eth/scaffold-eth-examples.git
# ๐โโ๏ธ Quick Start
### Manual setup
Prerequisites: [Node](https://nodejs.org/en/download/) plus [Yarn](https://classic.yarnpkg.com/en/docs/install/) and [Git](https://git-scm.com/downloads)
> clone/fork ๐ scaffold-eth-examples:
```bash
git clone https://github.com/scaffold-eth/scaffold-eth-examples.git
We skip local development since it would require mock contracts. Going directly to testnet makes the first steps simpler.
generate your account to deploy to testnet:
cd scaffold-eth-examples
yarn generate
The warnings are normal and you can ignore.
yarn account
You will need to fund your deployer account with kovan ETH before you can deploy your contracts.
Testnet ETH is available from https://faucets.chain.link/
yarn deploy
๐ Edit your smart contract RandomNumberConsumer.sol
in packages/hardhat/contracts
๐ Edit your smart contract DiceRolls.sol
in packages/hardhat/contracts
๐ Edit your smart contract MultiDiceRolls.sol
in packages/hardhat/contracts
๐ Edit your frontend App.jsx
in packages/react-app/src
๐ผ Edit your deployment script 00_deploy_your_contract.js
in packages/hardhat/deploy
๐ฑ Open http://localhost:3000 to see the app
๐ Keep solidity by example handy and check out the Solidity globals and units
With everything up your UI should look something like this:
Fund the contract with LINK
** Side Quest - use 00_deploy_your_contract.js to fund the contract with LINK after funding deployer account. **
Copy the contract address and send it some link. You don't need much, average oracle costs .1 LINK.
To test just go to requestRandomNumber and click send.
Once the transaction is mined you will see the requestId updated:
This value identifies the request that your contract just made to the Chainlink VRF contract.
It takes about 1 minute for the Oracle to call your contract with a response. After waiting for 1 minute you should see the randomResult updated:
In the Example UI you'll find an example of how to manage UI state when making such requests:
** ๐งโโ๏ธ ๐งโโ๏ธ ๐งโโ๏ธ Side Quest 1- How secure is it to expose our requestId publicly? ** Can we hack ๐ฅท the system and fulfill the request before the Oracle does?
Since you know the latest requestId, call rawFulfillRandomness() on RandomNumberConsumer, just like the Oracle would.
Use the Debug Contracts tab. Make the rawFulfillRandomness() call and provide any random number you want. See if you can make the contract store your bogus random number.
The transaction reverted. Why didn't it work? Check out the actual code and see what the reason might be. You won't find the function directly in RandomNumberConsumer though...
๐ Takeaway: randomness from Chainlink VRF is a two-step process.
When receiving randomness your contract can do something useful with it.
Let's see an example!
Let's roll some dice...
Make sure your DiceRolls contract is deployed and has some LINK.
Make sure to uncomment the DiceRolls code in App.jsx, in order to see it in the Debug Contracts Tab
You should find it below the RandomNumberConsumer:
Go to the Example UI and click on the Roll Dice! button. After 1 minute or so the Oracle should have responded.
You will see a new entry in the events UI:
You will see the event data in the console:
Check out the code in the Events.jsx component
Here is the solidity code broken down
This solidity code is far from optimal, it will charge a lot of gas. It shows you a generic way to create several random numbers from a single one. Our problem is quite simple though: we have a large random number and we need 6 small random numbers (between 1 and 6 each)
** ๐งโโ๏ธ ๐งโโ๏ธ ๐งโโ๏ธ Side Quest 2! Find a cheaper solution which doesn't use the expand() function. ** Check out Utilities.sol, it contains some code to get you started. Keep the original solution.
** ๐งโโ๏ธ ๐งโโ๏ธ ๐งโโ๏ธ Side Quest 3! Compare gas costs ** Find a way to see how much gas was consumed in the transaction which produced the dice roll event (hint: browser console / etherscan) Do this with your cheaper implementation and redeploy with the original one, then compare the results.
** ๐งโโ๏ธ ๐งโโ๏ธ ๐งโโ๏ธ Side Quest 4! Dice Roll UX ** Try to improve the UX in the Example UI. Replicate what the Request Random Number! button does - a spinner should appear while waiting for the Oracle response.
๐ You can yarn deploy --reset
any time and get fresh new contracts in the frontend:
Make sure to edit your 00_deploy_your_contract.js if you don't want to redeploy all of your contracts.
Check out PART 2 for a more advanced VRF setup!
Check out PART 3 for a tutorial on how to use public APIs and price feeds in your smart contracts!
๐ Global variables like msg.sender
and msg.value
are cryptographically backed and can be used to make rules
๐ Keep this cheat sheet handy
โณ Maybe we could use block.timestamp
or block.number
to track time in our contract
๐ Or maybe keep track of an address public owner;
then make a rule like require( msg.sender == owner );
for an important function
๐งพ Maybe create a smart contract that keeps track of a mapping ( address => uint256 ) public balance;
๐ฆ It could be like a decentralized bank that you function deposit() public payable {}
and withdraw()
๐ Events are really handy for signaling to the frontend. Read more about events here.
๐ฒ Spend some time in App.jsx
in packages/react-app/src
and learn about the ๐ฐ Providers
โ ๏ธ Big numbers are stored as objects: formatEther
and parseEther
(ethers.js) will help with WEI->ETH and ETH->WEI.
๐งณ The single page (searchable) ethers.js docs are pretty great too.
๐ The UI framework Ant Design
has a bunch of great components.
๐ Check the console log for your app to see some extra output from hooks like useContractReader
and useEventListener
.
๐ You'll notice the <Contract />
component that displays the dynamic form as scaffolding for interacting with your contract.
๐ฒ Try making a <Button/>
that calls writeContracts.YourContract.setPurpose("๐ Hello World")
to explore how your UI might work...
๐ฌ Wrap the call to writeContracts
with a tx()
helper that uses BlockNative's Notify.js.
๐งฌ Next learn about structs in Solidity.
๐ณ Maybe an make an array YourStructName[] public proposals;
that could call be voted on with function vote() public {}
๐ญ Your dev environment is perfect for testing assumptions and learning by prototyping.
๐ Next learn about the fallback function
๐ธ Maybe add a receive() external payable {}
so your contract will accept ETH?
๐ OH! Programming decentralized money! ๐ So rad!
๐ฐ Ready to deploy to a testnet? Change the defaultNetwork
in packages/hardhat/hardhat.config.js
๐ Generate a deploy account with yarn generate
and view it with yarn account
๐ Create wallet links to your app with yarn wallet
and yarn fundedwallet
โฌ๏ธ Installing a new package to your frontend? You need to cd packages/react-app
and then yarn add PACKAGE
โฌ๏ธ Installing a new package to your backend? You need to cd packages/harthat
and then yarn add PACKAGE
( You will probably want to take some of the ๐ hooks, ๐ components with you from ๐ scaffold-eth so we started ๐ eth-hooks )
๐ Good luck!
To deploy this project to Gitpod, click this button:
Documentation, tutorials, challenges, and many more resources, visit: docs.scaffoldeth.io
๐ Read the docs: https://docs.soliditylang.org
๐ Go through each topic from solidity by example editing YourContract.sol
in ๐ scaffold-eth
๐ง Learn the Solidity globals and units
Check out all the active branches, open issues, and join/fund the ๐ฐ BuidlGuidl!
๐ซ Extend the NFT example to make a "buyer mints" marketplace
โ๏ธ Learn how ecrecover works
๐ฉโ๐ฉโ๐งโ๐ง Build a multi-sig that uses off-chain signatures
โ๏ธ Learn how a simple DEX works
๐ฆ Ape into learning!
Join the telegram support chat ๐ฌ to ask questions and find others building with ๐ scaffold-eth!
๐ Please check out our Gitcoin grant too!