0% found this document useful (0 votes)
989 views

Solidity Tutorial

This document provides an overview and introduction to Solidity, a high-level programming language for implementing smart contracts on the Ethereum blockchain: Solidity is a contract-oriented, statically typed programming language that is used for implementing smart contracts on Ethereum. It is influenced by C++, Python and JavaScript. Solidity contracts are deployed to and executed by the Ethereum Virtual Machine. This tutorial provides an introduction to Solidity for novice developers.

Uploaded by

qaa-8735
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
989 views

Solidity Tutorial

This document provides an overview and introduction to Solidity, a high-level programming language for implementing smart contracts on the Ethereum blockchain: Solidity is a contract-oriented, statically typed programming language that is used for implementing smart contracts on Ethereum. It is influenced by C++, Python and JavaScript. Solidity contracts are deployed to and executed by the Ethereum Virtual Machine. This tutorial provides an introduction to Solidity for novice developers.

Uploaded by

qaa-8735
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 41

Solidity Tutorial

Solidity is a contract-oriented, high-level programming language for implementing


smart contracts. Solidity is highly influenced by C++, Python and JavaScript and
has been designed to target the Ethereum Virtual Machine (EVM).

Audience
This tutorial targets novice developers and those new to Solidity. It guides them in
understanding basic through more advanced concepts in Solidity. After completing
this tutorial, your firm foundation in Solidity and level of expertise will allow you to
begin developing and easily build on your knowledge.

Prerequisites
The tutorial assumes your familiarity with blockchain, and general programming.
Solidity - Overview
Solidity is a contract-oriented, high-level programming language for implementing
smart contracts. Solidity is highly influenced by C++, Python and JavaScript and
has been designed to target the Ethereum Virtual Machine (EVM).
Solidity is statically typed, supports inheritance, libraries and complex user-defined
types programming language.
You can use Solidity to create contracts for uses such as voting, crowdfunding,
blind auctions, and multi-signature wallets.

What is Ethereum?
Ethereum is a decentralized ie. blockchain platform that runs smart contracts i.e.
applications that run exactly as programmed without any possibility of downtime,
censorship, fraud or third-party interference.

The Ethereum Virtual Machine (EVM)


The Ethereum Virtual Machine, also known as EVM, is the runtime environment for
smart contracts in Ethereum. The Ethereum Virtual Machine focuses on providing
security and executing untrusted code by computers all over the world.
The EVM specialised in preventing Denial-of-service attacks and ensures that
programs do not have access to each other's state, ensuring communication can be
established without any potential interference.
The Ethereum Virtual Machine has been designed to serve as a runtime
environment for smart contracts based on Ethereum.

What is Smart Contract?


A smart contract is a computer protocol intended to digitally facilitate, verify, or
enforce the negotiation or performance of a contract. Smart contracts allow the
performance of credible transactions without third parties. These transactions are
trackable and irreversible.
The concept of smart contracts was first proposed by Nick Szabo in 1994. Szabo is
a legal scholar and cryptographer known for laying the groundwork for digital
currency.
It is fine if you do not understand Smart Contract right now, we will go into more
detail later
Environment Setup
This chapter explains how we can setup Solidity compiler on CentOS machine. If
you do not have a Linux machine then you can use our Online Compiler for small
contracts and for quickly learning Solidity.

Method 1 - npm / Node.js


This is the fastest way to install Solidity compiler on your CentoS Machine. We have
following steps to install Solidity Compiler −
Install Node.js
First make sure you have node.js available on your CentOS machine. If it is not
available then install it using the following commands −
# First install epel-release
$sudo yum install epel-release

# Now install nodejs


$sudo yum install nodejs

# Next install npm (Nodejs Package Manager )


$sudo yum install npm

# Finally verify installation


$npm --version
If everything has been installed then you will see an output something like this −
3.10.10
Install solc
Once you have Node.js package manager installed then you can proceed to install
Solidity compiler as below −
$sudonpm install -g solc
The above command will install solcjs program and will make it available globally
through out the system. Now you can test your Solidity compiler by issuing following
command −
$solcjs-version
If everything goes fine, then this will print something as follows −
0.5.2+commit.1df8f40c.Emscripten.clang
Now you are ready to use solcjs which has fewer features than the standard Solidity
compiler but it will give you a good starting point.

Method 2 - Docker Image


You can pull a Docker image and start using it to start with Solidity programming.
Following are the simple steps. Following is the command to pull a Solidity Docker
Image.
$docker pull ethereum/solc:stable
Once a docker image is downloaded we can verify it using the following command.
$docker run ethereum/solc:stable-version
This will print something as follows −
$ docker run ethereum/solc:stable -version

solc, the solidity compiler commandlineinterfaceVersion:


0.5.2+commit.1df8f40c.Linux.g++
Method 3: Binary Packages Installation
If you are willing to install full fledged compiler on your Linux machine, then please
check official website Installing the Solidity Compiler.

Basic Syntax
A Solidity source files can contain an any number of contract definitions, import
directives and pragma directives.
Let's start with a simple source file of Solidity. Following is an example of a Solidity
file −
pragma solidity >=0.4.0 <0.6.0;
contract SimpleStorage {
uint storedData;
function set(uint x) public {
storedData = x;
}
function get() public view returns (uint) {
return storedData;
}
}

Pragma
The first line is a pragma directive which tells that the source code is written for
Solidity version 0.4.0 or anything newer that does not break functionality up to, but
not including, version 0.6.0.
A pragma directive is always local to a source file and if you import another file, the
pragma from that file will not automatically apply to the importing file.
So a pragma for a file which will not compile earlier than version 0.4.0 and it will
also not work on a compiler starting from version 0.5.0 will be written as follows −
pragma solidity ^0.4.0;

Here the second condition is added by using ^.

Contract
A Solidity contract is a collection of code (its functions) and data (its state) that
resides at a specific address on the Ethereumblockchain.
The line uintstoredData declares a state variable called storedData of type uint and
the functions set and get can be used to modify or retrieve the value of the variable.
Importing Files
Though above example does not have an import statement but Solidity supports
import statements that are very similar to those available in JavaScript.
The following statement imports all global symbols from "filename".
import "filename";
The following example creates a new global symbol symbolName whose members
are all the global symbols from "filename".
import * as symbolName from "filename";
To import a file x from the same directory as the current file, use import "./x" as x;. If
you use import "x" as x; instead, a different file could be referenced in a global
"include directory".

Reserved Keywords
Following are the reserved keywords in Solidity –

abstract after alias apply

auto case catch copyof

default define final immutable

implements in inline let

macro match mutable null

of override partial promise

reference relocatable sealed sizeof

static supports switch try

typedef typeof unchecked

First Application

We're using Remix IDE to Compile and Run our Solidity Code base.

Step 1 − Copy the given code in Remix IDE Code Section.
Example
pragma solidity ^0.5.0;
contract SolidityTest {
constructor() public{
}
function getResult() public view returns(uint){
uint a = 1;
uint b = 2;
uint result = a + b;
return result;
}
}

Step 2 − Under Compile Tab, click Start to Compile button.


Step 3 − Under Run Tab, click Deploy button.
Step 4 − Under Run Tab, Select SolidityTest at 0x... in drop-down.
Step 5 − Click getResult Button to display the result.

Output
0: uint256: 3

Comments
Solidity supports both C-style and C++-style comments, Thus −
 Any text between a // and the end of a line is treated as a comment and is
ignored by Solidity Compiler.
 Any text between the characters /* and */ is treated as a comment. This may
span multiple lines.

Example
The following example shows how to use comments in Solidity.
function getResult() public view returns(uint){
// This is a comment. It is similar to comments in C++
/*
* This is a multi-line comment in solidity
* It is very similar to comments in C Programming
*/
uint a = 1;
uint b = 2;
uint result = a + b;
return result;
}

Variable - Types
While writing program in any language, you need to use various variables to store
various information. Variables are nothing but reserved memory locations to store
values. This means that when you create a variable you reserve some space in
memory.
You may like to store information of various data types like character, wide
character, integer, floating point, double floating point, boolean etc. Based on the
data type of a variable, the operating system allocates memory and decides what
can be stored in the reserved memory.

Value Types
Solidity offers the programmer a rich assortment of built-in as well as user defined
data types. Following table lists down seven basic C++ data types –

Type Keyword Values

Boolean bool true/false

Integer int/uint Signed and unsigned integers of varying sizes.

Integer int8 to int256 Signed int from 8 bits to 256 bits. int256 is
same as int.

Integer uint8 to Unsigned int from 8 bits to 256 bits. uint256 is


uint256 same as uint.

Fixed Point fixed/unfixed Signed and unsigned fixed point numbers of


Numbers varying sizes.

Fixed Point fixed/unfixed Signed and unsigned fixed point numbers of


Numbers varying sizes.

Fixed Point fixedMxN Signed fixed point number where M represents


Numbers number of bits taken by type and N represents
the decimal points. M should be divisible by 8
and goes from 8 to 256. N can be from 0 to 80.
fixed is same as fixed128x18.

Fixed Point ufixedMxN Unsigned fixed point number where M


Numbers represents number of bits taken by type and N
represents the decimal points. M should be
divisible by 8 and goes from 8 to 256. N can be
from 0 to 80. ufixed is same as ufixed128x18.

address
address holds the 20 byte value representing the size of an Ethereum address. An
address can be used to get the balance using .balance method and can be used to
transfer balance to another address using .transfer method.
address x = 0x212;
address myAddress = this;
if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10);

Variables
Solidity supports three types of variables.
 State Variables − Variables whose values are permanently stored in a
contract storage.
 Local Variables − Variables whose values are present till function is
executing.
 Global Variables − Special variables exists in the global namespace used to
get information about the blockchain.
Solidity is a statically typed language, which means that the state or local variable
type needs to be specified during declaration. Each declared variable always have a
default value based on its type. There is no concept of "undefined" or "null".

State Variable
Variables whose values are permanently stored in a contract storage.
pragma solidity ^0.5.0;
contract SolidityTest {
uint storedData; // State variable
constructor() public {
storedData = 10; // Using State variable
}
}

Local Variable
Variables whose values are available only within a function where it is defined.
Function parameters are always local to that function.
pragma solidity ^0.5.0;
contract SolidityTest {
uint storedData; // State variable
constructor() public {
storedData = 10;
}
function getResult() public view returns(uint){
uint a = 1; // local variable
uint b = 2;
uint result = a + b;
return result; //access the local variable
}
}
Example
pragma solidity ^0.5.0;
contract SolidityTest {
uint storedData; // State variable
constructor() public {
storedData = 10;
}
function getResult() public view returns(uint){
uint a = 1; // local variable
uint b = 2;
uint result = a + b;
return storedData; //access the state variable
}
}

Run the above program using steps provided in Solidity First Application chapter.
Output
0: uint256: 10
Global Variables
These are special variables which exist in global workspace and provide information
about the blockchain and transaction properties.

Name Returns

blockhash(uint blockNumber) returns Hash of the given block - only works for
(bytes32) 256 most recent, excluding current,
blocks

block.coinbase (address payable) 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 calldata) Complete calldata

msg.sender (address payable) Sender of the message (current caller)

msg.sig (bytes4) First four bytes of the calldata (function


identifier)
msg.value (uint) Number of wei sent with the message

now (uint) Current block timestamp

tx.gasprice (uint) Gas price of the transaction

tx.origin (address payable) Sender of the transaction

Solidity Variable Names


While naming your variables in Solidity, keep the following rules in mind.
 You should not use any of the Solidity reserved keywords as a variable
name. These keywords are mentioned in the next section. For example,
break or boolean variable names are not valid.
 Solidity variable names should not start with a numeral (0-9). They must
begin with a letter or an underscore character. For example, 123test is an
invalid variable name but _123test is a valid one.
 Solidity variable names are case-sensitive. For example, Name and name
are two different variables.

Variable Scope
Scope of local variables is limited to function in which they are defined but State
variables can have three types of scopes.
 Public − Public state variables can be accessed internally as well as via
messages. For a public state variable, an automatic getter function is
generated.
 Internal − Internal state variables can be accessed only internally from the
current contract or contract deriving from it without using this.
 Private − Private state variables can be accessed only internally from the
current contract they are defined not in the derived contract from it.

Example
pragma solidity ^0.5.0;
contract C {
uint public data = 30;
uint internal iData= 10;

function x() public returns (uint) {


data = 3; // internal access
return data;
}
}
contract Caller {
C c = new C();
function f() public view returns (uint) {
return c.data(); //external access
}
}
contract D is C {
function y() public returns (uint) {
iData = 3; // internal access
return iData;
}
function getResult() public view returns(uint){
uint a = 1; // local variable
uint b = 2;
uint result = a + b;
return storedData; //access the state variable
}
}

Operators
What is an Operator?
Let us take a simple expression 4 + 5 is equal to 9. Here 4 and 5 are
called operands and '+' is called the operator. Solidity supports the following types
of operators.

 Arithmetic Operators
 Comparison Operators
 Logical (or Relational) Operators
 Assignment Operators
 Conditional (or ternary) Operators
Lets have a look on all operators one by one.

Arithmetic Operators
Solidity supports the following arithmetic operators −
Assume variable A holds 10 and variable B holds 20, then –

Sr.No Operator & Description


.

1 + (Addition)
Adds two operands
Ex: A + B will give 30

2 - (Subtraction)
Subtracts the second operand from the first
Ex: A - B will give -10

3 * (Multiplication)
Multiply both operands
Ex: A * B will give 200

4 / (Division)
Divide the numerator by the denominator
Ex: B / A will give 2

5 % (Modulus)
Outputs the remainder of an integer division
Ex: B % A will give 0

6 ++ (Increment)
Increases an integer value by one
Ex: A++ will give 11

7 -- (Decrement)
Decreases an integer value by one
Ex: A-- will give 9

Example
The following code shows how to use arithmetic operators in Solidity.
pragma solidity ^0.5.0;

contract SolidityTest {
constructor() public{
}
function getResult() public view returns(uint){
uint a = 1;
uint b = 2;
uint result = a + b; //arithmetic operation
return result;
}
}

Run the above program using steps provided in Solidity First Application chapter.

Output
0: uint256: 3
Comparison Operators
Solidity supports the following comparison operators −
Assume variable A holds 10 and variable B holds 20, then −

Sr.No. Operator & Description

1 = = (Equal)
Checks if the value of two operands are equal or not, if yes, then the
condition becomes true.
Ex: (A == B) is not true.

2 != (Not Equal)
Checks if the value of two operands are equal or not, if the values are not
equal, then the condition becomes true.
Ex: (A != B) is true.

3 > (Greater than)


Checks if the value of the left operand is greater than the value of the right
operand, if yes, then the condition becomes true.
Ex: (A > B) is not true.

4 < (Less than)


Checks if the value of the left operand is less than the value of the right
operand, if yes, then the condition becomes true.
Ex: (A < B) is true.

5 >= (Greater than or Equal to)


Checks if the value of the left operand is greater than or equal to the value
of the right operand, if yes, then the condition becomes true.
Ex: (A >= B) is not true.

6 <= (Less than or Equal to)


Checks if the value of the left operand is less than or equal to the value of
the right operand, if yes, then the condition becomes true.
Ex: (A <= B) is true.

Logical Operators
Solidity supports the following logical operators −
Assume variable A holds 10 and variable B holds 20, then –

Sr.No Operator & Description


.

1
&& (Logical AND)
If both the operands are non-zero, then the condition becomes true.
Ex: (A && B) is true.

2
|| (Logical OR)
If any of the two operands are non-zero, then the condition becomes true.
Ex: (A || B) is true.

3
! (Logical NOT)
Reverses the logical state of its operand. If a condition is true, then the Logical
NOT operator will make it false.
Ex: ! (A && B) is false.

Bitwise Operators
Solidity supports the following bitwise operators −
Assume variable A holds 2 and variable B holds 3, then −

Sr.No Operator & Description


.

1
& (Bitwise AND)
It performs a Boolean AND operation on each bit of its integer arguments.
Ex: (A & B) is 2.

2
| (BitWise OR)
It performs a Boolean OR operation on each bit of its integer arguments.
Ex: (A | B) is 3.
3
^ (Bitwise XOR)
It performs a Boolean exclusive OR operation on each bit of its integer
arguments. Exclusive OR means that either operand one is true or operand
two is true, but not both.
Ex: (A ^ B) is 1.

4
~ (Bitwise Not)
It is a unary operator and operates by reversing all the bits in the operand.
Ex: (~B) is -4.

5
<< (Left Shift)
It moves all the bits in its first operand to the left by the number of places
specified in the second operand. New bits are filled with zeros. Shifting a value
left by one position is equivalent to multiplying it by 2, shifting two positions is
equivalent to multiplying by 4, and so on.
Ex: (A << 1) is 4.

6
>> (Right Shift)
Binary Right Shift Operator. The left operand's value is moved right by the
number of bits specified by the right operand.
Ex: (A >> 1) is 1.

7
>>> (Right shift with Zero)
This operator is just like the >> operator, except that the bits shifted in on the
left are always zero.
Ex: (A >>> 1) is 1.

Assignment Operators
Solidity supports the following assignment operators −

Sr.No Operator & Description


.

1
= (Simple Assignment )
Assigns values from the right side operand to the left side operand
Ex: C = A + B will assign the value of A + B into C

2
+= (Add and Assignment)
It adds the right operand to the left operand and assigns the result to the left
operand.
Ex: C += A is equivalent to C = C + A

3
−= (Subtract and Assignment)
It subtracts the right operand from the left operand and assigns the result to the
left operand.
Ex: C -= A is equivalent to C = C - A

4
*= (Multiply and Assignment)
It multiplies the right operand with the left operand and assigns the result to the
left operand.
Ex: C *= A is equivalent to C = C * A

5
/= (Divide and Assignment)
It divides the left operand with the right operand and assigns the result to the
left operand.
Ex: C /= A is equivalent to C = C / A

6
%= (Modules and Assignment)
It takes modulus using two operands and assigns the result to the left operand.
Ex: C %= A is equivalent to C = C % A

Note − Same logic applies to Bitwise operators so they will become like <<=, >>=,
>>=, &=, |= and ^=.

Conditional Operator (? :)
The conditional operator first evaluates an expression for a true or false value and
then executes one of the two given statements depending upon the result of the
evaluation.

Sr.No. Operator and Description

1
? : (Conditional )
If Condition is true? Then value X : Otherwise value Y

Example
pragma solidity ^0.5.0;

contract SolidityTest {
uint storedData;
constructor() public{
storedData = 10;
}
function getResult() public view returns(string memory){
uint a = 1; // local variable
uint b = 2;
uint result = a + b;
return integerToString(result);
}
function integerToString(uint _i) internal pure
returns (string memory _uintAsString) {

if (_i == 0) { //comparison operator


return "0";
}
uint j = _i;
uint len;

while (j != 0) { //comparison operator


len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint k = len - 1;

while (_i != 0) {
bstr[k--] = byte(uint8(48 + _i % 10));
_i /= 10;
}
return string(bstr);//access local variable
}
}

Run the above program using steps provided in Solidity First Application chapter.

Output
0: string: 3
Loops
While writing a contract, you may encounter a situation where you need to perform
an action over and over again. In such situations, you would need to write loop
statements to reduce the number of lines.
Solidity supports all the necessary loops to ease down the pressure of
programming.

Sr.No Loops & Description

1
While Loop
The most basic loop in Solidity is the while loop which would be discussed in
this chapter.

2
do...while Loop
The do...while loop is similar to the while loop except that the condition check
happens at the end of the loop.

3
For Loop
The for loop is the most compact form of looping. It includes the following three
important parts.

4
Loop Control
Solidity provides full control to handle loops and switch statements.

 
While Loop
The most basic loop in Solidity is the while loop which would be discussed in this
chapter. The purpose of a while loop is to execute a statement or code block
repeatedly as long as an expression is true. Once the expression
becomes false, the loop terminates.

Flow Chart
The flow chart of while loop looks as follows −

Syntax
The syntax of while loop in Solidity is as follows −
while (expression) {
Statement(s) to be executed if expression is true
}
do...while loop
The do...while loop is similar to the while loop except that the condition check
happens at the end of the loop. This means that the loop will always be executed at
least once, even if the condition is false.

Flow Chart
The flow chart of a do-while loop would be as follows −

Syntax
The syntax for do-while loop in Solidity is as follows −
do {
Statement(s) to be executed;
} while (expression);
Note − Don't miss the semicolon used at the end of the do...while loop.
For Loop
The for loop is the most compact form of looping. It includes the following three
important parts −
 The loop initialization where we initialize our counter to a starting value. The
initialization statement is executed before the loop begins.
 The test statement which will test if a given condition is true or not. If the
condition is true, then the code given inside the loop will be executed,
otherwise the control will come out of the loop.
 The iteration statement where you can increase or decrease your counter.
You can put all the three parts in a single line separated by semicolons.

Flow Chart
The flow chart of a for loop in Solidity would be as follows −

Syntax
The syntax of for loop is Solidity is as follows −
for (initialization; test condition; iteration statement) {
Statement(s) to be executed if test condition is true
}
Loop Control
Solidity provides full control to handle loops and switch statements. There may be a
situation when you need to come out of a loop without reaching its bottom. There
may also be a situation when you want to skip a part of your code block and start
the next iteration of the loop.
To handle all such situations, Solidity provides break and continue statements.
These statements are used to immediately come out of any loop or to start the next
iteration of any loop respectively.

The break Statement


The break statement, which was briefly introduced with the switch statement, is
used to exit a loop early, breaking out of the enclosing curly braces.
Flow Chart
The flow chart of a break statement would look as follows −
Decision Making
While writing a program, there may be a situation when you need to adopt one out
of a given set of paths. In such cases, you need to use conditional statements that
allow your program to make correct decisions and perform right actions.
Solidity supports conditional statements which are used to perform different actions
based on different conditions. Here we will explain the if..else statement.

Flow Chart of if-else


The following flow chart shows how the if-else statement works.

Solidity supports the following forms of if..else statement −

Sr.No Statements & Description

1
if statement
The if statement is the fundamental control statement that allows Solidity to
make decisions and execute statements conditionally.

2
if...else statement
The 'if...else' statement is the next form of control statement that allows Solidity
to execute statements in a more controlled way.

3
if...else if... statement.
The if...else if... statement is an advanced form of if...else that allows Solidity to
make a correct decision out of several conditions
The if statement is the fundamental control statement that allows Solidity to make
decisions and execute statements conditionally.

Syntax
The syntax for a basic if statement is as follows −
if (expression) {
Statement(s) to be executed if expression is true
}
Here a Solidity expression is evaluated. If the resulting value is true, the given
statement(s) are executed. If the expression is false, then no statement would be
not executed. Most of the times, you will use comparison operators while making
decisions.

The 'if...else' statement is the next form of control statement that allows Solidity to


execute statements in a more controlled way.

Syntax
if (expression) {
Statement(s) to be executed if expression is true
} else {
Statement(s) to be executed if expression is false
}
Here Solidity expression is evaluated. If the resulting value is true, the given
statement(s) in the 'if' block, are executed. If the expression is false, then the given
statement(s) in the else block are executed

The if...else if... statement is an advanced form of if...else that allows Solidity to


make a correct decision out of several conditions.

Syntax
The syntax of an if-else-if statement is as follows −
if (expression 1) {
Statement(s) to be executed if expression 1 is true
} else if (expression 2) {
Statement(s) to be executed if expression 2 is true
} else if (expression 3) {
Statement(s) to be executed if expression 3 is true
} else {
Statement(s) to be executed if no expression is true
}
There is nothing special about this code. It is just a series of if statements, where
each if is a part of the else clause of the previous statement. Statement(s) are
executed based on the true condition, if none of the conditions is true, then
the else block is executed.
Strings
Solidity supports String literal using both double quote (") and single quote ('). It
provides string as a data type to declare a variable of type String.
pragma solidity ^0.5.0;

contract SolidityTest {
string data = "test";
}

In above example, "test" is a string literal and data is a string variable. More
preferred way is to use byte types instead of String as string operation requires
more gas as compared to byte operation. Solidity provides inbuilt conversion
between bytes to string and vice versa. In Solidity we can assign String literal to a
byte32 type variable easily. Solidity considers it as a byte32 literal.
pragma solidity ^0.5.0;

contract SolidityTest {
bytes32 data = "test";
}

Escape Characters
Sr.No. Character & Description
1
\n
Starts a new line.
2
\\
Backslash
3
\'
Single Quote
4
\"
Double Quote
5
\b
Backspace
6
\f
Form Feed
7
\r
Carriage Return
8
\t
Tab
9
\v
Vertical Tab
10
\xNN
Represents Hex value and inserts appropriate bytes.
11
\uNNNN
Represents Unicode value and inserts UTF-8 sequence.

Bytes to String Conversion


Bytes can be converted to String using string() constructor.
bytes memory bstr = new bytes(10);
string message = string(bstr);
Arrays
Array is a data structure, which stores a fixed-size sequential collection of elements
of the same type. An array is used to store a collection of data, but it is often more
useful to think of an array as a collection of variables of the same type.
Instead of declaring individual variables, such as number0, number1, ..., and
number99, you declare one array variable such as numbers and use numbers[0],
numbers[1], and ..., numbers[99] to represent individual variables. A specific
element in an array is accessed by an index.
In Solidity, an array can be of compile-time fixed size or of dynamic size. For
storage array, it can have different types of elements as well. In case of memory
array, element type can not be mapping and in case it is to be used as function
parameter then element type should be an ABI type.
All arrays consist of contiguous memory locations. The lowest address corresponds
to the first element and the highest address to the last element.

Declaring Arrays
To declare an array of fixed size in Solidity, the programmer specifies the type of
the elements and the number of elements required by an array as follows −
type arrayName [ arraySize ];
This is called a single-dimension array. The arraySize must be an integer constant
greater than zero and type can be any valid Solidity data type. For example, to
declare a 10-element array called balance of type uint, use this statement −
uint balance[10];
To declare an array of dynamic size in Solidity, the programmer specifies the type of
the elements as follows −
type[] arrayName;
Initializing Arrays
You can initialize Solidity array elements either one by one or using a single
statement as follows −
uint balance[3] = [1, 2, 3];
The number of values between braces [ ] can not be larger than the number of
elements that we declare for the array between square brackets [ ]. Following is an
example to assign a single element of the array −
If you omit the size of the array, an array just big enough to hold the initialization is
created. Therefore, if you write −
uint balance[] = [1, 2, 3];
You will create exactly the same array as you did in the previous example.
balance[2] = 5;
The above statement assigns element number 3 rd in the array a value of 5.
Creating dynamic memory arrays
Dynamic memory arrays are created using new keyword.
uint size = 3;
uint balance[] = new uint[](size);
Accessing Array Elements
An element is accessed by indexing the array name. This is done by placing the
index of the element within square brackets after the name of the array. For
example −
uint salary = balance[2];
The above statement will take 3 rd element from the array and assign the value to
salary variable. Following is an example, which will use all the above-mentioned
three concepts viz. declaration, assignment and accessing arrays −

Members
 length − length returns the size of the array. length can be used to change
the size of dynamic array be setting it.
 push − push allows to append an element to a dynamic storage array at the
end. It returns the new length of the array.
Example
Try the following code to understand how the arrays works in Solidity.
pragma solidity ^0.5.0;

contract test {
function testArray() public pure{
uint len = 7;

//dynamic array
uint[] memory a = new uint[](7);

//bytes is same as byte[]


bytes memory b = new bytes(len);

assert(a.length == 7);
assert(b.length == len);

//access array variable


a[6] = 8;

//test array variable


assert(a[6] == 8);

//static array
uint[3] memory c = [uint(1) , 2, 3];
assert(c.length == 3);
}
}
Enums
Enums restrict a variable to have one of only a few predefined values. The values in
this enumerated list are called enums.
With the use of enums it is possible to reduce the number of bugs in your code.
For example, if we consider an application for a fresh juice shop, it would be
possible to restrict the glass size to small, medium, and large. This would make
sure that it would not allow anyone to order any size other than small, medium, or
large.

Example
Try the following code to understand how the enum works in Solidity.
pragma solidity ^0.5.0;

contract test {
enum FreshJuiceSize{ SMALL, MEDIUM, LARGE }
FreshJuiceSize choice;
FreshJuiceSize constant defaultChoice = FreshJuiceSize.MEDIUM;

function setLarge() public {


choice = FreshJuiceSize.LARGE;
}
function getChoice() public view returns (FreshJuiceSize) {
return choice;
}
function getDefaultChoice() public pure returns (uint) {
return uint(defaultChoice);
}
}

Run the above program using steps provided in Solidity First Application chapter.
First Click setLarge Button to set the value as LARGE then click getChoice to get
the selected choice.

Output
uint8: 2
Click getDefaultChoice Button to get the default choice.

Output
uint256: 1
Structs
Struct types are used to represent a record. Suppose you want to keep track of your
books in a library. You might want to track the following attributes about each book

 Title
 Author
 Subject
 Book ID

Defining a Struct
To define a Struct, you must use the struct keyword. The struct keyword defines a
new data type, with more than one member. The format of the struct statement is as
follows −
struct struct_name {
type1 type_name_1;
type2 type_name_2;
type3 type_name_3;
}
Example
struct Book {
string title;
string author;
uint book_id;
}

Accessing a Struct and its variable


To access any member of a structure, we use the member access operator (.). The
member access operator is coded as a period between the structure variable name
and the structure member that we wish to access. You would use the struct to
define variables of structure type. The following example shows how to use a
structure in a program.
Example
Try the following code to understand how the structs works in Solidity.
pragma solidity ^0.5.0;

contract test {
struct Book {
string title;
string author;
uint book_id;
}
Book book;

function setBook() public {


book = Book('Learn Java', 'TP', 1);
}
function getBookId() public view returns (uint) {
return book.book_id;
}
}

Run the above program using steps provided in Solidity First Application chapter.
First Click setBook Button to set the value as LARGE then click getBookId to get
the selected book id.
Output
uint256: 1

Mapping
Mapping is a reference type as arrays and structs. Following is the syntax to declare
a mapping type.
mapping(_KeyType => _ValueType)
Where
 _KeyType − can be any built-in types plus bytes and string. No reference
type or complex objects are allowed.
 _ValueType − can be any type.

Considerations
 Mapping can only have type of storage and are generally used for state
variables.
 Mapping can be marked public. Solidity automatically create getter for it.
Example
Try the following code to understand how the mapping type works in Solidity.
pragma solidity ^0.5.0;

contract LedgerBalance {
mapping(address => uint) public balances;

function updateBalance(uint newBalance) public {


balances[msg.sender] = newBalance;
}
}
contract Updater {
function updateBalance() public returns (uint) {
LedgerBalance ledgerBalance = new LedgerBalance();
ledgerBalance.updateBalance(10);
return ledgerBalance.balances(address(this));
}
}
First Click updateBalance Button to set the value as 10 then look into the logs
which will show the decoded output as −
Output
{
"0": "uint256: 10"
}

Conversions
Solidity allows implicit as well as explicit conversion. Solidity compiler allows implicit
conversion between two data types provided no implicit conversion is possible and
there is no loss of information. For example uint8 is convertible to uint16 but int8 is
convertible to uint256 as int8 can contain negative value not allowed in uint256.

Explicit Conversion
We can explicitly convert a data type to another using constructor syntax.
int8 y = -3;
uint x = uint(y);
//Now x = 0xfffff..fd == two complement representation of -3 in
256 bit format.

Conversion to smaller type costs higher order bits.


uint32 a = 0x12345678;
uint16 b = uint16(a); // b = 0x5678

Conversion to higher type adds padding bits to the left.


uint16 a = 0x1234;
uint32 b = uint32(a); // b = 0x00001234

Conversion to smaller byte costs higher order data.


bytes2 a = 0x1234;
bytes1 b = bytes1(a); // b = 0x12

Conversion to larger byte add padding bits to the right.


bytes2 a = 0x1234;
bytes4 b = bytes4(a); // b = 0x12340000

Conversion between fixed size bytes and int is only possible when both are of same
size.
bytes2 a = 0x1234;
uint32 b = uint16(a); // b = 0x00001234
uint32 c = uint32(bytes4(a)); // c = 0x12340000
uint8 d = uint8(uint16(a)); // d = 0x34
uint8 e = uint8(bytes1(a)); // e = 0x12
Hexadecimal numbers can be assigned to any integer type if no truncation is
needed.
uint8 a = 12; // no error
uint32 b = 1234; // no error
uint16 c = 0x123456; // error, as truncation required to 0x3456

Ether Units
In solidity we can use wei, finney, szabo or ether as a suffix to a literal to be used to
convert various ether based denominations. Lowest unit is wei and 1e12 represents
1 x 1012.
assert(1 wei == 1);
assert(1 szabo == 1e12);
assert(1 finney == 1e15);
assert(1 ether == 1e18);
assert(2 ether == 2000 fenny);

Time Units
Similar to currency, Solidity has time units where lowest unit is second and we can
use seconds, minutes, hours, days and weeks as suffix to denote time.
assert(1 seconds == 1);
assert(1 minutes == 60 seconds);
assert(1 hours == 60 minutes);
assert(1 day == 24 hours);
assert(1 week == 7 days);

Special Variables
Special variables are globally available variables and provides information about the
blockchain. Following is the list of special variables −

Sr.No Special Variable & Description


.

1
blockhash(uint blockNumber) returns (bytes32)
Hash of the given block - only works for 256 most recent, excluding current,
blocks.

2
block.coinbase (address payable)
Current block miner's address.

3
block.difficulty (uint)
current block difficulty.

4
block.gaslimit (uint)
Current block gaslimit.

5
block.number (uint)
Current block number.

6
block.timestamp
Current block timestamp as seconds since unix epoch.

7
gasleft() returns (uint256)
Remaining gas.

8
msg.data (bytes calldata)
Complete calldata.

9
msg.sender (address payable)
Sender of the message (current call).

10
msg.sig (bytes4)
First four bytes of the calldata (i.e. function identifier)

11
msg.value (uint)
Number of wei sent with the message.

12
now (uint)
Current block timestamp (alias for block.timestamp).

13
tx.gasprice (uint)
Gas price of the transaction.
14
tx.origin (address payable)
Sender of the transaction (full call chain).

Example
Try the following code to see the use of msg, a special variable to get the sender
address in Solidity.
pragma solidity ^0.5.0;

contract LedgerBalance {
mapping(address => uint) public balances;

function updateBalance(uint newBalance) public {


balances[msg.sender] = newBalance;
}
}
contract Updater {
function updateBalance() public returns (uint) {
LedgerBalance ledgerBalance = new LedgerBalance();
ledgerBalance.updateBalance(10);
return ledgerBalance.balances(address(this));
}
}

Run the above program using steps provided in Solidity First Application chapter.
First Click updateBalance Button to set the value as 10 then look into the logs
which will show the decoded output as −

Output
{
"0": "uint256: 10"
}
Style Guide
Style Guide helps to maintain code layout consistent and make code more
readable. Following are the best practices following while writing contracts with
Solidity.

Code Layout
 Indentation − Use 4 spaces instead of tab to maintain indentation level.
Avoid mixing spaces with tabs.
 Two Blank Lines Rule − Use 2 Blank lines between two contract definitions.
pragma solidity ^0.5.0;

contract LedgerBalance {
//...
}
contract Updater {
//...
}

 One Blank Line Rule − Use 1 Blank line between two functions. In case of
only declaration, no need to have blank lines.
pragma solidity ^0.5.0;

contract A {
function balance() public pure;
function account() public pure;
}
contract B is A {
function balance() public pure {
// ...
}
function account() public pure {
// ...
}
}

 Maximum Line Length − A single line should not cross 79 characters so that
readers can easily parse the code.
 Wrapping rules − First argument be in new line without opening parenthesis.
Use single indent per argument. Terminating element ); should be the last
one.
function_with_a_long_name(
longArgument1,
longArgument2,
longArgument3
);
variable = function_with_a_long_name(
longArgument1,
longArgument2,
longArgument3
);
event multipleArguments(
address sender,
address recipient,
uint256 publicKey,
uint256 amount,
bytes32[] options
);
MultipleArguments(
sender,
recipient,
publicKey,
amount,
options
);

 Source Code Encoding − UTF-8 or ASCII encoding is to be used preferably.


 Imports − Import statements should be placed at the top of the file just after
pragma declaration.
 Order of Functions − Functions should be grouped as per their visibility.
pragma solidity ^0.5.0;

contract A {
constructor() public {
// ...
}
function() external {
// ...
}

// External functions
// ...

// External view functions


// ...

// External pure functions


// ...

// Public functions
// ...

// Internal functions
// ...

// Private functions
// ...
}
 Avoid extra whitespaces − Avoid whitespaces immediately inside
parenthesis, brackets or braces.
 Control structures − Braces should open on same line as declaration. Close
on their own line maintaining the same indentation. Use a space with
opening brace.
pragma solidity ^0.5.0;

contract Coin {
struct Bank {
address owner;
uint balance;
}
}
if (x < 3) {
x += 1;
} else if (x > 7) {
x -= 1;
} else {
x = 5;
}
if (x < 3)
x += 1;
else
x -= 1;

 Function Declaration − Use the above rule for braces. Always add a
visibility label. Visibility label should come first before any custom modifier.
function kill() public onlyowner {
selfdestruct(owner);
}

 Mappings − Avoid whitespaces while declaring mapping variables.


mapping(uint => uint) map;
mapping(address => bool) registeredAddresses;
mapping(uint => mapping(bool => Data[])) public data;
mapping(uint => mapping(uint => s)) data;

 Variable declaration − Avoid whitespaces while declaring array variables.


uint[] x; // not unit [] x;

 String declaration − Use double quotes to declare a string instead of single


quote.
str = "foo";
str = "Hamlet says, 'To be or not to be...'";

Order of Layout
Elements should be layout in following order.
 Pragma statements
 Import statements
 Interfaces
 Libraries
 Contracts
Within Interfaces, libraries or contracts the order should be as −
 Type declarations
 State variables
 Events
 Functions

Naming conventions
 Contract and Library should be named using CapWords Style. For example,
SmartContract, Owner etc.
 Contract and Library name should match their file names.
 In case of multiple contracts/libraries in a file, use name of core
contract/library.
Owned.sol
pragma solidity ^0.5.0;

// Owned.sol
contract Owned {
address public owner;
constructor() public {
owner = msg.sender;
}
modifier onlyOwner {
//....
}
function transferOwnership(address newOwner) public onlyOwner
{
//...
}
}

Congress.sol
pragma solidity ^0.5.0;

// Congress.sol
import "./Owned.sol";

contract Congress is Owned, TokenRecipient {


//...
}

 Struct Names
− Use CapWords Style like SmartCoin.

 Event Names

− Use CapWords Style like Deposit, AfterTransfer.

 Function Names

− Use mixedCase Style like initiateSupply.

 Local and State variables

− Use mixedCase Style like creatorAddress, supply.

 Constants

− Use all capital letters with underscore to seperate words like MAX_BLOCKS.

 Modifier Names

− Use mixCase Style like onlyAfter.

 Enum Names

− Use CapWords Style like TokenGroup.


https://www.tutorialspoint.com/solidity/solidity_functions.htm

You might also like