Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

DAGX钱包详解

一夜雨十年灯潞
95 0 0
钱包结构
( A/ b/ K- {+ [& p/ g+ F! Y& J顾名思义,钱包是用来保存钱的。但在数字货币的世界中,钱包里面并没有“钱”。钱包账户里有多少“钱”都是记录在区块链上的,钱包里只是存储了账户对应的私钥,账户是从私钥相应的公钥衍生出来的。只要有了私钥,你就可以在数字货币世界里证明你的身份,发送区块链上属于你的资产。因此,钱包实际上是管理和存储私钥的工具。1 i+ ~; t4 _* n! [9 W4 y2 {, e3 H
Dagx钱包结构与Bitcoin类似,Bitcoin对管理和存储私钥以及通过私钥生成地址制定了一系列标准(BIP, Bitcoin Improvement Proposals),主要包括:
5 i' U7 H5 O: j9 v2 k$ M! l· BIP32:定义了HD钱包(Hierarchical Deterministic Wallet),允许从单一种子产生一树状结构储存多组私钥和公钥,可以方便的备份、转移以及分层权限控制等。HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生。下图展示了HD钱包的树状结构:
: j0 i  T, M( q! ?$ `" Y0 Z: T" b. C* c  E8 e/ z7 n
BIP39:将种子用方便记忆和书写的单词表示,一般由12个单词组成,称为助记词或助记码。由一系列单词生成种子是个标准化的方法,这样易于在钱包中转移、导出和导入。比如shrimp make call path pink draw gym song select brother social base,其相应的私钥为
4 F% [* b. l) x+ K8 ?0 z! cxprv9s21ZrQH143K4HQ8sBPNNkXHNuVYfivR96gtpJzMWCJVF5hdYjzT5nVQu6GfHAQLPstQtFp9GTWADUcKgzaV5EyL5JxT2rxkyg51ReGTVg8。
* t7 m0 h6 l( n% _- N0 i- zBIP43:为HD钱包路径引入purpose字段,路径记作m / purpose’ / *,比如m / 0’ / *表示BIP32的默认账户。
/ U! U9 v6 ^, f2 QBIP44:定义HD钱包路径字段,赋予树状结构中的各层特殊的意义,从而支持多币种、多账户,路径定义为:: X) y9 b; L. ]8 |; \) |
m / purpose' / coin_type' / account' / change / address_index
5 O: n# n* K* @) v  E: k$ J其中,purpose’固定是44’,代表使用BIP44;coin_type’用来表示不同币种,例如Bitcoin就是0’,Bitcoin Testnet是1’,Ethereum是60’;account’表示账户编码;change用来表示该地址是否为找零地址;address_index为地址编号。
9 s, [+ w5 T3 `5 @# f/ J3 n2 j4 \BIP45:定义多签名HD钱包路径字段,从而支持多签名地址,路径定义为:
& S/ _7 D9 K6 K0 i  ?% ~m / purpose' / cosigner_index / change / address_index
3 o3 n7 v4 W( L' L" u, n- @其中,purpose固定是45’,代表使用BIP45;cosigner_index表示多签名用户编号;其余字段与BIP44相同。' C. o( T. l, J% n
Dagx钱包采用的是符合BIP44标准的HD钱包,其采用的路径结构为:
, j3 i; E6 g# o! U, p, }) x( Jm / 44’ / 0’ / account’ / change / address_index
3 i( x0 Z7 C7 C( F3 o % a; n1 K, y6 @# y5 t0 ~, K
此外,除了使用account来标识账户外,还使用了该账户公钥的哈希值对账户进行唯一表示,表示方法为:
2 a7 e# W& Q6 H5 [var wallet = crypto.createHash(“sha256”).update(xPubKey, “utf8”).digest(“base64”);; s( }8 V9 ~- `% D% V+ p* B8 U/ u
Dagx中还有一类特殊的地址,即设备地址,其采用的路径结构为:) `8 W2 f- T& i5 z3 A0 }
m / 1’ / *' h2 D" \% I  Y1 ?
Dagx钱包使用了bitcore-lib和bitcore-mnemonic两个库进行钱包管理,简单的使用方法如下:
8 b3 E  `! T' T% i/ P var Mnemonic = require('bitcore-mnemonic');
  D% c2 x; h; ?- \    var Bitcore = require('bitcore-lib');) P  S% p) s/ v( A% V( L, d) U
// 生成助记词. H$ U% n1 ]2 C1 }" @7 K8 S% b1 S: u, {
 
8 [$ j6 j% V3 _+ A$ f// 'fee decorate step culture autumn game social very lemon drum embrace much'8 w$ t# S$ B6 L  w8 w$ }+ Z
 
+ \  s+ z4 h7 A0 W5 N/ |var mnemonic = new Mnemonic();
- E! a5 T/ F1 m, D' P3 @' [3 d 2 V8 ~9 i0 l1 h' I, v7 z
// 生成HD钱包私钥
6 g# j3 f6 e! O 
" F, p; B1 D" ?) }" H//
  p4 ?" _/ ]2 w& O1 n0 f) l  e 2 G8 d8 B5 q7 z. e
var xPrivKey = mnemonic.toHDPrivateKey(); : }/ S2 Q$ p$ @9 g& u) N) u
 
% U. Q$ X. g/ g0 g/ c// 生成HD钱包公钥,account=0
( J8 K+ b- I2 V5 v! |4 q ; ?, ]! m& l$ U3 [# f
//
* W2 B) W/ D% A; Q1 t; X2 | 
2 o/ Q  n3 `. M, Rvar xPubKey = Bitcore.HDPublicKey(xPrivKey.derive("m/44'/0'/0'")); 3 L% `5 B$ W& c( h( {; a
 ! u0 P5 j5 e* l$ U/ t7 L% _
// 生成设备私钥,用于产生设备地址
+ o. A' p/ d6 H/ J5 H, f& R ' R/ [( f2 _' |, n( Y/ J7 Z7 N
//
3 P  q8 P" A6 E: V2 k0 |, n! t' \ 
" d/ P( A( O6 @6 P4 c/ P" Evar devicePrivKey = xPrivKey.derive("m/1'");6 z5 P& [# A( \" u- T
; Q8 ~9 O7 V$ l- k# ]( Q
地址生成
) l% B3 g8 n6 M. [Dagx中包括三类地址:
0 l# x7 [. L" u7 w( l· 普通地址6 u0 u' z% q2 U: K$ u
· 共享地址
" f0 ^: r2 a8 Q0 c2 X9 y· 设备地址
2 J3 i' `+ j2 [9 J其中,普通地址和共享地址都是通过地址定义脚本生成的,二者的区别类似于Bitcoin中的P2PKH地址和P2SH地址,具体细节可参考《Dagx原理解析(三)地址、脚本及合约》;设备地址是采用设备公钥生成的,地址格式和校验规则与普通地址相同,只是前缀添加了0。
3 h( ?7 r6 W0 ]. y4 m. a. J9 `, |给定需要生成地址的对象,Dagx生成地址时采用的是ripemd160哈希,并给地址加上校验,使用的是Dagxcore/object_hash.js中的函数getChash160()函数。
" T; }; }+ |: ?0 |4 O$ ^' Y具体来说,设备地址生成方法:  _. g" k4 u% `3 n7 {6 l6 s
var ecdsa = require('secp256k1'); // 椭圆曲线非对称加密
, @( I; T) f  z) U  T 
% I2 X# ~3 D' ]9 ^: X// 获取设备公钥! Y) f  P8 y( Y& U2 C  R( x
 * P) F4 n& f5 E0 R/ O% w
var pubkey = ecdsa.publicKeyCreate(devicePrivKey.privateKey.bn.toBuffer({size:32}), true).toString('base64');
% q5 D3 c# y( O( v & R8 K4 s2 Q. w3 u
// 生成设备地址
! w& c, c: [# g! F) E8 ?: r3 N 8 p0 t  ^0 [& U5 m1 ^2 X1 T
var objectHash = require('Dagxcore/object_hash.js');
8 Z- c$ @. I7 L9 Q 
5 t% q) {9 }& O: H2 ~# A. Qvar device_address = '0' + objectHash.getChash160(pubkey);
, {* E0 k4 S7 W  F, O$ z* K, h普通地址生成方法:2 c+ b# ~3 N2 ^7 K% c
// change=0 address_index=0,生成公钥. A( L2 F6 r/ }& Z) ^1 K
 
0 @3 ^3 S: Y. ^# T* r7 Pvar pubkey = xPubKey.derive('m/0/0').publicKey.toBuffer().toString('base64');- x' C3 e& ?/ J$ y( G
 
: }; s: l' m1 U! \// 设定地址定义脚本,为单签名" `1 m5 x+ _8 I
 : x. I: l- n4 |
var arrDefinition = ["sig", {"pubkey": pubkey}];
. }- t+ V* W" J! ^) O 
' O6 D# s: I' p' n( y// 生成地址- p/ o# n* u/ ]* D* f, `- D" M
 
- V4 }9 o+ Y+ L& ]+ {' ivar address = objectHash.getChash160(arrDefinition);
2 Z: T! x! t8 j1 @, k共享地址的生成方法与普通地址基本一致,唯一的差别在于地址定义脚本要更加复杂一些。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

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

    0

  • 关注

    7

  • 主题

    11