Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

DAGX钱包详解

一夜雨十年灯潞
171 0 0
钱包结构
& _# b  ]- d( u2 N" E$ y- w( V顾名思义,钱包是用来保存钱的。但在数字货币的世界中,钱包里面并没有“钱”。钱包账户里有多少“钱”都是记录在区块链上的,钱包里只是存储了账户对应的私钥,账户是从私钥相应的公钥衍生出来的。只要有了私钥,你就可以在数字货币世界里证明你的身份,发送区块链上属于你的资产。因此,钱包实际上是管理和存储私钥的工具。
3 F( l  B: t# V- k- X# FDagx钱包结构与Bitcoin类似,Bitcoin对管理和存储私钥以及通过私钥生成地址制定了一系列标准(BIP, Bitcoin Improvement Proposals),主要包括:
- m/ W$ l2 g. {· BIP32:定义了HD钱包(Hierarchical Deterministic Wallet),允许从单一种子产生一树状结构储存多组私钥和公钥,可以方便的备份、转移以及分层权限控制等。HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生。下图展示了HD钱包的树状结构:
: D* G5 T  }  L. u. o
3 U) J9 v7 U* s2 m2 wBIP39:将种子用方便记忆和书写的单词表示,一般由12个单词组成,称为助记词或助记码。由一系列单词生成种子是个标准化的方法,这样易于在钱包中转移、导出和导入。比如shrimp make call path pink draw gym song select brother social base,其相应的私钥为+ c+ s/ \8 M9 ]3 C6 B7 R; P
xprv9s21ZrQH143K4HQ8sBPNNkXHNuVYfivR96gtpJzMWCJVF5hdYjzT5nVQu6GfHAQLPstQtFp9GTWADUcKgzaV5EyL5JxT2rxkyg51ReGTVg8。
- v( e1 r* z; o5 JBIP43:为HD钱包路径引入purpose字段,路径记作m / purpose’ / *,比如m / 0’ / *表示BIP32的默认账户。4 P$ G; s5 a; C8 p, _
BIP44:定义HD钱包路径字段,赋予树状结构中的各层特殊的意义,从而支持多币种、多账户,路径定义为:5 ^) L# o. R( @! a* k! e
m / purpose' / coin_type' / account' / change / address_index" w; |1 E' Z5 `3 w$ c+ L5 L
其中,purpose’固定是44’,代表使用BIP44;coin_type’用来表示不同币种,例如Bitcoin就是0’,Bitcoin Testnet是1’,Ethereum是60’;account’表示账户编码;change用来表示该地址是否为找零地址;address_index为地址编号。! P$ ^! u' f. j' ^4 C/ k( L
BIP45:定义多签名HD钱包路径字段,从而支持多签名地址,路径定义为:
* H% C- b2 c. @' l" L! h. e5 hm / purpose' / cosigner_index / change / address_index
5 y0 F/ J: G; T4 Y& H, k$ V其中,purpose固定是45’,代表使用BIP45;cosigner_index表示多签名用户编号;其余字段与BIP44相同。! P& E0 z4 P3 e% c+ y2 Q
Dagx钱包采用的是符合BIP44标准的HD钱包,其采用的路径结构为:" }* U1 o0 ^# l! G
m / 44’ / 0’ / account’ / change / address_index) ^5 S1 f' ?( I0 p
5 g' n- d3 r# u8 ?, ?8 I" G
此外,除了使用account来标识账户外,还使用了该账户公钥的哈希值对账户进行唯一表示,表示方法为:1 P; n9 [) N( b+ s5 C
var wallet = crypto.createHash(“sha256”).update(xPubKey, “utf8”).digest(“base64”);+ L, \  X5 O  W1 A1 D/ d
Dagx中还有一类特殊的地址,即设备地址,其采用的路径结构为:
, B  n: M- }, x& b/ Im / 1’ / *) K4 I" }" O) c; A* B2 ?
Dagx钱包使用了bitcore-lib和bitcore-mnemonic两个库进行钱包管理,简单的使用方法如下:7 K, W' c: f2 f7 ^) W4 l
var Mnemonic = require('bitcore-mnemonic');$ D- h& f: g2 J1 h, L" {
    var Bitcore = require('bitcore-lib');% }- e* I0 x/ F2 ?! M* M
// 生成助记词7 x5 P& u+ s( R% Y. A! ~
 
! b6 y/ y; [$ v; Q. E1 q8 T# c// 'fee decorate step culture autumn game social very lemon drum embrace much'
! I0 {2 o/ B9 g. i0 L 
( L" ^# Z# ~/ _$ N" Qvar mnemonic = new Mnemonic(); " z& \* l; h* j0 o: ?
 % G& L8 e& B! p) x  L$ L7 ^1 h
// 生成HD钱包私钥$ z0 w& J2 u" @  ]$ {0 \* }
 " q: F( B4 e( D8 Z7 G) h
//
  [' j  q5 j& d% c  Y5 ~( Z 
  q' U9 _" V2 ?& Avar xPrivKey = mnemonic.toHDPrivateKey();
3 p1 e* Z: W7 h' |. e4 l0 w 
" d1 h* n& @  {, B& f/ H) N$ l& q  n// 生成HD钱包公钥,account=0
; C# }' ?; }' W4 B$ c+ j0 A: U& o 
0 _# G( V+ |/ B1 N  h& O% ?* j# ?//
* M1 U, Q/ V5 ?* H* G% ^ 
% x' d7 Y! x# Ovar xPubKey = Bitcore.HDPublicKey(xPrivKey.derive("m/44'/0'/0'")); 0 W& O5 ]; ]" d2 `/ ~) w
 
& X1 D) T. d# c" O; [2 S// 生成设备私钥,用于产生设备地址, |3 G# F. i2 ]; q4 n$ d! y
 
, C5 g; y1 W: T7 D, K" A* g8 v6 p// " W" e8 P  S1 s: |, o
 
) m! x6 X. V' }0 Z1 \var devicePrivKey = xPrivKey.derive("m/1'");- Z8 k  a7 o3 n% }

- Q& o, w( c1 H. F- X1 ~地址生成
6 K# A5 {, K, XDagx中包括三类地址:( J4 U( c9 M1 C! l$ e
· 普通地址
. ^, ^3 [$ i" w6 S8 Z6 H  g· 共享地址
+ N0 b7 o$ T9 d7 [, @· 设备地址
4 e/ R! R+ R8 [- I4 B3 l$ k其中,普通地址和共享地址都是通过地址定义脚本生成的,二者的区别类似于Bitcoin中的P2PKH地址和P2SH地址,具体细节可参考《Dagx原理解析(三)地址、脚本及合约》;设备地址是采用设备公钥生成的,地址格式和校验规则与普通地址相同,只是前缀添加了0。' F$ I( H6 c5 k7 Z8 w3 _
给定需要生成地址的对象,Dagx生成地址时采用的是ripemd160哈希,并给地址加上校验,使用的是Dagxcore/object_hash.js中的函数getChash160()函数。& _: v  y( q$ n  H; T9 b  @
具体来说,设备地址生成方法:
4 I9 Q+ I' Q: u$ L( D! b+ }; ~5 w, u" nvar ecdsa = require('secp256k1'); // 椭圆曲线非对称加密9 Y7 x% |( x- _, o
 
, |" g2 m0 K4 G, V// 获取设备公钥
+ m0 j- E7 Z6 \$ r- m6 Y 2 R* [0 W& Y" Y
var pubkey = ecdsa.publicKeyCreate(devicePrivKey.privateKey.bn.toBuffer({size:32}), true).toString('base64');! n. b8 j1 g4 d
 7 }$ F+ v$ t5 y& E1 R+ {  m
// 生成设备地址3 O- H' c' @$ ^6 z
 
& u  D8 T& Z  `( s0 {9 g6 j. hvar objectHash = require('Dagxcore/object_hash.js');
2 y/ N' }- w7 O- z, k* Q/ \   L* s8 {$ Y% u
var device_address = '0' + objectHash.getChash160(pubkey);
& J! X2 v9 K9 o6 }$ f. R. z普通地址生成方法:- L9 I5 o  d8 A2 Z; \; O! P' o, U
// change=0 address_index=0,生成公钥% ]8 x( r% X% \: {8 z) y3 n
 9 l* N* m6 m  B* P- _
var pubkey = xPubKey.derive('m/0/0').publicKey.toBuffer().toString('base64');: \7 q2 s% K4 G! i; h
 4 k% h+ k. @8 h3 r/ y3 v
// 设定地址定义脚本,为单签名9 x. t" U) r9 }1 V" n! t7 J! R
 
5 t+ L' r2 B. d5 n9 v0 evar arrDefinition = ["sig", {"pubkey": pubkey}];  I4 X) h  r0 y" j: j4 [) h5 e
 - f6 E6 K- D  C, b
// 生成地址# E5 G$ p4 r+ ^' g
 
2 O# X' G5 C$ _0 [# N3 c. `+ V9 Wvar address = objectHash.getChash160(arrDefinition);& g( E; _0 E% h( [$ G
共享地址的生成方法与普通地址基本一致,唯一的差别在于地址定义脚本要更加复杂一些。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

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

    0

  • 关注

    7

  • 主题

    11