Status: Work-in-progress
Abstract
The first ever trusted platform for the transfer of tokens was first established by the Bitcoin network in on Jan-03-2009 18:15:05 UTC. On Jul-30-2015 15:26:13 +UTC, the first block #0 of the Ethereum blockchain was mined.
This programmable trusted platform is the brainchild of Vitalik Buterin, a Russian Canadian who is currently 22 years old. The Ethereum blockchain has since grown and is currently capitalised at more than ~ AUD 1 billion in less than 2 years, compared to Bitcoin’s ~ AUD 16 billion in 7+ years. It is the blockchain platform that has drawn the most developers, and many are still working out the whole new world of possibilities enabled by this platform.
While the Bitcoin blockchain main function is to facilitate the transfer of bitcoin tokens from account to account, Ethereum provides a platform where smart contracts, small programs on the blockchain, are able to securely receive, hold and send tokens.
In this seminar, I will give a live introduction to the Ethereum blockchain. I will demonstrate the deployment and execution of smart contracts and token contracts, and discuss some of the security issues. Finally I will walk through the mechanics of the https://cryptoderivatives.market/ decentralised trustless exchange contract market platform I deployed on 18 Nov 2016 and am still building out.
Presenter background: Bok Khoo is an actuary, consultant and quant developer working with banking and financial institutions and exchanges. He has recently taken a deep dive into the world of programmable blockchains after many sleepless nights.
Table of contents
- Ethereum Among The Other Cryptocurrencies
- Ethereum Blockchain Explorers
- The Ethereum Network
- Tokenising Fiat Currency
Ethereum Among The Other Cryptocurrencies
Ethereum is #2 at AUD 994 million market capitalisation. Compare to Bitcoin #1 at AUD 16.432 billion, total market capitalisation of AUD 19.11 billion, 634 alternative currencies and 2421 markets.
Compare to the AUD 30 billion profits from the Australian big four banks in 2015.
From https://coinmarketcap.com/:
From https://coinmarketcap.com/currencies/ethereum/:
From https://coinmarketcap.com/currencies/ethereum/#markets:
From https://poloniex.com/exchange#btc_eth:
Augur REP token prices fell from 0.00357322 to a low of 0.00010000 (x35 lower) in the 30 minute period on Dec 6 due to a whale’s account being hacked. From https://poloniex.com/exchange#btc_rep:
Ethereum Blockchain Explorers
The main Ethereum blockchain explorers are https://etherscan.io/, https://www.etherchain.org/ and https://live.ether.camp/. Compare to Bitcoin https://blockchain.info/.
From https://etherscan.io/:
The Ethereum Network
From https://ethstats.net/:
Summary, Links
– Links
– White Paper https://github.com/ethereum/wiki/wiki/White-Paper, Yellow Paper https://github.com/ethereum/yellowpaper http://paper.gavwood.com/
– https://ethereum.org/
– Node Clients – #s, languages
– Major Network Events (https://github.com/ethereum/go-ethereum/blob/a8ca75738a45a137ff7b2dfa276398fad26439da/params/util.go)
– Genesis https://etherscan.io/block/0
– Homestead Fork #1 https://etherscan.io/block/1150000
– The DAO, The DAO Hack
– The DAO Fork #2 https://github.com/ethereum/go-ethereum/blob/fed692f67e81bd3937a5efab38f56a9b99d04d41/params/dao.go https://etherscan.io/block/1920000
– Network Attacks
– https://ethereum.stackexchange.com/questions/9883/sync-stuck-at-block-2-306-843-with-wallet-0-8-7/9892#9892
– Network Attack Fork #3 – Gas Reprice https://etherscan.io/block/2463000
– Network Attack Fork #4 – State Cleaning https://etherscan.io/block/2675000
–
– Wallets
– Geth
– Parity
– Ethereum Wallet / Mist
– Metamask
– Jaxx
– Ledger Blue
– Solidity Online
Block explorer
block in geth
– show block details
– show transactions
https://ethereum.stackexchange.com/questions/4452/how-do-i-retrieve-the-voted-events-from-the-dao
Show Wallet
Tokenising Fiat Currency
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
pragma solidity ^0.4.2; // DigitalDollar // // (c) Bok Consulting Pty Ltd 2016 // // ERC Token Standard #20 // https://github.com/ethereum/EIPs/issues/20 contract ERC20Interface { // Get the total token supply function totalSupply() constant returns (uint256 totalSupply); // Get the account balance of another account with address _owner function balanceOf(address _owner) constant returns (uint256 balance); // Send _value amount of tokens to address _to function transfer(address _to, uint256 _value) returns (bool success); // Send _value amount of tokens from address _from to address _to // The transferFrom method is used for a withdraw workflow, allowing contracts to send // tokens on your behalf, for example to "deposit" to a contract address and/or to charge // fees in sub-currencies; the command should fail unless the _from account has // deliberately authorized the sender of the message via some mechanism; we propose // these standardized APIs for approval: function transferFrom(address _from, address _to, uint256 _value) returns (bool success); // Allow _spender to withdraw from your account, multiple times, up to the _value amount. // If this function is called again it overwrites the current allowance with _value. function approve(address _spender, uint256 _value) returns (bool success); // Returns the amount which _spender is still allowed to withdraw from _owner function allowance(address _owner, address _spender) constant returns (uint256 remaining); // Triggered when tokens are transferred. event Transfer(address indexed _from, address indexed _to, uint256 _value); // Triggered whenever approve(address _spender, uint256 _value) is called. event Approval(address indexed _owner, address indexed _spender, uint256 _value); } contract DigitalDollar is ERC20Interface { // Owner of this contract address public bank; // KYCed customers mapping(address => uint256) customerStatus; // Customer name mapping(address => string) names; // Balances for each account mapping(address => uint256) balances; // Owner of account approves the transfer of an amount to another account mapping(address => mapping (address => uint256)) allowed; // Total supply uint256 _totalSupply; // Functions with this modifier can only be executed by the bank modifier onlyBank() { if (msg.sender != bank) { throw; } _; } // Functions with this modifier can only be executed by the bank modifier onlyCustomer(address _customer) { if (customerStatus[_customer] != 1) { throw; } _; } // Constructor function DigitalDollar(address _bank, string _name) { bank = _bank; kyc(_bank, _name); } // KYC function kyc(address _customer, string name) onlyBank { customerStatus[_customer] = 1; names[_customer] = name; } // Suspend customer function suspend(address _customer) onlyBank { customerStatus[_customer] = 2; } // Whois function whois(address _customer) onlyBank constant returns (string name, string status) { uint256 _customerStatus = customerStatus[_customer]; if (_customerStatus == 1) { name = names[_customer]; status = "good"; } else if (_customerStatus == 2) { name = names[_customer]; status = "suspended customer"; } else { name = "unknown"; status = "not a customer"; } } // Bank transfers _owner's fiat dollars into a special account and digitises // the customer's fiat dollars function tokenise(address _owner, uint256 _amount) onlyBank onlyCustomer(_owner) { if (_amount > 0) { balances[_owner] += _amount; _totalSupply += _amount; Tokenise(_owner, _amount); } } function detokenise(address _owner, uint256 _amount) onlyBank onlyCustomer(_owner) { if (balances[_owner] >= _amount && _amount > 0) { balances[_owner] -= _amount; _totalSupply -= _amount; Detokenise(_owner, _amount); } } function totalSupply() constant returns (uint256 totalSupply) { totalSupply = _totalSupply; } // What is the balance of a particular account? function balanceOf(address _owner) constant returns (uint256 balance) { return balances[_owner]; } // Transfer the balance from owner's account to another account function bankTransfer(address _from, address _to, uint256 _amount) onlyBank onlyCustomer(_from) onlyCustomer(_to) returns (bool success) { if (balances[_from] >= _amount && _amount > 0) { balances[_from] -= _amount; balances[_to] += _amount; BankTransfer(_from, _to, _amount); return true; } else { return false; } } // Transfer the balance from owner's account to another account function transfer(address _to, uint256 _amount) onlyCustomer(_to) returns (bool success) { if (balances[msg.sender] >= _amount && _amount > 0) { balances[msg.sender] -= _amount; balances[_to] += _amount; Transfer(msg.sender, _to, _amount); return true; } else { return false; } } // Send _value amount of tokens from address _from to address _to // The transferFrom method is used for a withdraw workflow, allowing contracts to send // tokens on your behalf, for example to "deposit" to a contract address and/or to charge // fees in sub-currencies; the command should fail unless the _from account has // deliberately authorized the sender of the message via some mechanism; we propose // these standardized APIs for approval: function transferFrom( address _from, address _to, uint256 _amount ) onlyCustomer(_from) onlyCustomer(_to) returns (bool success) { if (balances[_from] >= _amount && allowed[_from][msg.sender] >= _amount && _amount > 0) { balances[_to] += _amount; balances[_from] -= _amount; allowed[_from][msg.sender] -= _amount; Transfer(_from, _to, _amount); return true; } else { return false; } } // Allow _spender to withdraw from your account, multiple times, up to the _value amount. // If this function is called again it overwrites the current allowance with _value. function approve(address _spender, uint256 _amount) onlyCustomer(msg.sender) onlyCustomer(_spender) returns (bool success) { allowed[msg.sender][_spender] = _amount; Approval(msg.sender, _spender, _amount); return true; } function allowance(address _owner, address _spender) onlyCustomer(msg.sender) onlyCustomer(_spender) constant returns (uint256 remaining) { return allowed[_owner][_spender]; } function () { } // Triggered when tokens are transferred. event BankTransfer(address indexed _from, address indexed _to, uint256 _amount); // Triggered when fiat currency is converted to tokens event Tokenise(address indexed _owner, uint256 _amount); // Triggered when tokens are converted back to fiat currency event Detokenise(address indexed _owner, uint256 _amount); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
> eth.accounts > ["0x5ad21746717442a76089bde62720412f29aee414", "0x08299c1c6721057529d157d697e4f2dde126a0a8", "0xabc2dcf10d878b7348224d9363db584c5fd3bcb5", "0xb1111e1846db6db66908d74392a1dbd852a1647d", "0xb0bbed06dc56bd2677860eafc8a4403c3be84602", "0xb4d60ce13ce70f5fe1a7a6c2a38f5f1c8c5ce95f"] // #2 Bank "0xabc2dcf10d878b7348224d9363db584c5fd3bcb5" // #3 Bill "0xb1111e1846db6db66908d74392a1dbd852a1647d" // #4 Bob "0xb0bbed06dc56bd2677860eafc8a4403c3be84602" // #5 Bad "0xb4d60ce13ce70f5fe1a7a6c2a38f5f1c8c5ce95f" var amount=web3.toWei(1.23, "ether") amount debug.verbosity(4) eth.sendTransaction({from: eth.accounts[0], to: eth.accounts[1], amount: amount}); debug.verbosity(3) |