Solidity Basics

End of this post you can get basic knowledge on Solidity Language. If you have any programming experience before, this post will boost your knowledge up to developing a complete Ethereum software solution.

To test Solidity codes which you write in this session, you can use online tool called Remix . Remix is a online Solidity Compiler and Testing Environment  which uses your browser folder and your machine resources to save data.

What is Solidity?

Solidity is Contract Oriented, Object Oriented, High Level Language for writing Smart Contract aiming  the Ethereum Virtual Machine. Solidity is influenced by C++, Python and Java Script.

What are the Basic Data Types in Solidity ?

Here i mentioned basic and most usable data types. With the time i will update this content.

bool - true, false


string - ""

int / uint - int8 (0 - 255) & int256 (0 - 2 power 256)

address - store Ethereum address

(keep in your mind, apart from the string all the other data types are passed by reference. string is pass by value.)

 What are the Access Modifiers in Block Chain?

public - can access everywhere

private - can access inside this contract only

internal - can access inside this contract as well as contracts derived from this

external - disallow accessing internally. Only allow external access

constant - earlier days this is used to indicate that the relevant function won't change the storage state. But later they have introduced more specific access modifiers as replace for constant. they are,
    view   - tells it never change the storage state (Use for Getters) 
    &
    pure   - tells it won't even read the storage state (Functions which do not read/write storage. Just imagine a function which only work with input parameters)


Custom modifiers - solidity allows you to create your own modifiers according to your requirement. 
Example :- Let's imagine the relevant function should execute by only the owner(your instance only, outside address are not allowed)


Other modifiers - actually solidity has some modifiers which is not used to control the access level but it control the Ether Transferring mechanism. For an  example we can use payable modifier for the fallback function(in future i will explain fallback functions) in order to mark the contract which is capable of accepting incoming Ether into the contract. 

Sample structure of a Solidity Contract

if you see carefully the above solidity example,
  • in variable declaration - access modifier come after the data type and finally declare the name of the variable 
  • in function declaration - access modifier come after the name of the function and if it return a value that return type is defined last.  
Here i simply demonstrate how to do a simple Contract in Solidity and compile it, deploy on Remix online IDE.

  

Let's we look at how to debug in solidity.




I think now you are much familiar with Remix online IDE. So let me explain how to read and understand the following sections.

Now we study actually how they calculate ActualTransactionCost for a method, Ex:- getGrade() that i demonstrated in Debugging video.


Execution Cost is calculated in the same manner. Finally they add both ExecutionCost and ActualTransactionCost and if it is a new creation of a Contract(deployment) then they add the ContractCreationCost as well for getting Transaction Cost.

Advanced data types in solidity with examples. 

Now i believe you have a good understanding on Remix IDE. So Following video which explain the Advanced Data Types was developed on Remix.

  • Array - Collection of data but same Type. Three ways of initializing an array in solidity.
   
  • Struct - collection of data but different Types. We can't create objects using  a Struct. It is a loose bag of Variables. So you can not return a Struct by a function.
     


     I said that you can't return a Struct. But you can do above hack if you    really    need to return, using the special functionality of Solidity called return multiple values as i shown above example (getMyDataSet function).

Restriction of returning string :- This is a limitation of Solidity, and the reason is that string is basically an arbitrary-length byte array (i.e. byte[]), and so string[] is a two-dimensional byte array (i.e. byte[][]). According to Solidity references, two-dimensional arrays as parameters are not yet supported.
But you can fix this if you know the max length of the string:-
function setStrings(byte[MAX_LENGTH][] row) {...}

Keep in your mind you can store a Struct inside another Struct.
  • Enum - List of finite set of values.
 
  • Address - Hold a 20 byte value (Ethereum Address).
       address has two properties. They are transfer and balance.

  • Mapping - kind of a hash table, dynamically sized array.

Verification in Solidity (require and assert).


        If you see carefully you will see though relevant validation failed but if it was    "require" then it will refund the remaining Gas and reverting all changes. 
        But if we use "assert" it won't refund remaining Gas. It will use remaining Gas and reverting all changes.
So require is mostly use for input validations and assert is used to catch run time errors.
Besides that we  have throw and revert.
throw - simply revert all the changes but consumes all the Gas. It is used to check that something owner should do. 
revert - it will refund all the remaining Gas to the caller and allows to return a value.

Import and Inheritance in Solidity

This video describes how to do inheritance in solidity and make Parent and Child relationship between two Contracts.




Event in Solidity 

Event is basically designed for listening to a particular occurrence. Also it enable logging facility in Solidity but it is not the major duty of Events. Actually events are inheritable members of Contracts. It's mean if B is A and A has an event then B can call that event. When you call an event it stores its arguments in the transaction's log related to the address of the Contract which called the Event. This log exists until the Block is accessible.  

simple Event Program
 As you can see now execution details consist new section called logs
 Now i am going to show you an interesting thing that how to access this backend by a simple front end UI and how to use this Event to give notification on the UI.


Interface, Library : write upgradeable Ethereum contracts in Solidity

I guess you remember that once we deploy our Contract into the Blockchain it can not be changed (Immutable). I mentioned this in one of my previous tutorial when i am describing the Ethereum concepts. But you can use interfaces and Library for creating upgradeable Ethereum contracts.

Write upgradeable contract using Interfaces.

Actually storing data is expensive. So if you upgrade contract which contain large storage variables then it might exceed your transaction Gas Limit because it copy your existing data to the newer version of the contract (the purpose of the Gas Limit is to prevent vulnerable behavior of Contract). So the best thing we can do is isolating the storage variables from the Logic Contract.

In order to do that we have to keep our our variables in a separate contract called storage contract. Then we can upgrade our logic part without affecting to the storage.

 

Write upgradeable contract using Library.

Actually library is a different type of Contract. Library doesn't have any storage. It means if library function is called then that particular caller Contract's context is used for executing the Library function. So memory of the particular Contract can be accessed by the Library function. 

Libraries are deployed only once at a specific address. Then we can reuse the Library code  using the DELEGATE feature of EVM. That is why i mentioned that Library function use the memory of calling Contract.
(Before you learn what is a DELEGATE Call, you should learn what is a Message Call. Message Calls have many similarities to transactions, such as having a target, a source, data payload, gas, Ether and return data. Contract can call other Contracts using Message Calls.) 
Actually DELEGATE call is a kind of Message Call but it variant from Message Call by the way how DELEGATE Call uses memory and use Balance.


Call Memory Balance
Message Call Use memory of Callee Use Balance(Gas) of Callee
Delegate Call Use memory of Caller Use Balance(Gas) of Caller



So now you know Libraries are singleton and it is not allowed for any storage variables.So we can use Libraries to encapsulate business logic(logic that frequently change) and it costs only upgrading one. Obviously it prevent upgrading many Contracts if we need a business logic change.



So this diagram is for you if you didn't get this solution 😼😼😼 describing how to write upgradeable contracts.

Let me dig into this again. You know Upgrading is impossible when we talking about the Contracts with storage variables. Because to update a Contract with variable is take a high cost(we have to rewrite the storage if we do a change for a existing Contract with variable) and probably it exceeds the Gas Limit.  
But what if we isolate the storage variables in a separate contract called Storage Contract which is inherited to a Interface and isolate the business logic in a Library. Now we can simply maintain a Contract(Usage Contract) for handling user calls and we can import the Interface and Library on top of the Usage Contract. Inside the functions in Usage Contract we can call the services written in the library and same time we can pass variables into Library Services taking from the Interface. 
Now think we have a situation like change the business logic. Now we can simply update only the Library Contract services without touching the Storage Contracts. It is very cheap and it make possible to update the Contract.
Now let's imagine we have a requirement to change the Storage variables. Now we can simply get rid of the Old Storage Contract and we can inherit a New Storage Contract to the Interface and we can now access the Storage using that interface inside the Usage Contract.

Globally Available Variables & functions

  • All Ether Units are available globally - wei, finney, szabo, ether           
        - so you can write these equations,  ex: 4 ether == 4000 finney
      

  • These time units are available globally - seconds, minutes, hours, days, weeks,
    years
        - so you can write this way, ex: 120 seconds == 2 minutes

         (if you really want to work with Standard Time, you have to use a time     library. There are some Git repositories for Solidity Standard Time)

     Special functions
  • block.blockhash(uint blockNumber) returns (bytes32): hash of the given block - only works for 256 most recent, excluding current, blocks - deprecated in version 0.4.22 and replaced by blockhash(uint blockNumber).
  • block.coinbase (address): current block miner’s address
  • block.difficulty (uint): current block difficulty
  • block.gaslimit (uint): current block gaslimit
  • block.number (uint): current block number
  • block.timestamp (uint): current block timestamp as seconds since unix epoch
  • gasleft() returns (uint256): remaining gas
  • msg.data (bytes): complete calldata
  • msg.gas (uint): remaining gas - deprecated in version 0.4.21 and to be replaced by gasleft()
  • msg.sender (address): sender of the message (current call)
  • msg.sig (bytes4): first four bytes of the calldata (i.e. function identifier)
  • msg.value (uint): number of wei sent with the message
  • now (uint): current block timestamp (alias for block.timestamp)
  • tx.gasprice (uint): gas price of the transaction
  • tx.origin (address): sender of the transaction (full call chain)
Let's we study most frequently used global functions ( msg.sender, msg.value )


Okay fellows this is the end of my short and sweet Ethereum Solidity Theory Tutorials and let's we meet with another new practical tutorial.
Cheers πŸ’«πŸ’«πŸ’«.

My Next Post : Create Complete Solidity based Blockchain Application

Comments

Most Popular

Introduction to Blockchain