1. 程式人生 > >JavaScript編寫自己的比特幣交易代碼

JavaScript編寫自己的比特幣交易代碼

例如 ets lock 管理 指向 pub broadcast 進行 風險

今天我們將編寫第一個比特幣交易代碼。為了實現這一目標,我們將使用名為bitcore的JavaScript庫。JavaScript是最流行的現代編程語言,幾乎每個開發人員都知道它,因此它使這篇文章具有普遍性並且對更廣泛的受眾有用。

在繼續閱讀本文之前,你應該至少掌握有關比特幣區塊鏈如何工作的基本技術知識。如果沒有,請花幾分鐘時間閱讀區塊鏈簡介。如果你有更多的時間,比如幾個小時,我建議你閱讀掌握比特幣。

讓我們從一個具有以下依賴關系的新NPM項目開始:

[...]
"dependencies": {
    "bitcore-explorers": "^1.0.1",
    "bitcore-lib": "^0.13.19"
}
[...]

打開index.js文件並導入bitcore庫:

var bitcore = require("bitcore-lib");

要花費比特幣我們需要一個包含比特幣的地址和一個允許我們花錢的私鑰。我們將導入WIF版本的私鑰。WIFWallet Import Format的縮寫。它可以在比特幣錢包之間輕松導入密鑰。 然後我們將從該私鑰創建一個testnet地址:

var privateKeyWIF = ‘cQN511BWtc2dSUMWySmZpr6ShY1un4WK42JegGwkSFX5a8n9GWr3‘;
var privateKey = bitcore.PrivateKey.fromWIF(privateKeyWIF);
var sourceAddress = privateKey.toAddress(bitcore.Networks.testnet);

警告!在那個例子中,我與你分享我的私鑰。你不應該在現實生活中這樣做。擁有私鑰的人是分配給該密鑰的地址的比特幣的所有者。這是所有權的標誌。

在這種情況下,我只是與你分享了用於創建testnet地址的密鑰。Testnet是一個為軟件和腳本測試而創建的比特幣網絡。它不包含真正的比特幣,只包含測試的比特幣。 你可以免費獲得它們。即使有人偷了他們也沒什麽大不了的。我可以冒這個風險為你提供開箱即用的示例。

如果有人使用/偷走了這個地址的所有測試比特幣,你可以給它接著充。復制地址mibK5jk9eP7EkLH175RSPGTLR27zphvvxa並將其粘貼到表單中。

是時候創建我們想要發送測試比特幣的targetAddress了。

var targetAddress = (new bitcore.PrivateKey).toAddress(bitcore.Networks.testnet);

如果有任何比特幣,請檢查我們的源地址。比特幣網絡使用UTXO來存儲該信息。UTXOUnspent Transaction Output的縮寫。

我們有一個問題,我們沒有比特幣網絡客戶端。整個節點需要至少125 GB的硬盤空間,這對我可憐的MacBook Air來說太多了。我們必須找到一種解決方法。我們不得不請某人為我們讀比特幣網絡。並廣播我們的交易。

在這種情況下,我們正在失去比特幣區塊鏈的最大優勢。系統的架構使我們不必信任任何一方。網絡共識,數學和加密使得區塊鏈中存儲的數據可信。但現在我們要求中間人為我們讀取這些數據。他可能會向我們提供虛假或過時的數據。

我們將使用來自bitcore-explorers庫的Insight。由於它非常受歡迎,我們只是在這裏學習,我們可以假設它可以信任。最終的解決方案應該是擁有自己的比特幣全節點。

好吧,讓我們使用Insight來檢查我們要花多少比特幣。

var Insight = require("bitcore-explorers").Insight;
var insight = new Insight("testnet");

insight.getUnspentUtxos(sourceAddress, function(error, utxos) {
  if (error) {
    console.log(error);
  } else {
    console.log(utxos);
    // transaction code goes here
}

UTXOs的輸出是一個數組。它的每個元素都包含有關作為UTXO所有者的地址和Satoshis(1 Satoshi = 0.00000001比特幣)的信息。它看起來像這樣:

[ <UnspentOutput: dbe9ce2ae27d7ffcba40195e7ee628e9165568115931386b27b0c0674fa019c5:1, satoshis: 5047177248, address: mibK5jk9eP7EkLH175RSPGTLR27zphvvxa> ]

是時候創建我們的交易了:

var tx = new bitcore.Transaction();

讓我們將收到的UTXOs設置為交易的input。需要註意的一件重要事情是:我們不是從address而是從UTXOs獲得比特幣。

tx.from(utxos);

讓我們設置我們想要交付給他的交易和金額的接收者。數量以Satoshis給出,這是比特幣的最小單位:1 Satoshi = 0.00000001比特幣。這是我們交易的output

tx.to(targetAddress, 10000);

是時候討論值的the changeUTXOs是指向我們地址但尚未用完的交易的輸出。UTXOs就像一張鈔票。如果你的口袋裏有5美元的鈔票並且想購買2美元的啤酒,你就不會削減一部分賬單並將其交給收銀員。你給5美元的鈔票並收到3美元的改變。它與UTXOs完全相同。你必須在交易中使用整個UTXO並指定change值和address,然後應返回change

WTF?我是否必須指定change值?在商店裏,當我以5美元的價格購買2美元的啤酒時,我收到3美元的回報。這很明顯。無需計算。

在比特幣中,存在一點差異。實際上,change只是交易的另一個輸出。outputs的總和應該比input的總和小一點。差異稱為mining fee。你將其支付給礦工以包含在交易區塊中。像bitcore.io這樣的錢包或庫估算了我們的mining fee。所以在我們的例子中,我們應該返回change到指定address

tx.change(sourceAddress);

你可以註意到我們使用了sourceAddress。結果,該地址的一些現有UTXOs消失了(它們將被用完),但也會創建一個新的(來自change的那個)。

在現實生活中,錢包為你的每筆交易使用新地址。這樣做的目的是改善匿名性。怎麽可能從一個private key中錢包能夠創建許多public keysaddress?閱讀確定性錢包以找到答案

大!一切都準備好了!我們現在唯一要做的就是用我們的private key簽署交易並將其發送到比特幣區塊鏈。正如我之前提到的,我們沒有自己的比特幣客戶端。我們使用外部工具與區塊鏈進行通信。問題是:我們能否相信它。當我們廣播交易時,該工具不存在捕獲私鑰或操縱交易的風險(例如,更改targetAddress)。如果該工具進行了上面列出的任何更改,則簽名將不再有效,並且將拒絕交易。唯一的風險是該工具根本不會發送交易。但我們可以在任何區塊鏈資源管理器中驗證它。所以我們可以毫不畏懼地再次使用Insight

tx.sign(privateKey);
tx.serialize();

insight.broadcast(tx, function(error, transactionId) {
  if (error) {
    console.log(error);
  } else {
    console.log(transactionId);
  }
});

這就是所有人!該交易被廣播到網絡。如果一切順利,我們將收到交易ID。然後將其復制並粘貼到比特幣區塊鏈瀏覽器中,看看它是否真的有效。

完整代碼可以在GitHub上找到。

JavaScript編寫自己的比特幣交易代碼