Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

DAGX钱包详解

一夜雨十年灯潞
166 0 0
钱包结构
& Q6 K, P5 i* q& z顾名思义,钱包是用来保存钱的。但在数字货币的世界中,钱包里面并没有“钱”。钱包账户里有多少“钱”都是记录在区块链上的,钱包里只是存储了账户对应的私钥,账户是从私钥相应的公钥衍生出来的。只要有了私钥,你就可以在数字货币世界里证明你的身份,发送区块链上属于你的资产。因此,钱包实际上是管理和存储私钥的工具。1 v, S$ C$ c, d. W% Z/ d( z
Dagx钱包结构与Bitcoin类似,Bitcoin对管理和存储私钥以及通过私钥生成地址制定了一系列标准(BIP, Bitcoin Improvement Proposals),主要包括:. T/ C4 x! G# M) S; m
· BIP32:定义了HD钱包(Hierarchical Deterministic Wallet),允许从单一种子产生一树状结构储存多组私钥和公钥,可以方便的备份、转移以及分层权限控制等。HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生。下图展示了HD钱包的树状结构:0 @, S. k' z7 v( G0 Y, L3 P" x

+ ~8 f, j. I9 H) j: p# z  }; ZBIP39:将种子用方便记忆和书写的单词表示,一般由12个单词组成,称为助记词或助记码。由一系列单词生成种子是个标准化的方法,这样易于在钱包中转移、导出和导入。比如shrimp make call path pink draw gym song select brother social base,其相应的私钥为% @" p# f. k3 L: E9 v: `
xprv9s21ZrQH143K4HQ8sBPNNkXHNuVYfivR96gtpJzMWCJVF5hdYjzT5nVQu6GfHAQLPstQtFp9GTWADUcKgzaV5EyL5JxT2rxkyg51ReGTVg8。
- F/ k% {# f/ z2 SBIP43:为HD钱包路径引入purpose字段,路径记作m / purpose’ / *,比如m / 0’ / *表示BIP32的默认账户。: V: X1 |8 |0 Y
BIP44:定义HD钱包路径字段,赋予树状结构中的各层特殊的意义,从而支持多币种、多账户,路径定义为:
: Y4 x9 k1 Z% t# K( Gm / purpose' / coin_type' / account' / change / address_index
1 _( c1 }8 k' D  Y其中,purpose’固定是44’,代表使用BIP44;coin_type’用来表示不同币种,例如Bitcoin就是0’,Bitcoin Testnet是1’,Ethereum是60’;account’表示账户编码;change用来表示该地址是否为找零地址;address_index为地址编号。( C. c# v  q7 Y( P1 g1 i' q  ?
BIP45:定义多签名HD钱包路径字段,从而支持多签名地址,路径定义为:' v! n* }+ e5 i3 l
m / purpose' / cosigner_index / change / address_index
( Y5 b$ _6 g  k$ u9 {其中,purpose固定是45’,代表使用BIP45;cosigner_index表示多签名用户编号;其余字段与BIP44相同。1 A+ o) A7 k9 T# V9 P
Dagx钱包采用的是符合BIP44标准的HD钱包,其采用的路径结构为:8 d8 W; [7 @7 x$ o/ v
m / 44’ / 0’ / account’ / change / address_index+ D  @2 B4 z8 s; i
# \# z! a6 C6 s. }+ E! P) M# e' O! T
此外,除了使用account来标识账户外,还使用了该账户公钥的哈希值对账户进行唯一表示,表示方法为:
0 h& Z; H" `2 d' evar wallet = crypto.createHash(“sha256”).update(xPubKey, “utf8”).digest(“base64”);
9 x6 T& L8 ?4 L, \Dagx中还有一类特殊的地址,即设备地址,其采用的路径结构为:. i: Q2 d; w; W: b* I
m / 1’ / *7 e) G4 M: E2 q
Dagx钱包使用了bitcore-lib和bitcore-mnemonic两个库进行钱包管理,简单的使用方法如下:
' F$ u# ~0 J+ ^4 R$ T var Mnemonic = require('bitcore-mnemonic');) M7 T& L# r9 @  U8 M9 ^" q
    var Bitcore = require('bitcore-lib');/ q  |# {; x' J) e
// 生成助记词
% [& D4 G: B. q/ \) Y  } 
" f9 V8 I1 l' Y2 `# n6 N" }// 'fee decorate step culture autumn game social very lemon drum embrace much'4 \5 B, E( Q$ r3 t* [; f6 `
 ; R! D* P  q! c
var mnemonic = new Mnemonic();
0 }9 I6 @0 Y( P9 |8 @4 p   e$ u, c# l, t4 M9 R  [/ b
// 生成HD钱包私钥
% K6 K6 }7 i; }; x 
, T2 |$ I; j4 H/ k//
! W9 W8 r/ w1 B* E/ O ) Y) M" G+ x1 B8 U+ x& p
var xPrivKey = mnemonic.toHDPrivateKey();
6 j9 f5 a* K1 O" f2 o4 X6 C5 Q 
5 h7 l& E/ H  Q6 F// 生成HD钱包公钥,account=0
* d! r0 `+ y  }  B# J/ i* s 2 P# z; M  L- A" F: Y' U- u
//
, ~6 J$ G# s2 U% X$ | 
: a5 ~) e0 S& o. ^3 c5 Qvar xPubKey = Bitcore.HDPublicKey(xPrivKey.derive("m/44'/0'/0'")); / A2 @, y; t" H3 Y! p6 B% v: f
 
2 O/ O) m( s$ K  |// 生成设备私钥,用于产生设备地址3 Y+ n  D0 q) G$ I' P
 4 A6 l( {+ V* G4 V+ m) g" L
//
, y* U; A. Y3 i: X- T" [; G & R; A4 W, j- F
var devicePrivKey = xPrivKey.derive("m/1'");
7 M1 T* b; R8 g1 y$ T: \1 M2 V 2 m5 @8 N8 i' ]; k+ K+ f. l" h
地址生成* }' r8 y8 S  c5 G8 I
Dagx中包括三类地址:0 p; {: T: s9 l3 g
· 普通地址
/ w4 p7 u8 d7 U4 V% b2 `" g# C· 共享地址
; o9 q& e& T8 i1 Y· 设备地址
3 _% X# e4 Y* \8 }; S$ f7 _0 Y其中,普通地址和共享地址都是通过地址定义脚本生成的,二者的区别类似于Bitcoin中的P2PKH地址和P2SH地址,具体细节可参考《Dagx原理解析(三)地址、脚本及合约》;设备地址是采用设备公钥生成的,地址格式和校验规则与普通地址相同,只是前缀添加了0。
0 I, V% }5 A. S& L4 f给定需要生成地址的对象,Dagx生成地址时采用的是ripemd160哈希,并给地址加上校验,使用的是Dagxcore/object_hash.js中的函数getChash160()函数。6 l' w6 y) C; {9 p! {$ Z
具体来说,设备地址生成方法:" r0 L+ H" O( L5 |
var ecdsa = require('secp256k1'); // 椭圆曲线非对称加密4 \; R% m, m/ l, H. w; A& b4 K+ Z( b
 - g9 ~. g' s. Y% m8 y& @. l
// 获取设备公钥  g& m5 ~. a5 V* c. G
 
- P0 I0 ~6 z- o. g- q% {var pubkey = ecdsa.publicKeyCreate(devicePrivKey.privateKey.bn.toBuffer({size:32}), true).toString('base64');
) T7 p" ]8 m" a0 L0 Z" k * R7 j! H* Q& o" C' u# J3 V* G1 u6 x, L
// 生成设备地址
6 E; s8 m# P2 W8 K5 y ! {# c2 u6 q  m0 ^, k. g
var objectHash = require('Dagxcore/object_hash.js');
9 c2 R) N$ D2 m& a ; o- E: C% I* U
var device_address = '0' + objectHash.getChash160(pubkey);/ H3 O$ W. q; J/ ?* v
普通地址生成方法:
9 g7 f2 I* b0 ^/ \" ]// change=0 address_index=0,生成公钥
1 R. b% c& M* T, R 
7 j8 b! N+ ^5 ]8 [8 |& n) Mvar pubkey = xPubKey.derive('m/0/0').publicKey.toBuffer().toString('base64');# v( [$ }  e' ]8 V; f2 [( o
 
( ]2 g: Z$ ?, Y// 设定地址定义脚本,为单签名- A+ Q2 H* \6 E. E1 G8 t  P# G
 
$ ~: \6 h3 i+ ^) Xvar arrDefinition = ["sig", {"pubkey": pubkey}];
3 v% t8 t7 L& U6 ~* j 
- @) N& V2 F& l; o5 r// 生成地址8 f0 G  m, H: {( X
 
+ F' \+ R1 P: Jvar address = objectHash.getChash160(arrDefinition);
  K( ?: y6 m( B: O共享地址的生成方法与普通地址基本一致,唯一的差别在于地址定义脚本要更加复杂一些。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

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

    0

  • 关注

    7

  • 主题

    11