Skip to main content

Building CRUD Smart Contract

crud

Introduction

In this article, we'll be building a CRUD smart contract using Solidity and Hardhat. CRUD stands for create, read, update, and delete, representing the basic actions we can perform on stored data. Our smart contract will allow us to carry out these operations. Additionally, we'll explore the workings of key-value storage within a smart contract. By the end of this article, you'll have a solid grasp of these operations and how key-value storage is implemented in smart contracts. So, let's dive right in and get started!

Prerequisite

Before going any further in this article, it is recommended that you first read our “Setting Up Hardhat for Velas Smart Contract Development” guide, This guide goes over the basics of Hardhat and provides instructions on how to set up your project.

Setting Hardhat Project

To get started, follow the steps in the prerequisite guides to setup your Hardhat project.

CRUD Smart Contract

Let’s start by creating CRUD.sol in the contracts directory. This is where we’ll be writing our smart contract code. Let’s start by creating an empty contract.

CRUD Contract

Our first step is to create an empty contract called CRUD. Add the following snippet to the Solidity file:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

contract CRUD { }

Data Storage

For the purpose of this article, we'll be using a mapping to store our data in the smart contract. A mapping is a way to store key-value pairs.

Let’s create a mapping called data inside the contract.

mapping(uint => string) public data;

Here, we specify that the key for the mapping will be of type uint and the value will be of type string. By setting the mapping’s visibility to public, we allow anyone to read the data stored in this mapping.

Create Function

The first function we'll implement is the createData function. This allows users to store data in our mapping by providing a key-value pair. Here's the function code:

function createData(uint _key, string memory _value) public {
require(bytes(data[_key]).length == 0, "Key is already used to store data!");
data[_key] = _value;
}

In this function, we store the user-provided _key and _value in our mapping. To avoid overwriting existing data, we also check if a value is already associated with the provided _key.

To perform this check, we convert the string value to bytes and then check the length. If the length is 0, it means no data is stored for that key. If the length is greater than 0, it means data is already stored, and we throw an error to prevent overwriting.

By including this check, we ensure that the function doesn't unintentionally overwrite existing data.

Read Function

Let’s dive into the next function, called readData. This function allows the user to get stored values by providing a _key and returns it to the user.

function readData(uint _key) public view returns(string memory) {
return data[_key];
}

Update Function

The update function works in the same way as createData; the only difference will be that if there is no data to update, we will throw an error.

function updateData(uint _key, string memory _value) public {
require(bytes(data[_key]).length != 0, "Key is not used yet!");
data[_key] = _value;
}

Delete Function

The last function to implement in the contract is the deleteData function, which deletes the stored data. We will just use the delete keyword to delete stored data.

function deleteData(uint _key) public {
delete data[_key];
}

Using delete doesn’t actually remove the key-value pair; instead, it sets value to the default value of that type. In our case for strings, the default value is an empty string.

Contract Deployment

To deploy our CRUD contract on the Velas testnet, we need a deployment script. Create a file called deploy.js and use the following code snippet:

const hre = require("hardhat");

async function main() {

const crud = await hre.ethers.deployContract("CRUD");
await crud.waitForDeployment();

console.log(
`Our CRUD contract is deployed to ${crud.target}`
);
}

main().catch((error) => {
console.error(error);
process.exitCode = 1;
});

In this script, we’ve used the deployContract method of the ethers object to create an instance of our CRUD contract. Then, use the waitForDeployment method to deploy and wait until the deployment is done. Finally, it logs the contract address in the terminal.

To deploy the contract on the Velas testnet, run the following command in the terminal:

npx hardhat run scripts/deploy.js --network velas_testnet

After executing this command, you’ll see the address of the deployed contract logged in the terminal.

Conclusion

In conclusion, we’ve successfully created a simple key-value store using a smart contract and performed basic CRUD operations. We’ve also learned how to store and manage data effectively using mapping in Solidity.

By understanding these basic concepts, you can dive deeper into more advanced topics in smart contract development. We will build our next tutorial based on our CRUD contract, so stay tuned for that.