Solidity - Getting Started

Solidity

Solidity is high-level language to create smart contracts on Ethereum blockchain.

  • Smart contracts are programs which govern the behavior of accounts within the Ethereum state.

  • Solidity was influenced by C++, Python and JavaScript and is designed to target the Ethereum Virtual Machine (EVM).

  • Solidity is statically typed, supports inheritance, libraries and complex user-defined types among other features.

Install solidity

npm install solc -g

Structure of Solidity File

Pragma

Pragma declares which version of Solidity compiler the code should use to prevent issues with future compiler versions potentially introducing changes that could break your code.

pragma solidity ^0.4.19;

Import

Import statements help modularize the code.

import "github.com/ethereum/dapp-bin/library/iterable_mapping.sol" as it_mapping;

Contract

Contracts in Solidity are similar to classes in object-oriented languages.

contract ZombieFactory {
//..
}

Events

Events lets app’s front-end know that something happened on the blockchain, like 'listening' for certain events and take action when they happen. Like, in this case, zombie was created, so the app can display it.

  • Events provide return values from smart contracts to UI.

  • Also provides notifications when transactions are complete because they are not emitted until the transaction has been successfully mined.

  • Can act as a cheaper form of storage.

  • Can be used for debugging purposes during development.

event NewZombie(uint zombieId, string name, uint dna);

State Variables

State Variables (variables declared outside of functions) are permanently stored in contract storage (written to the Ethereum blockchain).

Variables declared inside functions are stored in memory that disappear when function call ends.

contract ZombieFactory {
uint dnaDigits = 16; // State Variable
uint dnaModulus = 10 ** dnaDigits; // State Variable
}

Struct

Structs allow you to create more complicated data types that have multiple properties.

  • Struct - Custom data type with group of variables

  • Enum - Custom data type with group of constants

struct Zombie {
string name;
uint dna;
}

Enum Types

Enums helps to create custom types with finite set of ‘constant' values.

enum State { Active, Paused, Inactive } // Enum

Array

Array allows you to create a collection of something.

  • Fixed - uint[2]

  • Dynamic - uint[]

Zombie[] public zombies;

Mapping

Mapping is needed to create key-value pairs like in hash tables. Mappings are another way of storing organized data in Solidity like arrays.

mapping (uint => address) public zombieToOwner;
mapping (address => uint) ownerZombieCount;

Functions

Functions are executable units of code within a contract.

  • Naming functions with underscore (_), identifies them as private functions.

  • Naming parameter variable with underscore (_) differentiate them from global variables.

  • In Solidity, functions are public by default. That means anyone (or any other contract) can call your contract's function and execute its code. Therefore they need to be made private (where necessary).

function _createZombie(string _name, uint _dna) private {

Types of functions

  • Public (default)

    • No restriction

  • External

    • Only accessible from outside the contract (unless you use this)

  • Private

    • Only accessible from current contract

  • Internal

    • Accessible by current and all derived contracts

  • Constant / View

    • Just reads from blockchain

    • Doesn’t modify any state of contract

    • No gas cost, free to executex

  • Pure

    • Do not read or modify the state

  • Payable

    • To receive ether

Function Modifiers

Modifiers can be used to change the behavior of functions in a declarative way. For example, you can use a modifier to automatically check a condition prior to executing the function.

Elementary (value) Types

Boolean

bool: The possible values are constants true and false.

Operators:

  • ! (logical negation)

  • && (logical conjunction, “and”)

  • || (logical disjunction, “or”)

  • == (equality)

  • != (inequality)

Integer (int and uint 256 bits)

int / uint: Signed and unsigned integers of various sizes. Keywords uint8 to uint256 in steps of 8 (unsigned of 8 up to 256 bits) and int8 to int256. uint and int are aliases for uint256 and int256, respectively.

Operators:

  • Comparisons: <=, <, ==, !=, >=, > (evaluate to bool)

  • Bit operators: &, |, ^ (bitwise exclusive or), ~ (bitwise negation)

  • Shift operators: << (left shift), >> (right shift)

  • Arithmetic operators: +, -, unary -, *, /, % (modulo), ** (exponentiation)

Address

Address is a 20 byte value with member functions.

  • Balance

  • Transfer

  • Send

  • Call

  • Callcode - use delegateCall() instead

  • Delegatecall

Types of addresses

  • address: Holds a 20 byte value (size of an Ethereum address). Ether cannot be sent to this address.

  • address payable: Same as address, but with the additional members transfer and send. Ether can be sent to this address.

Ether Units

A literal number can take a suffix of wei, finney, szabo or ether to specify a subdenomination of Ether, where Ether numbers without a postfix are assumed to be Wei.

  • assert(1 wei == 1);

  • assert(1 szabo == 1e12);

  • assert(1 finney == 1e15);

  • assert(1 ether == 1e18);

Libraries & Ethereum Package Manager

Library

Exploits and DangersLibraries are contracts that do not have storage.

  • They cannot hold ether.

  • They cannot inherit or be inherited by other contracts.

Ethereum Package Manager

EthPM is npm for Ethereum contracts.

truffle install <package name>

Exploits and Dangers

Reentrancy

  • One of the major dangers of calling external contracts is that they can take over the control flow, and make changes to your data.

  • Attacker can call functions repeatedly before first invocation of the function is finished. This is what caused the DAO attack.

Prevention

Don't call external function until all internal work is done.

Cross function reentrancy

  • Reentrancy that can occur across multiple functions.

Prevention

Don't call external function until all internal work is done.

Transaction Ordering and Timestamp Dependence

  • Transactions broadcasted to the network but not yet included in a block are in the mempool.

  • Since transactions are in the mempool before they make it into a block, anyone can know what transactions are about to occur on the network.

Prevention

  • In exchanges, use batch auctions (also prevents across high frequency trading).

  • Use pre-commit scheme.

Integer Overflow and Underflow

  • Overflow - If a balance reaches the maximum uint value (2^256) it will circle back to zero.

  • Underflow - If a uint is made to be less than zero, it will cause an underflow and get set to its maximum value

Prevention

Make sure they don’t reach their maximum value.

Denial of Service

  • Another danger of passing execution to another contract is a denial of service attack.

  • For example, iterating through array to pay multiple users can cause whole payout system to fail if one address is forcing an error.

Prevention

Use pull over push payments.

Force Sending Ether

  • Another danger is using logic that depends on the contract balance.

  • Attacker can use selfdestruct function; will force the destroyed contract’s funds to be sent to the target.

Prevention

Add contract logic to prevent this.