Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

DAGX钱包详解

一夜雨十年灯潞
100 0 0
钱包结构* J$ Y0 `, E2 B7 M  V5 ]) Z6 p
顾名思义,钱包是用来保存钱的。但在数字货币的世界中,钱包里面并没有“钱”。钱包账户里有多少“钱”都是记录在区块链上的,钱包里只是存储了账户对应的私钥,账户是从私钥相应的公钥衍生出来的。只要有了私钥,你就可以在数字货币世界里证明你的身份,发送区块链上属于你的资产。因此,钱包实际上是管理和存储私钥的工具。5 `* B; `. `9 `! i2 v5 j  D/ ~
Dagx钱包结构与Bitcoin类似,Bitcoin对管理和存储私钥以及通过私钥生成地址制定了一系列标准(BIP, Bitcoin Improvement Proposals),主要包括:
- E- z2 Q2 h. c5 H1 p· BIP32:定义了HD钱包(Hierarchical Deterministic Wallet),允许从单一种子产生一树状结构储存多组私钥和公钥,可以方便的备份、转移以及分层权限控制等。HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生。下图展示了HD钱包的树状结构:  M: Z% y, R" L0 q0 y

/ C2 I9 u* ^1 I) O8 e3 i2 IBIP39:将种子用方便记忆和书写的单词表示,一般由12个单词组成,称为助记词或助记码。由一系列单词生成种子是个标准化的方法,这样易于在钱包中转移、导出和导入。比如shrimp make call path pink draw gym song select brother social base,其相应的私钥为
2 ^; p7 f/ Q9 K8 }, t6 u/ jxprv9s21ZrQH143K4HQ8sBPNNkXHNuVYfivR96gtpJzMWCJVF5hdYjzT5nVQu6GfHAQLPstQtFp9GTWADUcKgzaV5EyL5JxT2rxkyg51ReGTVg8。
& S' P5 B4 ~' ]BIP43:为HD钱包路径引入purpose字段,路径记作m / purpose’ / *,比如m / 0’ / *表示BIP32的默认账户。
0 O, y0 P) ~0 S( eBIP44:定义HD钱包路径字段,赋予树状结构中的各层特殊的意义,从而支持多币种、多账户,路径定义为:
  \" r- a* z4 p3 km / purpose' / coin_type' / account' / change / address_index0 `, b8 U' n2 B* v. ~- |
其中,purpose’固定是44’,代表使用BIP44;coin_type’用来表示不同币种,例如Bitcoin就是0’,Bitcoin Testnet是1’,Ethereum是60’;account’表示账户编码;change用来表示该地址是否为找零地址;address_index为地址编号。* J2 U' J* Q9 ]: h- ?
BIP45:定义多签名HD钱包路径字段,从而支持多签名地址,路径定义为:' ^( y; X6 K6 l9 W, ]! ]4 M$ ]2 s9 Z
m / purpose' / cosigner_index / change / address_index$ R! X/ U4 c2 I! S
其中,purpose固定是45’,代表使用BIP45;cosigner_index表示多签名用户编号;其余字段与BIP44相同。' d( _( ]& G( m; R& G$ V+ z7 d4 k
Dagx钱包采用的是符合BIP44标准的HD钱包,其采用的路径结构为:
$ {9 Z' R" V0 ~) ~m / 44’ / 0’ / account’ / change / address_index
, @8 ~: s5 d$ \8 B0 z ) w2 X6 `! G: S+ a' \0 A
此外,除了使用account来标识账户外,还使用了该账户公钥的哈希值对账户进行唯一表示,表示方法为:+ t# `7 e9 Z. u! u- U5 F0 t
var wallet = crypto.createHash(“sha256”).update(xPubKey, “utf8”).digest(“base64”);( J4 z7 c! q. J; [+ B4 e
Dagx中还有一类特殊的地址,即设备地址,其采用的路径结构为:
4 P2 A3 j; V# V1 [m / 1’ / *
1 y5 h: B& h$ e2 g2 K" P" ]3 JDagx钱包使用了bitcore-lib和bitcore-mnemonic两个库进行钱包管理,简单的使用方法如下:7 C6 s# |4 D4 e: h0 P& f3 L
var Mnemonic = require('bitcore-mnemonic');
0 Z: _0 q$ r) z8 O" H) s    var Bitcore = require('bitcore-lib');6 Q2 L% {; |8 ]/ ~
// 生成助记词2 c8 ^* i0 z* e$ ^5 l
 
3 o. w8 M3 o# d' h% B4 F5 Y" D7 g// 'fee decorate step culture autumn game social very lemon drum embrace much'
3 C. |' O& {3 V1 K% I1 ^1 G ! l! B. n) Z" Y; _, F2 s% I
var mnemonic = new Mnemonic(); - O+ a/ C1 _# _) c/ n) w4 M
 
: D0 G8 c- h. {/ c5 M' O1 j" @# H// 生成HD钱包私钥
7 K- N3 t- [" O$ C7 X8 F) o" R 
+ Q) J! ]7 g( C- Z5 q' n) ?//
) Y- t; K6 q0 U+ u! y9 J 
/ @8 t" n7 e- W7 \* ]; vvar xPrivKey = mnemonic.toHDPrivateKey(); 7 g; y* A8 h$ Q4 m  E$ I+ B
 
* Z( K5 d3 Y& N// 生成HD钱包公钥,account=0
3 h- X/ ?3 ]) Q! k4 t' d 3 Q/ U+ Z5 X+ J9 N* }" X( p# r
// ( L7 Y7 r( a$ B+ ~6 N. b  d
 
/ F6 q' |; N  ]% c3 @var xPubKey = Bitcore.HDPublicKey(xPrivKey.derive("m/44'/0'/0'")); 6 X1 j# o  W  l( C& f" M0 D
 & d: m/ `* M% k& L
// 生成设备私钥,用于产生设备地址
% J' F$ [7 S6 Q; c0 D/ W ) V( l& `  U& m& t
// : Q! f0 ~. |! ]5 q7 S) |6 B
 9 y1 w4 L7 \3 |$ O/ s0 n
var devicePrivKey = xPrivKey.derive("m/1'");
& M" o$ T3 r' G5 ^ : g+ R# }2 Q$ i  a
地址生成
5 C7 z/ B+ ~+ ]; l9 B5 jDagx中包括三类地址:4 z" u! s+ y0 B. R4 V7 r) q
· 普通地址( U$ F0 h; l( ^  |% ?# C# U# Z2 x
· 共享地址
7 q8 L$ r* D0 P- n' z7 h) h% [· 设备地址2 g5 s* @1 O: _7 L% I8 p; ?7 g$ i
其中,普通地址和共享地址都是通过地址定义脚本生成的,二者的区别类似于Bitcoin中的P2PKH地址和P2SH地址,具体细节可参考《Dagx原理解析(三)地址、脚本及合约》;设备地址是采用设备公钥生成的,地址格式和校验规则与普通地址相同,只是前缀添加了0。
8 k' b+ s, }4 i给定需要生成地址的对象,Dagx生成地址时采用的是ripemd160哈希,并给地址加上校验,使用的是Dagxcore/object_hash.js中的函数getChash160()函数。; u4 T- ~1 b* r
具体来说,设备地址生成方法:
) _$ W# \& }: h" N: fvar ecdsa = require('secp256k1'); // 椭圆曲线非对称加密
3 ?$ c. m0 S: A3 E5 |( V 
8 ]3 q  K' V, M  x3 ~9 i$ H// 获取设备公钥
" s* Z' x, c* I# V" V& K 
: P1 Q7 o) h- fvar pubkey = ecdsa.publicKeyCreate(devicePrivKey.privateKey.bn.toBuffer({size:32}), true).toString('base64');( m6 R$ [& o  O1 h
 
# `& B* i% B  v: O// 生成设备地址+ r: c. [. c  j3 o- F
 
2 `* G3 e, b3 Ovar objectHash = require('Dagxcore/object_hash.js');2 b9 @: f, `" U2 b4 }1 n
 ) x5 M9 y8 `1 B5 z& }2 n- J
var device_address = '0' + objectHash.getChash160(pubkey);
9 A/ w  D" l: R5 J普通地址生成方法:
$ S  R* Z  M$ x9 C// change=0 address_index=0,生成公钥! T1 E+ O+ ^2 W! T$ ?/ F' i
 ) X$ ~2 E6 l( L6 ^) y5 ~
var pubkey = xPubKey.derive('m/0/0').publicKey.toBuffer().toString('base64');  J6 K0 d6 K, W
 # g1 Y( e+ G3 v/ O- [
// 设定地址定义脚本,为单签名$ J+ ]( ]4 f  I2 E9 x" V
 ! L. ]$ v" X8 `4 i
var arrDefinition = ["sig", {"pubkey": pubkey}];! o' N# ^/ F0 {' B' G) Y" R
 9 X( r2 j+ b7 E' |0 T
// 生成地址
" z5 S' g  D$ K : L9 b$ v. d0 c) u& P
var address = objectHash.getChash160(arrDefinition);
5 k4 A9 A2 p5 u% ?/ N( C共享地址的生成方法与普通地址基本一致,唯一的差别在于地址定义脚本要更加复杂一些。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

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

    0

  • 关注

    7

  • 主题

    11