1 of 45

1

Programming in Solidity

Blockchain Technologies

Lecture # 06

2 of 45

Introduction

  • Solidity is an object-oriented, high-level language for implementing smart contracts.
  • Smart contracts are programs which govern the behaviour of accounts within the Ethereum state.
  • Solidity is statically typed, supports inheritance, libraries and complex user-defined types among other features.
  • With Solidity you can create contracts for uses such as voting, crowdfunding, blind auctions, and multi-signature wallets.

2

3 of 45

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.

3

4 of 45

  • Contracts in Solidity are similar to classes in object-oriented languages.
  • They contain persistent data in state variables, and functions that can modify these variables.
  • Contracts can be created “from outside” via Ethereum transactions or from within Solidity contracts.
  • A contract can have multiple functions of the same name but with different parameter types. This process is called “overloading” and also applies to inherited functions. 
  • Solidity supports multiple inheritance including polymorphism.

4

5 of 45

A Simple Smart Contract

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.4.16 <0.7.0;

contract SimpleStorage {

uint storedData;

function set(uint x) public {

storedData = x;

}

function get() public view returns (uint) {

return storedData;

}

}

5

6 of 45

  • Pragmas are common instructions for compilers about how to treat the source code
  • A contract in the sense of Solidity is a collection of code (its functions) and data (its state) that resides at a specific address on the Ethereum blockchain.

6

7 of 45

Importing files

  • Solidity supports import statements that are very similar to those available in JavaScript.
  • import "filename";
  • import * as symbolName from "filename";

7

8 of 45

8

9 of 45

Compiling a contract using Remix IDE

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;

}

}

9

10 of 45

Steps

  • Step 1 - Copy the given code in Remix IDE Code Section
  • 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

10

11 of 45

Structure of a contract

  • Contracts in Solidity are similar to classes in object-oriented languages.
  • Each contract can contain declarations of State Variables, Functions, Function Modifiers, Events, Struct Types and Enum Types.
  • Furthermore, contracts can inherit from other contracts.

11

12 of 45

Variables

  • While writing program in any language, you need to use various variables to store various information.

12

13 of 45

Types of 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.

13

14 of 45

State Variables

  • State variables are variables whose values are permanently stored in contract storage.

pragma solidity ^0.5.0;

contract SolidityTest {

uint storedData; // State variable

constructor() public {

storedData = 10;

// Using State variable

}

}

14

15 of 45

Local Variables

  • Variables whose values are available only within a function where it is defined. Function parameters are always local to that function.

15

16 of 45

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 result; //access the local variable

}

}

16

17 of 45

Global variables

  • These are special variables which exist in global workspace and provide information about the blockchain and transaction properties.

17

18 of 45

18

19 of 45

Scope of variable

  • 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.

19

20 of 45

Operators

  • Arithmetic operators
  • Comparison operators
  • Logical operators
  • Bitwise operators
  • Assignment operators
  • Conditional operators

20

21 of 45

Strings

pragma solidity ^0.5.0;

contract SolidityTest {

bytes32 data = "test";

}

  • Escape sequence

21

22 of 45

Loops

  • While loop

while (expression) {

Statement(s) to be executed if expression is true

}

  • Do while loop

do {

Statement(s) to be executed;

} while (expression);

22

23 of 45

Loops – contd…

  • For loop

for (initialization; test condition; iteration statement) {

Statement(s) to be executed if test condition is true

}

  • Break statement

23

24 of 45

Conditions

  • It is used to make a decision whether the statement or block of code will be executed or not. If the condition is true the statements will be executed, else no statement will execute.

if (expression) {

Statement(s) to be executed if expression is true

}

24

25 of 45

Arrays

  • uint balance[10];

  • uint size = 3;
  • uint balance[] = new uint[](size);
  • 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.
  • pop - Pop is used when the last element of the array is to be removed in any dynamic array.

25

26 of 45

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.

26

27 of 45

Example

address x = 0x212;

address myAddress = this;

if (x.balance < 10 && myAddress.balance >= 10)

x.transfer(10);

27

28 of 45

Functions

  • Functions are the executable units of code within a contract.

function bid() public payable { // Function

// ...

}

28

29 of 45

Struct

  • Structs are custom defined types that can group several variables

struct Voter { // Struct

uint weight;

bool voted;

address delegate;

uint vote;

}

29

30 of 45

Example

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;

}

}

30

31 of 45

Enum types

  • Enums can be used to create custom types with a finite set of ‘constant values’

enum State { Created, Locked, Inactive } // Enum

31

32 of 45

Example

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);

}

}

32

33 of 45

Mapping

  • Mapping is a reference type as arrays and structs.
  • Following is the syntax to declare a mapping type.
    • mapping(_KeyType => _ValueType)

33

34 of 45

Example

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));

}

}

34

35 of 45

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);

35

36 of 45

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);

36

37 of 45

Require

  • The require statements declare prerequisites for running the function i.e. it declares the constraints which should be satisfied before executing the code.
  • require(condition,"Error Message");

function requireStatement(uint _input) public view returns(string memory){

require(_input >= 0, "invalid uint8");

require(_input <= 255, "invalid uint8");

return "Input is Uint8";

}

37

38 of 45

Revert

  • This statement is similar to the require statement. It does not evaluate any condition and does not depends on any state or statement. It is used to generate exceptions, display errors, and revert the function call.

if (sum < 0 || sum > 255) {

revert(" Overflow Exist");

} else {

return ("No Overflow", sum);

}

38

39 of 45

Constructor

  • A contract can have only one constructor.
  • A constructor code is executed once when a contract is created and it is used to initialize contract state.

constructor() <Access Modifier> {

}

39

40 of 45

Inheritance

  • Solidity supports inheritance between smart contracts, where multiple contracts can be inherited into a single contract.

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

// Defining contract

contract parent {

uint256 internal sum;

function setValue() external {

uint256 a = 10;

uint256 b = 20;

sum = a + b;

}

}

40

41 of 45

// Defining child contract

contract child is parent {

function getValue() external view returns (uint256) {

return sum;

}

}

// Defining calling contract

contract caller {

child cc = new child();

// Defining function to call setValue and getValue functions

function testInheritance() public returns (uint256) {

cc.setValue();

return cc.getValue();

}

}

41

42 of 45

Events

  • Events are convenience interfaces with the EVM logging facilities.

event HighestBidIncreased(address bidder, uint amount); // Event

42

43 of 45

Example

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.7;

contract MyContract {

event transaction(address payable, uint256);

function sendEther(address payable to) public payable {

to.transfer(msg.value);

emit transaction(to,msg.value);

}

}

43

44 of 45

Library

  • A library in Solidity is a different type of smart contract that contains reusable code. Once deployed on the blockchain (only once), it is assigned a specific address and its properties / methods can be reused many times by other contracts in the Ethereum network.

pragma solidity ^0.5.0;

library libraryName {

// struct, enum or constant variable declaration

// function definition with body

}

44

45 of 45

Example

pragma solidity ^0.8.7;

library MathLib {

struct MathConstant {

uint Pi; // π (Pi) ≈ 3.1415926535...

uint Phi; // Golden ratio ≈ 1.6180339887...

uint Tau; // Tau (2pi) ≈ 6.283185...

uint Omega; // Ω (Omega) ≈ 0.5671432904...

uint ImaginaryUnit; // i (Imaginary Unit) = √–1

uint EulerNb; // Euler number ≈ 2.7182818284590452...

uint PythagoraConst; // Pythagora constant (√2) ≈ 1.41421...

uint TheodorusConst; // Theodorus constant (√3) ≈ 1.73205...

}

function multiply(uint a, uint b) public view returns (uint, address) {

return (a * b, address(this));

}

}

45