Coding in Solidity
pragma solidity^0.4.0;
contract StorageBasic {
uint storedValue;
function set(uint var) {
storedValue=var;
}
function get() constant returns (uint) {
return storedValue;
}
}
The first line of the code declares that the source code for the program is to be written
in Solidity 0.4.0. The code will be therefore compatible with EVMs that correspond to
Solidity 0.4.0 or are superior. The expression ‘pragma’ refers to the instructions given
to a compiler to sequentially execute the source code.
The whole program designs a smart contract ‘StorageBasic’ which has an unsigned
integer variable ‘storedValue’ and a member function ‘set()’ which takes the returned
value of the function ‘var()’ as its argument. Inside the body of the function,
‘storedValue’ is assigned the value that the function ‘get()’ returns.
In the meanwhile, the function ‘get()’ returns an unsigned integer value. Overall, the
whole code acts as a recursive function. This is considered best for smart contract
implementations within a blockchain.
Solidity syntax basics
In this section, we will discuss the Solidity syntax basics. You can use this knowledge
to build syntax for writing smart contracts using Solidity. A Solidity source file can
contain any number of pragma directives, contract definitions, and import directives.
Let’s start with a simple example of 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 that tells source code is written for Solidity version
0.4.0 and newer versions that doesn’t break functionality, excluding version 0.6.0.
Pragma directive is always local to a source file and if you try to import another file,
the pragma from the new file will not automatically apply to the importing file. So, if you
are creating a pragma for a file that 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:
pragma solidity ^0.4.0;
Here in this command, 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 Ethereum blockchain. The different components of the
contract help in declaring a state variable alongside configuring functions for
modification or retrieval of variable values.
Importing Files
Even though the above examples didn’t feature an import statement, Solidity supports
import statements that are very similar to those available in JavaScript. Let’s import all
global symbols from “filename”.
import "filename";
Now 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, an altogether different file could be referenced in a
global “include directory”.
Reserved Keywords
Reserved keywords are essential in helping to better understand Solidity as beginners.
With this knowledge, they can accurately identify correctly. Users could use this
knowledge of reserved keywords to develop logic using Solidity. Take a look at the
following reserved keywords in Solidity and you will get a better understanding.
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
Hello World in Solidity
Here we will put Solidity in action for writing a program for Hello World.
// SPDX-License-Identifier: MIT
// compiler version must be greater than or equal to 0.8.10
and less than 0.9.0
pragma solidity ^0.8.10;
contract HelloWorld {
string public greet = "Hello World!";
}
Solidity-Types
Writing a program in any language requires variables to store various information.
Variables could be termed to be reserved memory locations to store values. Creating
a variable will reserve some space in memory. And this variable could be used in
storing information like integer, character, wide character, floating-point, double
floating point, boolean, etc. The Operating System allocates memory and decides
what can be stored in this reserved memory based on the data type of a variable.
Solidity offers programmers a rich list of built-in and user-defined data types. Let’s
discuss the seven basic C++ data types to help you understand better.
Type Keyword Values
Boolean bool true/false
Integer int/uint Signed and unsigned integers of varying sizes.
Integer int8 to Signed int from 8 bits to 256 bits. int256 is the same as int.
int256
Integer uint8 to Unsigned int from 8 bits to 256 bits. uint256 is the same as
uint256 uint.
Fixed fixed/unfixed Signed and unsigned fixed-point numbers of varying sizes.
Point
Numbers
Fixed fixed/unfixed Signed and unsigned fixed-point numbers of varying sizes.
Point
Numbers
Fixed fixedMxN Signed fixed-point number where M represents the number of
Point bits taken by type and N represents the decimal points. M
Numbers should be divisible by 8 and go from 8 to 256. N can be from
0 to 80. fixed is the same as fixed128x18.
Fixed ufixedMxN Unsigned fixed-point number where M represents the number
Point of bits taken by type and N represents the decimal points. M
Numbers should be divisible by 8 and go from 8 to 256. N can be from
0 to 80. ufixed is the same as ufixed128x18.
Address represents the size of an Ethereum address. It holds 20 bytes of values in
storage. An address can be used to get the balance using the .balance method and
could be used to transfer balance using the .transfer method.
address x = 0x212;
address myAddress = this;
if (x.balance < 10 && myAddress.balance >= 10) x.transfer(10);
H2: Solidity-Variables
Solidity supports three types of variables:
State Variables: Variables whose values are stored permanently in a contract
storage.
pragma solidity ^0.5.0;
contract SolidityTest {
uint storedData; // State variable
constructor() public {
storedData = 10; // Using State variable
}
}
Local Variables: Variables whose values are present till function is executing.
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
}
}
Global Variables: These are some special variables that exist in the global
namespace used to get information about the blockchain.
Name Returns
blockhash(uint blockNumber) Hash of the given block - only works for 256 most
returns (bytes32) recent, excluding current, blocks
block.coinbase (address Current block miner's address
payable)
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
Since Solidity is a statically typed language, that means their state, local variables
need to be specified during declaration. Each declared variable has a default value
based on its type. The concept of “undefined” or “null” doesn’t exist here.
Solidity variable scope
The scope of local variables is limited to the function in which they are defined but
State Variables can have three types of scopes and they are:
Public: Public state variables can be accessed internally as well as via messages.
Internal: Internal state variables can be accessed only internally from the current
contract or a contract deriving from it without using this.
Private: Private state variables can be accessed only internally from the current
contract they are defined and not in the derived contract from it.
Solidity operators
What better way to explain than with an example? Let’s take a simple expression 4+5
= 9. Here, 4 and 5 are called operands, and ‘+’ is called the operator. Solidity supports
few types of operators like:
Arithmetic Operators: Addition (+), Subtraction (-), Multiplication (*), Division (/),
Modulus (%), Increment (++), and Decrement (--).
Comparison Operators: Equal (==), Not Equal (!=), Greater than (>), Less than (<),
Greater than or Equal to (>=), and Less than or Equal to (<=).
Logical Operators: Logical AND (&&), Logical OR (||), and Logical NOT (!).
Bitwise Operators: Bitwise AND (&), Bitwise OR (|), Bitwise NOT (~), Left Shift (<<),
Right Shift (>>), and Right Shift with Zero (>>>).
Assignment Operators: Simple Assignment (=), Add and Assignment (+=), Subtract
and Assignment (-=), Multiply and Assignment (*=), Divide and Assignment (/=), and
Modulus and Assignment (%=).
Conditional Operator: Conditional (?:) - If the condition is true then output is X,
otherwise it’s Y.
Solidity-Loops
Loops as in many languages are used in a scenario where you need to perform an
action over and over again. In those cases, you would need loop statements to reduce
the number of lines. Solidity supports all necessary loops to make programming easy.
Let’s discuss some loops here:
While Loop: It’s the basic loop used in Solidity.
Do…While Loop: In this loop, the condition check happens at the end of the loop.
For Loop: It’s the most compact form of looping.
Loop Control: Solidity offers full control over the loops and the switch statements.
You can use it to skip a part of the loop or block of code and iterate the next section
using this.
Solidity-Decision Making
There are scenarios where while writing programs, there comes a situation wherein
you need to adopt either of the two ways. You can use conditional statements in those
scenarios to allow your program to make correct decisions and perform the right
actions. Solidity supports a different set of conditional statements which are used to
perform a different set of actions based on different conditions. There are many
conditional statements that Solidity supports like if statement, if…else statement,
if…else if…statement.
Solidity-Strings
Solidity supports String literal in 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";
}
Here in the above example, “test” is a string literal, and data is a string variable. Solidity
provides inbuilt conversion between bytes to string and vice versa. We can assign
String literal to a byte32 type variable easily.
Solidity-Arrays
Array is a data structure, which stores a fixed-size sequential collection of elements of
the same type. It’s more useful to think of an array as a collection of the same type of
variables. You can index each element inside an array. In Solidity, arrays could be
compile-time fixed size or of dynamic size. All arrays hold contiguous memory
locations, which means they share their borders or are in continuous sections. The
lowest address corresponds to the first element and the highest address to the last
element. Using commands, you can Declare an array, initialize an array, create a
dynamic memory array, access array elements, etc.
Solidity-Functions
Functions are reusable code that can be called anywhere in your program. Functions
help in eliminating the need for writing the same code again and again. Functions help
programmers in writing modular codes. These functionalities allow programmers to
divide a big program into a number of small and manageable functions. Like all the
other advanced languages, Solidity supports all the features necessary to write
modular code using functions.
Solidity-Contracts
A Contractor in Solidity is similar to a Class in C++. A Contract has the following
properties:
Constructor: A special function declared with a constructor keyword which will be
executed once per contract and is invoked when a contract is created.
State Variables: Variables per contract to store the state of the contract.
Functions: Functions per contract that can modify the state variables to alter the state
of a contract.
Applications of Solidity
It is a highly advanced programming language that has made coding around
blockchain platforms extremely easy. Being easy to understand and relatively easy to
use, Solidity has many applications.
Voting: In the real world, voting comprises various fraudulent techniques
including manipulation of data, booth capturing, fake voters, manipulation in
voting machines, etc. To solve a few of these problems, we could make use of
contracts for envoy voting. Solidity can be used to design the code, and with
proper implementation, the process of voting will work smoothly, transparently,
and automatically.
Crowdfunding: If done through contracts, crowdfunding can solve various
problems associated with it like a commission of a third party, issues related to
managing data, etc. For crowdfunding, smart contracts can work out far better
than non-trusted centralized systems. These smart contracts can be developed
using Solidity.
Blind Auctions: Implementation of the blind auction in Solidity is quite
straightforward on Ethereum. An open auction can be created in which every
individual can make out each other’s bid, following which a blind auction can be
designed where it will not be possible for anyone to see the bid until it ends.
What is Solidity:
Solidity is a contract-oriented high level language for implementing smart
contracts. It was influenced by C++, JavaScript and Python and is designed to
target the EVM.
Contracts:
Contracts in solidity are similar to classes in object oriented language.
A contract can be created using “new” keyword
contract L {
function add(uint _p, uint _q) returns (uint) {
return _p + _q;
}
}
contract M {
address p;
function f(uint _p) {
p = new L();
}
}
Smart contracts:
Smart contract is a computer protocol which is used to streamline the process of
contracts by digitally enforcing, verifying and managing them.
Remix:
Remix is a browser-based IDE with integrated compiler and solidity run-time
environment without server side components
Solium:
Solium is a linter to identify and fix style and security issues in solidity
Doxity:
Doxity is a tool which is used in solidity as a documentation generator
Solograph:
Solograph is used to visualize solidity control flow and highlight potential security
vulnerabilities
Solidity Assembly:
Solidity defines an assembly language which can be used without solidity and can be
used as inline assembly inside solidity source code
Gas:
Gas is a measurement roughly equivalent to the computational steps
Block Gas limit:
It is used to control the amount of gas consumed during the transactions
ABI:
A data encoding scheme called “Application Binary Interface” (ABI) is used in for
working with smart contracts
Global Variables:
Solidity provides special variables that exist inside the global namespace are known
as Global Variables
blockhash(uint numberOfBlock) returns (bytes32) – hash function of the
given block which works for the 256 most recent blocks excluding the current
block
block.coinbase (address): shows the miner’s address of the current block
block.number (unit): number of current block
block.gaslimit (unit) : gaslimit of the current block
block.timestamp (uint): timestamp of current block
msg.gas (uint): the gas that remains
msg.value (uint): the amount of WEI sent along with the message
msg.sender (address): address of the message sender (current call)
msg.sig (bytes4): first four bytes of the call data
now (uint): timestamp for the current block
tx.origin (address): the sender of the transaction (whole call chain)
WEI:
The smallest denomination or base unit of Ether.
Pragma:
Pragmas in solidity are used to specify certain conditions under which the source
files can or cannot run
Example:
pragma solidity ^0.2.32
This code compiles with a compiler function >=0.2.32
A pseudocode example for pragma syntax
'pragma' Identifier ([^;]+) ';'
Import files:
Syntax to import the files
import "filename";
import * as symbolName from "filename"; or import "filename"
as symbolName;
import {symbol1 as alias, symbol2} from "filename";
Data Types:
Data type is a particular kind of data defined by the values it can take
Boolean
Boolean syntax:
bool: true or false
Operators:
Logical:
! (Logical negation)
&& (AND)
|| (OR)
Comparisons:
== (equality)
!= (inequality)
Integer
Unsigned Integer:
Eg: uint8 | uint16 | uint32 | unit64 | uint128 | uint256
(uint)
Signed integer: int8 | int16 | int32 | nit64 | int128 | int256
(uint)
Operators:
Comparisons:
<= (Less than or equal to)
< (Less than)
== (equal to)
!= (Not equal to)
>= (Greater than or equal to)
(Greater than)
Bitwise operators:
& (AND)
| (OR)
^ (Bitwise Exclusive OR)
~ (Bitwise negation)
Arithmetic Operators:
+ (Addition)
- (Subtraction)
Unary –
Unary +
*(Multiplication)
% (Division)
** (Exponential)
<< (Left shift)
>> (Right shift)
Address:
Holds an Ethereum address (20 byte value).
Operators: Comparisons: <=, <, ==, !=, >= and >
Methods:
Balance:
<address>.balance (unit256): balance of address in WEI
Transfer and send:
<address>.transfer(uint256 amount): send given amount of Wei
to Address, throws on failure
<address>.send(uint256 amount) returns (bool): send given
amount of Wei to Address, returns false on failure
Call:
<address>.call(...) returns (bool): issue low-level CALL,
returns false on failure
Array:
Array can be dynamic or fixed size array
uint[] dynamicSizeArray;
uint[9] fixedSizeArray;
Struct:
New types can be declared using Struct
Example:
struct Funder {
address addr;
uint amount:
}
Funder funders;
Mapping:
Mapping can be seen as hash tables, declared as mapping(_KeyType => _ValueType)
Function:
Syntax of a function:
function (<parameter types>)
{internal|external|public|private}
[pure|constant|view|payable] [returns (<return types>]
Pure functions:
function f(uint a) pure returns (uint) {
return a *24
}
Global functions:
Solidity provides special functions that exist inside the global namespace are
known as Global Functions
keccak256(…) returns (bytes32)- computes the ethereum SHA-3 hash
associated with the arguments
sha256(…) returns (bytes32) – Computes the SHA-256 argument hash
mulmod( uint a, uint b, uint c) returns (unit) : It computes (a*b)%c, if the
multiplication gets executed using arbitrary precision, thus not wrapping around
2**256
addmod(uint p, uint q, uint m) returns (uint): Computes (p+q)%m
ecrecover(bytes32 _hash, uint8 _v, bytes32 _r, bytes32 _s) returns (address):
recovers the address linked with the public key and if an error occurs, zero is
returned
ripemd160(…) returns (bytes20): computes the RIPEMD-160 (tightly packed)
argument hash
<address>.balance(uint256) : Returns the balance of the specified address in
WEI
<address>.send(uint256 amount) returns (bool): It sends the specified number of
WEI to the address given, on failure it returns false as an output
<address>.transfer(uint256 amount): Sends specified number of WEI to the
particular address, on failure throws
Access Modifiers:
Access Modifiers are keywords that sets the accessibility of classes, methods and
other members and is used to facilitate the encapsulation of the components
public – Accessible from the current contract, inherited contracts and externally
private – Accessible only from the current contract
internal – Accessible only from current contract and contracts inheriting from it
external – Can be accessed externally only
Interface:
Interface in solidity are defined as contracts, but the function bodies are omitted for
the functions
Example:
pragma solidity ^0.22;
interface Token {
function transfer(address recipient, uint amount);
}
Important Terms
Payable function: Functions that receive Ether are marked as payable functions
Events: Events writes the information from contract to Block chain logs
Voting: When the contract is quiet complex, it uses voting contract, it shows how
delegated voting can be done so that vote counting is automatic and completely
transparent at the same time
Delegate call: It is a reusable library code that can be applied to a contracts
storage in solidity
Logs: A feature called logs is used in solidity to implement events
NPM: It is a convenient and portable way to install Solidity compiler
Truffle: It is a test bed that will allow to easily test and compile the smart contract
Inheritance: In solidity inheritance is more syntactic. In the final compilation the
compiler copies the parent class members to create the bytecode of the derived
contract with the copied members
This: This is a keyword that refers to the instance of the contract where the call
is made
sender: This function refers to the address where the contract is being called
from
Pure: It is a modifier which assures not to be read from or modified
View: In solidity, view is a function that promises to not modify the state of the
contract
Suicide: Suicide is an alias for self destruct function, that is used to destroy the
current contract
Delete: Delete is used to delete all elements in an array
coinbase(address): It refers to the miner’s address of the current block
Address(contractVar).send(amount): If a built-in send function needs to be used,
it can be accessed using this function
Super: It is used to refer the contract that is higher by one level in the inheritance
hierarchy
TRANSACTION EXAMPLE:
A transaction of data (0x614) from 0x712 to 0x145