Our First Smart Contract with Solidity

Published by Mario Oettler on

In our very first smart contract, we want to return a greeting with a custom name if the user pays a small amount. We will work you through the process of coding, compiling, deploying, and interacting with your smart contract.

Let’s start!

Create a new file with the name “greeter.sol”.

By selecting the tab “files explorer”, you get to your workspace. There, you can create a new solidity file.

You can copy the source code given below into your editor window.

pragma solidity ^0.8.20;

contract greeter{
    
    string greeting = "Hello ";
    uint256 price = 1 gwei;
    address public owner;
    
    constructor(){
        owner = msg.sender;
    }
    
    
    function greetMe(string memory _name) public payable returns(string memory _greeting){
        if(msg.value >= price){
            return string(abi.encodePacked(greeting, _name));
        }else{
            return "";
        }
    }     
}

Now, we will explain the most interesting lines.

Line 1: This is a compiler directive that tells it what compiler version must be used.

Compiler: a compiler is a program that translates human readable source code into machine readable code (zeroes and ones).

Line 3: The keyword contract can be thought of like a class in object-oriented programming. The name of our contract is “greeter”. Everything written inside the curly brackets belongs to this smart contract.

In lines 5 to 7, we defined some variables. The syntax is type visibility (optional) name.

Variables are slots in the storage or memory of a program. The names of a variable help programmers to identify and them an assign values to them.

Variables store certain values like numbers, words (strings) or Boolean values. Different types of values are called data types. For example, numbers like 1, 5, 125 or 632532 have the data type integer. A word like “Hello” is of data type string.

Data types are important for the internal handling (storing, manipulating, displaying) of the variables. They also provide different functionality for the coders.

Common datay types in Solidity are:

  • string: can contain letters, numbers and special characters. “Hello World 123!” is a string.
  • uint256: is an unsigned integer number. The compiler reserves a slot of 256 bits for this number.
  • bool: Boolean values. Takes values 0 and 1. 0 means false, 1 means true.
  • address: contains an Ethereum address and provides some functionality like checking its balance.

In line 5, we define a variable of type string with the name greeting, and assign the value “Hello “ to it. Assigning values to a variable is done with the “=” operator.

In line 6, we define a variable of type uint256 (unsigned integer) and assign a value of 1 gwei to it. 1 gwei is 1e9 wei.

In line 7, we define a variable of type address and call it owner. It has the keyword public, which says that the compiler automatically creates a public get-function for retrieving the value of the variable. The address type takes an Ethereum address and provides methods like send, transfer, call, etc.

To learn more about visibility keywords like public, you can look at the solidity documentation.

In line 9, we have our constructor. The constructor is called only once when the smart contract is deployed to the blockchain.

Deploying a smart contract means copying it to the blockchain. After a successful deployment, the smart contract is visible to every user.

Curly brackets encapsule code blocks that belon together. They can be found in contracts, constructors, functions, if/else-commands, etc. Curly brackets start with an opening bracket { and end with a closing bracket }.

Code between brackets is often indented to allow for better readability.

The semicolon tells the compiler that a code line ends.

In line 10, the variable owner is filled with the address of the account that deployed the smart contract. msg.sender returns the address of the EOA that made the function call.

In line 13, we define a function called greetMe. It takes an input parameter of the type string. There is one peculiarity in Solidity. If the type of an input parameter is an array type (string or bytes) the storage location must be given. In most cases, this is memory.

In our function declaration, we have the keyword public again. Here, it means that the function can be called from within the smart contract and from outside the smart contract, either by an EOA or by another smart contract.

The keyword payable says that the function is entitled to receive ETH. If the keyword is missing, function calls that send Ether to it fail.

The returns-part tells what data type is returned. If the function doesn’t return anything, you can omit the returns-part.

Functions can be thought of encapsuled pieces of code that can be called repeatedly. In Solidity they start with the keyword “function”. Everything between the brackets belongs to the function.

Functions need a name.

Functions can (optional) also receive parameters when being called. Function parameters are declared in the brackets after the function name.

Functions can (optional) also specify a certain variable that is returned once the function ends. 

Function parameters have the following form:

type variable_name

Return values have the following form:

type variable_name

In line 14, we have an if/else statement. It evaluates the amount sent along with the function call by calling the method msg.value. msg is the transaction or message that called the function. Value is the Ether amount sent along with it.

In line 15, the strings from the variables greeting and _name are concatenated. This is a bit more cumbersome than in other programming languages. But Solidity is not meant for complicated string operations. The idea is to leave this to the user outside the blockchain.

Now, we want to compile the smart contract. You do this by going to the compile tab as you can see in the screenshot below. Then, select the correct compiler version. It should match the version you defined in the pragma. And finally, click on compile.

A warning will appear, which we will ignore for now. If there are any errors, an error message and a line indicator appear, pointing you to the error source.

In the next step, we will deploy our compiled smart contract.

Switch to the tab “deploy and run transactions”. Then select the environment. For now, we leave it to the default value and use the locally simulated blockchain. Check if a current version of the Remix VM is chosen. It is typically the default value. Then, select your smart contract and click “Deploy”.

If the deployment is successful, you can see a green tick in the console.

Besides that, the user interface for the smart contract appears. Unfold it by clicking on the arrow in the middle column. Both is shown in the following screenshot

Now, it is time to interact with our first smart contract.

You can read the value of the variable owner by clicking on the blue button with the caption owner. Do you remember that we said that the compiler automatically adds a get-function if the keyword public is provided? Here it is!

If you want to try the greetMe function, you have to enter a Name in the text field next to the button greetMe. And you have to send an amount along with the transaction. You can specify the amount (at least 1 gwei) by entering it into the field “value” in the upper part of the column. Don’t forget to change the denomination from wei to gwei as shown in the screenshot.

Now, click greetMe.

You will see a success message in the console. Open the debug field and scroll down to the line “decoded output”, as shown in the screenshot.

On the right side, you can find the greeting. In our case, “Hello World!”.

Congratulations! You just have created your first smart contract!

Categories: