Solidity is an object-oriented programming language for creating smart contracts. It is used to implement smart contracts on various blockchain platforms, especially Ethereum.
Solidity is a language which use curly braces same like C++, Python, and JavaScript, it targets Ethereum virtual machines (EVMs). It was developed by Christian Reitwiessner, Alex Beregszaszi, and several former core Ethereum contributors, allowing them to create smart contracts on blockchain platforms.
With Solidity, we can create contracts for applications such as voting, crowdfunding, blind auctions, and multi-signature wallets.
Below is an example of a simple Solidity program.
pragma solidity >=0.7.0 <0.8.0;contract StorageDevice {uint storeData;function set(uint y) public {storeData = y;}function get() public view returns (uint) {return storeData;}}
Let’s consider the following Solidity types:
A value type is a type that holds data directly in its own memory. Variables of these types are always passed by value, which means that value is always copied when it is assigned to another variable or passed to a function.
The following types are Solidity value types.
Signed integers are declared with the int
keyword and unsigned integers are declared with uint
, both of which are 32 bytes
by default.
If the variable does not contain so many bytes, it is always possible to change the variable size by explicitly specifying the number of bits, like in int128/uint128
. Also, uint8
to uint256
in increments of 8 (unsigned from 8 to 256 bits) and int8
to int256
.
Booleans (bool
) can hold two constant values true
and false
. Solidity supports all the usual Boolean operators such as !=
(inequality), ==
(equality) , !
(logical negation), &&
(logical conjunction, “and”), ||
(logical disjunction, “or”).
Fixed-point refers to a method of representing fractional numbers (not integers).
Note: Solidity doesn’t support fixed-point numbers at the moment. However, fixed-point numbers can be declared, but cannot be assigned to or from.
We have signed fixed-point numbers and unsigned fixed-point numbers, which are represented with the keywords fixed
and ufixed
respectively.
Keywords ufixedMxN
and fixedMxN
, where M
represents the number of bits taken in the style and N
represents the number of decimal parts. M
must be divisible by 8
and a number between 8
and 256
. N
must be a number between 0
and 80
.
These also work with the operators such as : <=
, <
, ==
, !=
, >=
, >
use for comparisons. And +
, -
, unary -
, *
, /
, %
(modulo) use for Arithmetic.
There are two variations of address type — address payable and address. These are almost the same. The address
holds a 20-byte value (size of an Ethereum address) while address payable
holds the same as an address, but with the additional members transfer
and send
.
The idea behind this difference is that an address payable
is one you can send Ether
, while a plain address cannot send Ether
.
There are two ways of converting addresses from one type to the other: implicit conversions and explicit conversions.
address payable
to address
is allowed, but conversion from address
to address payable
must be done explicitly through payable(address)
.uint160
, integer literals, bytes20
, and contract types allow explicit conversion to and from address
.Solidity reference types should be treated more carefully than value types. The reference type value can be changed with several different variables pointing to same address. Compare this with the value type. We can use a value type variable to get an independent copy.
When dealing with Solidity reference types, it is important to clearly identify the data area memory, storage, or calldata where the reference type is stored.
The location specified is important not only for data persistence but also for the semantics of assignments. We shall closely look at the assignment behavior:
storage
and memory
(or from calldata
) always create an independent copy.memory
to memory
create references only. This means that changes made to one memory variable are also visible in all other memory variables that reference the same data.storage
to the local storage variable also assigns references only.storage
. An example of this case is an assignment to a local variable member of a state variable or storage structure type, even if the local variable itself is a reference.Arrays can be fixed or dynamic at compile time. Fixed-sized arrays k
and element type T
types are written as T[k]
, and dynamic-sized arrays are written as T[]
.
An array of 6 dynamic uint
arrays has the following form: uint[] [6]
. By default in Solidity, the array x[3] consists of three elements of type uint
despite the fact that it can be an array.
note
Array elements can be of any type. However, there are some restrictions. The mapping must be stored in the location of the storage
data and the public function requires a parameter of type ABI.
Array slices are a view on a contiguous part of an array. They are written as x[start:end]
, in which start
and end
are expressions ensuing in a uint256
type (or implicitly convertible to it). The first detail of the slice is x[start
] and the remaining detail is x[end - 1]
.
If start
is greater than end
or end
is greater than the length of the array, an exception will be thrown.
Both start
and end
are optional. The start default is 0
and the end
default is the length of the array.
No variable can have an array slice as a type. It only exists in intermediate expressions.
Arrays have the following members length
, push
and pop
.
Length: length deals with the number of elements. For storage arrays, the length is fixed after they are created. However, it can be dynamic and rely on runtime parameters. The length is set on dynamically sized arrays to change their size.
Push: push adds an element to the end of a dynamic memory array and bytes (not a string). Newly added elements are initialized to zero.
Pop: pop removes elements at the end of a dynamic array of storage and bytes (not strings).