Smart Contracts

Introduction to Solidity

@tomusdrw

Tomasz Drwięga

Parity Technologies

Disclaimer

Any code presented on those slides is here only for educational purposes and is NOT production ready.

The code was not audited or tested properly and most probably doesn't work.

Never use it with real ETH.

Smart Contracts

Nick Szabo, 1994

"A smart contract is a
computerized transaction protocol that executes the terms of a contract.
The general objectives are to satisfy common contractual conditions (such as payment terms, liens, confidentiality, and even enforcement), minimize exceptions both malicious and accidental, and minimize the need for trusted intermediaries.
Related economic goals include lowering fraud loss, arbitrations and enforcement costs, and other transaction costs."

Smart Contracts

A decentralized program that controls money

and acts according to programmed rules without a trusted 3rd party.

Solidity

pragma solidity ^0.4.11;

contract Burn {
    uint256 public value;
    address public owner;
    
    function Burn() payable {
        value = msg.value;
        owner = msg.sender;
    }
}

A high-level "JavaScript-like" contract-oriented language compiled to EVM bytecode.

Compile Program:
Solidity -> EVM

Run Program:
Transactions (ABI + RLP)

Smart Contracts @ Ethereum

pragma solidity ^0.4.11;

contract Parity {
    uint256 public value;
    address public owner;
    
    function export() payable {
        value += msg.value;
        owner = msg.sender;
    }
}
0xc0de15de4d... at 0x123..456
binary at /usr/bin/parity
$ parity export blocks
from:      0x456..def
to:        0x123..456
value:     5 * 10^18 wei (5 ETH)
gas:       100,000
gasPrice:  4 * 10^9 wei (4 shannon)
nonce:     0
data:      0x444...
           ("call function export")


0x123456... (Transaction RLP)

Lock ether

(Forever)

pragma solidity ^0.4.11;

contract Burn {
    uint256 public value;
    address public owner;
    
    function Burn() payable {
        value = msg.value;
        owner = msg.sender;
    }
}

Lock ether

(For some time)

contract Lock {
    uint256 public value;
    address public owner;
    
    function Lock() payable {
        value = msg.value;
        owner = msg.sender;
    }

    function withdraw() {
        if (msg.sender != owner) {
            throw;
        }
        
        msg.sender.transfer(value);
    }
}

Lock ether

(For some time + modifier)

pragma solidity ^0.4.11;

contract Lock {
    uint256 public value;
    address public owner;

    modifier onlyOwner() {
        if (msg.sender != owner) throw;
        _;
    }
    
    function Lock() payable {
        value = msg.value;
        owner = msg.sender;
    }

    function withdraw() onlyOwner {
        msg.sender.transfer(value);
    }
}

Lock ether

(For some predefined time)

contract Lock {
    uint256 public value;
    address public owner;
    uint256 public lockedUntil;

    modifier onlyOwner() {
        if (msg.sender != owner) throw;
        _;
    }
    
    function Lock() payable {
        value = msg.value;
        owner = msg.sender;
        lockedUntil = now + 5 days;
    }

    function withdraw() onlyOwner {
        if (block.timestamp < lockedUntil) {
            throw;
        }
        msg.sender.transfer(value);
    }
}

Ok, but how to develop or run the contracts?

Browser Solidity / Remix

https://ethereum.github.io/browser-solidity/

 

Truffle

https://github.com/trufflesuite/truffle

Title Text

contract Lock {
    struct LockedFunds {
        uint256 value;
        uint256 until;
    }
    
    mapping(address => LockedFunds) public locked;

    function lock() payable {
        locked[msg.sender].value = msg.value;
        locked[msg.sender].until = block.number + 5;
    }
    
    function unlock() {
        var data = locked[msg.sender];
        if (data.value == 0) throw;
        if (block.number < data.until) throw;
        
        delete locked[msg.sender];
        msg.sender.transfer(data.value);
    }
}

MultiLock

(For some predefined time in blocks)

Title Text

contract Lock {
    struct LockedFunds { uint256 value; uint256 until; }
    
    address public owner;
    mapping(address => LockedFunds) public locked;
    
    function Lock() { owner = msg.sender; }

    function lock() payable {
        locked[msg.sender].value = msg.value;
        locked[msg.sender].until = block.number + 5;
    }
    
    function unlock() {
        var data = locked[msg.sender];
        if (data.value == 0) throw;
        if (block.number < data.until) throw;
        
        delete locked[msg.sender];
        msg.sender.transfer(data.value);
    }
    
    function withdraw() {
        if (msg.sender != owner) throw;
        
        owner.transfer(this.balance);
    }
}

MultiLock with fuse

(For some predefined time in blocks)

Multilock

did you spot any bugs in the code?

Title Text

contract Lock {
    struct LockedFunds { uint256 value; uint256 until; }
    
    address public owner;
    mapping(address => LockedFunds) public locked;
    
    function Lock() { owner = msg.sender; }

    function lock() payable {
        // make sure to increment value here otherwise the funds are lost!
        locked[msg.sender].value += msg.value;
        locked[msg.sender].until = block.number + 5;
    }
    function unlock() {
        // copy the structure to memory
        LockedFunds memory data = locked[msg.sender];
        if (data.value == 0) throw;
        if (data.until < block.number) throw;
        
        delete locked[msg.sender];
        msg.sender.transfer(data.value);
    }

    function withdraw() {
        if (msg.sender != owner) throw;

        owner.transfer(this.balance);
    }
}

MultiLock with fuse

(For some predefined time in blocks)

Title Text

pragma solidity ^0.4.21;
contract Lock {
    struct LockedFunds { uint256 value; uint256 until; }
    address public owner;
    mapping(address => LockedFunds) public locked;
     
    // Declare an event
    event FundsLocked(address indexed sender, uint256 value);
    
    function Lock() public { owner = msg.sender; }

    function lock() public payable {
        locked[msg.sender].value += msg.value;
        locked[msg.sender].until = block.number + 5;
        
        // emit an event
        emit FundsLocked(msg.sender, locked[msg.sender].value);
    }
    function unlock() public {
        LockedFunds memory data = locked[msg.sender];
        require(data.value != 0);
        require(data.until >= block.number);
        delete locked[msg.sender];
        msg.sender.transfer(data.value);
    }

    function withdraw() public {
        require(msg.sender == owner);
        owner.transfer(this.balance);
    }
}

Events

Smart Contracts (part 1)

By Tomasz Drwięga

Smart Contracts (part 1)

  • 589