π scaffold-eth
is everything you need to get started building decentralized applications powered by smart contracts
quickstart
git clone https://github.com/austintgriffith/scaffold-eth.git your-next-dapp
cd your-next-dapp
yarn install
you might get node-gyp errors, ignore them and run:
yarn start
in a second terminal window:
yarn chain
in a third terminal window:
yarn deploy
YourContract.sol
in packages/buidler/contracts
App.jsx
in packages/react-app/src
π± Open http://localhost:3000 to see the app
With everything up your dev environment starts looking something like this:
React dev server, Buidler blockchain, deploy terminal, code IDE, and frontend browser.
yarn run deploy
any time and get a fresh new contract in the frontend:
setPurpose
on your contract and "write" to the purpose
storage:
Look for the Buidler console.log() output in the yarn run chain
terminal:
uint8 public count = 1;
function dec() public {}
that does a count = count - 1;
π¬ What happens with you subtract 1 from 0? Try it out in the app to see what happens!
localhost
:
msg.sender
and msg.value
are cryptographically backed and can be used to make rules
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
mapping ( address => uint256 ) public balance;
function deposit() public payable {}
and withdraw()
App.jsx
in packages/react-app/src
and learn about the π° Providers
Ant Design
has a bunch of great components.
useContractReader
and useEventListener
.
<Contract />
component that displays the dynamic form as scaffolding for interacting with your contract.
<Button/>
that calls writeContracts.YourContract.setPurpose("π Hello World")
to explore how your UI might work
YourStructName[] public proposals;
that could call be voted on with function vote() public {}
π Next learn about the fallback function
πΈ Maybe add a receive() external payable {}
so your contract will accept ETH?
defaultNetwork
in packages/buidler/buidler.config.js
yarn run generate
and view it with yarn run account
( You will probably want to take some of the π hooks,
β± Quickstart: π¬ Smart Contract Sandbox
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
π₯. Watch the long form
Tutorial 1: π Programming Decentralized Money
Learn the basics of
Tutorial 2: π΅ The Token
Learn about tokens. [coming soon] What is a token? Why is it cool? How can I deploy one? Exotic mechanisms? (todo)
βοΈ Minimum Viable Decentralized Exchange
Tutorial 3: Learn the basics of Automated Market Makers like
π Connecting ETH to IPFS
Tutorial 4: Build a simple IPFS application in
β½οΈ GSN and Meta Transactions
Tutorial 5: Learn about to provide your users with better UX by abstracting away gas fees and blockchain mechanics. (todo)
Tutorial 6: π° Decentralized Deployment
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!
π scaffold-eth:
built with π©βπ¨ Nifty Ink
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.
π§ββοΈ Instant Wallet
An instant wallet running on xDAI insired by xdai.io.
π³ Personal Token Voting
Poll your holders! Build an example emoji voting system with
π xmoon.exchange
Exchange Reddit MOONs for ETH or DAI through xDAI. Learn about different
Obituary.space
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.
^^^
𧫠Building on Ethereum in 2020 (research)
β± Original Quickstart with TODO List:
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.)
yarn start
App.jsx
in packages/react-app/src
and open http://localhost:3000
yarn run chain
Note: 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
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
SmartContractWallet.sol
in packages/buidler/contracts
π€‘ There is a spelling error inpackages/buidler/contracts/SmartContractWallet.sol
!π€ Can you fix it and deploy the contract locally?
β’οΈ Warning: It is very important that you findSmartContractWallet.sol
inpackages/buidler/contracts
because there are other contract folders and it can get confusing.
myTest.js
in packages/buidler/contracts
:
yarn run test
yarn run accounts
π° Check account balance:
yarn run balance **YOUR-ADDRESS**
yarn run send --from 0 --amount 0.5 --to **YOUR-ADDRESS**
π§ Configure π·Buidler by editing
buidler.config.js
inpackages/buidler
β¨ The BuidlerEVM provides stack traces and console.log debugging for our contracts β¨
πββοΈ Speedrun (π₯ 7 min):
π¬ Smart Contract Sandbox:
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
YourContract.sol
in packages/buidler/contracts
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
yarn run watch
and as you change your Solidity, your frontend <Contract/> will hot reload to give you access to new variables and functions:
π Good luck, and go get 'em!
π Web3 Providers:
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 Buidler 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)
β Helpers:
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 forreact-app/src/helpers/Transactor.js
to use your BlockNative dappId
π Hooks:
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
);
π¦ Components:
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 callsetAddress
andsetInjectedProvider
for you.
β’οΈ Warning: You will need to update the configuration forWeb3Modal
to 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 yourinjectedProvider
compared to yourlocalProvider
ormainnetProvider
and alert your users if they are on the wrong network!
π Smart Contract Wallet:
SmartContractWallet.sol
in packages/buidler/contracts
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.
You can import any of the OpenZeppelin contracts:
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
π° The Graph -- TODO
π€ Save to your Git
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 master
π³ Ship it!
You 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