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