1. Ethereum Dapp - Asset Exchange YOSEMITE alpha
https://yosemiteX.com
Presented on Blockchain Day blockchain tech conference, Seoul 2017.11.08
Yosemite X Inc. 1755 University Ave. Palo Alto, CA 94301
Bezalel Lim (임병완) / bezalel@yosemiteX.com
Lead Developer @ Yosemite X Inc. / Yosemite Labs.
2. To show 3 Ethereum Dapps made by Yosemite X Inc.
● 1st Generation “Fully Decentralized” Asset Token Exchange
Ethereum Dapp PoC (2016)
● On/Off-chain Hybrid-architecture Asset Exchange YOSEMITE alpha
Ethereum Dapp (2017) - Real-Estate, Fine Art, …
● Token Sale (ICO) Ethereum Dapp (test version)
Dapp : Decentralized application
3. Asset-Share Smart Contract
[Smart Contract Code]
* Share(Token) ownership ledger
account-1 : 100 share
account-2 : 150 share
* Escrow for Token and Ether
* Make Buy/Sell Order
* Take Buy/Sell Order
* Asset Acquisition Proposal
* Voting For Buy Proposal
* Dividend
...
User
Ethereum Blockchain
Asset(Art,...) Metadata,
Image Files,
Authentication-related
Document Files
...
User Account
User
User Account
MakeBuyOrder
Vote
TakeBuyOrder
Ethereum Dapp (through Mist / Geth)
MakeSellOrder
Asset Token Registry Contract
0x54106a9b4b58b300...
102.243 ETH
0x481ab76d8ab8f980...
419.107 ETH
Decentralized P2P
Storage (IPFS)
Private KeyPrivate Key
Ethereum Dapp Architecture of 1st Generation
“Fully Decentralized” Asset Token Exchange System PoC, 2016
4. contract AssetShareToken {
...
/// @notice making buy order (providing ether liquidity). msg.value should be equal to ...
/// @param _token The amount of token to be traded, should have 9 trailing zeros
/// @param _ethPrice The Ether price per base token unit (10^18 token), should have 9 trailing zeros
/// @param _nonce nonce value generated by client to uniquely distinguish this buy order
function makeBuyOrder(uint256 _token, uint256 _ethPrice, uint256 _nonce) payable isTradable external {
checkTrailing9Zeros(_token);
checkTrailing9Zeros(_ethPrice);
if (msg.value != safeMul(_token, _ethPrice) / (1 ether)) throw;
bytes32 makeBuyHash = sha3(this, msg.sender, _token, _ethPrice, block.timestamp, _nonce);
if (buyOrders[makeBuyHash].user != 0) throw; // check existing order (possible conflict on same block and same nonce)
buyOrders[makeBuyHash] = OrderStatus(msg.sender, false, false, _token, _ethPrice, _token, msg.value);
ethInTrade[msg.sender] = safeAdd(ethInTrade[msg.sender], msg.value);
MakeBuy(makeBuyHash, msg.sender, _token, _ethPrice, block.timestamp, _nonce);
}
...
}
Asset Token Smart Contract
User Account
MakeBuyOrder
10 token
0.5 ETH/token
escrow 50 ETH
0x54106a9b4b58b300...
102.243 ETH
Smart Contract Code Example (Ethereum Solidity)
6. “Merkle Root Hash” can be used as unique identifier of underlying data (leaf data nodes)
If one bit of any leaf content node is changed, it will generate totally different merkle root hash.
Merkle Hash Examples :
blockhash of blockchain data structure, BitTorrent / IPFS file hash address
9. Decentralized Exchange
[ EtherDelta, YOSEMITE
PoC, … ]
Centralized Exchange
[ Bithumb, Korbit, Poloniex,
Kraken, … ]
Hybrid-style Exchange
[ YOSEMITE Alpha ]
Transaction
Performance
Very Slow
Very Low Throughput
High Speed
High Throughput
High Speed
High Throughput
Blockchain Fee User pays Gas Fee (Ether) No Gas Fee No Gas Fee
Data
Transparency /
Auditability
Fully transparent /
auditable, but bloats the
blockchain
not transparent, data could
be manipulated,
Not auditable
All trading data is transparent
and auditable
User Account
Blockchain Account
(created on client-side)
Server Generated User
Account
Blockchain Account
(created on client-side)
Fiat Stable Coin - Fiat Money, USDT Fiat-Pegged Token (dUSD)
User Interface
Difficult (only blockchain
experts can use)
Easy Easy
Trading Volume Very Low Volume Most Crypto Trading -
Crypto Exchange System Comparison
10. contract ERC223 {
totalSupply() constant returns (uint); balanceOf(address _owner) constant returns (uint);
name() constant returns (string _name); symbol() constant returns (bytes32 _symbol);
decimals() constant returns (uint8 _decimals);
transfer(address _to, uint _value) returns (bool success);
transfer(address _to, uint _value, bytes _data) returns (bool);
event Transfer(address indexed _from, address indexed _to, uint256 indexed _value, bytes _data);
}
contract ERC223Receiver {
tokenFallback(address _from, uint _value, bytes _data);
}
Ethereum ERC20 / ERC223 Token Standard
contract ERC20 {
totalSupply() constant returns (uint totalSupply); balanceOf(address _owner) constant returns (uint);
transfer(address _to, uint _value) returns (bool); transferFrom(address _from, address _to, uint _value) returns (bool);
approve(address _spender, uint _value) returns (bool); allowance(address _owner, address _spender) constant returns (uint);
event Transfer(address indexed _from, address indexed _to, uint _value);
event Approval(address indexed _owner, address indexed _spender, uint _value);
}
https://github.com/ethereum/EIPs/issues/20
https://github.com/ethereum/EIPs/issues/223
ERC223 Smart Contract
token ownership map
(ledger)
account-1 : 100.123
account-2 : 150.234
account-3 : 3242.0432
contract-1 : 21310.523
….
ERC223 Receiver
Smart Contract
if transfer target address(_to) is contract (e.g. exchange contract), then token contract calls target contract’s
tokenFallback function in which the target contract can generate its own Event Log
⇒ deposit operation in exchange contract can be done in 1 blockchain transaction and exchange system just
monitors its own exchange contract’s event logs, not for every ERC20 token contracts’ event log
call tokenFallback()
11. 2. Crypto-signed(with Ethereum account) user’s
buy/sell order message is sent to exchange
server and written in public p2p storage
3. Server matches buy/sell orders
and make crypto-signed (with
Ethereum account of server) trade
event message and stores in
database and public p2p storage
Asset-Share Smart Contract [ERC223]
Share ownership ledger
account-1 : 100 Shares
account-2 : 150 Shares
exchange-account : 21,310 Shares
….
Off-chain Exchange Server
User
Exchange (Vault) Contract
[ERC223 receiver]
1. Deposit dUSD / Asset-Share
Public Ethereum Blockchain
Public P2P Distributed
Storage (IPFS)
Trading System
Withdraw dUSD / Asset-Share
User Account
“Fully transparent and auditable”
“High Performance”
“No Gas Fee”
“Stable Trading Currency”
dUSD (Digital USD) Smart Contract
[ERC223]
dUSD ledger
account-1 : 2,300.12 dUSD
account-2 : 870.32 dUSD
exchange-account : 17,234,321.243 dUSD
….
Bank Account
balance : $82,243,231
dUSD Server
Total supply of dUSD Token ≤ $USD Balance of Bank Account
Issue / Redeem
smart contract log data
sync.
Asset Exchange YOSEMITE Hybrid System Architecture Diagram, 2017
12. signedBuyOrderMsg = buyOrderMsg + ( “si” → ECDSA.Sign(PKU
,buyOrderMsg) )
where PKU
is the private key of the user account, ECDSA.Sign is signing function of the elliptic curve digital signature algorithm,
buyOrderMsg/signedBuyOrderMsg are tightly packed (no whitespace) stringified json objects
buyOrderId = MerkleRootHash(signedBuyOrderMsg) = IPFS file address
where MerkleRootHash is a base58 encoded root hash of merkle tree/dag of file data on IPFS
signedBuyOrderMsg = IPFS.Get(buyOrderId)
where IPFS.Get is a file data retrieving function using the merkle root hash address of a file on IPFS
UserEthAddress = ECDSA.Recover(buyOrderMsg, signedBuyOrderMsg("si"))
where ECDSA.Recover is public key recovering function of the elliptic curve digital signature algorithm,
buyOrderMsg = signedBuyOrderMsg -"si"
[example]
buyOrderMsg = { "xa" : "0x33e50109...119cba0a088", "tt" : "OB", "ea" : "0x38909c7...d7b25e0590" , "sy" : "AS_PC_GN", "am" : "30",
"pr" : "30500000", "mfr" : 10, "tfr" : 20, "ts" : 1500882556820 }
signedBuyOrderMsg = { "xa" : "0x33e50109...119cba0a088", "tt" : "OB", "ea" : "0x38909c7...d7b25e0590" , "sy" : "AS_PC_GN", "am"
: "30", "pr" : "30500000", "mfr" : 10, "tfr" : 20, "ts" : 1500882556820, "si" : "0xdfef1901548ec804ecfa...72a5c8909d7961c1c" }
buyOrderId = “QmQjxtDWvHVMVp...9Y3r5g5QP2nX6Kev” (IPFS hash address)
signedBuyOrderMsg = IPFS.Get(“QmQjxtDWvHVMVp...9Y3r5g5QP2nX6Kev”)
“0x38909c7...d7b25e0590” = ECDSA.Recover(buyOrderMsg,”0xdfef1901548ec804ecfa...72a5c8909d7961c1c”)
Buy Order Message Example
Ethereum Account Address
Crypto Signature
13. S CTBD WRS TBC
Block of Exchange TXs
Crypto-hash of block data
(block json file IPFS hash address)
previous block hash
block-chaining
Public IPFS P2P Distributed Storage
Public Ethereum Blockchain Exchange Smart Contract [ERC223 token receiver] [Exchange Block Hash Anchoring Storage]
immutable ‘Trade-Buy’ json file
with server crypto-signature
QmQ9o...6FjrtpZmz QmXhCc...v4pmkQf
‘Sell-Order’ json file
with user crypto-signature
QmYDDEq...mMc2f
‘Block’ json file
IPFS hash addr. list for
transactions in this block
Block of Exchange TXs
Crypto-hash of block data
(block json file IPFS hash address)
previous block hash
Exchange block hash anchoring to public Ethereum blockchain to ensure exchange data immutability and transparency
at regular time intervals
WC
IPFS hash addr. list for
transactions in this block
Off-chain blockchain-like exchange data structure anchored to the public blockchain
17. YOS Token Sale / YOS Token Smart Contract
● YOS Token Sale Contract
○ 3 round token sale logic
○ get ETH and issue YOS ERC223 tokens for ETH contributor accounts
● YOS Token Smart Contract
○ ERC20 / ERC223 Standard Token
○ Snapshotable Token (inspired by MiniMe token)
■ Token distribution(ownership ledger) can be snapshotted at the
requested snapshot points (block numbers)
■ “Upgradable” Token Contract
○ Dividendable Token
■ Can distribute token dividend (profit of YOS token, e.g.
transaction fee profit of exchange service) in proportion of the
token distribution at the dividend time point (snapshot block
number)
Snapshotable Token Contract
snapshot of token
ownership ledger at a
specific block number
account-1 : 100.123
account-2 : 150.234
account-3 : 3242.0432
….
New token contract
upgraded from previous
snapshotable token
contract
Upgrade to new smart contract
at snapshot block number
https://github.com/YosemiteLabs/token-sale-contract-dev