Flutter — 區塊鏈虛擬貨幣錢包

Dave Chao
Flutter Taipei
Published in
9 min readApr 2, 2020

最近面試到來自區塊鏈公司的工程師,回憶起以前做區塊鏈虛擬貨幣錢包的日子,心裡想著如果用Flutter的話,要如何創造出虛擬貨幣錢包呢,因此試著研究一下。

本篇主要介紹如何透過Flutter產生虛擬貨幣錢包地址

Blockchain

說到區塊鏈,第一個想到的就是比特幣,它是最早出現,同時也是目前全球共識最強的加密貨幣。

什麼是比特幣?

Zombit新手大哉問 — 比特幣(上)
Zombit新手大哉問 — 比特幣(下)

區塊鏈技術就像是加密貨幣的心臟,若沒有區塊鏈技術,就沒有加密貨幣的一切。

什麼是區塊鏈?

Zombit新手大哉問 — 區塊鏈

HD Wallet

在虛擬貨幣世界裡,所有交易資料都是存放在區塊鏈上,而虛擬貨幣錢包存放的是私鑰。透過私鑰來找出對應的公鑰,再從公鑰產生出錢包地址,也就是帳戶。有了錢包地址,就可以進行交易了!

Block Explorer

目前大部分使用的都是 HD Wallet,它是透過 BIP32BIP39BIP44 共同定義出來的。(BIP 全名是 Bitcoin Improvement Proposals)

  • 透過 BIP39,產生 Mnemonic Code,也就是助記詞,然後再將 Mnemonic Code 經過 PBKDF2 Function 密碼學 運算出 Seed。
Mnemonic Code Converter
  • BIP32 定義 HD Wallet (Hierarchical Deterministic Wallets),整體架構是樹狀結構,並且儲存多組 Key Pairs(私鑰與公鑰),特色是可以從一個 Seed 產生出多個 Address。
BIP32 — HD Wallets
  • BIP44 主要定義 BIP32 樹狀結構中每個階層的意義。
m / purpose' / coin_type' / account' / change / address_index

purpose’:固定是 44,代表是使用 BIP44。

coin_type’:代表不同虛擬貨幣的幣別,例如 Bitcoin 是 0',Ether 是 60'。

account’:代表帳戶,從 0' 開始。

change:0 是External Chain,用於產生轉帳地址,1 是Internal Chain,用於產生找錢地址,只有BTC會使用到。

address_index:代表錢包地址的 Index,從 0 開始。

BIP44 — Derived Addresses

Bitcoin Address

Public Key 經過 SHA256 演算法與RIPEMD 160演算法,再用Base58Check Encode,最後得到Bitcoin Address。

Public Key to Bitcoin Address

Ether Address

Public Key 經過 Keccak-256 演算法,再擷取最後面的40 characters,最後得到Ether Address。

Public Key to Ether Address

Flutter + HD Wallet

BTC

  • 加入 Bitcoin-Flutter lib。
  • 透過generateMnemonic(),產生Mnemonic Code。
var mnemonic = bip39.generateMnemonic(strength: 128);/* Mnemonic Code
manage view hand phrase elegant layer stairs spend meat trip animal crop
*/
  • 透過mnemonicToSeed(“mnemonic”),產生Seed。
var seed = bip39.mnemonicToSeed(mnemonic);
var seedHex = bip39.mnemonicToSeedHex(mnemonic)
/* Seed
637c359d09cc67370ad2f057422205265ffeadcdcfa749628a4af996d41e243b2cb0f3a9b26eff390749ec2c085f69238fc38f3076278c63c9392969b2db2236
*/
  • 透過Seed,建立出HDWallet,然後再Derive出Public Key與Address。
var hdWallet = HDWallet.fromSeed(seed);
var pubKey = hdWallet.derivePath("m/44'/0'/0'/0/0").pubKey;
var address = hdWallet.derivePath("m/44'/0'/0'/0/0").address;
/*
Public Key
039003c86f83ebbc550d3dfac8139cd667841ce668b277e1273ed6e05539abcff2
Address
1B7Kf4iHQJUfzeUe3vv6fGGNXkfeAcG25N
/*

Derivation Path “m/44'/0'/0'/0/0” 說明如下:

44' 是 purpose’,代表是使用 BIP44。

第一個 0' 是 coin_type’,指的是 Bitcoin

第二個 0 是 account’,目前指的是第一個帳戶。

第三個 0 是 change,目前用於產生轉帳地址。

第四個 0 是 address_index,目前指的是第一個錢包地址。

ETH

  • 加入 以下四個 lib
  • 透過generateMnemonic(),產生Mnemonic Code。
var mnemonic = bip39.generateMnemonic(strength: 128);/* Mnemonic Code
manage view hand phrase elegant layer stairs spend meat trip animal crop
*/
  • 透過mnemonicToSeed(“mnemonic”),產生Seed。
var seed = bip39.mnemonicToSeed(mnemonic);
var seedHex = bip39.mnemonicToSeedHex(mnemonic)
/* Seed
637c359d09cc67370ad2f057422205265ffeadcdcfa749628a4af996d41e243b2cb0f3a9b26eff390749ec2c085f69238fc38f3076278c63c9392969b2db2236
*/
  • 取得Seed之後,透過BIP32,建立出HDWallet,然後再Derive出Public Key與Private Key,最後透過ethUtil.privateKeyToAddress(“private key”),取得Ether Address。
var hdWallet = bip32.BIP32.fromSeed(HEX.decode(seed));var ethWallet = hdWallet.derivePath("m/44'/60'/0'/0/0");
var ethPublicKey = HEX.encode(ethWallet.publicKey);
var ethPrivateKey = HEX.encode(ethWallet.privateKey);
var ethAddress = ethUtil.privateKeyToAddress(ethWallet.privateKey)
var ethAddressHex = HEX.encode(ethAddress);
/*
Public Key
02b8bdafdc4aa66382ac8c2361ac1046b9ac2dcbb1685f85fd78fd4b404fb684aa
Private Key
62fde5e9f9b7d8cc378bfbf0bedc38d6f364e1d62c751dc6c47f6f2a4b12e026
Address
71Ce8Ea779CaF185D8F01417dcbc48542C831Fd9
/*

Derivation Path “m/44'/60'/0'/0/0” 說明如下:

44' 是 purpose’,代表是使用 BIP44。

第一個 60' 是 coin_type’,指的是 Ether

第二個 0 是 account’,固定是 0,因為Ether只有一個帳戶。

第三個 0 是 change,固定是 0,因為Ether沒有找錢機制。

第四個 0 是 address_index,目前指的是第一個錢包地址。

希望今天的介紹能讓大家對區塊鏈虛擬貨幣錢包有更深入的了解 :)

--

--