BUILD A BASIC SMART CONTRACT

Tseke Daniel
7 min readOct 14, 2023

--

In our previous article we talked about solidity, smart contract and Remix IDE, we will cover everything we’ve learnt in this session. The smart contract we want to build will help us to send funds from one wallet address to another wallet address (sender to recipient). Don’t worry, you will not have to set up another project. We will use the remix playground to do everything from writing the code, to compiling, to debugging, and finally to testing it.

Let’s now head over to https://remix.ethereum.org/ . You should have the following screen stare at you for a while:

This playground provides us with all we need to write our first smart contract.

We will now create a new file named Blockchain.sol by clicking the document icon marked red in the image below and type the name of the file in the space provided:

.sol is the extension used for solidity files.

Solidity code always begins with the line below:

//SPDX-License-Identifier:MIT

Without this code, you will get a warning saying “SPDX license identifier not provided in source file.” but your code will still run. It is just like saying that you accept the terms and conditions of writing Solidity.

The next thing to do is to state the Solidity version you want to use.

pragma solidity ^0.8.17;

The caret (^) sign indicates that the program will be compatible with higher versions of solidity.

Now we have to define a contract named Blockchain . So we have:

contract Blockchain {

}

Inside the contract above, we will create a data-type called BlockStruck with the code below:

 struct BlockStruct{
uint index;
uint amount;
uint timestamp;
address sender;
address recipient;
}

We define all the keys we expect a value for in the struct. Since solidity is a strongly typed language, we specified a data-type before each key. The struct is similar to Object in JavaScript.

The next thing that we want to define is an event. An event is usually triggered at the end of a function’s execution to send data to the frontend. You can see it like console.log,some people also use it as a cheap way of storage.

We define a BlockEvent that we will trigger after adding a block to the chain.

event BlockEvent(uint amount, address sender, address recipient);

Unlike struct, circular braces are used for an event, and their keys are separated by commas (,). Also, notice that struct does not end with a semicolon, but event does.

Now that we have defined the structure of blocks, let’s use it to setup an array of blocks called chain like this:

 BlockStruct[] chain;

The code above defines the chain to be an array of BlockStruct. As always, we specify the data-type before the variable name.

Next, define a variable to keep track of how many blocks are in the chain:

uint chainCount;

You may choose to assign it a value on the same line (uint chainCount = 0;) or do it in the constructor function like this:

constructor() {
chainCount = 0;
}

The constructor is a special function within a smart contract that is executed only once, and that happens when the contract is deployed to the blockchain.

We define a function addBlock to add blocks to the chain


function addBlock(uint amount, address payable recipient) public {

}

Like the functions you already know, it begins with the function keyword followed by the name of the function addBlock and the argument it expects in braces.

One of the arguments (recipient) has a flag called payable, indicating that the wallet address is eligible to receive funds. Next to it is the function's visibility flag (public).

Visibility defines who can call a function or variable. It can be public, private, internal, or external.

  1. A public function can be called by any contract.
  2. private functions can only be called inside the contract where they are defined.
  3. Only contracts that inherit internal functions can call them.
  4. external functions are only accessible by other contracts.

In the addBlock, we start by incrementing the chainCount by one like this:

 chainCount ++;

Next, add the block of a transaction to the chain like this:

 chain.push (
BlockStruct(
chainCount,
amount,
block.timestamp,
msg.sender,
recipient
)
);

The BlockStruct takes values corresponding to the keys set when defining the struct. It is then added to the chain array using the .push method, now we have a new block in the chain. This code adds a new block to a blockchain array by creating a block with specific data and pushing it onto the chain, effectively extending the blockchain.

Finally, we trigger the BlockEvent we created a while ago

emit BlockEvent(amount, msg.sender, recipient);

emit is how you trigger the BlockEvent event, and the values inside the parentheses match the data fields you set when creating the event, so it records specific information when the event happens.

We define a function getChain . This function takes no argument but returns a BlockStruct.

    function getChain() public view returns(BlockStruct[] memory) {
return chain;
}

The program returns the chain; an array of all blocks.

Something to note in the function above is that we used view to show that this function returns a value. We also indicated the kind of data type we expect to be returned (returns (BlockStruck[] memory)) and the storage type to be used (memory).

There are two main storage types in solidity: Storage and Memory.

Storage is the default type of storage used to hold data permanently for a program while Memory is temporary and is less expensive in terms of gas.

The getChainCount, this function takes no argument. It returns the number of blocks added to the chain

    function getChainCount() public view returns(uint) {
return chainCount;
}

That completes the smart contract that we intended to create. Now the code looks like this:

//SPDX-License-Identifier:MIT

pragma solidity ^0.8.17;

contract Blockchain {


struct BlockStruct{
uint index;
uint amount;
uint timestamp;
address sender;
address recipient;
}

event BlockEvent(uint amount, address sender, address recipient);

BlockStruct[] chain;

uint chainCount;

constructor() {
chainCount = 0;
}

function addBlock(uint amount, address payable recipient) public {

chainCount ++;

chain.push(
BlockStruct(
chainCount,
amount,
block.timestamp,
msg.sender,
recipient
)
);

emit BlockEvent(amount, msg.sender, recipient);

}

function getChain() public view returns(BlockStruct[] memory) {
return chain;
}

function getChainCount() public view returns(uint) {
return chainCount;
}
}

How to Compile the Smart Contract

We need to compile the code to check if there are errors that we need to fix. The steps below will help us do just that:

  • Click on the third icon on the left side menu of the remix IDE:
  • Then click the Compile button:

The compilation was successful since we have no errors.

How to Deploy the Smart Contract

Now that compilation is successful, let’s deploy the contract.

  • Click on the fourth icon in the side menu:

select Remix VM (London) for the ENVIRONMENT. It has ten (10) accounts with 100 dummy ethers each that you may use for test purposes.

  • Then click the Deploy button. Now when you scroll to the bottom, you will find the Blockchain contract under Deployed Contracts.
  • Click the arrow by the deployed contract name to see the functions of the contract that you can interact with.

There are three (3) functions in the image above that match the three (3) functions we defined in our smart contract. Remix automatically creates a UI for you to test your contracts as soon as you deploy them. We will now test the functions we created to see how they respond.

How to test the addBlockToChain function

To test the addBlockToChain function

  • Click the caret (^) icon by the side of the function button and input box. That drops down a form.
  • Fill in 10 for the amount, and fill in one of the ten 10 account addresses for the recipient:
  • Click the transact button.

Note that you cannot send funds to the same address you used to deploy the contract. You must choose a different account.

How to test the getChain function

Click the getChain button to reveal the blocks in the chain so far:

It returns a tuple, which is a kind of array. Recall that chain is supposed to be an array containing a list of blocks.

How to test the getChainCount function

To get the number of blocks added, click the getChainCount button:

And just as we defined it, it returns a uint. There is just one item in the chain for now, but as you keep adding more blocks, the number will increase.

Congratulations! if you made it this far, you’ve learnt how to write your own smart contract, compile and deploy it.

--

--