Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

DAGX钱包详解

一夜雨十年灯潞
111 0 0
钱包结构
) |% I- s; p1 U* e顾名思义,钱包是用来保存钱的。但在数字货币的世界中,钱包里面并没有“钱”。钱包账户里有多少“钱”都是记录在区块链上的,钱包里只是存储了账户对应的私钥,账户是从私钥相应的公钥衍生出来的。只要有了私钥,你就可以在数字货币世界里证明你的身份,发送区块链上属于你的资产。因此,钱包实际上是管理和存储私钥的工具。
% Z5 C$ `2 g8 I7 n7 @% iDagx钱包结构与Bitcoin类似,Bitcoin对管理和存储私钥以及通过私钥生成地址制定了一系列标准(BIP, Bitcoin Improvement Proposals),主要包括:
% E( p: A) r$ R· BIP32:定义了HD钱包(Hierarchical Deterministic Wallet),允许从单一种子产生一树状结构储存多组私钥和公钥,可以方便的备份、转移以及分层权限控制等。HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生。下图展示了HD钱包的树状结构:
( u/ h% a% d7 x7 u; ^! e: }4 s3 _
. d! J2 C9 `5 c7 M& {2 x* kBIP39:将种子用方便记忆和书写的单词表示,一般由12个单词组成,称为助记词或助记码。由一系列单词生成种子是个标准化的方法,这样易于在钱包中转移、导出和导入。比如shrimp make call path pink draw gym song select brother social base,其相应的私钥为
0 @% s; T& i3 m9 s$ cxprv9s21ZrQH143K4HQ8sBPNNkXHNuVYfivR96gtpJzMWCJVF5hdYjzT5nVQu6GfHAQLPstQtFp9GTWADUcKgzaV5EyL5JxT2rxkyg51ReGTVg8。
; F- u( R  s/ F& r/ VBIP43:为HD钱包路径引入purpose字段,路径记作m / purpose’ / *,比如m / 0’ / *表示BIP32的默认账户。" q  G; f( `& l8 z  \, E* _- _
BIP44:定义HD钱包路径字段,赋予树状结构中的各层特殊的意义,从而支持多币种、多账户,路径定义为:
2 Z: c+ s* |1 m9 {2 Q8 d. \m / purpose' / coin_type' / account' / change / address_index
4 Z6 ~# q& x( E" d9 a1 _其中,purpose’固定是44’,代表使用BIP44;coin_type’用来表示不同币种,例如Bitcoin就是0’,Bitcoin Testnet是1’,Ethereum是60’;account’表示账户编码;change用来表示该地址是否为找零地址;address_index为地址编号。
' ?! I9 e) [8 i! O) @BIP45:定义多签名HD钱包路径字段,从而支持多签名地址,路径定义为:! N0 l% R% t9 X  A8 W9 t  a
m / purpose' / cosigner_index / change / address_index
, r3 r5 _9 c+ J其中,purpose固定是45’,代表使用BIP45;cosigner_index表示多签名用户编号;其余字段与BIP44相同。
5 b2 R6 p* n" h: t& kDagx钱包采用的是符合BIP44标准的HD钱包,其采用的路径结构为:
: z" b; Q4 o( [# ^4 m' am / 44’ / 0’ / account’ / change / address_index3 d: b' |2 p4 P1 k

. N! P8 ]: w) G& d0 Z& N' [; f此外,除了使用account来标识账户外,还使用了该账户公钥的哈希值对账户进行唯一表示,表示方法为:
  o- d, w. ?/ z4 E! `var wallet = crypto.createHash(“sha256”).update(xPubKey, “utf8”).digest(“base64”);+ u! N, p9 p- C, d7 Z# C" A1 a. A+ _
Dagx中还有一类特殊的地址,即设备地址,其采用的路径结构为:
/ V( j3 Q: C$ v- fm / 1’ / *
9 B6 J9 c3 q2 X$ |Dagx钱包使用了bitcore-lib和bitcore-mnemonic两个库进行钱包管理,简单的使用方法如下:+ g, e- E/ F( E& P5 z1 L
var Mnemonic = require('bitcore-mnemonic');
, Z2 f+ |( d% T* @2 i2 b2 ^    var Bitcore = require('bitcore-lib');$ M0 T; n& h& H# g. M& z6 c: z
// 生成助记词5 R8 s) y, ^3 J0 p  p
 ) W2 ?5 B3 s/ a2 x& }7 v
// 'fee decorate step culture autumn game social very lemon drum embrace much'
6 Z' X; U8 J# Z5 M4 } - d! z0 a" t" d2 R9 j
var mnemonic = new Mnemonic(); 7 z- f8 h8 w. u7 a. L
 2 R9 A7 a2 ^. z: X4 c; M2 k& E
// 生成HD钱包私钥; y( E8 v8 S9 ^& [& @6 x2 E
 4 [" A( e  L4 I2 ^& x
//
9 x, @6 R2 k, d) B; g$ h* W 4 }! u  M3 i8 i- v% Y# v
var xPrivKey = mnemonic.toHDPrivateKey(); 0 ^. t! a) h* S5 ?+ ~
 8 _& n3 o% ~  f9 C/ t, a  O
// 生成HD钱包公钥,account=0
$ [8 u6 I9 w4 ~3 {0 p$ F/ l5 M / H, m( E! {7 D6 v* S* j* Q$ z6 y
// 5 A' y; c$ L% w% Q. p
 $ Y% H5 `- x$ t! b- o& G% d0 j
var xPubKey = Bitcore.HDPublicKey(xPrivKey.derive("m/44'/0'/0'")); $ e& V* z# l8 J5 a, `" i5 y
 
' ?" V/ s/ Z; x0 {3 l% V+ j. c// 生成设备私钥,用于产生设备地址
" A3 f. Q1 n. g6 M ( F) L9 ~  t' r+ j! {" l/ d" L0 x" G% L
//
, ~* f5 Q6 b& E . \6 j7 u4 A5 |  X  c3 X$ U" `7 f
var devicePrivKey = xPrivKey.derive("m/1'");
# t+ `# d, a; ?3 V8 R- P# U# m
) s1 F; P* |* U* K4 A" g8 ]1 |! r+ u地址生成
; O4 j9 E# c/ {8 d5 }Dagx中包括三类地址:( X( q. R0 }9 T% i8 ]6 H
· 普通地址
& `' [# {" R# }1 t" L4 b2 Z' ?+ `· 共享地址
; `5 t5 Z" g- l% G/ g1 P* M7 \· 设备地址% _% w9 Y) Z6 c  T& v0 [
其中,普通地址和共享地址都是通过地址定义脚本生成的,二者的区别类似于Bitcoin中的P2PKH地址和P2SH地址,具体细节可参考《Dagx原理解析(三)地址、脚本及合约》;设备地址是采用设备公钥生成的,地址格式和校验规则与普通地址相同,只是前缀添加了0。/ U$ V7 b8 L+ {* q
给定需要生成地址的对象,Dagx生成地址时采用的是ripemd160哈希,并给地址加上校验,使用的是Dagxcore/object_hash.js中的函数getChash160()函数。' }2 I# P. p9 v) J& I
具体来说,设备地址生成方法:" ~* M, ?2 w- m
var ecdsa = require('secp256k1'); // 椭圆曲线非对称加密) q; [& o' _$ L8 J. N) W, a
 + b" h: K2 }3 b& R( j
// 获取设备公钥
* d8 m7 X/ }! q. S4 L# x 0 T  A8 [: i0 X$ c3 S
var pubkey = ecdsa.publicKeyCreate(devicePrivKey.privateKey.bn.toBuffer({size:32}), true).toString('base64');
+ |; l) p3 Q6 K/ j7 Q * `5 f# Z: w( J( ^
// 生成设备地址
$ V; \# P8 r' N/ V9 S& l" ]# L) G% ?& e 
$ o! Z7 {4 F& k9 x1 X2 j* kvar objectHash = require('Dagxcore/object_hash.js');
+ Z* E- P: s  h2 k% g+ f- r8 n & f2 Y+ N, R# r+ i
var device_address = '0' + objectHash.getChash160(pubkey);
, U8 E( I4 F! A& U8 d+ }2 t1 G* ]普通地址生成方法:$ N* w2 |# n' p
// change=0 address_index=0,生成公钥8 G8 J: C! m7 E: F
 
) f0 P: ?) j7 _- Z* W  l/ P( kvar pubkey = xPubKey.derive('m/0/0').publicKey.toBuffer().toString('base64');
3 R! l& x) c9 j6 ^9 m2 q ; g. S: C0 Y0 l1 l
// 设定地址定义脚本,为单签名2 g8 I- |1 C5 q6 c; Y; Z! V0 e
 
0 v, g- c7 W; U% dvar arrDefinition = ["sig", {"pubkey": pubkey}];
8 W! z" z  T  w" |7 i 2 ]$ Y6 s: x  K' c( |$ X
// 生成地址! _9 R; T8 g7 C7 g' f. q7 @
 # j3 |! p/ a' E7 R( _, K
var address = objectHash.getChash160(arrDefinition);6 t7 k6 u) E0 S/ K# V9 Q
共享地址的生成方法与普通地址基本一致,唯一的差别在于地址定义脚本要更加复杂一些。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

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

    0

  • 关注

    7

  • 主题

    11