Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

DAGX钱包详解

一夜雨十年灯潞
99 0 0
钱包结构
: V! D8 L8 I) Z4 ~顾名思义,钱包是用来保存钱的。但在数字货币的世界中,钱包里面并没有“钱”。钱包账户里有多少“钱”都是记录在区块链上的,钱包里只是存储了账户对应的私钥,账户是从私钥相应的公钥衍生出来的。只要有了私钥,你就可以在数字货币世界里证明你的身份,发送区块链上属于你的资产。因此,钱包实际上是管理和存储私钥的工具。
1 e5 P& q8 h+ F! MDagx钱包结构与Bitcoin类似,Bitcoin对管理和存储私钥以及通过私钥生成地址制定了一系列标准(BIP, Bitcoin Improvement Proposals),主要包括:
0 ?& S7 z( m) S' ~/ }; F  ?· BIP32:定义了HD钱包(Hierarchical Deterministic Wallet),允许从单一种子产生一树状结构储存多组私钥和公钥,可以方便的备份、转移以及分层权限控制等。HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生。下图展示了HD钱包的树状结构:4 }2 h/ {( G0 r. g7 T

1 X5 {( ]6 x6 N3 O# s8 w& cBIP39:将种子用方便记忆和书写的单词表示,一般由12个单词组成,称为助记词或助记码。由一系列单词生成种子是个标准化的方法,这样易于在钱包中转移、导出和导入。比如shrimp make call path pink draw gym song select brother social base,其相应的私钥为
4 E- \+ h" H) C; Sxprv9s21ZrQH143K4HQ8sBPNNkXHNuVYfivR96gtpJzMWCJVF5hdYjzT5nVQu6GfHAQLPstQtFp9GTWADUcKgzaV5EyL5JxT2rxkyg51ReGTVg8。  R7 w+ e: S2 D4 _7 h  H+ G
BIP43:为HD钱包路径引入purpose字段,路径记作m / purpose’ / *,比如m / 0’ / *表示BIP32的默认账户。
% \4 {( a  i' QBIP44:定义HD钱包路径字段,赋予树状结构中的各层特殊的意义,从而支持多币种、多账户,路径定义为:. @8 V0 t9 g; ^* s  ?! k0 a5 `% {% ~
m / purpose' / coin_type' / account' / change / address_index
) U8 ]2 q9 i- [% \& C其中,purpose’固定是44’,代表使用BIP44;coin_type’用来表示不同币种,例如Bitcoin就是0’,Bitcoin Testnet是1’,Ethereum是60’;account’表示账户编码;change用来表示该地址是否为找零地址;address_index为地址编号。
8 s. Q: H5 ~2 u6 UBIP45:定义多签名HD钱包路径字段,从而支持多签名地址,路径定义为:8 A1 H9 T0 s( w6 W" N) a2 e
m / purpose' / cosigner_index / change / address_index
9 W: X. M& f1 y0 c% C其中,purpose固定是45’,代表使用BIP45;cosigner_index表示多签名用户编号;其余字段与BIP44相同。0 N4 M3 U; h1 m! o
Dagx钱包采用的是符合BIP44标准的HD钱包,其采用的路径结构为:
1 e- f/ \/ ]% u% i5 [m / 44’ / 0’ / account’ / change / address_index' B8 W" o0 V( [+ S2 X

+ k" y# K& L$ j1 w此外,除了使用account来标识账户外,还使用了该账户公钥的哈希值对账户进行唯一表示,表示方法为:( [/ }" K3 S. X
var wallet = crypto.createHash(“sha256”).update(xPubKey, “utf8”).digest(“base64”);) ], F% P' {# H, L2 B- u' H
Dagx中还有一类特殊的地址,即设备地址,其采用的路径结构为:) t7 e' X  G8 Z/ y
m / 1’ / *
; s: w* b7 F: e5 L5 kDagx钱包使用了bitcore-lib和bitcore-mnemonic两个库进行钱包管理,简单的使用方法如下:, Q$ s' F" ~/ u! ?9 e9 Y& ?
var Mnemonic = require('bitcore-mnemonic');
( C6 d) Q/ I/ p$ W    var Bitcore = require('bitcore-lib');
. H4 e( t: H6 x  g, Q// 生成助记词! j6 k' U, O8 l4 C' f' ]1 Q
 / L1 p. a+ M* G
// 'fee decorate step culture autumn game social very lemon drum embrace much'. I/ C9 X* s4 A3 x0 o) L' E- Z
 ! v+ I! O( w; L2 _, w7 y% s, H1 Y
var mnemonic = new Mnemonic();
& Y/ j8 Y1 m# Z) F " E% v; k" D4 ], h0 U2 @
// 生成HD钱包私钥
8 u% w! O( |6 J: Q) y5 D 5 p  [3 C" L' Q7 r7 M
// 3 ^3 z/ e- o% R- i2 X8 K
 ( K+ r8 ^, m  c0 h
var xPrivKey = mnemonic.toHDPrivateKey(); ' U$ N  Q+ S1 P* z2 M9 p3 R
 6 [% @' k  K& N$ J
// 生成HD钱包公钥,account=0: i+ _$ E7 P8 F9 o% m4 Z# s/ W
 
- V5 p# [  Y3 N//
. e- _5 c5 o+ ~! j* c/ g 8 S' ^$ [$ X, N2 o  `
var xPubKey = Bitcore.HDPublicKey(xPrivKey.derive("m/44'/0'/0'"));   N2 H8 Z: T) [' K% E
 
, T1 A, W. C- a/ p// 生成设备私钥,用于产生设备地址
% E( K5 M3 z2 f1 d* G0 A 
7 @4 @0 ^$ A+ j% P5 o//
, M2 E1 o- K2 l1 p 
; \7 S0 [/ g' A0 bvar devicePrivKey = xPrivKey.derive("m/1'");
! W1 [( r7 P# e * a" e. P' e  |& z9 n
地址生成
( N" d- i/ p! }7 d8 jDagx中包括三类地址:
6 P4 {; m0 X& S! B9 K; R& P# Y+ Z· 普通地址1 a7 I6 t; H, F! \2 v, u" A6 {% o
· 共享地址
) N. V  |( p4 K% n· 设备地址
5 l" W, y* {. J/ P; p; o其中,普通地址和共享地址都是通过地址定义脚本生成的,二者的区别类似于Bitcoin中的P2PKH地址和P2SH地址,具体细节可参考《Dagx原理解析(三)地址、脚本及合约》;设备地址是采用设备公钥生成的,地址格式和校验规则与普通地址相同,只是前缀添加了0。4 @- g! Z2 T# \
给定需要生成地址的对象,Dagx生成地址时采用的是ripemd160哈希,并给地址加上校验,使用的是Dagxcore/object_hash.js中的函数getChash160()函数。' n, L9 {" f# z
具体来说,设备地址生成方法:7 f& {0 j3 h7 I+ V; p# i8 z
var ecdsa = require('secp256k1'); // 椭圆曲线非对称加密1 L7 M' ^! y  ]* V1 m
 4 p/ V4 c) o! K$ ?* e
// 获取设备公钥( ^9 E9 ~: v# q
 
( S& d" H/ b: d: _var pubkey = ecdsa.publicKeyCreate(devicePrivKey.privateKey.bn.toBuffer({size:32}), true).toString('base64');, v: s" Y1 ^# w: R" K4 e/ A; T
 , L/ G: H1 T" [9 {7 V
// 生成设备地址
' f: H5 ]: G* o& L 
$ c8 @: f0 C& m3 r; F1 w' Fvar objectHash = require('Dagxcore/object_hash.js');
8 ]2 K4 H5 b, M) Y3 @) C ! ?+ R! L* b! o: g( O8 N" s
var device_address = '0' + objectHash.getChash160(pubkey);
3 {; c; [- A% L5 u普通地址生成方法:7 l' e- W% I) S; E
// change=0 address_index=0,生成公钥, T% e! i  m( K/ R
 2 p8 {. E8 `8 O
var pubkey = xPubKey.derive('m/0/0').publicKey.toBuffer().toString('base64');3 e) Z# s* p) g
 
  g! f4 C) P, b( \// 设定地址定义脚本,为单签名; V- q8 p* |: j1 N5 V3 s8 z
 + o# E+ T0 B% H# q4 s# ]' f+ a
var arrDefinition = ["sig", {"pubkey": pubkey}];$ \7 Q, g2 }# t9 m3 u; e/ g4 Y
 
# W7 j! L" U$ c6 g/ H// 生成地址% E* `, h1 o6 y; l
 . Z. i0 G7 }, d, |0 o
var address = objectHash.getChash160(arrDefinition);' Y! h  `! g& ]' f! w" o9 `3 Z
共享地址的生成方法与普通地址基本一致,唯一的差别在于地址定义脚本要更加复杂一些。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

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

    0

  • 关注

    7

  • 主题

    11