非對稱加密, 助記詞, PIN, WIF

一錢包

1.1非對稱加密, 助記詞, PIN, WIF, 地址

1.1.1 非對稱加密算法

非對稱加密算法, 加密與解密使用不一樣的KEY, 咱們分別稱爲私鑰與公鑰,其中能夠經過私鑰生成公鑰javascript

在比特幣中, 私鑰本質上就是一個256位的隨機整數。java

ECPair, 是指經過橢圓曲線算法生成 鑰匙對。node

1.1.2 助記詞

在以太坊,私鑰爲128位的隨機數,很是難以記憶。 從而提出了助記詞來幫助記憶私鑰。算法

|128bit (16字節)|4 (checksum)|shell

具體方法爲, 在128位後面追加4位校驗碼。 長度變爲了132位,而後分紅12段,每段11位值查表獲得一個單, 共記12個助記詞npm

1.1.3 PIN

助記詞自己已經表明私鑰了, 可是這種文字很容易以明文顯示展現出來, 爲了安全。 以太坊能夠提供加入我的密碼,稱之爲PIN。以一種鹽的形式混入到私鑰中, 造成另外一個實際私鑰。安全

這就能夠造成keystore文件,該文件含有加密後的私鑰, 須要PIN來解密使用網絡

1.1.4 WIF (Wallet Import Format)

比特幣錢包導入格式,比特幣的私鑰爲256位。 爲了使私鑰看起來更簡潔,使用兩種方式對私鑰進行編碼:dom

非壓縮的私鑰格式: (已經不在使用了)函數

私鑰如:3cf316e3261041028bbced0a8d6b9d06e874d27b3093fe428741ce4458b4d1f3

BASE58(| 1 (0x80)| 256bit(64字節) | 4 (checksum) |) 即,

其中,checksum爲兩次sha256

能夠直接經過wif.encode(0x80, privatekey, fase)生成

結果以5開頭,如5JH8TRekVnj86FaSZEumgA4LDxzUSmLTNe5VUPcCHX8Z4qT4QKA

壓縮的私鑰格式:(當下正在使用格式)

BASE58(| 1 (0x80)| 256bit(64字節) | 1(0x01) | 4 (checksum) |) 即,

其中,checksum爲兩次sha256

能夠直接經過wif.encode(0x80, privatekey, true)生成

結果以K或L開頭,如KyGBudocz4pvJBLboJPvBpyhrE8g8igsQWepftnLouzLXejnQR88

bitcoinjs提供的ECPair老是使用壓縮格式的私鑰表示:

bitcoin = require('bitcoinjs-lib'),
BigInteger = require('bigi');
d = BigInteger.fromBuffer(Buffer.from(privatekey, 'hex')),
keyPair = new bitcoin.ECPair(d);

1.1.5 公鑰

比特幣

const bitcoin = require('bitcoinjs-lib');
wif = 'KyGBudocz4pvJBLboJPvBpyhrE8g8igsQWepftnLouzLXejnQR88',
ecPair = bitcoin.ECPair.fromWIF(wif); // 導入私鑰
// 計算公鑰:
let pubKey = ecPair.getPublicKeyBuffer(); // 返回Buffer對象
console.log(pubKey.toString('hex')); // 02或03開頭的壓縮公鑰

1.1.6 地址

比特幣

特幣的地址並非公鑰,而是公鑰的哈希,即從公鑰能推導出地址,但從地址不能反推公鑰,由於哈希函數是單向函數。

Base58(|1 (0x00) | 20 (hash160) | 4 (check) |)

首先對1+32=33字節的公鑰數據進行Hash160(即先計算SHA256,再計算RipeMD160),獲得20字節的哈希。而後,添加0x00前綴,獲得1+20=21字節數據,再計算4字節校驗碼,拼在一塊兒,總計獲得1+20+4=25字節數據:

address = ecPair.getAddress(); // 返回String地址

如1PwKkrF366RdTuYsS8KWEbGxfP4bikegcS

以太坊

地址是經過對公鑰作Keccak-256哈希,而後取最後的40位16進制字符獲得的。

如:0x24602722816b6cad0e143ce9fabf31f6026ec622

1.2 HD錢包

BIP39:以mnemonic+用戶口令爲種子,經過計算後最終獲得的64字節錢包種子。

以太坊

import Bip39 from 'bip39'
import util from 'ethereumjs-util'
import Wallet from 'ethereumjs-wallet'
var HDKey = require('ethereumjs-wallet/hdkey')
var _seed = Bip39.generateMnemonic(); 
console.log("助記詞:", _seed)
var _pass = "123456"  // 這是用戶自定義密碼PIN

var seedKey = Bip39.mnemonicToSeed(_seed, _pass)
var hdWallet = HDKey.fromMasterSeed(seedKey)
var key = hdWallet.derivePath("m/44'/60'/0'/0/" + _index)
var address = util.pubToAddress(key._hdkey._publicKey, true)
console.log("私鑰:",key._hdkey._privateKey.toString('hex'))
console.log("公鑰:",key._hdkey._publicKey.toString('hex'))
console.log("地址:",address.toString('hex'))

比特幣

var bitcoin = require('bitcoinjs-lib')
var bip39 = require('bip39')
var bip32 = require('bip32')


var _seed = bip39.generateMnemonic(); 
console.log("助記詞:", _seed)
var _pass = "123456"  // 這是用戶自定義密碼PIN

var seed = bip39.mnemonicToSeed(_seed, _pass)
var root  = bip32.fromSeed(seed)
var child0 = root.derivePath("m/44'/0'/0'/0/"+ _index);
console.log("私鑰",child0.privateKey.toString('hex'));
console.log("公鑰",child0.publicKey.toString('hex'));

var seedHex = bip39.mnemonicToSeedHex(_seed, _pass)
var hroot = bitcoin.HDNode.fromSeedHex(seedHex)
var hchild0 = hroot.derivePath("m/44'/0'/0'/0/" + _index);
console.log("地址:",hchild0.getAddress())

1.3 bitcore-lib 操做比特幣

1.3.1 安裝

npm i bitcore-lib

1.3.2 生成測試網地址

var bitcore = require('bitcore-lib');
var Networks = bitcore.Networks;
var PrivateKey = bitcore.PrivateKey;
// 設置成測試網絡
Networks.defaultNetwork = Networks.testnet;
var testKey = PrivateKey.fromRandom();
console.log("private:", testKey.toString());
var pubKey = testKey.publicKey;
console.log("public:", pubKey.toString())
var address = testKey.toAddress();
console.log('address:', address.toString())

輸出結果以下:
console.log("private:", testKey.toString());
private: 2e61e120df72942abdb3c93fce15ef82b855b7a2f1270707feecb34ff8a7730e
undefined
var pubKey = testKey.publicKey;
undefined
console.log("public:", pubKey.toString())
public: 038e2ae27f98b1ff10d4ff658cc846f2260b86123fca26a5edf29a943681a4ab01
undefined
var address = testKey.toAddress();
undefined
console.log('address:', address.toString())
address: mwZogrFFZhb8GqTSm4C7WFfSCJKeVovo4k

對於livenet生成地址如:1KLJV3ocK7w6JXH2f2BdShy2jiuETpTo59

1.3.3 轉帳

用安裝引用包

npm install bitcore-explorers --save
var Insight = require('bitcore-explorers').Insight;
var insight = new Insight('testnet');
var bitcore = require('bitcore-lib');

var Networks = bitcore.Networks;
var PrivateKey = bitcore.PrivateKey;
// 生成地址
var privateKey = PrivateKey('2e61e120df72942abdb3c93fce15ef82b855b7a2f1270707feecb34ff8a7730e', 'testnet');
var address = privateKey.toAddress()

// 目標地址的私鑰爲:99d3bb48b0b9b3493fce26b05c2302359b4a81b93606af1a149c5c2deb2bca6b
// 目標地址爲:mvWrzyVe1QMCcX3XrMEicXbt81Wd3Un35F
var address2 = PrivateKey('99d3bb48b0b9b3493fce26b05c2302359b4a81b93606af1a149c5c2deb2bca6b', 'testnet').toAddress();

insight.getUnspentUtxos(address, function(err,utxos){
    if(err){
        console.log(err);
    }else{
        console.log(utxos);
        var tx = bitcore.Transaction();
        tx.from(utxos);
        tx.to(address2, 100000);
        tx.change(address);
        tx.sign(privateKey);
        console.log("transaction:", tx.toObject());
        txs = tx.serialize();
        
        var scriptIn = bitcore.Script(tx.toObject().inputs[0].script);
        console.log('input script string:', scriptIn.toString());
        var scriptOut = bitcore.Script(tx.toObject().outputs[0].script);
        console.log("output script string:", scriptOut.toString());
        
        //tx.addData();
        insight.broadcast(txs, function(err, returnedTxId){
            if (err){
                console.log(err);
            }else{
                console.log('successful broadcast:' + returnedTxId)
            }
        });        
    }
});

若是有報告以下相似錯誤:

at Object.bitcore.versionGuard (/home/u18/node_modules/bitcore-explorers/node_modules/bitcore-lib/index.js:12:11)

打開文件index.js
bitcore.versionGuard = function(version) {
改成:
bitcore.versionGuard = function(version) { return;

最終正確輸出以下:

successful broadcast:1eff85255798bd3a91935912ff8046dc2511902a7fbbd24cf971f59957a8fae4

這個時候,就能夠把這個交易編號拿https://live.blockcypher.com/btc-testnet/上面去查看了

相關文章
相關標籤/搜索