The following article is based on Adam’s CharmingData channel and GitHub repository. β₯οΈ
In this tutorial, we will create, test, and deploy a smart contract called SimpleStorage
. This contract will allow your users to create their own sentence and store it on the blockchain. It will also allow users to retrieve the last sentence stored and display it on the page.
Consider the following Solidity contract:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; contract SimpleStorage { // Define a string called storeTheSentence. This is a state variable, which will be permanently stored in the blockchain. string storeTheSentence; constructor(string memory initialSentence) { // Assign the value of initialSentence to the storeTheSentence variable storeTheSentence = initialSentence; } // Declares a function called getSentence // Solidity funcions visibility: public, private, internal and external // Solidity view functions: https://www.geeksforgeeks.org/solidity-view-and-pure-functions/ function getSentence() public view returns (string memory) { return storeTheSentence; } // Declare a function called setSentence // The function takes 1 input parameter, a string named newSentence, with the calldata data location in the Ethereum Virtual Machine function setSentence(string calldata newSentence) external { // Assign the value of newSentence to the storeTheSentence variable storeTheSentence = newSentence; } }
This is a simple smart contract written in Solidity, the most popular programming language for implementing smart contracts on the Ethereum blockchain. The contract’s name is SimpleStorage
, and it primarily focuses on storing and retrieving a string (a sequence of characters).
Here’s a brief breakdown of the contract:
- State variable (
storeTheSentence
): This is a string variable that will store a sentence. This variable’s value is stored on the blockchain, making it a permanent, unerasable record. - Constructor function: When the contract is first deployed to the Ethereum blockchain, the constructor function is executed once. This function accepts one argument, a string (
initialSentence
), and assigns its value to the state variablestoreTheSentence
. getSentence()
function: This function is apublic view
function, which means anyone can call it to read the value ofstoreTheSentence
without changing any data or state in the contract. It does not cost any gas to call this function because it doesn’t change the state of the blockchain.setSentence()
function: This function is declared asexternal
, meaning it can only be called from outside the contract. It accepts one string argument (newSentence
) and assigns its value tostoreTheSentence
, effectively updating the stored sentence. As this function modifies the state of the contract, it requires a transaction to be sent and will cost gas to execute.
In essence, this contract allows anyone to store a sentence on the Ethereum blockchain and retrieve it. Due to the permanent and public nature of blockchain storage, the stored sentence would be visible to anyone and cannot be erased or modified once set (except by calling the setSentence
function again).
Let’s learn how to set it up in a step-by-step manner next. π
Backend
- Open the terminal (command line), create two new folders called
simple-storage
andbackend
. Go into thebackend
folder.
mkdir simple-storage cd simple-storage mkdir backend cd backend
- Set up a Hardhat project. Install the necessary libraries, by typing in the terminal:
npm init --yes npm install --save-dev --save-exact hardhat@2.14.0 npm install dotenv
- This library might be necessary to install as well, especially if you’re a Windows user:
npm install --save-dev @nomicfoundation/hardhat-toolbox@2
- Make sure you are still in the
backend
directory. Now, create a sample contract project by typing in the terminal:
npx hardhat
- Select
Create a Javascript Project
. Don’t change anything in the Hardhat project root, just click enter. Yes, add a.gitignore
.
- Open the
backend
folder and remove any present contracts inside thecontracts
folder. Insert yourSimpleStorage
contract. - Now, inside the
scripts
folder, replace the contect of thedeploy.js
file with the deploy.js code from this project. - Create a
.env
file inside thebackend
folder. This will be used to store your wallet key and your Quicknode endpoint. A QuickNode API endpoint gives you quick access to a network of nodes.
- Add these two lines inside the
.env
file, and update the content inside the quotation marks:
QUICKNODE_HTTP_URL="your-quicknode-http-provider-goes-here-inside-the-quotation-marks" PRIVATE_KEY="your-wallet-private-key-goes-here-inside-the-quotation-marks"
- Open the
hardhat.config.js
file inside thebackend
folder and replace its content with the hardhat.config.js code from this project. - Compile your Contract by going back to your terminal (ensure you are in the
backend
directory). And type:
npx hardhat compile
- Every time you modify your contract (
SimpleStorage
), you will have to repeat the above compile step.
- With your contract compiled, now we can deploy it to the sepolia testnet. In your terminal type:
npx hardhat run scripts/deploy.js --network sepolia
Save the contract address that was printed out. Go to https://sepolia.etherscan.io/ and insert the contract address into the Explorer input field. Take some time to explore the transaction details of your contract.
- Save this address somewhere. Don’t lose it!
Testing
Every Contract should be tested before deployment. In this case we deployed first becuause it’s freaking exciting to see our contract deployed. But we need tests to make sure our contract has no bugs and is secure.
- Open the
test
folder and remove any present files inside of it. Create a new file calledtesting.js
, and insert the testing.js code from this project. - Go back to the terminal, make sure you’re in the
backend
directory, and type:
npx hardhat test
Frontend
In this section of the tutorial we’ll create a dApp (decentralized app) that will connect to your contract and its functions, allowing you to interact with it. In other words, we’re building an interface for the contract.
- Open the terminal (command line) and go into the
simple-storage
directory. Create a sample Next app by typing:
npx create-next-app@13 frontend
- Make sure to choose these settings.
- Before running the sample app, you’ll need to remove the
.git
file that was automatically created inside the newfrontend
folder. To remove the file, type this command inside the terminal:
# Linux / macOS cd frontend rm -rf .git # Windows cd frontend rm -r -fo .git
- Install these packages using your terminal (you should still be in the
frontend
directory).
npm install web3modal npm install ethers@5
- Create a new folder called
constants
within thefrontend
directory. Inside theconstants
folder create a new file calledindex.js
. Add the following code insideindex.js
.
export const MY_CONTRACT_ADDRESS = "MY_CONTRACT_ADDRESS"; export const abi = MY_ABI;
- Replace the
MY_ABI
with the abi array that can be found in the following file:backend/artifacts/contracts/SimpleStorage.json
- Replace the
MY_CONTRACT_ADDRESS
with the address of the contract that you deployed in the Backend section of this tutorial.
- Finally, to build the interface of the contract, open the
index.js
file under thepages
folder (in thefrontend
folder) and replace its content with the index.js code from this project. - Add the Charming Data images using the instructions below. Once you understand how to add images to your app, feel free to replace with your own images, in which case you would need to update the images’ names inside the
pages/index.js
file (lines 143 & 154)
- Add the logo-charmingdata-small.ico and logocharmingdata.png to the public folder inside the frontend directory. Do not change image names.
- Go back to your terminal; make sure your in the
frontend
directory and type:
npm run dev
Sharing your dApp with others
We will use Vercel to deploy the frontend of our contract. Before starting with Vercel you will need to create a GitHub account if you don’t have one and push your code into a GitHub repository:
- Once your repositoy has been created in Github, go to Vercel and create an account by connecting your GitHub account.
- Once your GitHub account is connected, click the button to add a new project in Vercel.
- add your repository (you might have to import it as well)
- Select
Next.js
as the Framework Preset. In the Root Directory click Edit to selectfrontend
. - Click Deploy, and wait a few minutes. When done, click your domain link to see your dApp.
The previous text was originally written by Adam from CharmingData.