Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

DAGX钱包详解

一夜雨十年灯潞
127 0 0
钱包结构- |! }; {2 c( f6 F1 R
顾名思义,钱包是用来保存钱的。但在数字货币的世界中,钱包里面并没有“钱”。钱包账户里有多少“钱”都是记录在区块链上的,钱包里只是存储了账户对应的私钥,账户是从私钥相应的公钥衍生出来的。只要有了私钥,你就可以在数字货币世界里证明你的身份,发送区块链上属于你的资产。因此,钱包实际上是管理和存储私钥的工具。
4 ]. U) n3 O! X% F/ C6 FDagx钱包结构与Bitcoin类似,Bitcoin对管理和存储私钥以及通过私钥生成地址制定了一系列标准(BIP, Bitcoin Improvement Proposals),主要包括:8 G7 P" p+ j4 ?1 q
· BIP32:定义了HD钱包(Hierarchical Deterministic Wallet),允许从单一种子产生一树状结构储存多组私钥和公钥,可以方便的备份、转移以及分层权限控制等。HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生。下图展示了HD钱包的树状结构:
0 Q6 \, h( v5 ^- q" ?! n1 @4 g8 r: P9 U/ r: D1 u% }
BIP39:将种子用方便记忆和书写的单词表示,一般由12个单词组成,称为助记词或助记码。由一系列单词生成种子是个标准化的方法,这样易于在钱包中转移、导出和导入。比如shrimp make call path pink draw gym song select brother social base,其相应的私钥为
- H* v$ P) X) S7 E4 j2 qxprv9s21ZrQH143K4HQ8sBPNNkXHNuVYfivR96gtpJzMWCJVF5hdYjzT5nVQu6GfHAQLPstQtFp9GTWADUcKgzaV5EyL5JxT2rxkyg51ReGTVg8。
4 ^0 M7 t8 h5 y' j) v# _+ LBIP43:为HD钱包路径引入purpose字段,路径记作m / purpose’ / *,比如m / 0’ / *表示BIP32的默认账户。
' Y6 l4 F4 C6 O/ y+ SBIP44:定义HD钱包路径字段,赋予树状结构中的各层特殊的意义,从而支持多币种、多账户,路径定义为:& a% e" i4 ]9 {+ ^" R
m / purpose' / coin_type' / account' / change / address_index8 t- w0 b$ S, F) C& P" G% }8 x
其中,purpose’固定是44’,代表使用BIP44;coin_type’用来表示不同币种,例如Bitcoin就是0’,Bitcoin Testnet是1’,Ethereum是60’;account’表示账户编码;change用来表示该地址是否为找零地址;address_index为地址编号。( Z) m  F4 _7 ]- ]& C7 @
BIP45:定义多签名HD钱包路径字段,从而支持多签名地址,路径定义为:4 k6 o+ }/ e; m3 o  d4 L4 w
m / purpose' / cosigner_index / change / address_index$ @) f# a% q& @: M! j3 |
其中,purpose固定是45’,代表使用BIP45;cosigner_index表示多签名用户编号;其余字段与BIP44相同。
2 w- A0 ]$ x# ]' l5 cDagx钱包采用的是符合BIP44标准的HD钱包,其采用的路径结构为:3 d. _2 j0 r  E* \5 ?% f
m / 44’ / 0’ / account’ / change / address_index! V! F) q1 E0 e, O; o% z! B

/ C5 u5 y  C  _* i; F* V此外,除了使用account来标识账户外,还使用了该账户公钥的哈希值对账户进行唯一表示,表示方法为:  l5 A* I9 E5 g! Q
var wallet = crypto.createHash(“sha256”).update(xPubKey, “utf8”).digest(“base64”);
0 Z$ G& E4 t; LDagx中还有一类特殊的地址,即设备地址,其采用的路径结构为:
6 @" z1 t: A! r# U  z0 c( [m / 1’ / *% o7 L: h- f. C! q; U
Dagx钱包使用了bitcore-lib和bitcore-mnemonic两个库进行钱包管理,简单的使用方法如下:$ K$ A. J. R/ ^3 C4 d' n
var Mnemonic = require('bitcore-mnemonic');
, a# \: V" r1 Y# ~; E  D& s# B# }    var Bitcore = require('bitcore-lib');; A! B+ B. C; i' J; b
// 生成助记词
4 C1 p: _" i7 ~% f7 Z 
5 ]) ?6 n( C+ ?+ ~  o9 s// 'fee decorate step culture autumn game social very lemon drum embrace much'
. x' Z2 F$ \/ ]1 Z2 `- g1 j8 S 
; \. ~9 \5 R% J/ {var mnemonic = new Mnemonic(); . ?  T6 |% H  ?8 B2 \7 o
 ' O7 A- Q+ k. h2 N, D3 j1 c9 U
// 生成HD钱包私钥
! A; }' ?& Z1 J1 W7 G: z# G, l 
" F9 D, w. p5 m0 u* U: u' p% S" C// , [% Y9 ]; m6 ]
 
; I% X& j. u: h" k6 G) A; Svar xPrivKey = mnemonic.toHDPrivateKey(); ; d$ b2 z6 Q! p, f6 n5 ~
 
9 x) |( }/ F$ _- C// 生成HD钱包公钥,account=0  O  B4 ?' Y7 s4 G' I% F$ T# u; s2 z
 
& m8 H: u: |& `( q7 |/ }! V//
! b  _: e. ]0 e  R! `/ t' r' z 5 ]! J  u; a6 s/ \
var xPubKey = Bitcore.HDPublicKey(xPrivKey.derive("m/44'/0'/0'"));
1 z7 L2 ]2 Z  I: z- J , g4 S$ O, |! a6 f
// 生成设备私钥,用于产生设备地址
1 S7 \1 ?1 B  K9 G0 E- e% w2 A 7 O4 t% {# s- c; J4 h" c3 ?/ i9 ^
//
: k! R" Y$ k0 a% |2 I4 p! U. ^ 
( c7 b5 _9 a) @& O# X/ Wvar devicePrivKey = xPrivKey.derive("m/1'");5 u% M; L: G% h9 \% ]- z

2 a9 p1 ^1 j1 T* Y4 D7 \' v地址生成! f, s# r, A" q( M
Dagx中包括三类地址:2 q- [; }4 U) Z# U5 ~4 X& H5 t: B
· 普通地址
; M) U* K# N5 M3 n! y% ~· 共享地址
9 p4 W7 [- B3 u& N- |  v: g3 [3 b· 设备地址$ N% R. `; }# D1 Y+ @
其中,普通地址和共享地址都是通过地址定义脚本生成的,二者的区别类似于Bitcoin中的P2PKH地址和P2SH地址,具体细节可参考《Dagx原理解析(三)地址、脚本及合约》;设备地址是采用设备公钥生成的,地址格式和校验规则与普通地址相同,只是前缀添加了0。
6 J3 A- H5 G8 p给定需要生成地址的对象,Dagx生成地址时采用的是ripemd160哈希,并给地址加上校验,使用的是Dagxcore/object_hash.js中的函数getChash160()函数。6 A4 v+ R7 K; X% O+ F  w
具体来说,设备地址生成方法:$ h2 y% Y; k7 U% y" z0 x3 T2 H3 y
var ecdsa = require('secp256k1'); // 椭圆曲线非对称加密
* C$ ]  ?1 }* g2 e6 |# ^5 [8 Q - m, ^& [5 {6 T" _+ b1 }# {0 N9 N
// 获取设备公钥
$ \) I% m1 m! m" r. K9 y* g! Y 
0 I# o$ c$ H1 C- i1 Jvar pubkey = ecdsa.publicKeyCreate(devicePrivKey.privateKey.bn.toBuffer({size:32}), true).toString('base64');
7 o5 f' }3 ]8 b' x  N( M ) P- S1 [6 ^: w. w
// 生成设备地址
/ u  Y$ n- U1 m  | 6 H. R/ v2 R6 C" @
var objectHash = require('Dagxcore/object_hash.js');
: X  h( e+ v, p; e& V# o: @$ E  ] 0 q0 P8 I3 q' d/ }  j2 P, U
var device_address = '0' + objectHash.getChash160(pubkey);
& y/ N" J# Y' S5 n' I/ [普通地址生成方法:
! {& i# C! P! b' I/ w// change=0 address_index=0,生成公钥
' y( b# c* N' H1 P! f. l% k 7 D7 V, y6 J. E$ W8 K4 i* ]
var pubkey = xPubKey.derive('m/0/0').publicKey.toBuffer().toString('base64');
. x/ ^: }& b' m  |# l9 C ) t9 Y0 F* B2 w0 |
// 设定地址定义脚本,为单签名
: @. v* B& n" P& B. S  R( _- b8 ~ 
0 S" ~7 j# H6 S: u) _var arrDefinition = ["sig", {"pubkey": pubkey}];- r1 N; }( V* ?& C
 7 T6 \9 U7 i! y2 a1 G7 o
// 生成地址% V7 ~( Y* K  l+ r
 
& k& B* ^# N8 X  a4 [2 \var address = objectHash.getChash160(arrDefinition);
% s, z; T. L; j! t% Y7 c共享地址的生成方法与普通地址基本一致,唯一的差别在于地址定义脚本要更加复杂一些。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

    0

  • 关注

    7

  • 主题

    11