Intro

A deterministic wallet is a system of deriving keys from a single starting point known as a seed. The seed allows a user to easily back up and restore a wallet without needing any other information and can in some cases allow the creation of public addresses without the knowledge of the private key. Seeds are typically serialized into human-readable words in a Mnemonic phrase.

How MEW works with Ledger

  • https://github.com/kvhnuke/etherwallet/blob/f8fdab1ea92d436015119e3c2ba865308289e88d/app/scripts/controllers/decryptWalletCtrl.js#L21
  • https://github.com/kvhnuke/etherwallet/blob/f8fdab1ea92d436015119e3c2ba865308289e88d/app/scripts/controllers/decryptWalletCtrl.js#L43
  • https://github.com/kvhnuke/etherwallet/blob/f54c093c1b1e230b60e238582f2765afd61b2a05/app/scripts/staticJS/ledger-eth.js#L76
  • https://github.com/kvhnuke/etherwallet/blob/f54c093c1b1e230b60e238582f2765afd61b2a05/app/scripts/staticJS/ledger-eth.js#L45
  • https://github.com/LedgerHQ/blue-app-eth/blob/cdc8c7436c76d7600d855f1411b5bc00e55980b7/src_genericwallet/main.c#L63 0x02 -> INS_GET_PUBLIC_KEY
  • https://github.com/LedgerHQ/blue-app-eth/blob/cdc8c7436c76d7600d855f1411b5bc00e55980b7/src_genericwallet/main.c#L2153
  • https://github.com/LedgerHQ/blue-app-eth/blob/dca33eab262730e94353c9c6ea57027389bb03da/src_common/ethUtils.c#L177

How MEW show addresses

以ledger为例,MEW了获取"m/44'/60'/0'"这个路径下的公钥,然后使用hdkey,得到5个derivedKey(m/0 ~m/4), 再使用ethereumjs-util生成了前五个地址。

  • https://github.com/kvhnuke/etherwallet/blob/f8fdab1ea92d436015119e3c2ba865308289e88d/app/scripts/controllers/decryptWalletCtrl.js#L272 result['publicKey'], result['chainCode']
  • https://github.com/kvhnuke/etherwallet/blob/f8fdab1ea92d436015119e3c2ba865308289e88d/app/scripts/controllers/decryptWalletCtrl.js#L267 注:hdk来自于var HDKey = require('hdkey');
    • https://github.com/cryptocoinjs/hdkey/blob/0.7.1/lib/hdkey.js#L13
  • https://github.com/kvhnuke/etherwallet/blob/f8fdab1ea92d436015119e3c2ba865308289e88d/app/scripts/controllers/decryptWalletCtrl.js#L183
  • https://github.com/kvhnuke/etherwallet/blob/mercury/app/scripts/myetherwallet.js#L171
    • https://github.com/ethereumjs/ethereumjs-util/blob/v5.1.2/index.js#L287
    • https://github.com/ethereumjs/ethereumjs-util/blob/v5.1.2/index.js#L440

Let's see electrum

  • https://github.com/spesmilo/electrum/blob/3.0.1/lib/wallet.py#L1746
  • https://github.com/spesmilo/electrum/blob/3.0.1/lib/wallet.py#L93
  • https://github.com/spesmilo/electrum/blob/3.0.1/lib/wallet.py#L1645,L1655
  • https://github.com/spesmilo/electrum/blob/3.0.1/lib/wallet.py#L1638
  • https://github.com/spesmilo/electrum/blob/3.0.1/lib/keystore.py#L232
  • https://github.com/spesmilo/electrum/blob/3.0.1/lib/bitcoin.py#L1013
  • https://github.com/spesmilo/electrum/blob/3.0.1/lib/bitcoin.py#L878-L891
  • https://github.com/spesmilo/electrum/blob/3.0.1/lib/synchronizer.py

Server side

  • client side request address history
    • https://github.com/spesmilo/electrum/blob/3.0.1/lib/network.py#L640
  • https://github.com/spesmilo/electrum-server/blob/master/src/blockchain_processor.py#L310
  • https://github.com/spesmilo/electrum-server/blob/master/src/storage.py#L309
  • https://github.com/spesmilo/electrum-server/blob/master/src/storage.py#L205

注意electrum混合使用了自己的levelDB库和bitcoind,某些调用走bitcoind,而某些调用走自己的库,例如utxo,address等。electurm会在后台同步(catch_up)bitcoind的数据,从bitcoind中读取block,然后存放在自己的数据库里面。这是为了优化查询。

  • https://github.com/spesmilo/electrum-server/blob/master/src/blockchain_processor.py#L608
  • https://github.com/spesmilo/electrum-server/blob/master/src/blockchain_processor.py#L407

Account discovery

When the master seed is imported from an external source the software should start to discover the accounts in the following manner:

  1. derive the first account's node (index = 0)
  2. derive the external chain node of this account
  3. scan addresses of the external chain; respect the gap limit described below
  4. if no transactions are found on the external chain, stop discovery
  5. if there are some transactions, increase the account index and go to step 1

References

  • BIPs
    • BIP39 : Mnemonic code for generating deterministic keys
      • https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki
    • BIP32 : Hierarchical Deterministic Wallets
      • https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
    • BIP43/BIP44 : Multi-Account Hierarchy for Deterministic Wallets
      • https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki
      • https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
      • https://github.com/satoshilabs/slips/blob/master/slip-0044.md
  • https://en.bitcoin.it/wiki/Deterministic_wallet
  • https://en.bitcoin.it/wiki/Deterministic_wallet_tools