Learn all about Solidity Ethereum

0
75
Source : https://en.bitcoinwiki.org/wiki/Solidity

What is solidity ?

Solidity is a contract-oriented, high level programming language for implementing smart contracts. Solidity has been designed to target the Ethereum Virtual Machine .

Solidity === Smart Contracts.

Solidity’s code is encapsulated in contracts. A contract is the fundamental building block of Ethereum applications — all variables and functions belong to a contract, and this will be the starting point of all your projects.

pragma solidity >=0.5.0 <0.6.0;
contract HelloWorld {
}

In the above code, we have provided version considering our code is compatible for any version b/w 0.5 to 0.6. We have also created a contract named ‘HelloWorld’

Online IDE ~ Remix www.remix.ethereum.org

State Variables and Integers

State variables are permanently stored in contract storage. This means they are written to Ethereum Blockchain. Think of them like writing to DB.

contract Example {
// This will be stored permanently in the blockchain
   uint myUnsignedInteger = 100;
string name = "vivek"
}

Uint datatype is an unsigned integer. It should be non negative.

Data Types

Value Type:

Boolean(true / false), Integers(int / uint), Address(size of Ethereum address), String, enums

Reference Types :

Arrays, Struct, Mapping

Math Operations

Addition: x + y
Subtraction: x — y,
Multiplication: x * y
Division: x / y
Modulus / remainder: x % y (for example, 13 % 5 is 3, because if you divide 5 into 13, 3 is the remainder)
Exponential Operation
uint x = 5 ** 2; // equal to 5² = 25

Structs

Similar to struct in C programming language. When we need to create complex data types with multiple properties, we use structs.

struct Person {
  uint age;
  string name;
}

Arrays

A collection of data is called arrays. Two types : Fixed Arrays and Dynamic Arrays.

As the name suggests , fixed arrays have predefined size, while dynamic arrays do not come with a size.

// Array with a fixed length of 2 elements:
uint[2] fixedArray;
// another fixed Array, can contain 5 strings:
string[5] stringArray;
// a dynamic Array — has no fixed size, can keep growing:
uint[] dynamicArray;

You can combine struct and arrays. Create a struct and then have an array of structs. Just like having an object and having an array of objects in Object oriented paradigm(like Java).

pragma solidity >=0.5.0 <0.6.0;
contract StudentFactory {
   struct student {
string name;
uint roll;
}
   student[] public students; // creates an array named students of student type objects
}

Function Declaration

function eatHamburgers(string memory _name, uint _amount) public {
}

The visibility of the function is public. There are two ways you can pass argument to a Solidity function :

By value & By Reference

eatHamburgers(“vitalik”, 100);

Private/Public functions

In Solidity, the functions are public by default so anybody can call the public function in the network. However for security purposes we make functions private so that only the owners can call the function.

function _eatHamburgers(string memory _name, uint _amount) private {
}

By convention, private functions starters with an underscore in it’s name.

Internal/External Keywords-

Two more types of function visibility. Internal is similar to private, except that it’s accessible to inherited contracts i.e inheritance.

External is similar to public. All the contracts can call this function, except the contact where this function is declared.

Return in functions

The function declaration contains the type of return values.

function sayHi() public view/pure returns (string memory) {
return “Hi”;
}

The functions can be marked as pure/view. You mark your function as pure when you are not even accessing the passed data. If the function doesn’t modify data, and only views it then it is marked as view.

Type Casting

Conversion between data types is called Type casting.

uint8 a = 5;
uint b = 6;
// line below throws an error because a*b returns a uint, not uint8:
uint8 c = a * b;
// we have to typecast b as a uint8 to make it work:
uint8 c = a * uint8(b);

Events

Events are used to communicate to frontend that there was something which happened on the backend blockchain network.

// declare the event
event NotifyOnFrontend(uint x);
function add(uint _x, uint _y) public returns (uint) {
  uint result = _x + _y;
//fire an event to let the frontend know the function was called
emit NotifyOnFrontend(result);
return result;
}

Your frontend code should have web3 installed, and should be listening to “NotifyOnFrontend” event , for this to work. Your JavaScript framework or vanilla JS will have to listen to this event to receive it :

YourContract.NotifyOnFrontend(function(error, result) {
// do something with result
})

Mappings

This is another way to store organized data like array, and struct

mapping (address => uint) public accountBalance;

This is a key value store. address is the key and accountBalance is the value.

This could be used to store multiple objects(data) in blockchain. Check example below :

Example :

contract Example {
struct UserInfo {
unit age;
string dob;
}
mapping(string => UserInfo) allusers;

function setUserInfo(string _name, uint _age, string _dob) public {
allusers[_name].age = _age;
allusers[_name].dob = _dob;
}
   function getUserInfo(string _name) public view returns(uint, string) {
return (allusers[_name].age, allusers[_name].dob);
}
}

Now if can call setUserInfo multiple times with different values like :

setuserInfo("Vivek",26, 25/05/1995)
setuserInfo("Supu", 23, 01/09/1998)

To get those values you just pass the name :

getUserInfo("Vivek"); // 26 25/05/1995
getuserInfo("Supu"); // 24 01/09/1998

Global variables

These variables are available to all functions like msg.sender . Any Solidity program you write , should be called by an owner. The address of the sender is stored in msg.sender global variable.

Require

Requires is used to validate the two statements and take decisions based on that. If conditions are true, code runs successfully, if not then an error is thrown

function sayHi(string memory _name) public returns (string memory) {
 /**Compares if _name equals “Vivek” Throws an error and exits if not true. Solidity doesn’t have native string comparison, so we
compare their keccak256 hashes to see if the strings are equaq **/
  require(keccak256(abi.encodePacked(_name)) ==   keccak256(abi.encodePacked(“Vivek”)));
  // If it’s true, proceed with the function:
  return “Hi!”;
}
sayHi(“Vivek”) // executes successfully
sayHi(“Supu”) // throws an error

Thus require is quite useful for verifying certain conditions that must be true before running a function.

Inheritance

Rather than making one extremely long contract, sometimes it makes sense to split your code logic across multiple contracts to organize the code.

contract Animal {
  function catchphrase() public returns (string memory) {
    return “Animal”;
  }
}
contract Cat is Animal {
  function anotherCatchphrase() public returns (string memory) {
    return “Cat is an Animal”;
}
}

Import

Split the code into multiple files and use import to use a functionality in another file.

This is normally how you will handle long codebases in your Solidity projects.

Storage vs Memory

Storage refers to variables stored permanently on the blockchain. Memory variables are temporary, and are erased between external function calls to your contract. Think of it like your computer’s hard disk vs RAM.

Interacting with other contracts in Blockchain network

I will cover a separate article on this . However for now, keeping it short :

To interact with other contracts we declare an interface like object. We create a contract and inside that we declare a function which we want to call/use from another contract. The function is just the skeleton, it doesn’t contain the body.

contract GetNumber {
  function getNum(uint _num) public returns(uint){
    return _num;
}

Say there was a contract where we wanted to use the above getNum function. To do that we will create a contract in our project, and declare a getNum function skeleton(without function body) .

contract NumberInterface {
  function getNum(uint _num) public returns(uint);
}

And now we can call the getNum function from NumberInterface contract.

After you deploy a contract to Ethereum, it becomes immutable i.e. it cannot be modified. The initial code you deploy to a contract is there to stay, permanently, on the blockchain. This is one reason security is such a huge concern in Solidity. If there’s a flaw in your contract code, there’s no way for you to patch it later. You would have to tell your users to start using a different smart contract address that has the fix.

Function Modifiers

A function modifier looks just like a function, but uses the keyword modifier instead of the keyword function. These are used for special cases like when you want only your owner to do something and not everybody.

This helps to update key portions of the DApp while preventing other users from messing with our contracts. One use case I have worked with is — when we want to validate a statement before executing any use case.

Gas

Users pay in gas to run contract on the Ethereum network . Gas is calculated in units of Ether (the currency on Ethereum). The total gas cost of your function is equal to the sum of gas cost for all its individual operations.

More on Storage

Storage memory is written permanently to the blockchain. Forever! Thousands of nodes across the world need to store that data on their hard drives, and this amount of data keeps growing over time as the blockchain grows. So there’s a cost to doing that.

In order to keep costs down, you want to avoid writing data to storage except when absolutely necessary. Sometimes this involves seemingly inefficient programming logic — like rebuilding an array in memory every time a function is called instead of simply saving that array in a global storage variable for quick lookups.
Hence it is advised to use memory type wherever possible so that the data is not stored permanently which in turn saves cost . Yes, loops would be cheaper in Solidity, rather than using storage. So use memory with for loop wherever possible. This is completely opposite to what is done in languages like Java, Python as computation of a for loop costs more.

For loop

Syntax is similar to Javascript.

for (uint i = 1; i <= 10; i++) {
// body
}

Payable modifier

payable functions are part of what makes Solidity and Ethereum so cool — they are a special type of function that can receive Ether. Let that sink in for a minute. When you call an API function on a normal web server, you can’t send US dollars along with your function call — nor can you send Bitcoin.

But in Ethereum, because both the money (Ether), the data (transaction payload), and the contract code itself all live on Ethereum, it’s possible for you to call a function and pay money to the contract at the same time.

This allows for some really interesting logic, like requiring a certain payment to the contract in order to execute a function.

Note :

In Ethereum, when you call a function on a contract, you broadcast it to a node or nodes on the network as a transaction. The nodes on the network then collect a bunch of transactions, try to be the first to solve a computationally-intensive mathematical problem as a “Proof of Work”, and then publish that group of transactions along with their Proof of Work (PoW) as a block to the rest of the network.

Tokens

So basically a token is just a contract that keeps track of who owns how much of that token, and some functions so those users can transfer their tokens to other addresses.

Assert and require difference

assert is similar to require, where it will throw an error if false. The difference between assert and require is that require will refund the user the rest of their gas when a function fails, whereas assert will not.

Metamask

This is a browser extension for Chrome and Firefox that lets users securely manage their Ethereum accounts and private keys, and use these accounts to interact with websites that are using Web3.js.

Application Binary Interface.

After you deploy your contract, it gets a fixed address on Ethereum where it will live forever. After the deployment of smart contracts in Ethereum network an ABI is also generated. Basically it’s a representation of your contracts’ methods in JSON format that tells Web3.js how to format function calls in a way your contract will understand.

Web3Js

Etherum’s JS frontend library is termed web3.js

GitHub - ChainSafe/web3.js: Ethereum JavaScript API

References :

Conclusion

Hope this helped in learning basics of Solidity programming. Please hit the follow button and all claps are highly appreciated. Happy learning. Cheers!

Join Coinmonks Telegram Channel and Youtube Channel learn about crypto trading and investing

Also, Read


Learn all about Solidity Ethereum was originally published in Coinmonks on Medium, where people are continuing the conversation by highlighting and responding to this story.