npm
(npx
) version 8.5.5node
version 16.13.1npm
project (default settings are fine):package.json
file for you that looks like this:Enter
to accept all the default settings and install the sample project's dependencies (hardhat
, @nomiclabs/hardhat-waffle
, ethereum-waffle
, chai
, @nomiclabs/hardhat-ethers
, ethers
).contracts
- folder where your smart contracts liveBuyMeACoffee
logicscripts
- folder where your hardhat javscript scripts livedeploy
logicbuy-coffee
scriptwithdraw
script to cash out our tipshardhat.config.js
- configuration file with settings for solidity version and deploymentGreeter.sol
contract.BuyMeACoffee.sol
constructor
saves the address of the wallet that was responsible for deploying inside an owner
variable as a payable
address. This is useful for later when we want to withdraw any tips collected by the contract.buyCoffee
function is the most important function on the contract. It accepts two strings, a _name
, and a _message
, and it also accepts ether due to the payable
modifier. It uses the _name
and _message
inputs to create a Memo
struct that is stored on the blockchain.buyCoffee
function, they must submit some ether due to the require(msg.value > 0)
statement. The ether is then held on the contract balance
until it is withdrawn.memos
array holds all of the Memo
structs generated from coffee purchases.NewMemo
log events are emitted every time a coffee is purchased. This allows us to listen for new coffee purchases from our frontend website.withdrawTips
is a function that anyone can call, but will only ever send money to the original deployer of the contract.address(this).balance
fetches the ether stored on the contractowner.send(...)
is the syntax for creating a send transaction with etherrequire(...)
statement that wraps everything is there to ensure that if there are any issues, the transaction is reverted and nothing is lostrequire(owner.send(address(this).balance))
scripts
folder, there should be a sample script already populated sample-script.js
. Let's rename that file to buy-coffee.js
and paste in the following code:main()
function. The commented code shows the flow of the script:hre.waffle.provider.getBalance
hre.ethers.getContractFactory
hre.ethers.utils.parseEther
0
address has 9999.99877086625
ETH. This is because it started with 10k ETH as one of the pre-populated hardhat addresses, but it had to spend a tiny amount to deploy to the local blockchain.== bought coffee ==
, Address 1 purchases one coffee. Two other wallets that are not shown ALSO purchase coffees. In total, 3 coffees were purchased for a total tip amount of 3.0
ETH. You can see that Address 2 (which represents the contract address), is holding on to 3.0
ETH.withdrawTips()
function is called in == withdrawTips ==
, the contract goes back down to 0
ETH, and the original deployer, aka Address 0, has now earned some money and is sitting on 10002.998724967892122376
ETH.scripts/deploy.js
that will be super simple, just for deploying our contract to any network we choose later (we'll choose Goerli later if you haven't noticed).deploy.js
file should look like this:deploy.js
script coded and saved, if you run the following command:network
that the Hardhat tool uses is a local development network, right on your computer. It's fast and deterministic, and great for some quick sanity checking. hardhat.config.json
file comes in.hardhat.config.js
file, you will see some sample deploy code. Delete that and paste this version in:hardhat-ethers
, hardhat-waffle
, and dotenv
at the top of the configuration file, our entire Hardhat project will have access to those dependencies.dotenv
yet, that's an important tool we'll talk about that in a bit.process.env.GOERLI_URL
and process.env.PRIVATE_KEY
are how we can access environment variables to use in our config file while not exposing the secret values.modules.exports
, we are using solidity compiler version 0.8.4
. Different compiler versions support different features and syntax sets, so it's important to match this version with the pragma
declaration at the top of our BuyMeACoffee.sol
smart contract.pragma solidity ^0.8.0;
. In this case, even though the numbers don't match exactly, that's okay because the karat ^
symbol means that any version that's greater than or equal to 0.8.0
will work.modules.exports
, we define a networks
setting that contains one test network configuration for goerli
. dotenv
module. As its name implies, dotenv
helps us connect a .env
file to the rest of our project. Let's set it up.dotenv
:.env
file:.env
file with the variables that we need:.gitignore
that ensures you don't accidentally push the file to version control. Make sure that .env
is listed in your .gitignore
GOERLI_URL
- sign up for an account on Alchemy, create an Ethereum -> Goerli app, and use the HTTP URLGOERLI_API_KEY
- from your same Alchemy Ethereum Goerli app, you can get the last portion of the URL, and that will be your API KEYdotenv
installed and your .env
file populated, we are ALMOST ready to deploy to the Goerli testnet!Error HH8
, then I highly recommend searching Google and Stack Overflow or Ethereum Stackexchange for solutions. It's common to run into those issues when something in your hardhat.config.js
, .env
, or your dotenv
module isn't set up correctly.withdraw.js
script.scripts/withdraw.js
withdrawTips()
function to pull money out from our contract balance and send it over to the owner's wallet:--network goerli
flag this time, and that's because our script hard-codes the network configuration directly inside the logic:Next.js
web applicationcontractAddress
in pages/index.js
pages/index.js
utils/BuyMeACoffee.json
BuyMeACoffee.sol
smart contract earlier.Albert
and replace it with your name / anon profile / ENS domain, or whatever it is you'd like for people to call you.cmd + F
or ctrl + F
to look for all instances of Albert
to replace.artifacts/contracts/BuyMeACoffee.sol/BuyMeACoffee.json
utils/BuyMeACoffee.json
npm run dev
to start a local server to test out your changes. The website should load in a few seconds:Connect your wallet
.Connect your wallet
, a MetaMask window will pop up asking if you want to confirm the connection by signing a message. This message signing does not require any gas fees or costs.