Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

DAGX钱包详解

一夜雨十年灯潞
167 0 0
钱包结构
: b  ~9 s: p0 J& z3 }  `5 e$ g& X顾名思义,钱包是用来保存钱的。但在数字货币的世界中,钱包里面并没有“钱”。钱包账户里有多少“钱”都是记录在区块链上的,钱包里只是存储了账户对应的私钥,账户是从私钥相应的公钥衍生出来的。只要有了私钥,你就可以在数字货币世界里证明你的身份,发送区块链上属于你的资产。因此,钱包实际上是管理和存储私钥的工具。3 u" h4 {/ V! h6 u' Q
Dagx钱包结构与Bitcoin类似,Bitcoin对管理和存储私钥以及通过私钥生成地址制定了一系列标准(BIP, Bitcoin Improvement Proposals),主要包括:
, l: @# ~. \( ~3 }4 U/ p· BIP32:定义了HD钱包(Hierarchical Deterministic Wallet),允许从单一种子产生一树状结构储存多组私钥和公钥,可以方便的备份、转移以及分层权限控制等。HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生。下图展示了HD钱包的树状结构:
' ]8 E3 K- k) {, z/ Q
' h, F  F8 v( f$ tBIP39:将种子用方便记忆和书写的单词表示,一般由12个单词组成,称为助记词或助记码。由一系列单词生成种子是个标准化的方法,这样易于在钱包中转移、导出和导入。比如shrimp make call path pink draw gym song select brother social base,其相应的私钥为" k% [* W, f7 |# S" U
xprv9s21ZrQH143K4HQ8sBPNNkXHNuVYfivR96gtpJzMWCJVF5hdYjzT5nVQu6GfHAQLPstQtFp9GTWADUcKgzaV5EyL5JxT2rxkyg51ReGTVg8。/ I1 ?3 x4 S9 z3 K5 Q: B
BIP43:为HD钱包路径引入purpose字段,路径记作m / purpose’ / *,比如m / 0’ / *表示BIP32的默认账户。
: h; n$ D$ Z* F& qBIP44:定义HD钱包路径字段,赋予树状结构中的各层特殊的意义,从而支持多币种、多账户,路径定义为:
) k2 b# L% c  k% ~& }m / purpose' / coin_type' / account' / change / address_index
% j+ [, |- L/ q; {. k" p* X其中,purpose’固定是44’,代表使用BIP44;coin_type’用来表示不同币种,例如Bitcoin就是0’,Bitcoin Testnet是1’,Ethereum是60’;account’表示账户编码;change用来表示该地址是否为找零地址;address_index为地址编号。8 C6 A% Q+ V( t# h9 q, [  g3 x( K
BIP45:定义多签名HD钱包路径字段,从而支持多签名地址,路径定义为:
( k+ |. ^' T; z/ K3 V5 i4 d5 Lm / purpose' / cosigner_index / change / address_index* ?6 g( S2 |0 s$ A5 Y: A1 J
其中,purpose固定是45’,代表使用BIP45;cosigner_index表示多签名用户编号;其余字段与BIP44相同。3 i( R8 ^4 Y  O' a4 Q
Dagx钱包采用的是符合BIP44标准的HD钱包,其采用的路径结构为:
/ }& _5 z: J% p/ V/ bm / 44’ / 0’ / account’ / change / address_index- m8 v! u( Z' L  t5 e1 y$ l* @; D
- i" b$ D- b9 L! k1 t
此外,除了使用account来标识账户外,还使用了该账户公钥的哈希值对账户进行唯一表示,表示方法为:
7 |( Y" O9 k, evar wallet = crypto.createHash(“sha256”).update(xPubKey, “utf8”).digest(“base64”);' [; k8 d  {$ X* i& I
Dagx中还有一类特殊的地址,即设备地址,其采用的路径结构为:6 V; Z7 ?! H/ U, v2 D
m / 1’ / *
* C9 t3 A7 D% WDagx钱包使用了bitcore-lib和bitcore-mnemonic两个库进行钱包管理,简单的使用方法如下:
! f8 D1 \$ z$ A( i  f var Mnemonic = require('bitcore-mnemonic');; M# a) p- s# S8 \* q: ^
    var Bitcore = require('bitcore-lib');2 Z6 M, E" b# O7 ]5 z
// 生成助记词6 |1 B' h1 H4 ^* O' P3 y! U9 J
 6 p% C- V* Z: q6 w! b5 Z
// 'fee decorate step culture autumn game social very lemon drum embrace much'
% [1 }( }6 v- C! A; h9 ?$ i5 T ) b- {: h+ U3 ]2 H7 G: y
var mnemonic = new Mnemonic(); , ~/ Z4 {: x, Q& l6 k- j  {
 
: {: {9 C' N$ k5 y+ @. d// 生成HD钱包私钥
& r$ q7 c! n- ] 
3 V3 k" p" \, {+ e// ; K4 U; U, v  r1 l
 
/ S- |0 G; S; G, Z* \var xPrivKey = mnemonic.toHDPrivateKey(); : W. `+ h8 s. d" e9 O! R" L1 U6 A* S
 
% K, A3 l" M9 \# X// 生成HD钱包公钥,account=0, S3 r" X4 `8 G: Y
 / [2 ~7 n* \: C$ S( E
// 2 J  ^, D3 H4 l& i$ y- b
 
: N) r6 q8 N2 p  hvar xPubKey = Bitcore.HDPublicKey(xPrivKey.derive("m/44'/0'/0'"));
  r" G' b6 I; U. N' R 
1 T* h$ k# h) Y: S% E: Q! F3 O// 生成设备私钥,用于产生设备地址4 A$ i" u" Z2 Q( l* s
 ) |  r* M2 u0 V( M$ b3 N) C  s; x
//
9 n4 c  Q2 P! V& E+ {! a) M 4 R" d7 f  H+ u9 _7 C4 m
var devicePrivKey = xPrivKey.derive("m/1'");
# y& a7 V* w2 }/ `! d5 \ : S) R2 W% _2 g7 T
地址生成) J) k6 y" F9 M5 f& Z: \
Dagx中包括三类地址:( e7 q1 v7 U, _' X+ f
· 普通地址$ [: d3 v% j- [$ H5 `+ C' y# b
· 共享地址
" e+ m% G. s8 N4 X· 设备地址: B) A% X7 u: `: I% J
其中,普通地址和共享地址都是通过地址定义脚本生成的,二者的区别类似于Bitcoin中的P2PKH地址和P2SH地址,具体细节可参考《Dagx原理解析(三)地址、脚本及合约》;设备地址是采用设备公钥生成的,地址格式和校验规则与普通地址相同,只是前缀添加了0。+ b8 A; k3 @; W$ @/ p6 z
给定需要生成地址的对象,Dagx生成地址时采用的是ripemd160哈希,并给地址加上校验,使用的是Dagxcore/object_hash.js中的函数getChash160()函数。2 `7 T' s- X, V( Z% s& k
具体来说,设备地址生成方法:
' L; q0 W& a- Z2 Jvar ecdsa = require('secp256k1'); // 椭圆曲线非对称加密
+ M5 _7 k7 B' ]4 y  f- @4 \$ z 
; e/ z5 u5 c. {* C2 u6 l: D// 获取设备公钥
6 J9 b  m0 t1 k( v0 z1 N: F - E3 `  M! ?; j2 `8 O1 Y: Y7 g
var pubkey = ecdsa.publicKeyCreate(devicePrivKey.privateKey.bn.toBuffer({size:32}), true).toString('base64');
- P$ X$ Y" _  v6 K3 Z 
. c8 G0 {% ^9 p3 A// 生成设备地址
: l0 s& U/ ~; {2 m . q. B- d3 L: U: G% ]# m; g8 W
var objectHash = require('Dagxcore/object_hash.js');
. r: a6 I; @+ S2 y! o 
4 w0 [2 i9 E1 [/ kvar device_address = '0' + objectHash.getChash160(pubkey);
* E9 E: q7 Z- o/ A普通地址生成方法:
$ e+ e% J# y  D) s// change=0 address_index=0,生成公钥
& R8 Z! o% p9 T7 K: E7 t$ Q" A 
' q" b" P3 D+ T: x4 Uvar pubkey = xPubKey.derive('m/0/0').publicKey.toBuffer().toString('base64');
' D( L8 |* s! D/ N, G. m  f& i/ P % e; ~, L: @( f; t( E
// 设定地址定义脚本,为单签名
) g( H, W9 Q; C 
8 h+ z1 Y3 C' t! i3 d% K/ D& Svar arrDefinition = ["sig", {"pubkey": pubkey}];( Q6 a1 E) \" e) r
 
$ R, y6 [) T0 G// 生成地址  A' t( \3 m9 Y" B
 0 i; q; X  _! X' X4 n' V
var address = objectHash.getChash160(arrDefinition);2 H* ]! v1 A7 P0 G4 h: Y! l
共享地址的生成方法与普通地址基本一致,唯一的差别在于地址定义脚本要更加复杂一些。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

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

    0

  • 关注

    7

  • 主题

    11