Get started with the Bitcoin Testnet 比特幣開發

在初學使用比特幣時,建議先使用Testnet開發,這樣在不冒險失去或花費比特幣風險的情況下嘗試了。這是我所做工作的教程式提要,內容包括:

  1. 選擇一個JS比特幣庫。
  2. 創建比特幣私鑰/公鑰對。
  3. 免費在Testnet上獲取比特幣。
  4. 通過第三方API從Testnet區塊鏈讀取數據。

5.構建有效的事務,包括OP_RETURN事務。

6.將這些事務推送到第三方API,以傳輸到Testnet網絡。

Setup

node v10.16.0
npm v6.9.0

建立一個資料

mkdir bitcointestnet
npm init

選擇一個JS比特幣庫

  • 它仍處於活動狀態(在撰寫本文時,是2天前的最新提交)。
  • 它有大量的貢獻者和發行者。
  • 主要貢獻者dcousens也為Bitcoin Core貢獻了很多。
  • 就功能而言,它非常全面,除了地址外還包括支付腳本。
  • 有許多範例與有人解決回答問題 (最重要的點)

bitcore-lib看起來是另一個非常相似的選項,但是1.範例不全面 2.它是Bitpay維護的

安裝最新版本的最簡單方法是使用yarn或npm:

yarn add bitcoinjs-lib
# or
npm install bitcoinjs-lib

我寫這篇時用 v 5.1.7 版本

創建比特幣私鑰/公鑰對

我們可以這樣做:

const bitcoin = require('bitcoinjs-lib')
const { testnet } = bitcoin.networks
const myKeyPair = bitcoin.ECPair.makeRandom({ network: testnet })

是“橢圓曲線”,“ ECPair”中的“ EC”代表“橢圓曲線”,也就是比特幣安全的基礎數學。

myKeyPair具有使用這些密鑰進行簽名交易的方法,我們利用myKeyPair產生私鑰、公鑰與地址。請嘗試以下操作:

const myWIF = myKeyPair.toWIF() // eg 'cUQv17kNEpY3j6x1x9tSS1QDUHH94gYzEYLcUpVSSRqb1subMW6x'const myPublicKey = myKeyPair.publicKey.toString('hex'); //eg '02f12b93c7347c33c1fa83f076a269d060c8bffe0d5a69d254fcab39bd8a32529c'const myAddress = bitcoin.payments.p2pkh({ pubkey: myKeyPair.publicKey, network: testnet });// eg 'mrTebkFmXCdvejQXFwA78xgBeJCH6uKrEm'

myWIF是您的電子錢包導入格式(WIF)的私鑰,其中還包含有關它是主網絡還是Testnet的信息,以及以base58編碼形式用於防止輸入錯誤的校驗和。 (base58由數字以及大寫和小寫字母組成,O,0,l和I除外,它們很容易彼此混淆。)您可以使用myWIF將錢包導入許多GUI錢包提供程序,例如Blockchain.info。其他任何人也可以,所以如果您以後使用真正的比特幣進行此操作,請保持myWIF的秘密。

myAddress的編碼類似,只是您可以將它提供給想要向您發送比特幣的人,這裡要注意的是測試鏈與正式鏈的地址是不同的。

testnet address : mrTebkFmXCdvejQXFwA78xgBeJCH6uKrEm
main address : 1EeHuYstLN7E6WvKVSvwRBRMUXTDEgPafp

獲得免費的Testnet bitcoin硬幣

我發現最好的水龍頭是https://testnet.manu.backend.hamburg/faucet,它將在一次付款中為您提供比特幣-足夠玩。現在您有了地址,只需在此處的表格中輸入以獲得硬幣即可。幾分鐘後,您應該會看到您的交易得到了一些確認,這實際上意味著網絡現在識別出您擁有那些比特幣。

Image for post
Image for post

恭喜,您現在是一些毫無價值的加密貨幣的驕傲擁有者!順便說一句,將您的Testnet硬幣用完後,將它們退還給水龍頭被認為是禮貌的,以便其他人可以使用它們。

從Testnet區塊鏈讀取數據

文檔站點在這裡。展開“地址”部分,單擊“參數”,然後在“地址ID”字段中輸入您的地址。單擊“獲取”,您應該看到有關您的地址的各種信息,尤其是有關剛從水龍頭髮送的比特幣的信息。 (如果沒有任何顯示,則可能需要等待幾分鐘才能檢測到該事務。)

現在,在Node中進行操作。我將axios用於一些友好的Promises。

yarn add axios
# or
npm install axios

我安裝v 0.19.2版本

這是使用其API的同一smartbit查詢:

const axios = require('axios');
const myAddress = 'mjJ5gQ89ZryZ5wrJQp3ELTu5V7KNX8s3uu';
const urlForMyAddress = `https://testnet-api.smartbit.com.au/v1/blockchain/address/${myAddress}`
axios
.get(urlForMyAddress)
.then(response => console.log(response.data))
Image for post
Image for post

或者,如果我們僅對地址的未完成交易感興趣:

const myAddress = 'mjJ5gQ89ZryZ5wrJQp3ELTu5V7KNX8s3uu';
const urlForMyAddress = `https://testnet-api.smartbit.com.au/v1/blockchain/address/${myAddress}`
const urlForMyUnspentTransactions = `${urlForMyAddress}/unspent`
axios
.get(urlForMyUnspentTransactions)
.then(response => console.log(response.data))
Image for post
Image for post

建立有效的交易

  1. 確定我們要發送比特幣的地址。
  2. 確定發送多少錢到那個地址。
  3. 為將交易包括在區塊中的礦工計算適當的費用。
  4. 查找一筆交易,該交易的輸出未使用到我們的地址,以用作我們交易的輸入。
  5. 簽署交易輸入。
  6. 將輸出添加到我們的交易中,以便接收者獲得我們想要給他們的比特幣。
  7. 將輸出添加回我們自己的地址以進行更改。

如果您還沒有地方可以發送比特幣,請創建第二個密鑰對以將硬幣發送到,並指定一個金額以satoshis進行發送:

const receiver = bitcoin.ECPair.makeRandom({ network: testnet })
const amountToSend = 5000000 // 0.05 BTC

該費用很重要,因為如果您將其設置得太低,那麼您的交易對礦工就不會有吸引力,並且可能需要很長時間才能出現在區塊鏈中,甚至可能永遠不會被接受。在沒有這麼多流量的Testnet上,這不是問題,但對比特幣主網絡來說卻是一個大問題。

const getRecommendedFee = () => {
const url = 'https://bitcoinfees.earn.com/api/v1/fees/recommended'
const medianTransactionSize = 226 // bytes
return axios
.get(url)
.then(response => response.data.fastestFee * medianTransactionSize)
}
Image for post
Image for post

現在,我們擁有開始構建交易所需的一切。

const buildTransaction = (keyPair, receiverAddress, amount) =>
Promise.all([
getUnspentTransactionsForAddress(keyPair.getAddress()),
getRecommendedFee(),
])
.then(([unspentTransactions, recommendedFee]) => {
const unspent = unspentTransactions[0]
const totalCost = amount + recommendedFee
const change = unspent.value_int - totalCost

const tx = new bitcoin.TransactionBuilder(testnet)
tx.addInput(unspent.txid, unspent.n)
tx.sign(0, keyPair)
tx.addOutput(receiverAddress, amount)
tx.addOutput(keyPair.getAddress(), change)

return tx.build()
})

我們得到一個地址未使用的交易清單。我們選擇第一個交易(例如水龍頭中的交易)。我們還通過API獲得建議的交易費用。

然後,我們開始建立交易。我們使用其交易ID和unspent.n將未用完的輸出添加為輸入,這將指定我們正在使用的該交易中的哪個輸出(請記住,事務可以有多個輸出)。然後,我們使用密鑰對對輸入進行簽名(0指定我們正在對哪個輸入進行簽名,即第一個)。

然後,我們添加將所需金額發送到接收方地址的輸出,然後將更改返回到我們自己的地址。我們通過從未用金額中減去我們要發送的金額和我們要支付的費用,計算出有多少更改。

重要信息:我們需要將更改發送回我們的地址,因為輸出中未指定的任何金額都將被用作採礦費。忘記這一步可能會非常昂貴!

最後,我們建立交易並將其返回。

建立OP_RETURN交易

我們需要一個稍微不同的功能:

const buildOpReturnTransaction = (keyPair, message) =>
Promise.all([
getUnspentTransactionsForAddress(keyPair.getAddress()),
getRecommendedFee(),
])
.then(([unspentTransactions, recommendedFee]) => {
const unspent = unspentTransactions[0]
const change = unspent.value_int - recommendedFee
const dataToStore = Buffer.from(message)
const opReturnScript = bitcoin.script.nullData.output.encode(dataToStore)

const tx = new bitcoin.TransactionBuilder(testnet)
tx.addInput(unspent.txid, unspent.n)
tx.sign(0, keyPair)
tx.addOutput(opReturnScript, 0)
tx.addOutput(keyPair.getAddress(), change)

return tx.build()
})

就像在我們收到未使用的交易和建議的費用之前一樣。我們將消息轉換為緩衝區(以防緩衝區還沒有緩衝區),並創建一個OP_RETURN腳本,將其用作輸出之一,發送0個satoshis。我們會將所有未使用的金額(減去費用)寄回我們自己的地址。和之前一樣,我們構建事務並將其返回。

重要提示:如果您將任何硬幣發送到OP_RETURN腳本,它們將永遠消失。收費有誤,一個好的礦工可能(但可能不會!)決定將硬幣退還給您。使用OP_RETURN犯錯誤,即使他們願意,也沒有人可以找回他們。

將交易發佈到比特幣網路

const pushTransaction = transaction => {
const url = 'https://testnet-api.smartbit.com.au/v1/blockchain/pushtx'
const params = { hex: transaction.toHex() }
return axios.post(url, params)
}

簡單!您也可以將請求發佈到/ decodetx而不是/ pushtx,以便在廣播之前仔細檢查交易外觀是否符合您的期望。

這是使用我們的函數創建OP_RETURN交易的示例:

const importantMessage = 'For good luck, I like my rhymes atrocious\nSupercalafragilisticexpialidocious'
buildTransaction(myKeyPair, importantMessage)
.then(pushTransaction)
.then(response => console.log(response.data))

在瀏覽器的Testnet區塊鏈資源管理器中進行檢查-僅搜索您的地址,您應該在公共區塊鏈上看到OP_RETURN輸出和消息(一旦交易包含在區塊中)。

您還可以稍後使用smartbit的/ address / $ {myAddress} / op_returns端點將這些消息從區塊鏈中移出。

結論

Written by

撰寫任何事情,O型水瓶混魔羯,咖啡愛好者,Full stack/blockchain developer,Founder of Blockchain&Dapps meetup and DeFi-Decentralized-Finance-SG meetup,Udemy teacher。

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store