您好,登錄后才能下訂單哦!
用JavaScript開發比特幣應用BitcoinJS-lib的過程是怎樣的,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。
在這個教程中,我們將學習如何使用Bitconjs-lib開發庫來開發一個簡單的JavaScript版本的比特幣應用。我們要實現的特性包括:離線創建比特幣私鑰和地址、進行賬戶充值、離線構造轉賬裸交易并廣播到比特幣網絡中等。
BitcoinJS-lib是一個npm包,可以用于node.js或瀏覽器javascript環境中。可以使用npm或yarn安裝BitcoinJS-lib開發包:
npm install bitcoinjs-lib
首先引入bitcoinjs-lib開發庫:
const Btc = require('bitcoinjs-lib')
比特幣的主鏈和測試鏈有不同的網絡參數,出于簡化和安全性考慮,我們使用測試鏈來開發這個教程中的應用,因此引入測試鏈網絡參數:
const TestNet = Btc.networks.testnet
每個比特幣地址都對應一對密鑰(私鑰和公鑰),因此我們首先用BitcoinJS創建密鑰對并從密鑰對推導出地址:
let keyPair = Btc.ECPair.makeRandom({ network: TestNet }) let address = keyPair.getAddress() let wifKey = keyPair.toWIF() console.log(`Address: ${address} \n WifKey: ${wifKey}`)
在上邊的代碼中,我們首先使用BitcoinJS的ECPair
類的靜態方法makeRandom()
生成一個隨機密鑰對,然后使用密鑰對的getAddress()
方法推導出對應的比特幣地址,并使用toWif()
獲取WIF格式的私鑰,最后顯示出得到的地址和WIF格式的私鑰。
代碼運行結果如下(你的結果應該與此不同):
Address: mqVKYrNJcMkdK2QHFNEd1P6Qfc1Sqs3hu1 WifKey: cTEAh3DsC7KE4mzY5YFTYommzr7czbdiBfLPsXZrF6o3zSQLLw9Q
如果你有其他錢包到處的WIF格式的私鑰,也可以導入BitcoinJS并推導出對應的地址,例如:
let wifKey = 'cTEAh3DsC7KE4mzY5YFTYommzr7czbdiBfLPsXZrF6o3zSQLLw9Q' let keyPair = new Btc.ECPair.fromWIF(privKey, TestNet) console.log("Address:", keyPair.getAddress())
結果類似如下:
Address: mqVKYrNJcMkdK2QHFNEd1P6Qfc1Sqs3hu1
要記住私鑰有點麻煩,我們可以用密碼來輔助推導私鑰,這樣就可以進一步推導出公鑰和地址。下面的代碼使用BitcoinJS和nodejs大數計算庫bigi實現:
const BigInteger = require('bigi') let passphrase = 'J@vaScr1pt' let keyPair = generateAddressFromSHA256Hash(passphrase); console.log('Address: ', keyPair.getAddress()) function generateAddressFromSHA256Hash(passphrase) { let hash = Btc.crypto.sha256(passphrase); let d = BigInteger.fromBuffer(hash); let keyPair = new Btc.ECPair(d, null, { network: TestNet }); return keyPair; }
結果如下:
Address: mqVKYrNJcMkdK2QHFNEd1P6Qfc1Sqs3hu1
現在使用generateAddressFromSHA256Hash()
函數,我們就可以在任何時候用J@VaSc1pt
這個密碼來會付出地址mqVKYrNJcMkdK2QHFNEd1P6Qfc1Sqs3hu1
以及其對應的密鑰對了。
在繼續之前,我們需要為創建的比特幣地址充點比特幣。在網上有一些比特幣測試鏈的Faucet,可以用來為任意指定的比特幣地址充入一些比特幣以便進行開發和測試。我使用的是這個,當然你可以搜索出更多的這種Faucet。
讓Faucet給我們的測試地址充值結果如下:
cool,現在我們有了1.3個比特幣可以繼續測試了!
有兩種辦法查詢一個比特幣地址的余額、UTXO等信息:使用自己的節點,或者使用第三方API。出于簡化考慮,在本教程中我們使用第三方API來查詢指定比特幣地址的余額與UTXO:
onst request = require('request'); let addr = 'mqVKYrNJcMkdK2QHFNEd1P6Qfc1Sqs3hu1' let apiUrl = 'https://testnet.blockexplorer.com/api/addr/' // log unspent transactions request.get(apiUrl + addr + '/utxo', (err, req, body) => { console.log('utxo => ', JSON.parse(body)) } ); // log balance request.get(apiUrl + addr + '/balance', (err, req, body) => { console.log('balance => ', JSON.parse(body)) } );
結果如下:
utxo => [{ address: 'mqVKYrNJcMkdK2QHFNEd1P6Qfc1Sqs3hu1', txid: '2d742aa8409ee4cd8afcb2f59aac6ede47b478fafbca2335c9c04c6aedf94c9b', vout: 0, scriptPubKey: '76a9146d622b371423d2e450c19d98059867d71e6aa87c88ac', amount: 1.3, satoshis: 130000000, height: 1180957, confirmations: 14 }] balance => 130000000 // 1.3 BTC = 130000000 satoshis
構造比特幣裸交易要復雜一點,我們需要自己組織交易的輸入和輸出。
首先用BitcoinJS的交易構造器TransactionBuider
創建一個交易對象:
let tx = new Btc.TransactionBuilder(TestNet)
然后我們聲明轉出賬號和轉入賬號:
let keyPair1 = generateAddressFromSHA256Hash('J@vaScr1pt') let keyPair2 = generateAddressFromSHA256Hash('B*tc0in')
然后聲明轉賬金額、手續費等參數,并計算找零金額:
let amountWeHave = 130000000 // 1.3 BTC let amountToKeep = 100000000 // 1 BTC let transactionFee = 1000 // .00001 BTC let amountToSend = amountWeHave - amountToKeep - transactionFee
好了,現在可以為交易添加輸入了。還記得前面我們查詢出來的交易輸出嗎?這個交易輸出我們將用作新交易的輸入:
[{ txid: '2d742aa8409ee4cd8afcb2f59aac6ede47b478fafbca2335c9c04c6aedf94c9b', vout: 0, satoshis: 130000000, }]
使用BitcoinJS交易對象的addInput()
方法添加交易輸入:
tx.addInput('2d742aa8409...', 0)
接下來添加交易輸出,我們需要聲明交易輸出目標地址和金額:
tx.addOutput(keyPair2.getAddress(), amountToSend)
由于交易輸入金額大于上述交易輸出金額,因此我們還需要添加找零輸出:
tx.addOutput(keyPair1.getAddress(), amountToKeep)
現在我們進行簽名,由于用的是keyPair1的比特幣,因此需要使用keyPair1的私鑰進行簽名:
tx.sign(0, keyPair1)
接下來把簽名交易序列化為16進制碼流,以便廣播到比特幣網絡中:
let tx_hex = tx.build().toHex()
完整的代碼如下:
let tx = new Btc.TransactionBuilder(TestNet) let keyPair1 = generateAddressFromSHA256Hash('J@vaScr1pt') let keyPair2 = generateAddressFromSHA256Hash('B*tc0in') let amountWeHave = 130000000 // 1.3 BTC let amountToKeep = 100000000 // 1 BTC let transactionFee = 1000 // .00001 BTC let amountToSend = amountWeHave - amountToKeep - transactionFee tx.addInput('2d742aa8409ee4cd8afcb2f59aac6ede47b478fafbca2335c9c04c6aedf94c9b', 0) tx.addOutput(keyPair2.getAddress(), amountToSend) tx.addOutput(keyPair1.getAddress(), amountToKeep) tx.sign(0, keyPair1) let tx_hex = tx.build().toHex()console.log('our beautiful transaction: ', tx_hex)
輸出結果如下:
01000000019b4cf9ed6a4cc0c93523cafbfa78b447de6eac9af5b2fc8acde49e40 a82a742d000000006b483045022100b8e1bc891bbd910960cf00b52b87493ddf80 8c0b6816b05724b62c507c2ea552022071d775d9b89e0bbc1c2d1b907b700dbda5 8d880508ba7f6e11a3acc659d3ebe20121034ec9060d1935b235794e22f5335b4e 5c55e764ba9bddab2cf7f199dac7309ce1ffffffff0298bfc901000000001976a9 1423e6e135110f5fcacbd77323382bb70e4f76105f88ac00e1f505000000001976 a9146d622b371423d2e450c19d98059867d71e6aa87c88ac00000000
在廣播裸交易之前,檢查一下裸交易的內容是一種有效的調試方法。我們可以使用BlockCypher提供的解碼工具來查看裸交易的內容,結果如下
{ "addresses": [ "mqVKYrNJcMkdK2QHFNEd1P6Qfc1Sqs3hu1", "minnXa8Qarg5WbxPQg3vjLZdpbZGHavCzC" ], "block_height": -1, "block_index": -1, "confirmations": 0, "double_spend": false, "fees": 1000, "hash": "64697ab2a3c76b8c5930ca128316238bba5b172b2f8f61a0046b6630b1f80f08", "inputs": [ { "addresses": [ "mqVKYrNJcMkdK2QHFNEd1P6Qfc1Sqs3hu1" ], "age": 1180957, "output_index": 0, "output_value": 130000000, "prev_hash": "2d742aa8409ee4cd8afcb2f59aac6ede47b478fafbca2335c9c04c6aedf94c9b", "script": "483045022100b8e1bc891bbd910960cf00b52b87493ddf808c0b6816b05724b62c507c2ea552022071d775d9b89e0bbc1c2d1b907b700dbda58d880508ba7f6e11a3acc659d3ebe20121034ec9060d1935b235794e22f5335b4e5c55e764ba9bddab2cf7f199dac7309ce1", "script_type": "pay-to-pubkey-hash", "sequence": 4294967295 } ], "outputs": [ { "addresses": [ "minnXa8Qarg5WbxPQg3vjLZdpbZGHavCzC" ], "script": "76a91423e6e135110f5fcacbd77323382bb70e4f76105f88ac", "script_type": "pay-to-pubkey-hash", "value": 29999000 }, { "addresses": [ "mqVKYrNJcMkdK2QHFNEd1P6Qfc1Sqs3hu1" ], "script": "76a9146d622b371423d2e450c19d98059867d71e6aa87c88ac", "script_type": "pay-to-pubkey-hash", "value": 100000000 } ], "preference": "low", "received": "2017-09-04T05:24:14.417939071Z", "relayed_by": "54.158.194.253", "size": 226, "total": 129999000, "ver": 1, "vin_sz": 1, "vout_sz": 2 }
一旦生成比特幣裸交易,可以在網上找到很多提供廣播比特幣裸交易的服務。如果你希望在代碼中進行廣播,也可以使用這個API。
廣播完成后,你可以在區塊瀏覽器中查看交易確認情況:
看完上述內容,你們掌握用JavaScript開發比特幣應用BitcoinJS-lib的過程是怎樣的的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。