Hi 游客

更多精彩,请登录!

比特池塘 区块链技术 正文

DAGX钱包详解

一夜雨十年灯潞
165 0 0
钱包结构! d' z' e% N- D9 d1 q3 z
顾名思义,钱包是用来保存钱的。但在数字货币的世界中,钱包里面并没有“钱”。钱包账户里有多少“钱”都是记录在区块链上的,钱包里只是存储了账户对应的私钥,账户是从私钥相应的公钥衍生出来的。只要有了私钥,你就可以在数字货币世界里证明你的身份,发送区块链上属于你的资产。因此,钱包实际上是管理和存储私钥的工具。
" i6 ]1 e! I/ WDagx钱包结构与Bitcoin类似,Bitcoin对管理和存储私钥以及通过私钥生成地址制定了一系列标准(BIP, Bitcoin Improvement Proposals),主要包括:. z/ }! T. E! _! N- ], z
· BIP32:定义了HD钱包(Hierarchical Deterministic Wallet),允许从单一种子产生一树状结构储存多组私钥和公钥,可以方便的备份、转移以及分层权限控制等。HD钱包包含以树状结构衍生的密钥,使得父密钥可以衍生一系列子密钥,每个子密钥又可以衍生出一系列孙密钥,以此类推,无限衍生。下图展示了HD钱包的树状结构:
- b8 ]! m! O' }2 v0 f- u( {& }8 [9 {! B. C) @
BIP39:将种子用方便记忆和书写的单词表示,一般由12个单词组成,称为助记词或助记码。由一系列单词生成种子是个标准化的方法,这样易于在钱包中转移、导出和导入。比如shrimp make call path pink draw gym song select brother social base,其相应的私钥为# y6 N/ ?( c  F1 a. F
xprv9s21ZrQH143K4HQ8sBPNNkXHNuVYfivR96gtpJzMWCJVF5hdYjzT5nVQu6GfHAQLPstQtFp9GTWADUcKgzaV5EyL5JxT2rxkyg51ReGTVg8。: p% G/ }9 ~. v) J
BIP43:为HD钱包路径引入purpose字段,路径记作m / purpose’ / *,比如m / 0’ / *表示BIP32的默认账户。" s6 ~' Y! _  d9 U
BIP44:定义HD钱包路径字段,赋予树状结构中的各层特殊的意义,从而支持多币种、多账户,路径定义为:' ~, q# A0 b! n* [. S1 G8 _
m / purpose' / coin_type' / account' / change / address_index
& J7 N5 \) L, s0 n6 P% `9 v. x其中,purpose’固定是44’,代表使用BIP44;coin_type’用来表示不同币种,例如Bitcoin就是0’,Bitcoin Testnet是1’,Ethereum是60’;account’表示账户编码;change用来表示该地址是否为找零地址;address_index为地址编号。
' q/ w5 H3 h+ v9 vBIP45:定义多签名HD钱包路径字段,从而支持多签名地址,路径定义为:3 m7 ]0 C, J) Q* C* g4 }! o9 ?
m / purpose' / cosigner_index / change / address_index
$ p# i! v3 u* E其中,purpose固定是45’,代表使用BIP45;cosigner_index表示多签名用户编号;其余字段与BIP44相同。
1 |5 K% @! }2 h( MDagx钱包采用的是符合BIP44标准的HD钱包,其采用的路径结构为:* |  ]0 K# M, z5 P
m / 44’ / 0’ / account’ / change / address_index) i8 s) A/ J$ a
* t0 T' i+ S) E
此外,除了使用account来标识账户外,还使用了该账户公钥的哈希值对账户进行唯一表示,表示方法为:
  J# d/ B5 Y  H, @( f, Ivar wallet = crypto.createHash(“sha256”).update(xPubKey, “utf8”).digest(“base64”);
5 c; u3 y$ a- p; [) X5 V$ D( h0 zDagx中还有一类特殊的地址,即设备地址,其采用的路径结构为:
# {' J% V& n+ T( [. j+ Cm / 1’ / *
: ?+ u7 [* o# y& pDagx钱包使用了bitcore-lib和bitcore-mnemonic两个库进行钱包管理,简单的使用方法如下:/ k" o. z& O# H& s' s
var Mnemonic = require('bitcore-mnemonic');
" n6 ~+ R3 G* T) W    var Bitcore = require('bitcore-lib');
% \& G, o# N( _: c0 p$ L// 生成助记词2 ]+ ?% [/ @9 q0 _9 m; x& |  R4 N
 $ }4 w& t( h' X% g
// 'fee decorate step culture autumn game social very lemon drum embrace much'
# y: X( H- n6 r3 Q 
; d5 N1 b! }. [var mnemonic = new Mnemonic();
* L" H8 T- S6 i( K7 X * d. z4 ]# _$ y  Z! e( m
// 生成HD钱包私钥
' k, x6 {8 {% G1 }/ \, @ 
2 H( w8 U9 [2 n  Y// % ~& e, q( {+ m# d+ t6 k$ E! H) y
 + d5 D/ K. E- m: O1 z3 G9 z# z
var xPrivKey = mnemonic.toHDPrivateKey(); 8 e3 F! l' U; z# i+ P+ U
 * g5 _  Q/ `4 R, f" Z8 m
// 生成HD钱包公钥,account=01 ?8 q# o  T! L! F9 Q' \
 4 A9 I7 [5 ?4 x( i) d$ p
// . D/ |$ e3 M+ _! k! s
 " _/ Q7 i8 \' a1 ?2 C& I
var xPubKey = Bitcore.HDPublicKey(xPrivKey.derive("m/44'/0'/0'")); ) P& Q1 Y4 ]! r4 Y  X, ?9 K+ B
 + A4 z- Y$ \- C% m" B2 p
// 生成设备私钥,用于产生设备地址
: D  ~9 v* ^9 @9 w7 ]6 m) X 3 `' {& v6 \" `0 F; G3 C/ q% ~5 h, u
//
6 g- \' D4 }* P( G$ D' D  d 
& [* [$ I  V$ N0 D, Jvar devicePrivKey = xPrivKey.derive("m/1'");# L" q5 x- n% Z. ~8 D6 o
  h$ V0 ^3 c, R8 k# L+ Y: i
地址生成% Z9 F2 i- }# p
Dagx中包括三类地址:9 V  T1 C7 G4 ]
· 普通地址
* O2 k/ K) W7 d) H· 共享地址& B1 ]0 S  E- j; Y# E0 y) h- z
· 设备地址" Y2 Y! i* T; |
其中,普通地址和共享地址都是通过地址定义脚本生成的,二者的区别类似于Bitcoin中的P2PKH地址和P2SH地址,具体细节可参考《Dagx原理解析(三)地址、脚本及合约》;设备地址是采用设备公钥生成的,地址格式和校验规则与普通地址相同,只是前缀添加了0。0 X" `. q5 T2 B0 B& A
给定需要生成地址的对象,Dagx生成地址时采用的是ripemd160哈希,并给地址加上校验,使用的是Dagxcore/object_hash.js中的函数getChash160()函数。- b8 A4 M0 P5 f) W, G" G
具体来说,设备地址生成方法:: x! w5 Z; j% v5 A
var ecdsa = require('secp256k1'); // 椭圆曲线非对称加密
. _# E# W  B5 B* y9 z) g 2 F2 F1 q9 d" E4 G. S
// 获取设备公钥0 L+ X# l/ O6 A2 d9 B; p
 
0 a6 e4 \0 ^/ P: Qvar pubkey = ecdsa.publicKeyCreate(devicePrivKey.privateKey.bn.toBuffer({size:32}), true).toString('base64');
/ D7 L) i7 |( R; ?" [ ; j5 j3 q$ Z. V6 |( Y  n
// 生成设备地址1 n4 S' l" h+ H2 W+ m
 : G. {; G0 R* ?0 o6 i( j( {- i; n
var objectHash = require('Dagxcore/object_hash.js');3 _; b- J. m+ h; E8 b
 
7 f9 o  l: j! H& N) Svar device_address = '0' + objectHash.getChash160(pubkey);& P/ ~0 x9 A( r( r- c3 u
普通地址生成方法:
8 l! K6 Q0 e+ U6 q6 M. A4 N// change=0 address_index=0,生成公钥; C5 }: d+ `' k
 
5 r! M2 P  S* p4 d# tvar pubkey = xPubKey.derive('m/0/0').publicKey.toBuffer().toString('base64');( S) {5 Z; F* v# e* N* G, B
 8 z% m; b# `; Y
// 设定地址定义脚本,为单签名" k; x: |+ g! I8 T! {( I
 . U4 N; }/ k2 F9 F' H- R" {
var arrDefinition = ["sig", {"pubkey": pubkey}];- ~9 V7 I9 y7 [. u7 r% e. |5 {
 
/ g9 _, a, T9 j% c  z// 生成地址2 K0 v9 g" v6 s. ?5 m) j0 G/ j
 
# _% Z: b8 F. G$ r) F% H8 U- uvar address = objectHash.getChash160(arrDefinition);
; \' M( b- N: u1 F+ x9 H1 N5 |共享地址的生成方法与普通地址基本一致,唯一的差别在于地址定义脚本要更加复杂一些。
BitMere.com 比特池塘系信息发布平台,比特池塘仅提供信息存储空间服务。
声明:该文观点仅代表作者本人,本文不代表比特池塘立场,且不构成建议,请谨慎对待。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

成为第一个吐槽的人

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

    0

  • 关注

    7

  • 主题

    11