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
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);
}
> 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)


