SOLIDITY
SOLIDITY
Private Network:
● Private networks are useful for developers to experiment with smart contracts without the cost
and security implications of deploying on a public network.
● Examples of private blockchain frameworks include Hyperledger Fabric, Quorum, and Corda.
Example:
● A group of developers working on a project might set up a private Ethereum network for testing
smart contracts among themselves before deploying to a wider audience.
Public Testnet:
○ A public testnet is a blockchain network that mirrors the functionalities of the mainnet but uses
testnet tokens, which have no real-world value. It allows developers to test their smart contracts in
an environment that simulates the conditions of the mainnet without the risk of losing real assets.
○ Public testnets are open to the public, and anyone can interact with them to test decentralized
applications (DApps) and smart contracts.
Example:
○ The Ethereum testnet, such as Ropsten or Rinkeby, allows developers to deploy and test their
smart contracts using testnet ETH instead of real Ether.
Public Mainnet:
○ The public mainnet is the live and production-ready blockchain network where real assets, such as
cryptocurrency, are used. It is the network that is open to the public, and transactions on this
network have real-world consequences.
○ Deploying a smart contract on the mainnet means that it is accessible to everyone, and the
contract's code and state are immutable.
Example:
○ Deploying a smart contract on the Ethereum mainnet means that it becomes part of the Ethereum
blockchain, and users can interact with it using real Ether.
What is a Contract in Solidity?
contract SimpleContract {
// State variable
uint256 public counter;
// Constructor (executed once during contract deployment)
constructor() {
counter = 0;
}
// Contract definition
contract SimpleSmartContract {
// State variables
○ Description: An external function can only be called from outside the contract.
External functions cannot be called internally or by other contracts.
○ Example:
// Function logic
● Private (private):
○ Description: A private function or state variable can only be accessed within the
current contract. It is not accessible by derived contracts or external contracts.
○ Example:
Variable names in Solidity, like in many programming languages, are used to identify
and reference different pieces of data. Some conventions for naming variables in
Solidity include:
1. Camel Case:
○ Example: myVariableName
2. Descriptive Names:
○ Use names that clearly describe the purpose of the variable.
○ Example: totalSupply, userAddress, contractOwner
3. Avoid Ambiguous Names:
○ Choose names that reduce the chances of confusion and ambiguity.
○ Example: Instead of temp, use a more descriptive name like
temporaryVariable.
4. Constants:
○ Use uppercase letters and underscores for constant variable names.
○ Example: MAX_SUPPLY, TOKEN_DECIMALS
Variable type initial default values
Solidity - Variable Scopes
In Solidity, variable scopes determine where a variable can be accessed and
modified within the code. Understanding variable scopes is crucial for writing secure
and efficient smart contracts. Here are the main variable scopes in Solidity:
1. Global Scope:
○ Definition: Variables declared outside any function or block have global
scope.
○ Accessibility: Global variables can be accessed and modified from
anywhere within the contract.
○ Example:
uint256 globalVariable;
● Example:
}
Block Scope:
if (someCondition) {
}
Constructor Scope:
● Example:
constructor() {
}
Parameter Scope:
● Example:
}
Abstract Contracts in Solidity
In Solidity, an abstract contract is a contract that cannot be instantiated on its own, and it serves as a blueprint for other
contracts. It can contain abstract functions that must be implemented by the contracts that inherit from it. Abstract
contracts are used to define common interfaces and ensure that certain functions are present in derived contracts
without providing the full implementation.
}
Abstract Functions:
}
Derived Contract Implementation:
● Contracts that inherit from an abstract contract must provide concrete implementations for all
abstract functions.
● Use the override keyword to indicate that a function in the derived contract is intended to
override an abstract function.
return 42;
}
Solidity Comments :
In Solidity, comments are annotations within the code that are not executed but provide additional
information to developers. Comments are essential for documenting code, making it more
readable, and helping others understand the logic and purpose of different parts of the codebase.
Solidity supports two types of comments: single-line comments and multi-line comments.
Single-Line Comments:
Single-line comments start with // and continue until the end of the line. Anything written after //
on that line is treated as a comment and is ignored by the Solidity compiler.
/*
This is a
multi-line comment
*/
contract MyContract {
/*
Function description:
*/
}
Solidity Address Type :
In Solidity, the address type is used to store Ethereum addresses. Ethereum addresses are
hexadecimal identifiers that represent user accounts or smart contracts on the Ethereum blockchain.
Solidity also has several address-related types and functions to interact with addresses. Here's a brief
overview:
1. Address Type:
○ Definition: The basic address type is address. It is 20 bytes long and represents an
Ethereum address.
○ Usage: Used to store Ethereum addresses of user accounts or smart contracts.
Example:
Example:
Address Members:
● Members: The balance and transfer members are associated with the address type.
● Usage:
○ balance: Returns the balance of the address in Wei.
○ transfer(uint256 amount): Sends a certain amount of Ether from one address to another.
Example:
recipient.transfer(1 ether);
}
● Address Payable:
○ Definition: The address payable type is an extension of the address type, allowing it to receive Ether and
interact with functions like transfer.
○ Usage: Used for variables and function parameters that can receive Ether.
Example:
address payable public receiver;
● Address Functions:
○ Functions: Solidity provides various functions and modifiers for working with addresses, such as msg.sender and
require.
○ Usage: Used for access control, authentication, and conditional execution based on the sender's address.
Example:
function onlyOwner() public view {
}
Solidity If Statement:
The if statement is used to execute a block of code if a specified condition evaluates to
true. If the condition is false, the block is skipped.
// Example of if statement
if (condition) {
}
Solidity if-else Statement :
In Solidity, as in many programming languages, the if and else statements are used for
conditional execution of code. These statements allow you to create branches in your code
based on specified conditions.
if Statement:
if (condition) {
} else {
}
Example:
/ SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract IfElseExample {
// State variable
value = newValue;
} else {
// Executed if the condition is false
value = 0;
}
}
}
Solidity if - else if - else conditional expressions
:
The if-else if-else statement allows you to test multiple conditions in a sequential manner.
Each condition is tested one by one, and the block of code associated with the first true condition is
executed. If none of the conditions are true, the else block (if provided) is executed.
if (condition1) {
} else if (condition2) {
} else {
}
Example :
// Solidity version declaration
pragma solidity ^0.8.0;
// Contract definition
contract ExampleIfElse {
// State variable
uint256 public age;
// Interface declaration
interface MyInterface {
}
Key Points:
In this example, the ERC20 interface declares the function signatures for standard ERC-20 token
functions such as totalSupply, balanceOf, transfer, allowance, approve, and
transferFrom. It also declares two events, Transfer and Approval. Contracts that claim to
implement this interface must provide actual implementations for all the functions declared in the
interface.
Loops In Solidity :
In Solidity, loops are used to execute a set of statements repeatedly until a specified condition is met.
Solidity supports two main types of loops: for and while.
For Loop:
The for loop is used when the number of iterations is known in advance. It consists of three parts:
initialization, condition, and iteration expression.
contract ForLoopExample {
sum = 0;
sum += i;
}
While Loop:
The while loop is used when the number of iterations is not known in advance, and the loop continues until a specified condition becomes false.
contract WhileLoopExample {
factorial = 1;
uint256 i = 1;
while (i <= n) {
factorial *= i;
i++;
}
Do-While Loop:
While Solidity doesn't have a native do-while loop, you can achieve similar functionality using a while loop
with an initial condition that always evaluates to true.
contract DoWhileLoopExample {
sum = 0;
uint256 i = 1;
do {
sum += i;
i++;
}
Solidity Constructor :
In Solidity, a constructor is a special function that is automatically executed only once when a smart contract is
deployed to the Ethereum blockchain. The constructor is used to initialize the state variables and perform any
one-time setup that needs to be done during contract deployment. It is defined using the constructor keyword.
contract MyContract {
// State variables
// Constructor
constructor(uint256 initialValue) {
// Initialization logic
myNumber = initialValue;
}
Key Points:
1. Declaration:
○ The constructor is declared with the constructor keyword.
○ It has the same name as the contract.
2. Execution:
○ The constructor is executed only once during the contract deployment.
○ It is responsible for initializing state variables and performing any necessary setup.
3. Arguments:
○ Constructors can take parameters, allowing external actors to pass initial values
during contract deployment.
○ Parameters are specified within the parentheses after the constructor keyword.
4. Initialization:
○ The constructor's body contains the initialization logic for state variables and any
other setup that should occur during deployment.
○ State variables can be assigned initial values within the constructor.
Example:
// Constructor
constructor(string memory _name, string memory _symbol, uint256 _totalSupply) {
// Initialization logic
name = _name;
symbol = _symbol;
totalSupply = _totalSupply;
owner = msg.sender; // Set the contract deployer as the owner
}
}
Constructor Inheritance in Solidity :
In Solidity, constructor inheritance refers to the way constructors are handled when a contract
inherits from another contract. When a derived contract inherits from a base contract, it may have
its own constructor, and it can choose to explicitly invoke the constructor of the base contract
during deployment. This process ensures that both the base and derived contracts perform their
initialization logic.
// Event declaration
}
Key Points:
1. Event Declaration:
○ Events are declared using the event keyword.
○ The event can have parameters, and these parameters define the data that
will be logged when the event is triggered.
2. Indexed Parameters:
○ You can specify certain parameters as indexed. Indexed parameters
allow efficient searching for specific values when querying logs.
3. Event Emission:
○ The emit keyword is used to trigger or emit an event.
○ Events are typically emitted within the functions of the smart contract
where a relevant state change occurs.
Example:
// Contract definition
contract EventExample {
// State variable
uint256 public counter;
// Event declaration
event IncrementEvent(address indexed _caller, uint256 _newValue);
When this contract is deployed and the incrementCounter function is called, it increments the
counter and triggers the IncrementEvent, logging the caller's address (msg.sender) and
the new value of the counter.
How to listen to events in Solidity?
Listening to events in Solidity is typically done using external applications, tools, or
libraries, rather than directly within Solidity code. In the context of decentralized
applications (DApps), front-end or back-end applications often listen for events
emitted by smart contracts to react to changes in the contract's state.
Example:
// Import web3.js library
const Web3 = require('web3');
// Connect to a local Ethereum node (you should replace this with your node's URL)
const web3 = new Web3('http://localhost:8545');
myContract.events.Transfer()
})
});
1. Import the web3.js library.
2. Connect to an Ethereum node using the Web3 constructor.
3. Specify the address and ABI of the deployed smart contract.
4. Create a contract instance using the smart contract's ABI and address.
5. Subscribe to the Transfer event using the events object on the contract instance.
6. Handle the data event when a new Transfer event is emitted by the smart contract.
Note:
● Make sure to replace http://localhost:8545 with the actual URL of your Ethereum
node.
● Replace the contractABI array with the ABI of your specific smart contract.
● The web3.js version and usage might vary depending on the version you are using.
Solidity - Functions in Smart Contracts
In Solidity, functions are units of code that perform specific tasks or operations within a smart contract.
Functions can be called by external actors, such as users or other contracts, to interact with the contract's
state and behavior.
Function Declaration:
// Function declaration
// Function logic
return arg1 * 2;
}
Key Points:
1. Visibility Modifiers:
○ Functions can have visibility modifiers (public, internal, external, or private)
to specify who can call them.
2. Function Name:
○ Functions have names that are used to identify and call them.
3. Parameters:
○ Functions can take parameters, which are input values provided when calling the
function.
4. Return Values:
○ Functions can return values, which represent the output or result of the function's
computation.
5. Function Modifiers:
○ Function modifiers (e.g., view, pure, payable) specify additional characteristics of
the function.
Examples:
// Function logic
// No return statement
// Function logic
return a + b;
}
3. Internal Function with Function Modifier:
// Function logic
}
Function Modifiers:
1. view and pure:
○ Use view for functions that do not modify state.
○ Use pure for functions that do not read or modify state.
// View function
function getBalance() public view returns (uint256) {
return address(this).balance;
}
// Pure function
function multiply(uint256 a, uint256 b) public pure returns (uint256) {
return a * b;
}
2. payable:
// Payable function
}
Function Overloading:
Solidity supports function overloading, allowing you to define multiple functions with the same name but
different parameter lists. Overloaded functions must have different parameter types or a different number
of parameters.
// Function overloading
contract ModifierExample {
address public owner;
In this example:
● The onlyOwner modifier checks if the caller of the function is the owner of the contract.
● The changeOwner function uses the onlyOwner modifier to restrict access to only the contract owner.
Fallback Function:
The fallback function is a special function that is executed when a contract receives Ether without any specific function call.
It is a way for a contract to handle unexpected or direct Ether transfers. The fallback function does not take any parameters
and is marked with the fallback keyword.
Example:
contract FallbackExample {
In this example:
● The receive function serves as the fallback function, and it is triggered when the contract receives Ether without a
specific function call.
● The external payable modifier indicates that the function can receive Ether.
Function visibility specifier
In Solidity, function visibility specifiers determine who is allowed to call a function. There are four visibility
specifiers: public, internal, external, and private. Each specifier has different access rules, and
the choice of visibility affects how functions can be accessed and by whom.
1. public:
Public functions can be called from anywhere, both within the contract and externally.
Example:
contract VisibilityExample {
uint256 public publicValue;
// Public function
function setPublicValue(uint256 newValue) public {
publicValue = newValue;
}
}
In this example, the setPublicValue function is declared as public, allowing external actors (other contracts or users)
to call it. The publicValue state variable is also marked as public, making it accessible from outside the contract.
2. internal:
Internal functions can only be called from within the current contract and its derived contracts.
Example:
contract VisibilityExample {
uint256 internalValue;
// Internal function
internalValue = newValue;
In this example, the setInternalValue function is marked as internal, making it accessible only from within the
current contract and any contracts that inherit from it.
3. external:
External functions can only be called from outside the current contract.
Example:
contract VisibilityExample {
uint256 externalValue;
// External function
externalValue = newValue;
In this example, the setExternalValue function is marked as external, making it accessible only from external
contracts or transactions. External functions cannot be called from within the contract itself.
private:
Private functions can only be called from within the current contract. They are not accessible from derived contracts
or external contracts.
Example:
contract VisibilityExample {
uint256 privateValue;
// Private function
privateValue = newValue;
In this example, the setPrivateValue function is marked as private, making it accessible only from within the current
contract. It is not visible to external contracts or derived contracts.
Solidity - Arrays in Smart Contracts
In Solidity, arrays are data structures that allow you to store and manipulate collections of elements of the
same data type. Solidity supports both fixed-size arrays and dynamic arrays.
Fixed-Size Arrays:
1. Declaration:
Fixed-size arrays have a predetermined size that cannot be changed after declaration.
2. Initialization:
Dynamic Arrays:
1. Declaration:
○ Dynamic arrays can change in size during execution.
dynamicArray.push(newValue);
3. Accessing Elements:
Elements in a dynamic array are accessed using their index.
The length of a dynamic array can be obtained using the length property.
Multi-dimensional Arrays:
In Solidity, multi-dimensional arrays are arrays of arrays, allowing you to create structures with multiple
dimensions. You can have arrays with two or more dimensions, and each dimension can have its own length.
Multi-dimensional arrays are particularly useful for representing grids, matrices, or other complex data
structures.
1. Declaration:
A multi-dimensional array is declared by specifying the size of each dimension.
2. Initialization:
Elements of a multi-dimensional array can be initialized during declaration.
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
3. Accessing Elements:
Elements in a multi-dimensional array are accessed using two indices.
contract MultiDimArrayExample {
// Two-dimensional array
uint256[][] public twoDimArray;
return twoDimArray[row][col];
In this contract:
Operators in Solidity are symbols or keywords that perform operations on variables and values. Solidity
supports a variety of operators, including arithmetic operators, comparison operators, logical operators,
and assignment operators. Here's a brief explanation of some common operators with examples:
Arithmetic Operators:
1. Addition (+):
2. Subtraction (-):
4. Division (/):
5. Modulus (%):
2. Inequality (!=):
Returns true if both the left and right operands are true.
2. Logical OR (||):
1. Assignment (=):
○ Assigns the value on the right to the variable on the left.
uint256 x = 10;
uint256 x = 5;
x += 3; // x is now 8
uint256 x = 10;
x -= 4; // x is now 6
Solidity - Enumerations (Enums)
In Solidity, enumerations, often referred to as enums, are user-defined data types that allow
developers to create a set of named values. Enums are useful for representing a finite set of possible
states or options within a contract. Each value in an enum is assigned an integer value starting from
zero, and these values are used as identifiers.
Enum Declaration:
Enums are declared using the enum keyword, followed by the name of the enumeration and a list of possible values.
// Enum declaration
enum Status {
Pending,
Approved,
Rejected
}
In this example, we have an enum named Status with three possible values: Pending, Approved, and Rejected. By
default, these values are assigned integer values starting from zero (Pending is 0, Approved is 1, and Rejected is 2).
Using Enums in Contracts:
Enums can be used within contracts to define variables and function parameters with the enum type.
contract DocumentApproval {
// Enum declaration
enum Status {
Pending,
Approved,
Rejected
}
● The DocumentApproval contract contains an enum named Status with the possible states of a document: Pending,
Approved, and Rejected.
● The contract includes a Document struct with a field for the document name and a field of the Status enum type to
represent the status of the document.
● The contract uses a mapping to associate each document ID with its corresponding Document struct.
● The updateDocumentStatus function allows changing the status of a document by providing the document ID and the
new status from the Status enum.
In this example, a public string variable named greeting is declared and initialized with the value "Hello,
World!".
Concatenation:
Solidity does not directly support string concatenation. However, you can use the abi.encodePacked function to
concatenate strings.
You can obtain the length of a string using the bytes type, which represents the raw bytes of the string.
In this example, messageLength will be the number of bytes in the string "Greetings!".
Solidity - Structs
Structs are used to represent the object or classes in java, interface, and
classes in typescript.
Struct Initialization:
Struct Operations:
Struct Arrays:
In Solidity, you declare a mapping by specifying the key and value types within the
mapping keyword.
You can also declare mappings with other data types as keys or values, and even use more
complex data structures as values. For instance:
How to add values to Mapping in solidity?
In Solidity, you can add values to a mapping by assigning a value to a specific key using the
square bracket notation.
In this example:
You can then call the setBalance function to add or update balances for different
addresses:
After calling the setBalance function, the balances mapping will contain the
assigned values for the corresponding addresses.
Solidity - Memory VS Storage
Storage:
Currency Units: