区块链-创建钱包(以太坊)
一,基本概念
所有问题大体可以分为三类:区块链基本概念,钱包安全知识以及钱包转账交易
1,区块链的基本特性
(1)去中心化
因为整个网络没有中心统治者。系统依靠的是网络上多个参与者的公平约束,所以任意每几个节点的权利和义务都是均等的,而且每一个节点都会储存这个区块链上所有数据。即使该节点被损坏或遭受攻击,仍然不会对账簿造成任何威胁。
(2)不可逆
区块链上的信息必须不可撤销,不能随意销毁。系统是开源的,整个系统都必须是公开透明的,因此某笔交易被全网广播以后,达到 6 个确认以上就成功记录在案了,且不可逆转不可撤销。注: imToken 是 12 个区块确认。
(3)不可篡改
确保信息或合约无法伪造。账簿在某个人或某几人手上,造假的可能性就非常高,但每个人手里都有一本账簿,除非整个游戏里超过51%的人都更改某一笔账目,否则任何的篡改都是无效的,这也是集体维护和监督的优越性。
(4)匿名性
各区块节点的身份信息不需要公告或验证, 信息传递可以匿名进行。举个简单的例子, 就是你在区块链上向一个钱包地址发起交易, 但是却无法知道这个地址背后确切对应的是那一个人, 或者你的私钥被某一个黑客盗窃了, 无法从一个钱包地址中得知黑客是谁。
2,以太坊基本概念
(1)钱包地址
以0x开头的42位的哈希值 (16进制) 字符串
(2)keystore
明文私钥通过加密算法加密过后的 JSON 格式的字符串, 一般以文件形式存储
(3)助记词
12 (或者 15、18、21) 单词构成, 用户可以通过助记词导入钱包, 但反过来讲, 如果他人得到了你的助记词, 不需要任何密码就可以轻而易举的转移你的资产, 所以要妥善保管自己的助记词
(4)明文私钥
64位的16进制哈希值字符串, 用一句话阐述明文私钥的重要性 “谁掌握了私钥, 谁就掌握了该钱包的使用权!” 同样, 如果他人得到了你的明文私钥, 不需要任何密码就可以轻而易举的转移你的资产
通俗地去解释,以银行账户为类比,这些名词分别对应内容如下:
- 钱包地址 = 银行卡号
- 密码 = 银行卡密码
- 私钥 = 银行卡号 + 银行卡密码
- 助记词 = 银行卡号 + 银行卡密码
- Keystore+ 密码 = 银行卡号 + 银行卡密码
- Keystore ≠ 银行卡号
二,创建钱包
1,生成助记词
1 import bip39 from \'react-native-bip39\' 2 getMnemonic()=>{ 3 bip39.generateMnemonic().then(function (mnemonic) { 4 alert(mnemonic) 5 getwallet(mnemonic) 6 }, function (err) { 7 // alert(err) 8 }) 9 }
2,生成Seed与钱包对象wallet
使用助记词计算出Seed,然后得到wallet
1 import crypto from \'crypto\' 2 //HDKey 3 var BITCOIN_VERSIONS = {private: 0x0488ADE4, public: 0x0488B21E} 4 5 function HDKey (versions) { 6 this.versions = versions || BITCOIN_VERSIONS 7 this.depth = 0 8 this.index = 0 9 this._privateKey = null 10 this._publicKey = null 11 this.chainCode = null 12 this._fingerprint = 0 13 this.parentFingerprint = 0 14 } 15 HDKey.fromMasterSeed = function (seedBuffer, versions) { 16 var I = crypto.createHmac(\'sha512\', MASTER_SECRET).update(seedBuffer).digest() 17 var IL = I.slice(0, 32) 18 var IR = I.slice(32) 19 20 var hdkey = new HDKey(versions) 21 hdkey.chainCode = IR 22 hdkey.privateKey = IL 23 24 return hdkey 25 } 26 //WalletHDKey 27 function EthereumHDKey () { 28 } 29 30 function fromHDKey (hdkey) { 31 var ret = new EthereumHDKey() 32 ret._hdkey = hdkey 33 return ret 34 } 35 36 EthereumHDKey.fromMasterSeed = function (seedBuffer) { 37 return fromHDKey(HDKey.fromMasterSeed(seedBuffer)) 38 } 39 //获取钱包对象 40 getwallet = (mnemonic) => { 41 let index = 0 42 var masterSeed = bip39.mnemonicToSeed(mnemonic) 43 var wallet = wallethdkey.fromMasterSeed(masterSeed).derivePath("m/44\'/60\'/0\'/0").deriveChild(index).getWallet() 44 }
3,生成钱包地址与keystore文件
1 1Wallet = function (priv,pub) {this._privKey = priv;this._pubKey = pub}Wallet.prototype.getV3Filename = function (timestamp) { 2 var ts = timestamp ? new Date(timestamp) : new Date() 3 return [ 4 \'UTC--\', 5 ts.toJSON().replace(/:/g, \'-\'), 6 \'--\', 7 this.getAddress().toString(\'hex\') 8 ].join(\'\') 9 } 10 Wallet.prototype.getAddress = function () { 11 return ethUtil.publicToAddress(this.pubKey) 12 } 13 Wallet.prototype.toV3 = function (password, opts, callback) { 14 opts = opts || {} 15 var salt = opts.salt || crypto.randomBytes(32) 16 var iv = opts.iv || crypto.randomBytes(16) 17 var derivedKey 18 var kdf = opts.kdf || \'scrypt\' 19 var kdfparams = { 20 dklen: opts.dklen || 32, 21 salt: salt.toString(\'hex\') 22 } 23 if (kdf === \'pbkdf2\') { 24 kdfparams.c = opts.c || 262144 25 kdfparams.prf = \'hmac-sha256\' 26 derivedKey = crypto.pbkdf2Sync(Buffer.from(password), salt, kdfparams.c, kdfparams.dklen, \'sha256\') 27 } 28 else { 29 throw new Error(\'Unsupported kdf\') 30 } 31 32 var ciphertext = Buffer.concat([ cipher.update(this.privKey), cipher.final() ]) 33 34 var mac = ethUtil.sha3(Buffer.concat([ derivedKey.slice(16, 32), Buffer.from(ciphertext, \'hex\') ])) 35 36 return { 37 version: 3, 38 id: uuid.v4({ random: opts.uuid || crypto.randomBytes(16) }), 39 address: this.getAddress().toString(\'hex\'), 40 crypto: { 41 ciphertext: ciphertext.toString(\'hex\'), 42 cipherparams: { 43 iv: iv.toString(\'hex\') 44 }, 45 cipher: opts.cipher || \'aes-128-ctr\', 46 kdf: kdf, 47 kdfparams: kdfparams, 48 mac: mac.toString(\'hex\') 49 } 50 } 51 52 } 53 getAddressAndWallet=(wallet)=>{ 54 var address = \'0x\' + wallet.getAddress().toString(\'hex\')//获取钱包地址 55 //生成keystore文件 56 let timestamp = (new Date()).valueOf(); 57 wallet.getV3Filename(timestamp);//named keystore file 58 //输入支付宝密码,生成keystore文件 59 //从钱包获取keystore保存在手机的本地文件,防止手机卸载而丢失keystore文件 60 let keystore = wallet.toV3(password, { kdf: \'pbkdf2\' }); 61 }
4,获取私钥,用于交易
1 Wallet.prototype.getPrivateKey = function () { 2 return this.privKey 3 } 4 Wallet.prototype.getPublicKey = function () { 5 return this.pubKey 6 } 7 var privatekey = wallet.getPrivateKey().toString(\'hex\')//获取私钥 8 var getPublicKey = wallet.getPublicKey().toString(\'hex\')