Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

DAGX钱包详解

一夜雨十年灯潞
148 0 0
钱包结构- Y  m8 h5 E* U8 T) X5 e* y4 Y% X
顾名思义,钱包是用来保存钱的。但在数字货币的世界中,钱包里面并没有“钱”。钱包账户里有多少“钱”都是记录在区块链上的,钱包里只是存储了账户对应的私钥,账户是从私钥相应的公钥衍生出来的。只要有了私钥,你就可以在数字货币世界里证明你的身份,发送区块链上属于你的资产。因此,钱包实际上是管理和存储私钥的工具。2 k( d8 A# b+ j8 J2 N+ p
Dagx钱包结构与Bitcoin类似,Bitcoin对管理和存储私钥以及通过私钥生成地址制定了一系列标准(BIP, Bitcoin Improvement Proposals),主要包括:! o0 `/ K! v% [
· BIP32:定义了HD钱包(Hierarchical Deterministic Wallet),允许从单一种子产生一树状结构储存多组私钥和公钥,可以方便的备份、转移以及分层权限控制等。HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生。下图展示了HD钱包的树状结构:
' H* i/ A. E# ^
6 j0 N( ]7 }7 ZBIP39:将种子用方便记忆和书写的单词表示,一般由12个单词组成,称为助记词或助记码。由一系列单词生成种子是个标准化的方法,这样易于在钱包中转移、导出和导入。比如shrimp make call path pink draw gym song select brother social base,其相应的私钥为
, ?; ?0 L% ]  g' Cxprv9s21ZrQH143K4HQ8sBPNNkXHNuVYfivR96gtpJzMWCJVF5hdYjzT5nVQu6GfHAQLPstQtFp9GTWADUcKgzaV5EyL5JxT2rxkyg51ReGTVg8。
1 v  [4 l8 S* B) [6 E9 |1 O) PBIP43:为HD钱包路径引入purpose字段,路径记作m / purpose’ / *,比如m / 0’ / *表示BIP32的默认账户。, `, s5 L1 F$ @* O! K5 J% F$ @
BIP44:定义HD钱包路径字段,赋予树状结构中的各层特殊的意义,从而支持多币种、多账户,路径定义为:; a$ t& y) _# k; A& I4 p
m / purpose' / coin_type' / account' / change / address_index
8 L2 O2 N& M% D+ M" H' _其中,purpose’固定是44’,代表使用BIP44;coin_type’用来表示不同币种,例如Bitcoin就是0’,Bitcoin Testnet是1’,Ethereum是60’;account’表示账户编码;change用来表示该地址是否为找零地址;address_index为地址编号。
8 F% U3 t; i7 I9 p  S" B- r, QBIP45:定义多签名HD钱包路径字段,从而支持多签名地址,路径定义为:
( _( c/ z- A: [+ I+ cm / purpose' / cosigner_index / change / address_index+ m9 w# z1 {/ c$ ~: ~* x& a3 T
其中,purpose固定是45’,代表使用BIP45;cosigner_index表示多签名用户编号;其余字段与BIP44相同。! u6 u9 s  h- _# X6 M
Dagx钱包采用的是符合BIP44标准的HD钱包,其采用的路径结构为:. B, G4 ~# X2 i7 \. Z! r9 S6 }" u
m / 44’ / 0’ / account’ / change / address_index0 c0 {# m! ?  Z0 H- N4 K% S. E

: C% e9 M$ f8 H# T% ^  s此外,除了使用account来标识账户外,还使用了该账户公钥的哈希值对账户进行唯一表示,表示方法为:
6 y; S0 q/ K( L! j% ?- K1 m; d, dvar wallet = crypto.createHash(“sha256”).update(xPubKey, “utf8”).digest(“base64”);" ~3 L" ]+ I% b7 w
Dagx中还有一类特殊的地址,即设备地址,其采用的路径结构为:7 f' q. @2 N- r, }
m / 1’ / *, M* o) H" p4 T6 K0 X8 w
Dagx钱包使用了bitcore-lib和bitcore-mnemonic两个库进行钱包管理,简单的使用方法如下:- `! n$ M$ f) Q$ H- |3 M5 `
var Mnemonic = require('bitcore-mnemonic');; v5 ~& j2 A' w
    var Bitcore = require('bitcore-lib');
  T# w. @! ^3 W& [// 生成助记词' K0 d6 b: W5 U1 M1 a. a7 O3 I
 
2 D3 L% j/ v8 U6 F" K* E4 V// 'fee decorate step culture autumn game social very lemon drum embrace much'/ A5 m* M2 N5 m0 ]+ z+ _
 
* m- z- R, l+ Z! U' P5 V1 ?var mnemonic = new Mnemonic();
& ~# \. I+ I2 E# ] 1 p4 S: Q6 C: [, {8 b+ |
// 生成HD钱包私钥
) @! M; @# V7 B! h5 B 
( i3 J3 r9 ?: \. E, F6 \7 f+ \//
7 l% ^5 ]' ~5 g" l& W 5 R0 ~/ ?6 \, S
var xPrivKey = mnemonic.toHDPrivateKey();
  R( V+ k9 ^: w+ m4 L - B6 ]) t6 e- \; Q. c* R
// 生成HD钱包公钥,account=07 X+ i  E" z, y
 
! m8 X" [! r: [0 c9 b) o$ E// / B, N& m5 z4 p% P' W$ a8 Y- a
 
2 B- X, p- ]1 d& z) ^5 I; {var xPubKey = Bitcore.HDPublicKey(xPrivKey.derive("m/44'/0'/0'")); * R* f! Z" g# S; C
 
# S# Z; E5 C7 b4 z" H// 生成设备私钥,用于产生设备地址" Z% D$ ~3 s) o( v
 
8 Y7 i* b6 Y6 X/ Q// ! i% w" O1 ^5 _. ?
 % G$ ~/ w& s7 l3 r0 T7 f
var devicePrivKey = xPrivKey.derive("m/1'");/ D& y' a# l$ {; Q
1 C2 B: d1 r2 V0 P" F( I
地址生成
7 D! u* `/ @# f8 TDagx中包括三类地址:
. A& r' O- J, `" |3 @· 普通地址
6 q5 M# b3 X& a1 \· 共享地址
' m; t8 Q! Q. i8 J+ m1 w· 设备地址
2 |5 A" F* P* b) p/ ]其中,普通地址和共享地址都是通过地址定义脚本生成的,二者的区别类似于Bitcoin中的P2PKH地址和P2SH地址,具体细节可参考《Dagx原理解析(三)地址、脚本及合约》;设备地址是采用设备公钥生成的,地址格式和校验规则与普通地址相同,只是前缀添加了0。% `2 N- p, J: k  J5 u
给定需要生成地址的对象,Dagx生成地址时采用的是ripemd160哈希,并给地址加上校验,使用的是Dagxcore/object_hash.js中的函数getChash160()函数。4 W# j7 T3 `- u7 s& T
具体来说,设备地址生成方法:
* @2 S% r9 q3 V6 I, {" O3 Mvar ecdsa = require('secp256k1'); // 椭圆曲线非对称加密
$ j/ ~! M/ b$ |0 n 
1 z2 X- _* P/ i% q' O7 q' ^7 \// 获取设备公钥
8 [3 R) @1 V8 Z; r3 j 
1 P9 O2 E, P) E8 v% L6 K7 Wvar pubkey = ecdsa.publicKeyCreate(devicePrivKey.privateKey.bn.toBuffer({size:32}), true).toString('base64');
- H, W" f6 T& r! i) M5 e! I# N ) C6 E' `/ }2 u. B+ i6 f; O) P7 r
// 生成设备地址2 X1 S( D$ M; M! f( B
 4 P! v) I* l! W& l; a; Z. [
var objectHash = require('Dagxcore/object_hash.js');
! Z* d- h. B: v% ] 
- }& @& r, W. r& xvar device_address = '0' + objectHash.getChash160(pubkey);
2 [1 |; }, B; [) e普通地址生成方法:
" B$ I" V( F( O2 ^' c// change=0 address_index=0,生成公钥: J, u% q8 }& e2 }
 
" i" D- Q( J5 F4 a  p1 C* Pvar pubkey = xPubKey.derive('m/0/0').publicKey.toBuffer().toString('base64');6 L; M% c$ v9 t. Q% x/ x, k3 J! _
 2 j# o# S+ _/ O6 `0 s; Y
// 设定地址定义脚本,为单签名7 H. N+ X% L8 N* _
 
* d4 M8 `# n- W" u/ _5 xvar arrDefinition = ["sig", {"pubkey": pubkey}];9 a2 v2 u  W- \1 W4 v
 
) Z3 t0 C6 q5 {& E% }1 K// 生成地址( L% r+ b& D; M* m' K2 d- L- ]% n) J6 l
 
8 D  e2 h  X+ t7 j0 H# I" ivar address = objectHash.getChash160(arrDefinition);5 E  h2 Y% `+ u9 ^( M
共享地址的生成方法与普通地址基本一致,唯一的差别在于地址定义脚本要更加复杂一些。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

一夜雨十年灯潞 初中生
  • 粉丝

    0

  • 关注

    7

  • 主题

    11