Building CRUD Smart Contract
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.