Smart Contract and Solidity: The beginner's Guide

Smart Contract and Solidity: The beginner's Guide

Solidity is a language used to develop smart contracts in Ethereum, the same way we have Rust and AssemblyScript for NEAR protocol. To develop such smart contracts, we make use of Remix IDE. But first, let's understand what a smart contract is:

Smart Contracts

Smart contracts are simply programs stored on a blockchain that run when predetermined conditions are met. They are used to automate the execution of an agreement so that no third-party is involved and all the participants are certain about the outcome.

Features of smart contract

  1. Deterministic: Smart contracts can only perform functions for which they are designed only when the required conditions are met.

  2. Immutable: Once deployed, the contents of a smart contract can't be changed.

  3. Autonomy: No third-party is involved in its execution.

  4. Self-enforcing: These are self-enforcing when the conditions and rules are met at all stages.

Few Apps

  1. Real Estate - Smart contract can transfer the ownership of an apartment once the money has been transferred to seller's account(wallet).

  2. Music Industry - Royalties can be credited to the owner’s account when the song is used for commercial purposes. It can also work in resolving ownership disputes.

The working of smart contracts under business logic can be understood by the following illustration:

image.png

image.png

image.png

image.png

image.png

image.png

Alright! Now that we've grasped the concept of smart contracts, let's dive into the coding part.

Solidity

Datatypes

Value types:

  • uint (default type uint256, default value:0)
  • int (default type int256, default value:0)
  • bool (default value: false)
  • address (default value: 0x0000000000000000000000000000000000000000)
  • enum (default value: the first element of enum)
  • byte (default value: 0x00)
  • string (default value: "")

Reference types:

  • fixed/dynamic size arrays (default value: [])
  • structs (default value: a struct where all members are set to initial values)
  • mapping (default value: empty mapping)

Functions

Similar to C++, Java etc., functions in solidity have:

  1. function name
  2. access specifier(public, private, external ~ can be accessed from other smart contracts through transactions, internal ~ similar to protected)
  3. return type

And, apart from the above features, it also contains a keyword that specifies the behavior of the function. That keyword can either be:

  1. View: Function can only read the state(global) variables
  2. Pure: Function can neither read nor modify the state variables
  3. Payable: Payable functions provide a mechanism to receive funds in your contract

Examples:

function chooseWinner() external payable
{
    if(getBalance()!=0){
        uint pos = uint(keccak256(abi.encodePacked(block.timestamp,block.difficulty)))%num_of_participants;
        payable(map_participant[pos].add).transfer(address(this).balance);
        winner = map_participant[pos].add;
    }
    else{
        winner=0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2;
    }
}

The above payable function is from a lottery smart contract that randomly chooses the winner.

function getBalance() public view returns(uint){
return address(this).balance;
}

The above example is that of View. Notice how we are not making any changes to any variable and only returning the balance of the current address.

Lastly, here's the example of Pure:

function getSum(int a, int b) public pure returns(int){
        return a+b;
    }

Constructors

Constructors in solidity are similar to constructors in other object oriented programming languages.

contract banking{

    uint balance;

    constructor(){
        balance = 500;
    }
}

They are defined by the keyword constructor and not by the name of smart contract. Note: Solidity doesn't support constructor overloading.

Similarity with C++/Java

Being an object oriented programming language, solidity showcases a few similarities with C++ and Java:

  1. Has similar syntax i.e ending of statements with semicolon, if-else, curly braces etc. Also, it supports try-catch for exception handling.
  2. Supports inheritance(being an OOP). In the inheritance that we are familiar with in C++ and Java, we inherit the data members from the base class into derived class, whereas in solidity's terms it means that a new contract can be built on an existing contract.
  3. As Java programs run on JVM, Python programs run on PVM, Solidity programs run on EVM, which stands for Ethereum Virtual Machine, which is the runtime environment for transaction execution in Ethereum.
  4. Statically typed

Real-life banking comparison

Now that we have understood the various functions, their features and behavior, let's try to simulate a simple banking application that does the following:

  • When a new account is created, it adds 500 ethers to it.
  • Check Balance
  • Deposit/Withdraw amount

For the first part, we'd simply need a constructor:

 uint balance;

    constructor(){
        balance = 500;
    }

I'm keeping the balance as state variable. Next, we need a function to check the balance. Since, balance is a state variable, we simply have to return it using the function.

function checkBal() public view returns (uint){
        return balance;
    }

Next comes the deposit function,

function deposit(uint amt) public returns (uint){

        balance = balance + amt;
        return balance;
    }

And lastly, the withdraw function:

function withdraw(uint amt, address a) public returns (uint){
        if(amt > 100 && eligibilty(a)){
            if(amt <= balance){
                balance -= amt;
            }
        }
        else if(amt <=100){
             if(amt <= balance){
                balance -= amt;
            }
        }


        return balance;
    }

    function eligibilty(address a) public pure returns (bool){
        if(a == 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4){
            return true;
        }
        return false;
    }

Since I needed to make use of at least one pure function, I added the eligibility criteria. The entire contract looks like this:

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract banking{

    uint balance;

    constructor(){
        balance = 500;
    }

    function checkBal() public view returns (uint){
        return balance;
    }

    function deposit(uint amt) public returns (uint){

        balance = balance + amt;
        return balance;
    }

    function withdraw(uint amt, address a) public returns (uint){
        if(amt > 100 && eligibilty(a)){
            if(amt <= balance){
                balance -= amt;
            }
        }
        else if(amt <=100){
             if(amt <= balance){
                balance -= amt;
            }
        }


        return balance;
    }

    function eligibilty(address a) public pure returns (bool){
        if(a == 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4){
            return true;
        }
        return false;
    }
}

That's all! I hope you got an idea about the basics of solidity and smart contracts in general. Thanks for reading!