Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

DAGX钱包详解

一夜雨十年灯潞
72 0 0
钱包结构
+ D2 a) x  ~. v9 l9 H! x% f) ?顾名思义,钱包是用来保存钱的。但在数字货币的世界中,钱包里面并没有“钱”。钱包账户里有多少“钱”都是记录在区块链上的,钱包里只是存储了账户对应的私钥,账户是从私钥相应的公钥衍生出来的。只要有了私钥,你就可以在数字货币世界里证明你的身份,发送区块链上属于你的资产。因此,钱包实际上是管理和存储私钥的工具。4 W4 `4 u, e8 X0 s4 q- @: Q
Dagx钱包结构与Bitcoin类似,Bitcoin对管理和存储私钥以及通过私钥生成地址制定了一系列标准(BIP, Bitcoin Improvement Proposals),主要包括:
3 J6 F1 ~. e8 W; h· BIP32:定义了HD钱包(Hierarchical Deterministic Wallet),允许从单一种子产生一树状结构储存多组私钥和公钥,可以方便的备份、转移以及分层权限控制等。HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生。下图展示了HD钱包的树状结构:
" D7 g  U/ h4 Y& M9 V- ^- {' Z6 Z+ u4 ?4 F5 s9 I2 @% v$ S/ A/ G
BIP39:将种子用方便记忆和书写的单词表示,一般由12个单词组成,称为助记词或助记码。由一系列单词生成种子是个标准化的方法,这样易于在钱包中转移、导出和导入。比如shrimp make call path pink draw gym song select brother social base,其相应的私钥为1 D6 \5 T! e8 g. Z
xprv9s21ZrQH143K4HQ8sBPNNkXHNuVYfivR96gtpJzMWCJVF5hdYjzT5nVQu6GfHAQLPstQtFp9GTWADUcKgzaV5EyL5JxT2rxkyg51ReGTVg8。/ `. E, b1 _! @# h. r5 h8 H$ S
BIP43:为HD钱包路径引入purpose字段,路径记作m / purpose’ / *,比如m / 0’ / *表示BIP32的默认账户。8 E/ Z7 H% e0 L7 C1 @4 R/ S
BIP44:定义HD钱包路径字段,赋予树状结构中的各层特殊的意义,从而支持多币种、多账户,路径定义为:
& a8 h5 ^; e" M7 o# _m / purpose' / coin_type' / account' / change / address_index
2 o' C* F. Z2 l% {其中,purpose’固定是44’,代表使用BIP44;coin_type’用来表示不同币种,例如Bitcoin就是0’,Bitcoin Testnet是1’,Ethereum是60’;account’表示账户编码;change用来表示该地址是否为找零地址;address_index为地址编号。# ~7 a2 b% u2 ]; g/ l
BIP45:定义多签名HD钱包路径字段,从而支持多签名地址,路径定义为:
7 L1 [* ~' w1 E9 f/ ^, C- N- zm / purpose' / cosigner_index / change / address_index/ a. b  X% H2 O7 M
其中,purpose固定是45’,代表使用BIP45;cosigner_index表示多签名用户编号;其余字段与BIP44相同。4 {# O) y1 A1 j1 V7 s/ P
Dagx钱包采用的是符合BIP44标准的HD钱包,其采用的路径结构为:
8 A6 _& `" i6 R7 Z9 Vm / 44’ / 0’ / account’ / change / address_index8 W- y8 a% [! k, L* g5 g+ d- R

+ o9 M( S" i+ O! Y此外,除了使用account来标识账户外,还使用了该账户公钥的哈希值对账户进行唯一表示,表示方法为:
% I( i9 l1 L0 |  x: ?var wallet = crypto.createHash(“sha256”).update(xPubKey, “utf8”).digest(“base64”);
. W0 D; W6 r; b- m. G. O1 m! uDagx中还有一类特殊的地址,即设备地址,其采用的路径结构为:% q: k$ k' c$ V1 V" V0 u" l) f' K
m / 1’ / *9 z6 L: D( U7 I# w$ }" x
Dagx钱包使用了bitcore-lib和bitcore-mnemonic两个库进行钱包管理,简单的使用方法如下:$ b+ F% T1 D" @- V4 K* C7 j4 ?
var Mnemonic = require('bitcore-mnemonic');( c* O+ @+ k# v# ^0 K0 _; d
    var Bitcore = require('bitcore-lib');$ C8 m1 x8 ]9 }6 x# L: L+ _
// 生成助记词
, k) M# A) p; w, L0 P. p ; Q: g0 D4 s( F7 G% u% W# u
// 'fee decorate step culture autumn game social very lemon drum embrace much'
- C+ X& C) h( v* s / x  E+ u6 |6 `( w) R
var mnemonic = new Mnemonic();
0 ~! ^0 O. {8 W3 Q  k! D8 j 7 B! u7 z1 S) O: k  j
// 生成HD钱包私钥9 d% h- _! d) b! U3 l2 r; j$ l) s
 
4 s. J$ d2 S  U# K// + h- v( B: Y* O
 
: e% q1 g% P/ `var xPrivKey = mnemonic.toHDPrivateKey(); ; ?7 P: n4 l# H/ A- r0 f" o
 
/ d( b: I) u" j3 H, ~6 X/ H// 生成HD钱包公钥,account=0
5 _' x* ?/ g/ r* n( }" |5 U 
% v. P: q$ Z' {5 e//
& U0 _- s; F0 c/ \2 N5 ^ ' T" C/ h9 j/ I* D* x. V
var xPubKey = Bitcore.HDPublicKey(xPrivKey.derive("m/44'/0'/0'")); 7 ?7 G# Q5 G' X  Q3 g+ F
 & N+ u; _3 i3 u
// 生成设备私钥,用于产生设备地址* s( Q; j; M  m) Q
 * |8 r# j& [; M1 b# G9 Z
//
1 _& _( K( i1 c 
; Z  |. H' C3 I) Nvar devicePrivKey = xPrivKey.derive("m/1'");
. N  `- j' i. f: B1 [. V) D
: X1 i. l& n; `1 g地址生成$ x6 {0 A( l) j- ]  P. w, D
Dagx中包括三类地址:
7 q% ^, w) ?! Z! H· 普通地址; ]" k$ o6 q! R6 M2 `8 {
· 共享地址. R" C& [* C/ N9 T# v
· 设备地址
; [4 g9 x7 l, G8 C0 Y- h/ _6 X. K7 x其中,普通地址和共享地址都是通过地址定义脚本生成的,二者的区别类似于Bitcoin中的P2PKH地址和P2SH地址,具体细节可参考《Dagx原理解析(三)地址、脚本及合约》;设备地址是采用设备公钥生成的,地址格式和校验规则与普通地址相同,只是前缀添加了0。
) }/ u) _" n- P  X0 [6 B* a- I给定需要生成地址的对象,Dagx生成地址时采用的是ripemd160哈希,并给地址加上校验,使用的是Dagxcore/object_hash.js中的函数getChash160()函数。+ k" W6 R9 N+ z2 M* `, Y
具体来说,设备地址生成方法:
1 X2 v, T& z, M1 ?% yvar ecdsa = require('secp256k1'); // 椭圆曲线非对称加密& T) N- v1 S+ {2 [2 n: W  P
 
3 w2 I$ d# D9 p. W/ R9 n  t$ k// 获取设备公钥7 M( X) q% S7 D0 @
 / l& m* B# Y' A5 f5 T
var pubkey = ecdsa.publicKeyCreate(devicePrivKey.privateKey.bn.toBuffer({size:32}), true).toString('base64');3 q: D( M; ~6 F6 F# `
   r7 w# i9 J2 k# {5 j! B
// 生成设备地址) o/ x6 p$ Q2 j2 B4 `/ T
 
9 R% D9 ]8 l( ovar objectHash = require('Dagxcore/object_hash.js');! u/ L6 p8 \% g9 C
 
3 T* T( k3 `* J/ r6 F) W1 ^var device_address = '0' + objectHash.getChash160(pubkey);
8 A% H" Y4 V- K$ m1 _9 k/ V1 W普通地址生成方法:
, r2 `% t: \3 r% p2 l7 R// change=0 address_index=0,生成公钥  I- r5 z# S. v9 T
 6 S3 Q! S* G& D/ @2 j
var pubkey = xPubKey.derive('m/0/0').publicKey.toBuffer().toString('base64');5 Q8 B: \$ t7 Y$ A+ x/ N
 7 S3 A3 m( Q+ s1 N+ y
// 设定地址定义脚本,为单签名& I- j- l3 r# o. X* s3 z. z3 n5 q
 
( a* x. A; c7 o0 B% O! fvar arrDefinition = ["sig", {"pubkey": pubkey}];
4 E, y4 H$ d5 f! b6 @ 
3 @' b! S& A2 e* I1 G4 U// 生成地址! N- P0 \" v3 U. p
 
5 s( x4 ?( s. E7 Hvar address = objectHash.getChash160(arrDefinition);, l4 o4 _$ s, B6 Y5 y. ?( k
共享地址的生成方法与普通地址基本一致,唯一的差别在于地址定义脚本要更加复杂一些。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

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

    0

  • 关注

    7

  • 主题

    11