Skip to content

Commit bbb9685

Browse files
committed
docs(readme): Token Vendor overview, contracts, usage & submission notes
1 parent 52a37cc commit bbb9685

File tree

1 file changed

+86
-238
lines changed

1 file changed

+86
-238
lines changed

README.md

Lines changed: 86 additions & 238 deletions
Original file line numberDiff line numberDiff line change
@@ -1,294 +1,142 @@
1-
# 🏗 Scaffold-ETH 2
1+
# 🏵️ Token Vendor — SpeedRunEthereum Challenge
22

3-
<h4 align="center">
4-
<a href="https://docs.scaffoldeth.io">Documentation</a> |
5-
<a href="https://scaffoldeth.io">Website</a>
6-
</h4>
3+
A minimal ERC‑20 + vending machine dApp built with **Scaffold‑ETH 2** (Next.js + Viem + Wagmi + Hardhat). The app lets users **buy** your ERC‑20, **transfer** it, and **sell it back** to the Vendor using the standard **approve → transferFrom** pattern.
74

8-
🧪 An open-source, up-to-date toolkit for building decentralized applications (dapps) on the Ethereum blockchain. It's designed to make it easier for developers to create and deploy smart contracts and build user interfaces that interact with those contracts.
9-
10-
⚙️ Built using NextJS, RainbowKit, Hardhat, Wagmi, Viem, and Typescript.
11-
12-
-**Contract Hot Reload**: Your frontend auto-adapts to your smart contract as you edit it.
13-
- 🪝 **[Custom hooks](https://docs.scaffoldeth.io/hooks/)**: Collection of React hooks wrapper around [wagmi](https://wagmi.sh/) to simplify interactions with smart contracts with typescript autocompletion.
14-
- 🧱 [**Components**](https://docs.scaffoldeth.io/components/): Collection of common web3 components to quickly build your frontend.
15-
- 🔥 **Burner Wallet & Local Faucet**: Quickly test your application with a burner wallet and local faucet.
16-
- 🔐 **Integration with Wallet Providers**: Connect to different wallet providers and interact with the Ethereum network.
17-
18-
![Debug Contracts tab](https://github.com/scaffold-eth/scaffold-eth-2/assets/55535804/b237af0c-5027-4849-a5c1-2e31495cccb1)
19-
20-
## Requirements
21-
22-
Before you begin, you need to install the following tools:
23-
24-
- [Node (>= v20.18.3)](https://nodejs.org/en/download/)
25-
- Yarn ([v1](https://classic.yarnpkg.com/en/docs/install/) or [v2+](https://yarnpkg.com/getting-started/install))
26-
- [Git](https://git-scm.com/downloads)
27-
28-
# 🚩 Challenge: 🏵 Token Vendor 🤖
29-
30-
![readme-2](https://raw.githubusercontent.com/scaffold-eth/se-2-challenges/challenge-token-vendor/extension/packages/nextjs/public/hero.png)
31-
32-
🤖 Smart contracts are kind of like "always on" _vending machines_ that **anyone** can access. Let's make a decentralized, digital currency. Then, let's build an unstoppable vending machine that will buy and sell the currency. We'll learn about the "approve" pattern for ERC20s and how contract to contract interactions work.
33-
34-
🏵 Create `YourToken.sol` smart contract that inherits the **ERC20** token standard from OpenZeppelin. Set your token to `_mint()` **1000** (* 10 ** 18) tokens to the `msg.sender`. Then create a `Vendor.sol` contract that sells your token using a payable `buyTokens()` function.
35-
36-
🎛 Edit the frontend that invites the user to input an amount of tokens they want to buy. We'll display a preview of the amount of ETH it will cost with a confirm button.
37-
38-
🔍 It will be important to verify your token's source code in the block explorer after you deploy. Supporters will want to be sure that it has a fixed supply and you can't just mint more.
39-
40-
🌟 The final deliverable is an app that lets users purchase your ERC20 token, transfer it, and sell it back to the vendor. Deploy your contracts on your public chain of choice and then `yarn vercel` your app to a public web server. Submit the url on [SpeedRunEthereum.com](https://speedrunethereum.com)!
41-
42-
> 💬 Meet other builders working on this challenge and get help in the [Challenge Telegram](https://t.me/joinchat/IfARhZFc5bfPwpjq)!
5+
> This repository is a completed submission for the **Token Vendor** challenge on [speedrunethereum.com](https://speedrunethereum.com/challenge/token-vendor).
436
447
---
458

46-
## Checkpoint 0: 📦 Environment 📚
47-
48-
> Start your local network (a blockchain emulator in your computer):
49-
50-
```
51-
yarn chain
52-
```
53-
54-
> in a second terminal window, 🛰 deploy your contract (locally):
55-
56-
```sh
57-
yarn deploy
58-
```
59-
60-
> in a third terminal window, start your 📱 frontend:
61-
62-
```sh
63-
yarn start
64-
```
9+
## 🚀 Live
6510

66-
📱 Open http://localhost:3000 to see the app.
11+
- **App**: [https://nextjs-llt7ljkl8-dormins-projects.vercel.app/](https://nextjs-llt7ljkl8-dormins-projects.vercel.app/)
12+
- **Network**: Sepolia (chain id **11155111**)
13+
- **Contracts**
14+
- `Vendor`**0x98219Dc8ECAFDe3B5ed9dAd5DD8bc14963Dd0F87**
15+
- `YourToken`**0x35f5CB22E33E7063514a26b3D8680B3Bc86F8176**
6716

68-
> 👩‍💻 Rerun `yarn deploy --reset` whenever you want to deploy new contracts to the frontend, update your current contracts with changes, or re-deploy it to get a fresh contract address.
17+
Paste any address above into a block explorer to view code/txs.
6918

7019
---
7120

72-
⚠️ We have disabled AI in Cursor and VSCode and highly suggest that you do not enable it so you can focus on the challenge, do everything by yourself, and hence better understand and remember things. If you are using another IDE, please disable AI yourself.
21+
## ✨ What’s inside
7322

74-
🔧 If you are a vibe-coder and don't care about understanding the syntax of the code used and just want to understand the general takeaways, you can re-enable AI by:
75-
- Cursor: remove `*` from `.cursorignore` file
76-
- VSCode: set `chat.disableAIFeatures` to `false` in `.vscode/settings.json` file
23+
- **YourToken.sol** — ERC‑20 (OpenZeppelin). Fixed supply, minted in the constructor to deployer.
24+
- **Vendor.sol** — Vending machine contract:
25+
- `tokensPerEth = 100`
26+
- `buyTokens()` payable — swaps ETH → tokens
27+
- `sellTokens(uint256)` — requires prior `approve`, swaps tokens → ETH
28+
- `withdraw()` — owner‑only, withdraws all ETH
29+
- Events: `BuyTokens`, `SellTokens`, `Withdraw`
30+
- **Deploy script** transfers `1000 * 10**18` tokens to the Vendor and transfers Vendor ownership to the **frontend/owner** address.
7731

7832
---
7933

80-
## Checkpoint 1: 🏵Your Token 💵
34+
## 🛠 Quickstart (local)
8135

82-
> 👩‍💻 Edit `YourToken.sol` to inherit the **ERC20** token standard from OpenZeppelin
36+
> Recommended Node: **v20.18.x** (Hardhat does not officially support Node 21).
8337
84-
> Mint **1000** (* 10 ** 18) to your frontend address using the `constructor()`.
38+
```bash
39+
# 1) Install deps (root)
40+
yarn
8541

86-
(Your frontend address is the address in the top right of http://localhost:3000)
87-
88-
> You can `yarn deploy --reset` to deploy your contract until you get it right.
89-
90-
### 🥅 Goals
91-
92-
- [ ] Can you check the `balanceOf()` your frontend address in the `Debug Contracts` tab? (`YourToken` contract)
93-
- [ ] Can you `transfer()` your token to another account and check _that_ account's `balanceOf`?
94-
95-
![debugContractsYourToken](https://github.com/scaffold-eth/se-2-challenges/assets/55535804/5fb4daeb-5d05-4522-96b3-76f052a68418)
96-
97-
> 💬 Hint: Use an incognito window to create a new address and try sending to that new address. Can use the `transfer()` function in the `Debug Contracts` tab.
98-
99-
---
100-
101-
## Checkpoint 2: ⚖️ Vendor 🤖
102-
103-
> 👩‍💻 Edit the `Vendor.sol` contract with a **payable** `buyTokens()` function
42+
# 2) Start local chain
43+
cd packages/hardhat
44+
yarn chain
10445

105-
Use a price variable named `tokensPerEth` set to **100**:
46+
# 3) In a new terminal: deploy locally
47+
cd packages/hardhat
48+
yarn deploy --reset
10649

107-
```solidity
108-
uint256 public constant tokensPerEth = 100;
50+
# 4) In a third terminal: start the dapp
51+
cd packages/nextjs
52+
yarn start
53+
# open http://localhost:3000
10954
```
11055

111-
> 📝 The `buyTokens()` function in `Vendor.sol` should use `msg.value` and `tokensPerEth` to calculate an amount of tokens to `yourToken.transfer()` to `msg.sender`.
112-
113-
> 📟 Emit **event** `BuyTokens(address buyer, uint256 amountOfETH, uint256 amountOfTokens)` when tokens are purchased.
114-
115-
Edit `packages/hardhat/deploy/01_deploy_vendor.ts` to deploy the `Vendor` (uncomment Vendor deploy lines).
56+
### Environment
11657

117-
Uncomment the `Buy Tokens` sections in `packages/nextjs/app/token-vendor/page.tsx` to show the UI to buy tokens on the Token Vendor tab.
118-
119-
### 🥅 Goals
120-
121-
- [ ] When you try to buy tokens from the vendor, you should get an error: **'ERC20InsufficientBalance'**
122-
123-
⚠️ This is because the Vendor contract doesn't have any YourTokens yet!
124-
125-
⚔️ Side Quest: send tokens from your frontend address to the Vendor contract address and _then_ try to buy them.
126-
127-
> ✏️ We can't hard code the vendor address like we did above when deploying to the network because we won't know the vendor address at the time we create the token contract.
128-
129-
> ✏️ So instead, edit `YourToken.sol` to mint the tokens to the `msg.sender` (deployer) in the **constructor()**.
130-
131-
> ✏️ Then, edit `deploy/01_deploy_vendor.ts` to transfer 1000 tokens to vendor address.
132-
133-
```js
134-
await yourToken.transfer(vendorAddress, hre.ethers.parseEther("1000"));
58+
`packages/hardhat/.env`
13559
```
136-
137-
> 🔎 Look in `packages/nextjs/app/token-vendor/page.tsx` for code to uncomment to display the Vendor ETH and Token balances.
138-
139-
> You can `yarn deploy --reset` to deploy your contract until you get it right.
140-
141-
![TokenVendorBuy](https://github.com/scaffold-eth/se-2-challenges/assets/55535804/7669cc68-e942-4630-95c8-91cd21af5ba0)
142-
143-
### 🥅 Goals
144-
145-
- [ ] Does the `Vendor` address start with a `balanceOf` **1000** in `YourToken` on the `Debug Contracts` tab?
146-
- [ ] Can you buy **10** tokens for **0.1** ETH?
147-
- [ ] Can you transfer tokens to a different account?
148-
149-
⚠️ Uncomment the import of Ownable.sol contract!
150-
151-
> 📝 Edit `Vendor.sol` to inherit _Ownable_.
152-
153-
`contract Vendor is Ownable {`
154-
155-
> 📝 Change constructor of `Vendor.sol` to:
156-
157-
`constructor(address tokenAddress) Ownable(msg.sender) {`
158-
159-
In `deploy/01_deploy_vendor.ts` you will need to call `transferOwnership()` on the `Vendor` to make _your frontend address_ the `owner`:
160-
161-
```js
162-
await vendor.transferOwnership("**YOUR FRONTEND ADDRESS**");
60+
ALCHEMY_API_KEY=
61+
ETHERSCAN_V2_API_KEY=
62+
DEPLOYER_PRIVATE_KEY_ENCRYPTED={...}
63+
FRONTEND_ADDRESS=0xyourOwnerWallet
16364
```
16465

165-
### 🥅 Goals
166-
167-
- [ ] Is your frontend address the `owner` of the `Vendor`?
168-
169-
> 📝 Finally, add a `withdraw()` function in `Vendor.sol` that lets the owner withdraw all the ETH from the vendor contract.
170-
171-
### 🥅 Goals
172-
173-
- [ ] Can **only** the `owner` withdraw the ETH from the `Vendor`?
174-
175-
### ⚔️ Side Quests
66+
`packages/nextjs/.env.local` (optional; defaults are provided)
67+
```
68+
NEXT_PUBLIC_ALCHEMY_API_KEY=
69+
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=
70+
```
17671

177-
- [ ] What if you minted **2000** and only sent **1000** to the `Vendor`?
72+
> Ensure `.env*` files are **gitignored**. Do **not** commit private keys or encrypted key blobs.
17873
17974
---
18075

181-
## Checkpoint 3: 🤔 Vendor Buyback 🤯
182-
183-
👩‍🏫 The hardest part of this challenge is to build your `Vendor` to buy the tokens back.
184-
185-
🧐 The reason why this is hard is the `approve()` pattern in ERC20s.
186-
187-
😕 First, the user has to call `approve()` on the `YourToken` contract, approving the `Vendor` contract address to take some amount of tokens.
188-
189-
🤨 Then, the user makes a _second transaction_ to the `Vendor` contract to `sellTokens(uint256 amount)`.
190-
191-
🤓 The `Vendor` should call `yourToken.transferFrom(msg.sender, address(this), theAmount)` and if the user has approved the `Vendor` correctly, tokens should transfer to the `Vendor` and ETH should be sent to the user.
192-
193-
> 📝 Edit `Vendor.sol` and add a `sellTokens(uint256 amount)` function!
194-
195-
⚠️ You will need extra UI for calling `approve()` before calling `sellTokens(uint256 amount)`.
196-
197-
🔨 Use the `Debug Contracts` tab to call the approve and sellTokens() at first but then...
198-
199-
🔍 Look in the `packages/nextjs/app/token-vendor/page.tsx` for the extra approve/sell UI to uncomment!
200-
201-
![VendorBuyBack](https://github.com/scaffold-eth/se-2-challenges/assets/55535804/99063aaa-368d-4156-997d-08dff99af11b)
202-
203-
### 🥅 Goal
76+
## 🔍 Verify (optional)
20477

205-
- [ ] Can you sell tokens back to the vendor?
206-
- [ ] Do you receive the right amount of ETH for the tokens?
78+
From `packages/hardhat`:
20779

208-
### ⚔️ Side Quests
209-
210-
- [ ] Should we disable the `owner` withdraw to keep liquidity in the `Vendor`?
211-
- [ ] It would be a good idea to display Sell Token Events. Create an **event** `SellTokens(address seller, uint256 amountOfTokens, uint256 amountOfETH)` and `emit` it in your `Vendor.sol` and uncomment `SellTokens Events` section in your `packages/nextjs/app/events/page.tsx` to update your frontend.
212-
213-
![Events](https://github.com/scaffold-eth/se-2-challenges/assets/55535804/662c96b5-d53f-4efa-af4a-d3106bfd47f0)
214-
215-
### ⚠️ Test it!
216-
217-
- 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!
80+
```bash
81+
yarn verify --network sepolia 0x35f5CB22E33E7063514a26b3D8680B3Bc86F8176 # YourToken (no args)
82+
yarn verify --network sepolia 0x98219Dc8ECAFDe3B5ed9dAd5DD8bc14963Dd0F87 "0x35f5CB22E33E7063514a26b3D8680B3Bc86F8176" # Vendor(tokenAddress)
83+
```
21884

21985
---
22086

221-
## Checkpoint 4: 💾 Deploy your contracts! 🛰
222-
223-
📡 Edit the `defaultNetwork` to [your choice of public EVM networks](https://ethereum.org/en/developers/docs/networks/) in `packages/hardhat/hardhat.config.ts`
224-
225-
🔐 You will need to generate a **deployer address** using `yarn generate` This creates a mnemonic and saves it locally.
87+
## 📋 How to use (on Sepolia)
22688

227-
👩‍🚀 Use `yarn account` to view your deployer account balances.
228-
229-
⛽️ You will need to send ETH to your deployer address with your wallet, or get it from a public faucet of your chosen network.
230-
231-
🚀 Run `yarn deploy` to deploy your smart contract to a public network (selected in `hardhat.config.ts`)
232-
233-
> 💬 Hint: You can set the `defaultNetwork` in `hardhat.config.ts` to `sepolia` or `optimismSepolia` **OR** you can `yarn deploy --network sepolia` or `yarn deploy --network optimismSepolia`.
89+
1. Connect wallet (burner or MetaMask) on Sepolia.
90+
2. **Buy**: enter tokens to buy → wallet pays `amount / tokensPerEth` ETH.
91+
3. **Transfer**: send tokens to any address via `transfer`.
92+
4. **Sell**: `approve(Vendor, amount)` then `sellTokens(amount)` to receive ETH back.
23493

23594
---
23695

237-
## Checkpoint 5: 🚢 Ship your frontend! 🚁
238-
239-
✏️ Edit your frontend config in `packages/nextjs/scaffold.config.ts` to change the `targetNetwork` to `chains.sepolia` (or `chains.optimismSepolia` if you deployed to OP Sepolia)
240-
241-
💻 View your frontend at http://localhost:3000 and verify you see the correct network.
242-
243-
📡 When you are ready to ship the frontend app...
96+
## 🧩 Tech stack
24497

245-
📦 Run `yarn vercel` to package up your frontend and deploy.
98+
- Solidity, Hardhat, hardhat‑deploy
99+
- OpenZeppelin ERC20, Ownable
100+
- Next.js (app router), Viem, Wagmi, RainbowKit
101+
- Tailwind + daisyUI
246102

247-
> You might need to log in to Vercel first by running `yarn vercel:login`. Once you log in (email, GitHub, etc), the default options should work.
248-
249-
> If you want to redeploy to the same production URL you can run `yarn vercel --prod`. If you omit the `--prod` flag it will deploy it to a preview/test URL.
250-
251-
> Follow the steps to deploy to Vercel. It'll give you a public URL.
252-
253-
> 🦊 Since we have deployed to a public testnet, you will now need to connect using a wallet you own or use a burner wallet. By default 🔥 `burner wallets` are only available on `hardhat` . You can enable them on every chain by setting `onlyLocalBurnerWallet: false` in your frontend config (`scaffold.config.ts` in `packages/nextjs/`)
254-
255-
#### Configuration of Third-Party Services for Production-Grade Apps.
256-
257-
By default, 🏗 Scaffold-ETH 2 provides predefined API keys for popular services such as Alchemy and Etherscan. This allows you to begin developing and testing your applications more easily, avoiding the need to register for these services.
258-
This is great to complete your **SpeedRunEthereum**.
259-
260-
For production-grade applications, it's recommended to obtain your own API keys (to prevent rate limiting issues). You can configure these at:
261-
262-
- 🔷`ALCHEMY_API_KEY` variable in `packages/hardhat/.env` and `packages/nextjs/.env.local`. You can create API keys from the [Alchemy dashboard](https://dashboard.alchemy.com/).
103+
---
263104

264-
- 📃`ETHERSCAN_API_KEY` variable in `packages/hardhat/.env` with your generated API key. You can get your key [here](https://etherscan.io/myapikey).
105+
## ✅ Submission notes
265106

266-
> 💬 Hint: It's recommended to store env's for nextjs in Vercel/system env config for live apps and use .env.local for local testing.
107+
- `tokensPerEth` hard‑coded to **100**.
108+
- Vendor preloaded with **1000 YTK** in the deploy script.
109+
- Vendor ownership transferred to `FRONTEND_ADDRESS` from `.env`.
110+
- Frontend route: `/token-vendor` includes **Buy / Transfer / Approve+Sell** UX and shows balances.
267111

268112
---
269113

270-
## Checkpoint 6: 📜 Contract Verification
271-
272-
Run the `yarn verify --network your_network` command to verify your contracts on etherscan 🛰
114+
## 🔐 Security
273115

274-
👀 You may see an address for both YourToken and Vendor. You will want the Vendor address.
275-
276-
👉 Search this address on [Sepolia Etherscan](https://sepolia.etherscan.io/) (or [Optimism Sepolia Etherscan](https://sepolia-optimism.etherscan.io/) if you deployed to OP Sepolia) to get the URL you submit to 🏃‍♀️[SpeedRunEthereum.com](https://speedrunethereum.com).
116+
- Addresses are public by design. **Never** commit private keys, mnemonics or the encrypted key JSON.
117+
- Keep owner funds in a non‑burner wallet.
277118

278119
---
279120

280-
> 🏃 Head to your next challenge [here](https://speedrunethereum.com).
121+
## 📦 Scripts
281122

282-
> 💬 Problems, questions, comments on the stack? Post them to the [🏗 scaffold-eth developers chat](https://t.me/joinchat/F7nCRK3kI93PoCOk)
123+
```bash
124+
# Deploy to Sepolia
125+
cd packages/hardhat
126+
yarn deploy --network sepolia --reset
283127

284-
## Documentation
128+
# Verify on Sepolia (see Verify above)
285129

286-
Visit our [docs](https://docs.scaffoldeth.io) to learn how to start building with Scaffold-ETH 2.
130+
# Build frontend
131+
cd packages/nextjs
132+
yarn build
287133

288-
To know more about its features, check out our [website](https://scaffoldeth.io).
134+
# Deploy frontend to Vercel (once linked)
135+
vercel --prod
136+
```
289137

290-
## Contributing to Scaffold-ETH 2
138+
---
291139

292-
We welcome contributions to Scaffold-ETH 2!
140+
## 📄 License
293141

294-
Please see [CONTRIBUTING.MD](https://github.com/scaffold-eth/scaffold-eth-2/blob/main/CONTRIBUTING.md) for more information and guidelines for contributing to Scaffold-ETH 2.
142+
MIT

0 commit comments

Comments
 (0)