In this article, we’ll walk through how to build a full stack Ethereum dApp with Solidity and Next.js from scratch.
If you want to learn how to interact with a simple smart contract from the client side, this article is for you.
Here’s the Solidity Next.js Starter on GitHub, we’ll reference the code throughout this article.
Let’s dive in.
The repository for this tutorial has two packages named
packages/contracts - This package contains everything related to the smart contract files and Hardhat development environment.
Here’s the complete list of tools we’re using:
When you’re viewing a repository for the first time, it’s always useful to know what the scripts in
package.json do. Here’s a breakdown for the
yarn start- Starts your local Hardhat network
yarn test- Tests
yarn deploy- Deploys
Greeter.solto your local Hardhat network
yarn deploy:goerli- Deploys
Greeter.solto the Goerli test network
yarn format- Formats all code using Prettier
packages/app - This package contains everything related to the Next.js application.
Everything I’m using to ship production dApps is included:
Here’s what the app scripts do:
yarn dev- Starts the Next.js local development environment
yarn build- Creates an optimised production build of your app
yarn start- Starts the Next.js application in production mode
yarn lint- Checks for problems in your code using ESLint
yarn format- Formats all code using Prettier
To start this tutorial with the Solidity Next.js Starter repository, you’ll need the following in advance:
Now we’ve walked through how the code is organised, let’s dig in to how to get everything running on your local machine:
git clone https://github.com/tomhirst/solidity-nextjs-starter.git to clone this repository to your local machine.
Enter the repository folder with
cd solidity-nextjs-starter, then install all dependencies using
Solidity Next.js Starter uses Yarn workspaces, so this will install the relevant dependencies for each packages in one command.
contracts folder with
cd packages/contracts and start your local hardhat node with
yarn start. If you’re successful, you’ll be presented with a number of accounts (one of which you’ll need later). Here’s an example:
Account #0: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (10000 ETH) Private Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
In a new terminal window, deploy the
Greeter contract using
yarn deploy. If you’re successful, you’ll get a contract address (that you’ll also need later) like this:
Greeter with greeting "Hello, world!" deployed to 0x5FbDB2315678afecb367f032d93F642f64180aa3
app folder with
cd packages/app from the root directory.
You’ll need a RainbowKit project ID. You can get one from WalletConnect Cloud and it will look something like this:
206a512b7abd9c469123b45fb272b68e (not a real key).
.env.example and rename the file
.env. Then add your RainbowKit project ID like this:
NEXT_PUBLIC_CHAIN_ID should already be set to the Hardhat local network ID of
31337 (change this when you want your app to run on other chains).
NEXT_PUBLIC_CONTRACT_ADDRESS using the contract address you recieved when you deployed. For example:
Once your environment variables are set, run the application using
yarn dev. To view, open up
localhost:3000 (or whatever port Next.js has assigned) in your browser.
To fully demo the apps’ features, you’ll need a web3 wallet extension. If you don’t have MetaMask installed already, you can get it here.
If you haven’t used Hardhat before, you’ll need to add a test account to write to the smart contract that you deployed. Do this by importing one of the accounts you noted down earlier to MetaMask using the accounts’ private key (for example,
Once connected to the app with the test account, you can set a new greeting on the blockchain by using the form on page. You’ll get a confirmation message if you’re successful.
Eventually, you’ll want to take your work from a local environment to a production one. Here’s how to deploy your smart contract and application to publically viewable environments, so other people can use them:
Up to now, your smart contract has been running locally. The next step is to deploy it to a live test network. We’ll use Goerli for this.
First you need some Goerli test ETH. You can get some from a Goerli Faucet.
packages/contracts directory, duplicate
.env. You’ll need an Alchemy API key and the private key of the wallet you’d like to deploy your Goerli contract from. I recommend using a burner account that doesn’t hold any valuable assets on other chains.
Set the environment variables like so:
yarn deploy:goerli. If you’re successful, you’ll get a message ike this in your terminal window:
Greeter with greeting "Hello, world!" deployed to 0x2D3Dff7366c8FA680801E563E008C8303B36FBC6
Here’s a version of the contract I deployed earlier: 0x2D3Dff7366c8FA680801E563E008C8303B36FBC6
Let’s verify your newly deployed contract with Etherscan. First, get an Etherscan API key here. Then add it to your
yarn verify:goerli [your-contract-address] 'Hello, world!' to verify your contract. Be sure to pass the address of the contract you just deployed and the constructor parameter, which in this case is the default greeting.
If you’re successful, you’ll get a message like this:
Successfully verified contract Greeter on the block explorer.
Let’s look at deploying your application.
To interact with smart contracts on a testnet or mainnet from your app, you’ll need an Alchemy API key. You can get one here if you didn’t get one earlier.
Add this to
packages/app like so:
This will let you point your front end at a publically viewable contract on a network like Goerli or mainnet.
You can deploy the application to Vercel by clicking this button:
Be sure to deploy from the
packages/app directory and set these environment variables:
NEXT_PUBLIC_ALCHEMY_API_KEY=[your-api-key] NEXT_PUBLIC_CONTRACT_ADDRESS=[your-contract-address] NEXT_PUBLIC_CHAIN_ID=[your-chain-id] NEXT_PUBLIC_RAINBOWKIT_PROJECT_ID=[your-project-id]
Here’s an app I deployed earlier: https://solidity-nextjs-starter-app.vercel.app/
All suggestions for improvement are welcome. Please submit a pull request to contribute.
All code in this repository is unaudited. Use at your own risk.