is everything you need to get started building decentralized applications powered by smart contracts
git clone https://github.com/austintgriffith/scaffold-eth.git your-next-dapp
cd your-next-dappyarn install
yarn start
in a second terminal window:
yarn chain
in a third terminal window:
yarn deploy
π Edit your smart contract YourContract.sol in packages/hardhat/contracts
π Edit your frontend App.jsx in packages/react-app/src
π± 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 dev environment starts looking something like this:
React dev server, HardHat blockchain, deploy terminal, code IDE, and frontend browser.
π You can yarn run deploy any time and get a fresh new contract in the frontend:
π΅. Each browser has an account in the top right and you can use the faucet (bottom left) to get β½οΈ testnet eth for gas:
π¨ Once you have funds, you can call setPurpose on your contract and "write" to the purpose storage:
Look for the HardHat console.log() output in the yarn run chain terminal:
π¨βπ« Maybe start super simple and add a counter uint8 public count = 1;
β¬οΈ Then a function dec() public {} that does a count = count - 1;
π¬ What happens when you subtract 1 from 0? Try it out in the app to see what happens!
π½ UNDERFLOW!
π§« You can iterate and learn as you go. Test your assumptions!
π΅ Send testnet ETH between browsers or even on an instantwallet.io selecting localhost:
π 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
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
π©βπ You can "graduate" from π scaffold-eth and start using π· HardHat and π¦ create-eth-app "standalone"
( You will probably want to take some of the π hooks, π components with you from π scaffold-eth so we started π eth-hooks )
π Good luck!
Learn how to quickly iterate on a smart contract app using the <Contract /> component.
Join the telegram support chat π¬ to ask questions and find others building with π scaffold-eth!
π₯. Watch the long form π scaffold-eth introduction on youtube for the EEA.
Learn the basics of π scaffold-eth and building on Ethereum. π·ββοΈ HardHat, π¦ create-eth-app, π₯ hot reloading smart contracts, π° providers, π hooks, π components, and building a decentralized application. π₯ Guided Tutorial
Learn about tokens. [coming soon] What is a token? Why is it cool? How can I deploy one? Exotic mechanisms? (todo)
Learn the basics of Automated Market Makers like π¦ Uniswap. Learn how π°Reserves affect the π price, βοΈ trading, and π¦ slippage from low liqudity.
Build a simple IPFS application in π scaffold-eth to learn more about distributed file storage and content addressing. π₯ Live Tutorial
Learn about to provide your users with better UX by abstracting away gas fees and blockchain mechanics. (todo)
Learn how to deploy your smart contract to a production blockchain. Then deploy your applicaton to Surge, S3, and IPFS. Finally, register an ENS and point it at the decentralized content! π₯ Live Tutorial
π‘ Using The Graph with π scaffold-eth
Paintings come to life as you "ink" new creations and trade them on Ethereum. A deep dive into πΌ NFTs, π³ OpenSea, π react-canvas-draw, π¨ react-color, and π¬ onboarding user experience.
πββοΈ SpeedRun πΉ (TODO)
An instant wallet running on xDAI insired by xdai.io.
Poll your holders! Build an example emoji voting system with π scaffold-eth. π Cryptographically signed votes but tracked off-chain with π‘ Zapier and π Google Sheets.
Exchange Reddit MOONs for ETH or DAI through xDAI. Learn about different π° providers and how π bridges can connect different chains with different security models.
Remember someone permanently on the blockchain. Write an obituary and upload a photo of a person and their memory will be encoded on the blockchain, forever.
^^^ β PR your π scaffold-eth project in above!!! ^^^
First, you'll need NodeJS>=10 plus Yarn and Git installed.
πΎ install:
git clone https://github.com/austintgriffith/scaffold-eth.git rad-new-dapp
cd rad-new-dapp
git checkout quickstart
yarn installβοΈ This will take some time. How about a quick tour of the file structure with your favorite code editor?
π‘ Sometimes the install throws errors like "node-gyp", try the next step even if you see problems.
(You can also download the Apple command line tools to fix the warning.)
π frontend
yarn startπ Edit your frontend App.jsx in packages/react-app/src and open http://localhost:3000
β blockchain
yarn run chainNote: You'll need to run this command in a new terminal window
π Use this eth.build to double-check your local chain and account balances
βοΈ Compile your contracts:
yarn run compileπ’ Deploy your contracts to the frontend:
yarn run deployπ Watch for changes then compile, deploy, and hot reload the frontend:
yarn run watchπ₯ Your dapp hot reloads as you build your smart contracts and frontend together π₯
π Edit your smart contract SmartContractWallet.sol in packages/hardhat/contracts
π€‘ There is a spelling error in
packages/hardhat/contracts/SmartContractWallet.sol!
π€ Can you fix it and deploy the contract locally?
β’οΈ Warning: It is very important that you find
SmartContractWallet.solinpackages/hardhat/contractsbecause there are other contract folders and it can get confusing.
π¬Test your contracts by editing myTest.js in packages/hardhat/contracts:
yarn run testπ List your local accounts:
yarn run accountsπ° Check account balance:
yarn run balance **YOUR-ADDRESS**πΈ Send ETH:
yarn run send --from 0 --amount 0.5 --to **YOUR-ADDRESS**π§ Configure π·HardHat by editing
hardhat.config.jsinpackages/hardhat
β¨ The HardHat network provides stack traces and console.log debugging for our contracts β¨
πΎ install:
git clone https://github.com/austintgriffith/scaffold-eth.git smart-contract-sandbox
cd smart-contract-sandbox
yarn installβοΈ start
#run in original terminal window:
yarn start
#run in terminal window 2:
yarn run chain
#run in terminal window 3:
yarn run deployπ Edit or rename your smart contract YourContract.sol in packages/hardhat/contracts
π Edit your frontend App.jsx in packages/react-app/src
π± Open http://localhost:3000 to see the app
β’οΈ Make sure are running your local chain yarn run chain and your contract is deployed with yarn run deploy
π₯ Try yarn run watch and as you change your Solidity, your frontend <Contract/> will hot reload to give you access to new variables and functions:
π½ Video Guide
π RTFM: Check out solidity by example and check out the Solidity globals and units
π Good luck, and go get 'em!
The frontend has three different providers that provide different levels of access to different chains:
mainnetProvider: (read only) Infura connection to main Ethereum network (and contracts already deployed like DAI or Uniswap).
localProvider: local HardHat accounts, used to read from your contracts (.env file points you at testnet or mainnet)
injectedProvider: your personal MetaMask, WalletConnect via Argent, or other injected wallet (generates burner-provider on page load)
π Ant.design is the UI library with components like the grids, menus, dates, times, buttons, etc.
Transactor: The transactor returns a tx() function to make running and tracking transactions as simple and standardized as possible. We will bring in BlockNative's Notify library to track our testnet and mainnet transactions.
const tx = Transactor(props.injectedProvider, props.gasPrice);Then you can use the tx() function to send funds and write to your smart contracts:
tx({
to: readContracts[contractName].address,
value: parseEther("0.001"),
});tx(writeContracts["SmartContractWallet"].updateOwner(newOwner));β’οΈ Warning: You will need to update the configuration for
react-app/src/helpers/Transactor.jsto use your BlockNative dappId
Commonly used Ethereum hooks located in packages/react-app/src/:
usePoller(fn, delay): runs a function on app load and then on a custom interval
usePoller(() => {
//do something cool at start and then every three seconds
}, 3000);useBalance(address, provider, [pollTime]): poll for the balance of an address from a provider
const localBalance = useBalance(address, localProvider);useBlockNumber(provider,[pollTime]): get current block number from a provider
const blockNumber = useBlockNumber(props.provider);useGasPrice([speed]): gets current "fast" price from ethgasstation
const gasPrice = useGasPrice();useExchangePrice(mainnetProvider, [pollTime]): gets current price of Ethereum on the Uniswap exchange
const price = useExchangePrice(mainnetProvider);useContractLoader(provider): loads your smart contract interface
const readContracts = useContractLoader(localProvider);
const writeContracts = useContractLoader(injectedProvider);useContractReader(contracts, contractName, variableName, [pollTime]): reads a variable from your contract and keeps it in the state
const title = useContractReader(props.readContracts, contractName, "title");
const owner = useContractReader(props.readContracts, contractName, "owner");useEventListener(contracts, contractName, eventName, [provider], [startBlock]): listens for events from a smart contract and keeps them in the state
const ownerUpdates = useEventListener(
readContracts,
contractName,
"UpdateOwner",
props.localProvider,
1
);Your commonly used React Ethereum components located in packages/react-app/src/:
π¬ <Address />: A simple display for an Ethereum address that uses a Blockie, lets you copy, and links to Etherescan.
<Address value={address} />
<Address value={address} size="short" />
<Address value={address} size="long" blockexplorer="https://blockscout.com/poa/xdai/address/"/>
<Address value={address} ensProvider={mainnetProvider}/>π <AddressInput />: An input box you control with useState for an Ethereum address that uses a Blockie and ENS lookup/display.
const [ address, setAddress ] = useState("")
<AddressInput
value={address}
ensProvider={props.ensProvider}
onChange={(address)=>{
setAddress(address)
}}
/>TODO GIF
π΅ <Balance />: Displays the balance of an address in either dollars or decimal.
<Balance
address={address}
provider={injectedProvider}
dollarMultiplier={price}
/>π€ <Account />: Allows your users to start with an Ethereum address on page load but upgrade to a more secure, injected provider, using Web3Modal. It will track your address and localProvider in your app's state:
const [address, setAddress] = useState();
const [injectedProvider, setInjectedProvider] = useState();
const price = useExchangePrice(mainnetProvider);<Account
address={address}
setAddress={setAddress}
localProvider={localProvider}
injectedProvider={injectedProvider}
setInjectedProvider={setInjectedProvider}
dollarMultiplier={price}
/>π‘ Notice: the
<Account />component will callsetAddressandsetInjectedProviderfor you.
β’οΈ Warning: You will need to update the configuration for
Web3Modalto use your Infura Id
π‘ <Provider />: You can choose to display the provider connection status to your users with:
<Provider name={"mainnet"} provider={mainnetProvider} />
<Provider name={"local"} provider={localProvider} />
<Provider name={"injected"} provider={injectedProvider} />π‘ Notice: you will need to check the network id of your
injectedProvidercompared to yourlocalProviderormainnetProviderand alert your users if they are on the wrong network!
π Edit your smart contract SmartContractWallet.sol in packages/hardhat/contracts
π Then edit the SmartContractWallet.js React component in packages/react-app/src
yarn run compile and yarn run deploy or just yarn run watch
π Run this eth.build with your contract address to ask it who its owner is.
π OpenZeppelin Contracts -- TODO
You can import any of the OpenZeppelin contracts:
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";π° The Graph -- π₯ speed run tutorial video
β½οΈ GSN -- See Nifty.ink!
Create a new repo with the same name as this project and then:
git remote add origin https://github.com/**YOUR_GITHUB_USERNAME**/**YOUR_COOL_PROJECT_NAME**.git
git push -u origin masterYou can deploy your static site and your dapp can go live:
yarn run build
# ship it!
yarn run surge
OR
yarn run s3
OR
yarn run ipfs















