Smart Contract to Store a Sentence on ETH

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:

  1. 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.
  2. 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 variable storeTheSentence.
  3. getSentence() function: This function is a public view function, which means anyone can call it to read the value of storeTheSentence 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.
  4. setSentence() function: This function is declared as external, meaning it can only be called from outside the contract. It accepts one string argument (newSentence) and assigns its value to storeTheSentence, 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

  1. Open the terminal (command line), create two new folders called simple-storage and backend. Go into the backend folder.
mkdir simple-storage
cd simple-storage
mkdir backend
cd backend
  1. 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
  1. This library might be necessary to install as well, especially if you’re a Windows user:
npm install --save-dev @nomicfoundation/hardhat-toolbox@2
  1. 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.
  1. Open the backend folder and remove any present contracts inside the contracts folder. Insert your SimpleStorage contract.
  2. Now, inside the scripts folder, replace the contect of the deploy.js file with the deploy.js code from this project.
  3. Create a .env file inside the backend 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"
  1. Open the hardhat.config.js file inside the backend folder and replace its content with the hardhat.config.js code from this project.
  2. 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.
  1. 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.

  1. Open the test folder and remove any present files inside of it. Create a new file called testing.js, and insert the testing.js code from this project.
  2. 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.

  1. 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.
  1. Before running the sample app, you’ll need to remove the .git file that was automatically created inside the new frontend 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
  1. Install these packages using your terminal (you should still be in the frontend directory).
npm install web3modal
npm install ethers@5
  1. Create a new folder called constants within the frontend directory. Inside the constants folder create a new file called index.js. Add the following code inside index.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.
  1. Finally, to build the interface of the contract, open the index.js file under the pages folder (in the frontend folder) and replace its content with the index.js code from this project.
  2. 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)
  1. 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:

  1. Once your repositoy has been created in Github, go to Vercel and create an account by connecting your GitHub account.
  2. 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)
  1. Select Next.js as the Framework Preset. In the Root Directory click Edit to select frontend.
  2. 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.