Blockchains

Tomasz Drwięga

@tomusdrw

Parity Technologies

How do they work?

Agenda

Part 1: Blocks & Transactions

  • What is blockchain?
  • JSON-RPC APIs
  • rust-web3

Part 2: Smart Contracts

  • Writing contracts in Solidity
  • Smart Contract Events
  • ETHABI

What is Blockchain?

  • Distributed data structure - to organize "transactions"/events
  • Consensus Algorithm - to decide who is allowed to modify that structure
  • Some crypto - to make it secure/tamperproof
  • Incentives - to make it run by itself

List of changes

List of changes

List of changes

Metadata

/ Previous state

Metadata

/ Previous state

Metadata

/ Previous state

Genesis State

Blockchain

Immutable data structure containing all the changes that were applied in any point in time

Blockchain

Hashes - prevent tampering (e.g. KECCAK256)

Signatures - authorize the actions (e.g. ECDSA)

Parent = hash(B0)
Timestamp = 150..000
Number = 1
Hash = hash(B1)
transfer(A, B, 5)
sig(A)
transfer(C, B, 1)
sig(C)
Parent = hash(B2)
Timestamp = 150..000
Number = 2
Hash = hash(B1)
transfer(B, A, 5)
sig(B)

Consensus Algorithm

Who is allowed to create new blocks?

sig(Authority1)
hash(B0)
hash(B1)
sig(Authority2)
hash(B2)
sig(Authority1)

Proof of Authority

We only accept blocks signed by a hardcoded list of authorities.

Blocks need to be signed in turns at most 1 block per 3 seconds.

Consensus Algorithm

Who is allowed to create new blocks?

Difficulty=2
Sol.=0b001..
SolvedBy=A
hash(B0)
hash(B1)
hash(B2)

Proof of Work

We only accept blocks with a solution to a puzzle.

The difficulty of the puzzle can be adjusted to have a stable rate of new blocks.

Difficulty=4
Sol.=0b00001..
SolvedBy=B
Difficulty=3
Sol.=0b0001..
SolvedBy=A

Why would you waste energy to create new blocks?

It's incentivised

=

You get a reward

How does it work?

(Boot) Node 1

Node 2

New Node

Hey! Could you give me all your peers?

How does it work?

(Boot) Node 1

Node 2

New Node

Hey! Send me all them blocks, will ya?

Block 5

Block 4

Block 0

How does it work?

(Boot) Node 1

Node 2

New Node

Hey! I've got a transaction to include in block.

Block 5

Block 5

Block 5

transfer(N, B, 5)
sig(N)

How does it work?

(Boot) Node 1

Node 2

New Node

Block 5

Block 5

Block 5

transfer(N, B, 5)
sig(N)
transfer(N, B, 5)
sig(N)

Cool, I'm mining and will include the tx for a small fee.

How does it work?

(Boot) Node 1

Node 2

New Node

Block 6

Block 5

Block 5

transfer(N, B, 5)
sig(N)
transfer(N, B, 5)
sig(N)
Block 6

Managed to mine new block, here it is guys!

How does it work?

(Boot) Node 1

Node 2

New Node

Block 6

Block 6

Block 6

Canonical Chain

What if two different blocks are produced with the same parent hash?

Which one should you choose?

Block 1

Block 2

Block 3

Block 3

Fork

Canonical Chain

We use "the longest" chain.

Ethereum re-organizes to a chain with the highest difficulty.

Block 1

Block 2

Block 3

Block 3

Block 4

Take away note: The latest state you see can sometimes be reverted - wait for confirmations.

What is Bitcoin?

Bitcoin is the first public blockchain ever.

Block Time 10 minutes
Consensus Proof of Work - hashcash
State Account Balances of BTC / UTXO*
Transactions Value Transfers*
Launched 2009
Block Reward 12BTC (halving) ~ 21M total coins

What is Ethereum?

Ethereum is the World Computer

Block Time 14 seconds
Consensus Proof of Work - ethash*
State Arbitrary
Transactions Turing-complete / programmable
Launched 2015
Block Reward 5ETH (+uncles) ~ Unlimited coins

Questions?

Blockchains allow for trustless transactions between multiple parties.

List of important words

  • Genesis Block
  • Blockchain
  • Protocol
  • Consensus
  • Incentives
  • Miner
  • Hashing Power
  • Hard/Soft Fork
  • Canonical Chain
  • Chain re-org
  • Decentralization
  • Distributed Ledger
  • Bitcoin
  • UTXO
  • Ethereum / EVM
  • Smart Contracts
  • Altcoins
  • Tokens
  • Fiat currency

How to query the blockchain?

Running the node

$ parity ui --chain=dev --mode=offline --ws-origins=all
# or 
$ parity ui --chain=dev --network-id=<random-number> --ws-origins=all


$ cd ~/.local/share/io.parity.ethereum/dapps
# ~/Library/Application Support/io.parity.ethereum/dapps
# %AppData%\Parity\Ethereum\dapps
$ git clone --depth=1 -b built https://github.com/tomusdrw/etherdisplay

JSON-RPC

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "eth_getBlockByNumber",
  "params": ["latest", false]
}
# apt install httpie
$ http localhost:8545 jsonrpc=2.0 id=1 method=eth_getBlockByNumber params:='["latest",false]'

# Or with CURL
$ curl localhost:8545 -H "Content-Type:application/json" -X POST --data \
  '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockByNumber","params":["latest",false]}'
{
    "id": 1, 
    "jsonrpc": "2.0", 
    "result": {
        "author": "0x05a56e2d52c817161883f50c441c3228cfe54d9f", 
        "difficulty": "0x3ff800000", 
        "extraData": "0x476574682f76312e302e302f6c696e75782f676f312e342e32", 
        "gasLimit": "0x1388", 
        "gasUsed": "0x0", 
        "hash": "0x88e96d4537bea4d9c05d12549907b32561d3bf31f45aae734cdc119f13406cb6", 
        "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", 
        "miner": "0x05a56e2d52c817161883f50c441c3228cfe54d9f", 
        "mixHash": "0x969b900de27b6ac6a67742365dd65f55a0526c41fd18e1b16f1a1215c2e66f59", 
        "nonce": "0x539bd4979fef1ec4", 
        "number": "0x1", 
        "parentHash": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", 
        "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 
        "sealFields": [
            "0xa0969b900de27b6ac6a67742365dd65f55a0526c41fd18e1b16f1a1215c2e66f59", 
            "0x88539bd4979fef1ec4"
        ], 
        "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", 
        "size": "0x219", 
        "stateRoot": "0xd67e4d450343046425ae4271474353857ab860dbc0a1dde64b41b5cd3a532bf3", 
        "timestamp": "0x55ba4224", 
        "totalDifficulty": "0x7ff800000", 
        "transactions": [], 
        "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", 
        "uncles": []
    }
}

Documentation of all methods:

https://github.com/paritytech/parity/wiki/JSONRPC-eth-module

JSON-RPC

Some useful methods for today.

// Returns a block data 
// and transactions in it
eth_getBlockByNumber(
    <block-number>,
    <include-transactions>,
);


// Returns a balance of an account.
eth_getBalance(
    <address>,
);

Smart Contracts

Solidity

Smart Contract is like an agent behind a regular address.

pragma solidity ^0.4.11;

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

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

(For some time)

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

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

Lock ether

(For many users)

pragma solidity ^0.4.17;
contract Lock {

    mapping(address => uint256) public locked;

    function lock() public payable {
        locked[msg.sender] = msg.value;
    }
    
    function unlock() public {
        var value = locked[msg.sender];
        require(value != 0);
        
        delete locked[msg.sender];
        msg.sender.transfer(value);
    }
}

Can you spot a bug in this contract?

Title Text

contract SimpleToken { // TODO Use SafeMath!
    uint256 constant rate = 1000;
    event Transfer(address indexed _from, address indexed _to, uint _value);
    
    uint256 public totalSupply;
    mapping(address => uint256) public balanceOf;
    mapping(address => uint256) public lockTime;

    function buyTokens() payable {
        var tokens = msg.value * rate;
        var unlockAt = block.number + 256 * 24; // 24h

        totalSupply += tokens;
        balanceOf[msg.sender] += tokens;
        lockTime[msg.sender] = unlockAt;
    }
    function burnTokens(uint256 _value) {
        var tokens = _value * rate;
        require(block.number >= lockTime[msg.sender]);
        require(balanceOf[msg.sender] >= tokens);
        
        balanceOf[msg.sender] -= tokens;
        totalSupply -= tokens;
        delete lockTime[msg.sender];
        
        msg.sender.transfer(_value);
    }
    function transfer(address _to, uint _value) returns (bool success) {
        if (block.number < lockTime[msg.sender]) return false;
        if (balanceOf[msg.sender] < _value) return false;
        if (_value == 0 || balanceOf[_to] + _value <= balanceOf[_to]) return false;
        
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
        
        Transfer(msg.sender, _to, _value);
        
        return true;
    }
}

Token Contract

Token Standard (ERC20)

https://theethereum.wiki/w/index.php/ERC20_Token_Standard

// https://github.com/ethereum/EIPs/issues/20
contract ERC20 {
    function totalSupply()
        constant returns (uint totalSupply);
    function balanceOf(address _owner)
        constant returns (uint balance);
    function transfer(address _to, uint _value)
        returns (bool success);
    function transferFrom(address _from, address _to, uint _value)
        returns (bool success);
    function approve(address _spender, uint _value)
        returns (bool success);
    function allowance(address _owner, address _spender)
        constant returns (uint remaining);

    event Transfer(
        address indexed _from, address indexed _to, uint _value
    );
    event Approval(
        address indexed _owner, address indexed _spender, uint _value
    );
}

Remote Purchase

Done wrong

contract Purchase {
    uint public value;
    address public seller;
    address public buyer;
   
    function Purchase(uint _value) {
        seller = msg.sender;
        value = _value;
    }

    /// Confirm the purchase as buyer.
    function confirmPurchase() payable {
        require(msg.value == value);
        buyer = msg.sender;
    }
    
    /// Confirm that you (the buyer) received the item.
    function confirmReceived() {
        require(msg.sender == buyer);
        seller.transfer(this.balance);
    }
}

Safe Remote Purchase

(Simplified)

contract Purchase {
    uint public value;
    address public seller;
    address public buyer;
   
    // Seller needs to deposit double the value of the item.
    function Purchase() payable {
        seller = msg.sender;
        value = msg.value / 2;
        require(value * 2 == msg.value);
    }
    
    function abort() {
        require(msg.sender == seller);
        require(buyer == 0);
        seller.transfer(this.balance);
    }

    /// Confirm the purchase as buyer. Deposit double the value of the item.
    function confirmPurchase() payable {
        require(msg.value == 2 * value);
        buyer = msg.sender;
    }
    
    /// Confirm that you (the buyer) received the item.
    function confirmReceived() {
        require(msg.sender == buyer);
        buyer.transfer(value); // transfer half of the deposit
        seller.transfer(this.balance); // transfer the entire deposit
        delete value;
    }
}

Commit-Reveal pattern

  • Auction has 2 phases: commit and then reveal
  • First you commit the price you want to pay as sha3(price + somestring) and you lock funds > price
  • Then you reveal somestring:
    • if it's incorrect you loose the deposit
    • otherwise you are the highest bidder or you get your deposit back

How to do a blind auction?

Project-specifics

Blockchains + mobile

Not really working that well currently, reading state of the blockchain is difficult.

Most likely we will need a "centralized" server anyway.

(Good thing being is that we can provide some proofs that the data has not been tampered)

  • Public blockchains are expensive - you need to minimize the data you store there
  • People will loose private keys - need to handle that
  • Public blockchains operate using it's own currency - you need to use exchanges

Public Chains

Good:

  • Interoperability - the tokens are tradeable, but they should have some value
  • Anyone can easily join the system
  • Good for inter-op between known parties
  • Shared infrastructure, but tamper-proof
  • Everyone can read, write access can be controlled on-chain
  • Configurable (block time, block size, empty blocks, etc).
  • No need for internal currency (no fees)

Consortia Chains

Parity-specific technology. Allows to securely store sensitive/encrypted data and give access only to specific parties.

Secret Store

Example: Company A stores a document. Access to the document is given to Company B. B can fetch the document and decrypt it using some fancy math.

(NOTE: A does not need to provide the same document encrypted specifically for B!)

Identity

  • On the blockchain we store encrypted "claims".
  • Each claim has different encryption key.
  • User can share decryption key with a company.
  • Additionally the data can be signed to make sure it's valid.
    (i.e. name, age and nationality confirmed by someone who saw the actual ID)
  • (We can either sign data before encryption or after - gives different guarantees)
  • Claims can be less specific and can have expirtaion i.e:
    • User is a Biker
    • User is below 40

Identity (2)

  • User can delete the data at any point.
  • This should inform parties using it that they are not allowed to store the data any more.
  • Alternatively user can list (3rd) parties that are allowed to read data

Loyalty

  • Coins issued by authorized ServiceProviders
  • We store:
    • number of coins user currently have
    • number of coins issued for this user by each SP
  • User can spend their coins however they like
  • SP can give them coin-discount in case the user has historically more than x-coins issued by this SP

Loyalty

Example:

  • User has 5 spendable coins
  • But she already got 100 coins from Hotel A in the past.
  • Hotel A gives User a coffee for 3 coins instead of 5 (because the user previously earned over 100 coins from this hotel, so she is loyal to that hotel).

Loyalty

Accounting:

  • To generate 5 coins you need to lock $5
  • By spending less coins (discount) you get less back, consider this as "returning customer cost"

In other words there are two types of coins:

  • Spendable: represents locked money
    (can expire?)
  • Loyalty, SP-specific: represents how many times the user used the services (can expire with time)

Loyalty

Option 1: Put everything on the blockchain

and allow anyone to participate - exchanges can be provided by anyone, but requires some internal currency.

 

Option 2: Separate company allowed to issue/unlock coins. At the end of the month Service Provider gets a bill - how much it needs to pay for generated coins.

Blockchains Intro

By Tomasz Drwięga

Blockchains Intro

Workshop

  • 682