精通比特幣(第三章)【比特幣核心】

風靈使發表於2018-09-29

Bitcoin是一個開源專案,原始碼可以根據開放(MIT)許可證提供,可免費下載並用於任何目的。 開源意味著不僅僅是自由使用。 這也意味著比特幣是由一個開放的志願者社群開發的。 起初這個社群只有中本聰。 到2016年,比特幣的原始碼有超過400個貢獻者,大約十幾位開發人員幾乎全職工作,幾十名開發人員兼職。 任何人都可以為程式碼貢獻 - 包括你!

當由中本聰建立比特幣時,軟體實際上是在後來大名鼎鼎的[satoshi_whitepaper]白皮書之前完成的。 中本聰想在寫作之前確保它有效工作。 那麼這個第一個實踐,就叫做“比特幣(Bitcoin)”或者“Satoshi客戶”,實際上已經被大大的修改和改進了。它已經演變成所謂的比特幣核心,以區別於其他相容的實現方式。 比特幣核心是比特幣系統的參考實現,這意味著它是如何實施的權威參考。 Bitcoin Core實現了比特幣的所有方面,包括錢包,交易和區塊驗證引擎,以及P2P網路中的完整網路節點。

**警示 **即使Bitcoin Core包含錢包的參考實現,但這並不意味著可以用作使用者或應用程式的生產錢包。 建議應用程式開發人員使用現代標準(如BIP-39和BIP-32)構建錢包(請參閱助記詞]和[hd錢包]章節)。 BIP就是比特幣改進提案(Bitcoin Improvement Proposal)。

下圖為比特幣核心的架構。

在這裡插入圖片描述圖3-1比特幣核心架構(來源Eric Lombrozo)

3.1比特幣開發環境

如果您是開發人員,您將需要使用所有工具,庫和支援軟體來設定開發環境,以編寫比特幣應用程式。 這一章涉及的技術細節較深,我們將逐步介紹該過程。 如果你覺得過於繁瑣(並且您實際上並沒有設定開發環境),建議你跳到下一章,技術性比本章淺顯一些。

3.2從原始碼編譯比特幣核心

Bitcoin Core的原始碼可以作為ZIP存檔下載,也可以從GitHub克隆權威的原始碼庫。 在GitHub比特幣頁面GitHub bitcoin page上,選擇“下載ZIP”。 或者,使用git命令列在系統上建立原始碼的本地副本。

提示在本章的許多例子中,我們將使用作業系統的命令列介面(也稱為“shell”),通過“terminal”應用程式訪問。 shell將顯示提示你鍵入命令,並且shell反饋一些文字和一個新的提示您的下一個命令。 提示符可能在您的系統上看起來不同,但在以下示例中,它由符號表示(非使用者)。在示例中,當您在符號後面看到文字時,不要鍵入符號,而是在其後面鍵入命令,然後按鍵執行該命令。在示例中,每個命令下面的行是作業系統對該命令的響應。當你看到下一個字首時,應該繼續輸入下一個新的命令,可以一直重複這個過程。

在本例中,我們使用git命令來建立原始碼的本地副本(“clone”):

$ git clone https://github.com/bitcoin/bitcoin.git
Cloning into 'bitcoin'...
remote: Counting objects: 66193, done.
remote: Total 66193 (delta 0), reused 0 (delta 0), pack-reused 66193
Receiving objects: 100% (66193/66193), 63.39 MiB | 574.00 KiB/s, done.
Resolving deltas: 100% (48395/48395), done.
Checking connectivity... done.
$

提示Git是最廣泛使用的分散式版本控制系統,是任何軟體開發人員工具包的重要組成部分。 您可能需要在作業系統上安裝git命令或git的圖形使用者介面。

當git克隆操作完成後,您將在目錄比特幣中擁有原始碼儲存庫的完整本地副本。 在提示符下鍵入“cd bitcoin”,進入為此目錄:

$ cd bitcoin

3.2.1選擇比特幣核心版本

預設情況下,本地副本將與最新的程式碼同步,這可能是不穩定的或Beta版的比特幣。 在編譯程式碼之前,先檢視一個釋出標籤tag,選擇一個特定的版本。 這將使本地副本與關鍵字標籤所標識的程式碼庫的特定快照同步。 開發人員使用標籤來標記版本號的特定版本的程式碼。 首先,要找到可用的標籤,我們使用git tag命令:

$ git tag
v0.1.5
v0.1.6test1
v0.10.0
...
v0.11.2
v0.11.2rc1
v0.12.0rc1
v0.12.0rc2
...

tag列表顯示所有釋出的比特幣版本。 根據慣例,用於測試的釋出候選版本具有字尾“rc”。 可以在生產系統上執行的穩定版本沒有字尾。 從上面的列表中,選擇最高版本的版本,在編寫時是v0.11.2。 要使原生程式碼與此版本同步,請使用git checkout命令:

$ git checkout v0.11.2
HEAD is now at 7e27892... Merge pull request #6975

您可以通過輸入命令git status來確認您有所需的版本“checkout”:

$ git status
HEAD detached at v0.11.2
nothing to commit, working directory clean

3.2.2配置構建比特幣核心

原始碼中包括文件,可以在多個檔案中找到。通過在提示符下鍵入“more README.md”並使用空格鍵進入下一頁,檢視bitcoin目錄中README.md中的主要文件。在本章中,我們將在Linux上構建命令列比特幣客戶端,也稱為比特幣(bitcoind)。在系統中檢視編譯bitcoind命令列客戶端的說明,方法是輸入“more doc / build-unix.md” 。可以在doc目錄中找到macOS和Windows的替代說明,分別為build-osx.md或build-windows.md

仔細檢視build前提條件,這些前提是build文件的第一部分。這些是在您開始編譯比特幣之前必須存在於系統上的庫。如果缺少這些先決條件,build過程將失敗並顯示錯誤。如果發生這種情況是因為您缺失先決條件,則可以安裝它,然後從您所在的地方恢復build過程。假設安裝了先決條件,您可以通過使用autogen.sh指令碼生成一組build指令碼來啟動build過程。

注意Bitcoin Core build過程已經從0.9開始更改為使用autogen / configure / make系統。 舊版本使用簡單的Makefile,與以下示例的方法略有不同。 因此要按照要編譯的版本的說明進行操作。 在0.9中引入的autogen / configure / make可能是用於所有未來版本程式碼的build系統,並且是以下示例中演示的系統。

$ ./autogen.sh
...
glibtoolize: copying file 'build-aux/m4/libtool.m4'
glibtoolize: copying file 'build-aux/m4/ltoptions.m4'
glibtoolize: copying file 'build-aux/m4/ltsugar.m4'
glibtoolize: copying file 'build-aux/m4/ltversion.m4'
...
configure.ac:10: installing 'build-aux/compile'
configure.ac:5: installing 'build-aux/config.guess'
configure.ac:5: installing 'build-aux/config.sub'
configure.ac:9: installing 'build-aux/install-sh'
configure.ac:9: installing 'build-aux/missing'
Makefile.am: installing 'build-aux/depcomp'
...

autogen.sh指令碼建立一組自動配置指令碼,它會詢問系統以發現正確的設定,並確保您擁有編譯程式碼所需的所有庫。 其中最重要的是配置指令碼,它提供了許多不同的選項來自定義構建過程。 鍵入“./configure --help”檢視各種選項:

    $ ./configure --help
    `configure' configures Bitcoin Core 0.11.2 to adapt to many kinds of systems.

    Usage: ./configure [OPTION]... [VAR=VALUE]...

    ...
    Optional Features:
      --disable-option-checking  ignore unrecognized --enable/--with options
      --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
      --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]

      --enable-wallet         enable wallet (default is yes)

      --with-gui[=no|qt4|qt5|auto]
    ...

配置指令碼允許您通過使用–enable-FEATURE和–disable-FEATURE標誌來啟用或禁用bitcoind的某些功能,其中FEATURE由功能名稱替換,如幫助輸出中所列。 在本章中,我們將構建具有所有預設功能的bitcoind客戶端。 我們不會使用配置標誌,但您應該檢視它們以瞭解可選功能是客戶端的一部分。 如果您處於學術環境中,計算機實驗室的限制可能需要您在主目錄中安裝應用程式(例如,使用–prefix = $ HOME)。

以下是一些有用的選項,可以覆蓋configure指令碼的預設行為:

--prefix=$HOME

這將覆蓋生成的可執行檔案的預設安裝位置(它是/ usr / local /)。 使用$ HOME將所有內容放在您的主目錄或不同的路徑中。

--disable-wallet

這用於禁用參考錢包的實現。

--with-incompatible-bdb

如果您正在構建錢包,請允許使用不相容版本的Berkeley DB庫。

--with-gui=no

不要構建圖形使用者介面,圖形介面需要Qt庫。 這隻構建伺服器和命令列。

接下來,執行configure指令碼來自動發現所有必需的庫,併為您的系統建立一個自定義的構建指令碼:

$ ./configure
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
...
[many pages of configuration tests follow]
...
$

如果一切順利,configure命令將會以建立可定製的構建指令碼結束。這些構建指令碼允許我們編譯bitcoind。如果有缺失的庫或是錯誤,configure命令將會以錯誤資訊終止。如果出現了錯誤,可能是因為缺少庫或是有不相容的庫。重新檢查構建文件,確認你已經安裝缺失的必備條件。然後執行configure,看看錯誤是否消失了。

3.2.3構建Bitcoin核心可執行檔案

下一步,你將編譯原始碼,這個過程根據CPU和記憶體資源不同,但一般可能需要1個小時完成。在編譯的過程中,你應該過幾秒或是幾分鐘看一下輸出結果。如果出現了問題,你會看到錯誤。如果中斷了,編譯的過程可以在任何時候恢復。輸入make命令就可以開始編譯了:

$ make
Making all in src
  CXX      crypto/libbitcoinconsensus_la-hmac_sha512.lo
  CXX      crypto/libbitcoinconsensus_la-ripemd160.lo
  CXX      crypto/libbitcoinconsensus_la-sha1.lo
  CXX      crypto/libbitcoinconsensus_la-sha256.lo
  CXX      crypto/libbitcoinconsensus_la-sha512.lo
  CXX      libbitcoinconsensus_la-hash.lo
  CXX      primitives/libbitcoinconsensus_la-transaction.lo
  CXX      libbitcoinconsensus_la-pubkey.lo
  CXX      script/libbitcoinconsensus_la-bitcoinconsensus.lo
  CXX      script/libbitcoinconsensus_la-interpreter.lo

[... many more compilation messages follow ...]

$

如果一切順利,bitcoind現在已經編譯完成。最後一步就是通過sudo make install 命令,安裝 bitcoind 可執行檔案到你的系統路徑下,可能會提示您輸入使用者密碼,因為此步驟需要管理員許可權:

$ sudo make install
Password:
Making install in src
 ../build-aux/install-sh -c -d '/usr/local/lib'
libtool: install: /usr/bin/install -c bitcoind /usr/local/bin/bitcoind
libtool: install: /usr/bin/install -c bitcoin-cli /usr/local/bin/bitcoin-cli
libtool: install: /usr/bin/install -c bitcoin-tx /usr/local/bin/bitcoin-tx
...
$

bitcoind 預設的安裝位置是/usr/local/bin。你可以通過詢問系統下面2個可執行檔案的路徑,來確認bitcoin是否安裝成功。

$ which bitcoind
/usr/local/bin/bitcoind

$ which bitcoin-cli
/usr/local/bin/bitcoin-cli

3.2.4執行比特幣核心節點

比特幣的對等網路由網路“節點”組成,主要由志願者和一些構建比特幣應用程式的商業機構執行。 那些執行的比特幣節點具有直接和權威的比特幣區塊鏈檢視,並且具有所有交易的本地副本,由其自己的系統獨立驗證。 通過執行節點,您不必依賴任何第三方來驗證交易。 此外,通過執行比特幣節點,您可以通過使其更健壯的方式為比特幣網路做出貢獻。

但是,執行節點需要一個具有足夠資源來處理所有比特幣交易的永久連線的系統。 根據您是否選擇索引所有交易並保留塊的完整副本,您可能還需要大量的磁碟空間和RAM。 到2016年底,全索引節點需要2 GB的RAM和125 GB的磁碟空間,以便它有增長的空間。 比特幣節點還傳輸和接收比特幣交易和塊,消耗網際網路頻寬。 如果您的網際網路連線受限,有頻寬上限或按流量計費,建議您不要在其上執行比特幣全節點,或以限制其頻寬的方式執行它(請參閱資源有限的系統)。

**提示 **Bitcoin Core預設情況下保留區塊鏈的完整副本,與2009年成立以來在比特幣網路上發生的每一筆交易相關。此資料集的大小為120GB,下載可能需要幾天或幾周,具體取決於 CPU和網際網路連線的速度。直到完整的塊鏈資料集被下載完成之前,Bitcoin Core將無法處理交易或更新帳戶餘額。 確保您有足夠的磁碟空間,頻寬和時間來完成初始同步。 您可以配置Bitcoin Core通過丟棄舊塊來減少塊鏈的大小(請參閱資源有限的系統),但是在丟棄資料之前仍將下載整個資料集。

儘管有這些資源需求,但仍有成千上萬的志願者執行比特幣節點。 一些在簡單的系統上執行,就像樹莓派Raspberry Pi(一塊35美元的計算機,一張卡的大小)。 許多志願者還在租用的伺服器上執行比特幣節點,通常是Linux的一些變體。 虛擬專用伺服器(VPS)或雲端計算伺服器例項可用於執行比特幣節點。 這些伺服器可以從各種供應商每月租用25至50美元。

為什麼要執行一個節點? 以下是一些最常見的原因:

如果您正在開發比特幣軟體,並且需要依靠比特幣節點進行可程式設計(API)訪問網路和區塊鏈。

如果您正在構建必須根據比特幣共識規則驗證交易的應用程式。 比特幣軟體公司通常執行幾個節點。

如果你想支援比特幣。 執行節點使網路更加健壯,能夠提供更多的錢包,更多的使用者和更多的交易。

如果您不想依賴任何第三方來處理或驗證您的交易。

如果您正在閱讀本書並對開發比特幣軟體感興趣,那麼您應該執行自己的節點。

3.2.5首次執行比特幣核心

當你第一次執行bitcoind時,它會提醒你用一個安全密碼給JSON-RPC介面建立一個配置檔案。該密碼控制對Bitcoin Core提供的應用程式程式設計介面(API)的訪問。

通過在終端輸入bitcoind就可以執行bitcoind了:

$ bitcoind
Error: To use the "-server" option, you must set a rpcpassword in the configuration file:
/home/ubuntu/.bitcoin/bitcoin.conf
It is recommended you use the following random password:
rpcuser=bitcoinrpc
rpcpassword=2XA4DuKNCbtZXsBQRRNDEwEY2nM6M4H9Tx5dFjoAVVbK
(you do not need to remember this password)
The username and password MUST NOT be the same.
If the file does not exist, create it with owner-readable-only file permissions.
It is also recommended to set alertnotify so you are notified of problems;
for example: alertnotify=echo %s | mail -s "Bitcoin Alert" admin@foo.com

你可以看到,第一次執行bitcoind它會告訴你,你需要建立一個配置檔案,至少有一個rpcuser和rpcpassword條目。 另外,建議您設定警報機制。 在下一節中,我們將介紹各種配置選項,並設定一個配置檔案。

3.2.6配置比特幣核心節點

在首選編輯器中編輯配置檔案,並設定引數,用bitcoind推薦的強密碼替換密碼。 請勿使用本書中顯示的密碼。 在.bitcoin目錄(在使用者的主目錄下)中建立一個檔案,以便它被命名為.bitcoin / bitcoin.conf並提供使用者名稱和密碼:

rpcuser=bitcoinrpc
rpcpassword=CHANGE_THIS

除了rpcuser和rpcpassword選項,Bitcoin Core還提供了100多個配置選項,可以修改網路節點的行為,區塊鏈的儲存以及其操作的許多其他方面。

要檢視這些選項的列表,請執行bitcoind --help:

 bitcoind --help
Bitcoin Core Daemon version v0.11.2

Usage:
  bitcoind [options]                     Start Bitcoin Core Daemon

Options:

  -?
       This help message

  -alerts
       Receive and display P2P network alerts (default: 1)

  -alertnotify=<cmd>
       Execute command when a relevant alert is received or we see a really
       long fork (%s in cmd is replaced by message)
...
[many more options]
...

  -rpcsslciphers=<ciphers>
       Acceptable ciphers (default:
       TLSv1.2+HIGH:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!3DES:@STRENGTH)

以下是您可以在配置檔案中設定的一些最重要的選項,或作為bitcoind的命令列引數:

alertnotify

執行指定的命令或指令碼,通常通過電子郵件將緊急警報傳送給該節點的所有者。

conf

配置檔案的另一個位置。 這只是作為bitcoind的命令列引數有意義,因為它不能在它引用的配置檔案內。

datadir

選擇要放入所有塊鏈資料的目錄和檔案系統。 預設情況下,這是您的主目錄的.bitcoin子目錄。 確保這個檔案系統具有幾GB的可用空間。

prune

通過刪除舊的塊,將磁碟空間要求降低到這個兆位元組。 在資源受限的節點上不能滿足完整塊的節點使用這個。

txindex

維護所有交易的索引。 這意味著可以通過ID以程式設計方式檢索任何交易的塊鏈的完整副本。

maxconnections

設定接受連線的最大節點數。 從預設值減少該值將減少您的頻寬消耗。 如果您的網路是按照流量計費,請使用。

maxmempool

將交易記憶體池限制在幾兆位元組。 使用它來減少節點的記憶體使用。

maxreceivebuffer/maxsendbuffer

將每連線記憶體緩衝區限制為1000位元組的多個倍數。 在記憶體受限節點上使用。

minrelaytxfee

設定您將繼續的最低費用交易。 低於此值,交易被視為零費用。 在記憶體受限的節點上使用它來減少記憶體中交易池的大小。

交易資料庫索引和txindex選項

預設情況下,Bitcoin Core構建一個僅包含與使用者錢包有關的交易的資料庫。 如果您想要使用諸如getrawtransaction(參見探索和解碼交易)之類的命令訪問任何交易,則需要配置Bitcoin Core以構建完整的交易索引,這可以通過txindex選項來實現。 在Bitcoin Core配置檔案中設定txindex = 1。 如果不想一開始設定此選項,後期再想設定為完全索引,則需要使用-reindex選項重新啟動bitcoind,並等待它重建索引。

下面的完整索引節點的例子配置顯示瞭如何將上述選項與完全索引節點組合起來,作為比特幣應用程式的API後端執行。

例3-1完整索引節點的例子

alertnotify=myemailscript.sh "Alert: %s"
datadir=/lotsofspace/bitcoin
txindex=1
rpcuser=bitcoinrpc
rpcpassword=CHANGE_THIS

下面是小型伺服器資源不足配置示例。

例3-2小型伺服器資源不足配置示例

alertnotify=myemailscript.sh "Alert: %s"
maxconnections=15
prune=5000
minrelaytxfee=0.0001
maxmempool=200
maxreceivebuffer=2500
maxsendbuffer=500
rpcuser=bitcoinrpc
rpcpassword=CHANGE_THIS

編輯配置檔案並設定最符合您需求的選項後,可以使用此配置測試 bitcoind。 執行Bitcoin Core,使用選項printtoconsole在前臺執行輸出到控制檯:

$ bitcoind -printtoconsole

Bitcoin version v0.11.20.0
Using OpenSSL version OpenSSL 1.0.2e 3 Dec 2015
Startup time: 2015-01-02 19:56:17
Using data directory /tmp/bitcoin
Using config file /tmp/bitcoin/bitcoin.conf
Using at most 125 connections (275 file descriptors available)
Using 2 threads for script verification
scheduler thread start
HTTP: creating work queue of depth 16
No rpcpassword set - using random cookie authentication
Generated RPC authentication cookie /tmp/bitcoin/.cookie
HTTP: starting 4 worker threads
Bound to [::]:8333
Bound to 0.0.0.0:8333
Cache configuration:
* Using 2.0MiB for block index database
* Using 32.5MiB for chain state database
* Using 65.5MiB for in-memory UTXO set
init message: Loading block index...
Opening LevelDB in /tmp/bitcoin/blocks/index
Opened LevelDB successfully

[... more startup messages ...]

一旦您確信正在載入正確的設定並按預期執行,您可以按Ctrl-C中斷程式。要在後臺執行Bitcoin Core作為程式,請使用守護程式選項啟動它,如bitcoind -daemon。要監視比特幣節點的進度和執行狀態,請使用命令bitcoin-cli getinfo:

$ bitcoin-cli getinfo
{
    "version" : 110200,
    "protocolversion" : 70002,
    "blocks" : 396328,
    "timeoffset" : 0,
    "connections" : 15,
    "proxy" : "",
    "difficulty" : 120033340651.23696899,
    "testnet" : false,
    "relayfee" : 0.00010000,
    "errors" : ""
}

這顯示執行Bitcoin Core版本0.11.2的節點,塊連結高度為396328個塊和15個活動網路連線。

一旦您對所選擇的配置選項感到滿意,您應該將bitcoin新增到作業系統中的啟動指令碼中,以使其連續執行,並在作業系統重新啟動時自動啟動。 您可以在contrib / init下的bitcoin的源目錄中的各種作業系統和README.md檔案中找到一些示例啟動指令碼,顯示哪個系統使用哪個指令碼。

3.3 通過命令列使用比特幣核心的JSON-RPC API介面

比特幣核心客戶端實現了JSON-RPC介面,這個介面也可以通過命令列幫助程式bitcoin-cli訪問。命令列可以使用API進行程式設計,讓我們有能力進行互動實驗。開始前,呼叫help命令檢視可用的比特幣RPC命令列表:

$ bitcoin-cli help
addmultisigaddress nrequired ["key",...] ( "account" )
addnode "node" "add|remove|onetry"
backupwallet "destination"
createmultisig nrequired ["key",...]
createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,...}
decoderawtransaction "hexstring"
...
...
verifymessage "bitcoinaddress" "signature" "message"
walletlock
walletpassphrase "passphrase" timeout
walletpassphrasechange "oldpassphrase" "newpassphrase"

這些命令中的每一個可能需要多個引數。 要獲得更多幫助,詳細說明和引數資訊,請在幫助後新增命令名稱。 例如,要檢視getblockhash RPC命令的幫助:

$ bitcoin-cli help getblockhash
getblockhash index

Returns hash of block in best-block-chain at index provided.

Arguments:
1. index         (numeric, required) The block index

Result:
"hash"         (string) The block hash

Examples:
> bitcoin-cli getblockhash 1000
> curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getblockhash", "params": [1000] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/

在幫助資訊的最後,您將看到RPC命令的兩個示例,使用bitcoin-cli helper或HTTP客戶端的curl。 這些例子演示如何呼叫命令。 複製第一個示例並檢視結果:

$ bitcoin-cli getblockhash 1000
00000000c937983704a73af28acdec37b049d214adbda81d7e2a3dd146f6ed09

結果是一個區塊雜湊,這在下面的章節中有更詳細的描述。 但是現在,該命令應該在您的系統上返回相同的結果,表明您的Bitcoin Core節點正在執行,正在接受命令,並且有關於塊1000的資訊返回給您。

在下一節中,我們將演示一些非常有用的RPC命令及其預期輸出。

3.3.1 獲得比特幣核心客戶端狀態的資訊

命令: getinfo

比特幣 getinfo RPC命令顯示關於比特幣網路節點、錢包、區塊鏈資料庫狀態的基礎資訊。使用 bitcoin-cli 執行它:

$ bitcoin-cli getinfo
{
    "version" : 110200,
    "protocolversion" : 70002,
    "blocks" : 396367,
    "timeoffset" : 0,
    "connections" : 15,
    "proxy" : "",
    "difficulty" : 120033340651.23696899,
    "testnet" : false,
    "relayfee" : 0.00010000,
    "errors" : ""
}

資料以JavaScript物件表示法(JSON)返回,這是一種格式,可以輕鬆地被所有程式語言“消費”,但也是非常人性化的。 在這些資料中,我們看到比特幣軟體客戶端(110200)和比特幣協議(70002)的版本號。 我們看到當前的塊高度,顯示了這個客戶端知道了多少塊(396367)。 我們還會看到有關比特幣網路和與此客戶端相關的設定的各種統計資訊。

**提示 **比特幣特客戶端“趕上”當前的blockchain高度需要一些時間,因為它從其他bitcoin客戶端下載塊。 您可以使用getinfo檢查其進度,以檢視已知塊的數量。

3.3.1 .1探索和解碼交易

命令:getrawtransactiondecodeawtransaction

在買咖啡的故事中,Alice從Bob咖啡廳買了一杯咖啡。 她的交易記錄在交易ID(txid)0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2的封鎖上。 我們使用API通過傳遞交易ID作為引數來檢索和檢查該交易:

$ bitcoin-cli getrawtransaction 0627052b6f28912f2703066a912ea577f2ce4da4caa5a↵
5fbd8a57286c345c2f2

0100000001186f9f998a5aa6f048e51dd8419a14d8a0f1a8a2836dd734d2804fe65fa35779000↵
000008b483045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1deccbb6498c75c4↵
ae24cb02204b9f039ff08df09cbe9f6addac960298cad530a863ea8f53982c09db8f6e3813014↵
10484ecc0d46f1918b30928fa0e4ed99f16a0fb4fde0735e7ade8416ab9fe423cc54123363767↵
89d172787ec3457eee41c04f4938de5cc17b4a10fa336a8d752adfffffffff0260e3160000000↵
0001976a914ab68025513c3dbd2f7b92a94e0581f5d50f654e788acd0ef8000000000001976a9↵
147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac00000000

提示交易ID在交易被確認之前不具有權威性。 在區塊鏈中缺少交易雜湊並不意味著交易未被處理。 這被稱為“交易可擴充套件性”,因為在塊中確認之前可以修改交易雜湊。 確認後,txid是不可改變的和權威的。

命令getrawtransaction以十六進位制返回順序交易。 為了解碼,我們使用decodeawtransaction命令,將十六進位制資料作為引數傳遞。 您可以複製getrawtransaction返回的十六進位制,並將其作為引數貼上到decodeawtransaction中:

$ bitcoin-cli decoderawtransaction 0100000001186f9f998a5aa6f048e51dd8419a14d8↵
a0f1a8a2836dd734d2804fe65fa35779000000008b483045022100884d142d86652a3f47ba474↵
6ec719bbfbd040a570b1deccbb6498c75c4ae24cb02204b9f039ff08df09cbe9f6addac960298↵
cad530a863ea8f53982c09db8f6e381301410484ecc0d46f1918b30928fa0e4ed99f16a0fb4fd↵
e0735e7ade8416ab9fe423cc5412336376789d172787ec3457eee41c04f4938de5cc17b4a10fa↵
336a8d752adfffffffff0260e31600000000001976a914ab68025513c3dbd2f7b92a94e0581f5↵
d50f654e788acd0ef8000000000001976a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a8↵
88ac00000000
{
  "txid": "0627052b6f28912f2703066a912ea577f2ce4da4caa5a5fbd8a57286c345c2f2",
  "size": 258,
  "version": 1,
  "locktime": 0,
  "vin": [
    {
      "txid": "7957a35fe64f80d234d76d83a2...8149a41d81de548f0a65a8a999f6f18",
      "vout": 0,
      "scriptSig": {
        "asm":"3045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1decc...",
        "hex":"483045022100884d142d86652a3f47ba4746ec719bbfbd040a570b1de..."
      },
      "sequence": 4294967295
    }
  ],
  "vout": [
    {
      "value": 0.01500000,
      "n": 0,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 ab68...5f654e7 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a914ab68025513c3dbd2f7b92a94e0581f5d50f654e788ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA"
        ]
      }
    },
    {
      "value": 0.08450000,
      "n": 1,
      "scriptPubKey": {
        "asm": "OP_DUP OP_HASH160 7f9b1a...025a8 OP_EQUALVERIFY OP_CHECKSIG",
        "hex": "76a9147f9b1a7fb68d60c536c2fd8aeaa53a8f3cc025a888ac",
        "reqSigs": 1,
        "type": "pubkeyhash",
        "addresses": [
          "1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK"
        ]
      }
    }
  ]
}

交易解碼展示這筆交易的所有成分,包括交易的輸入及輸出。在這個例子中,我們可以看到這筆給我們新地址存入 50mBTC的交易使用了一個輸入並且產生兩個輸出。這筆交易的輸入是前一筆確認交易的輸出(展示位以d3c7開頭的 vin txid)。兩個輸出則是50mBTC存入額度及返回給傳送者的找零。

我們可以使用相同命令(例如 gettransaction )通過檢查由本次交易的txid索引的前一筆交易進一步探索區塊鏈。通過從 一筆交易跳到另外一筆交易,我們可以追溯一連串的交易,因為幣值一定是從一個擁有者的地址傳送到另一個擁有者的地址。

3.3.2 探索區塊

命令: getblockgetblockhash

探索區塊類似於探索交易。 但是,塊可以由塊高度或塊雜湊引用。 首先,讓我們找到一個塊的高度。 在買咖啡故事中,我們看到Alice的交易已被包含在框277316中。我們使用getblockhash命令,它將塊高度作為引數,並返回該塊的塊雜湊值:

$ bitcoin-cli getblockhash 277316
0000000000000001b6b9a13b095e96db41c4a928b97ef2d944a9b31b2cc7bdc4

既然我們知道我們的交易在哪個區塊中,我們可以使用getblock命令,並把區塊雜湊值作為引數來查詢對應的區塊:

$ bitcoin-cli getblock 0000000000000001b6b9a13b095e96db41c4a928b97ef2d944a9b3↵
1b2cc7bdc4
{
  "hash": "0000000000000001b6b9a13b095e96db41c4a928b97ef2d944a9b31b2cc7bdc4",
  "confirmations": 37371,
  "size": 218629,
  "height": 277316,
  "version": 2,
  "merkleroot": "c91c008c26e50763e9f548bb8b2fc323735f73577effbc55502c51eb4cc7cf2e",
  "tx": [
    "d5ada064c6417ca25c4308bd158c34b77e1c0eca2a73cda16c737e7424afba2f",
    "b268b45c59b39d759614757718b9918caf0ba9d97c56f3b91956ff877c503fbe",
    "04905ff987ddd4cfe603b03cfb7ca50ee81d89d1f8f5f265c38f763eea4a21fd",
    "32467aab5d04f51940075055c2f20bbd1195727c961431bf0aff8443f9710f81",
    "561c5216944e21fa29dd12aaa1a45e3397f9c0d888359cb05e1f79fe73da37bd",
[... hundreds of transactions ...]
    "78b300b2a1d2d9449b58db7bc71c3884d6e0579617e0da4991b9734cef7ab23a",
    "6c87130ec283ab4c2c493b190c20de4b28ff3caf72d16ffa1ce3e96f2069aca9",
    "6f423dbc3636ef193fd8898dfdf7621dcade1bbe509e963ffbff91f696d81a62",
    "802ba8b2adabc5796a9471f25b02ae6aeee2439c679a5c33c4bbcee97e081196",
    "eaaf6a048588d9ad4d1c092539bd571dd8af30635c152a3b0e8b611e67d1a1af",
    "e67abc6bd5e2cac169821afc51b207127f42b92a841e976f9b752157879ba8bd",
    "d38985a6a1bfd35037cb7776b2dc86797abbb7a06630f5d03df2785d50d5a2ac",
    "45ea0a3f6016d2bb90ab92c34a7aac9767671a8a84b9bcce6c019e60197c134b",
    "c098445d748ced5f178ef2ff96f2758cbec9eb32cb0fc65db313bcac1d3bc98f"
  ],
  "time": 1388185914,
  "mediantime": 1388183675,
  "nonce": 924591752,
  "bits": "1903a30c",
  "difficulty": 1180923195.258026,
  "chainwork": "000000000000000000000000000000000000000000000934695e92aaf53afa1a",
  "previousblockhash": "0000000000000002a7bbd25a417c0374cc55261021e8a9ca74442b01284f0569",
  "nextblockhash": "000000000000000010236c269dd6ed714dd5db39d36b33959079d78dfd431ba7"
}

該塊包含419筆交易,列出的第64筆交易(0627052b …)是Alice的咖啡付款。 高度條目告訴我們這是區塊鏈中的第277316塊。

3.3.3使用比特幣核心的程式設計介面

bitcoin-cli helper對於探索Bitcoin Core API和測試功能非常有用。 但是應用程式設計介面的全部要點是以程式設計方式訪問功能。 在本節中,我們將演示從另一個程式訪問Bitcoin Core。

Bitcoin Core的API是一個JSON-RPC介面。 JSON代表JavaScript物件符號,它是一種非常方便的方式來呈現人類和程式可以輕鬆閱讀的資料。 RPC代表遠端過程呼叫,這意味著我們通過網路協議呼叫遠端(位於比特幣核心節點)的過程(函式)。 在這種情況下,網路協議是HTTP或HTTPS(用於加密連線)。

當我們使用bitcoin-cli命令獲取命令的幫助時,它給了我們一個例子,它使用curl,通用的命令列HTTP客戶端來構造這些JSON-RPC呼叫之一:

$ curl --user myusername --data-binary '{"jsonrpc": "1.0", "id":"curltest", "method": "getinfo", "params": [] }' -H 'content-type: text/plain;' http://127.0.0.1:8332/

此命令顯示curl向本地主機(127.0.0.1)提交HTTP請求,連線到預設比特幣埠(8332),並使用text / plain編碼向getinfo方法提交jsonrpc請求。

如果您在自己的程式中實現JSON-RPC呼叫,則可以使用通用的HTTP庫構建呼叫,類似於前面的curl示例所示。

然而,大多數程式語言中都使用庫,以“包裝”比特幣核心API的方式使其簡單得多。 我們將使用python-bitcoinlib庫來簡化API訪問。 請記住,這需要您有一個執行的Bitcoin Core例項,將用於進行JSON-RPC呼叫。

下面的例子通執行getinfo中的Python指令碼進行簡單的getinfo呼叫,並從Bitcoin Core返回的資料中列印區塊引數。

例3-3通過Bitcoin Core的JSON-RPC API執行

code/rpc_example.py[]

執行結果如下:

$ python rpc_example.py
394075

它告訴我們,我們的本地Bitcoin Core節點在其塊鏈中有394075個塊。 這不是一個驚人的結果,但它演示了使用庫作為Bitcoin Core的JSON-RPC API的簡化介面的基本使用。

接下來,我們使用getrawtransaction和decodetransaction呼叫來檢索Alice咖啡付款的詳細資訊。 在下面的例子中,我們檢索Alice的交易並列出交易的輸出。 對於每個輸出,我們顯示收件人地址和值。 作為提醒,Alice的交易有一個輸出支付Bob的咖啡館和一個輸出找回Alice。

例3-4檢索交易並迭代其輸出

code/rpc_transaction.py[]

執行結果如下:

$ python rpc_transaction.py
([u'1GdK9UzpHBzqzX2A9JFP3Di4weBwqgmoQA'], Decimal('0.01500000'))
([u'1Cdid9KFAaatwczBwBttQcwXYCpvK8h7FK'], Decimal('0.08450000'))

上述兩個例子都比較簡單。 你真的不需要一個程式來執行它們; 你可以很容易地使用bitcoin-cli helper。 然而,下一個示例需要數百個RPC呼叫,並更清楚地說明了使用程式設計介面的方便。

在時,我們首先檢索塊277316,然後通過引用每個交易ID來檢索每個419個交易。 接下來,我們迭代每個交易的輸出並將其加起來。例3-5檢索塊並新增所有交易輸出

code/rpc_block.py[]

執行結果如下:

$ python rpc_block.py

('Total value in block: ', Decimal('10322.07722534'))

我們的示例程式碼計算出,此塊中交易的總價值為10,322.07722534 個BTC(包括25 BTC獎勵和0.0909 BTC費用)。 通過搜尋塊雜湊或高度來比較區塊瀏覽器站點報告的數量。 一些區塊瀏覽器報告不包括獎勵的總價值,不包括交易費用。 看看是否可以發現差異。

3.4 其他替代客戶端、資料庫、工具包

除了參考客戶端(bitcoind),還可以使用其他的客戶端和資料庫去連線比特幣網路和資料結構。這些工具都由一系列 的程式語言執行,用他們各自的語言為比特幣程式提供原生的互動。以下列出了一部分由程式語言組織的一些最好的庫,客戶端和工具包:

C/C++

Bitcoin Core The reference implementation of bitcoin

libbitcoin Cross-platform C++ development toolkit, node, and consensus library

bitcoin explorer Libbitcoin’s command-line tool

picocoin A C language lightweight client library for bitcoin by Jeff Garzik

JavaScript

bcoin A modular and scalable full-node implementation with API

Bitcore Full node, API, and library by Bitpay

BitcoinJS A pure JavaScript Bitcoin library for node.js and browsers

Java

bitcoinj A Java full-node client library

Bits of Proof (BOP) A Java enterprise-class implementation of bitcoin

Python

python-bitcoinlib A Python bitcoin library, consensus library, and node by Peter Todd

pycoin A Python bitcoin library by Richard Kiss

pybitcointools A Python bitcoin library by Vitalik Buterin

Ruby

bitcoin-client A Ruby library wrapper for the JSON-RPC API

Go

btcd A Go language full-node bitcoin client

Rust

rust-bitcoin Rust bitcoin library for serialization, parsing, and API calls

C#

NBitcoin Comprehensive bitcoin library for the .NET framework

Objective-C

CoreBitcoin Bitcoin toolkit for ObjC and Swift

更多的庫存在各種其他程式語言,也會一直更新的。

相關文章