前言
入坑區塊鏈,對於第一個把區塊鏈技術推向巔峰的比特幣不能不瞭解。而瞭解一項技術應用的最佳途徑莫過於親自編譯和閱讀比特幣的原始碼,儘管筆者可能力有不逮,但願意一試。我想,過程可能很艱難,終點會有美麗的風景等著我。
推薦精通比特幣第二版,講解比特幣原理非常不錯的一本書。
bitcoin github專案介紹
開啟bitcoin的github地址,我們發現共有四個目錄:
-
bitcoin 比特幣核心原始碼 C++
-
bips 有關比特幣改進建議的相關文件 我們經常聽到的“”
-
libbase58 比特幣base58編解碼庫 C
-
libblkmaker 比特幣區塊模板庫 C
開啟bitcoin,我們看一下核心程式碼的架構:
擼起袖子就是幹
1.從github拉取對應版本的bitcoin原始碼
//拉取bitcoin原始碼
git clone https://github.com/bitcoin/bitcoin.git
//切換版本到最新
git checkout 0.16
複製程式碼
2.按官方build文件依次執行
看官方build文件竟意外地發現,可以用Qt來構建和除錯bitcoin。有了IDE之後,在看原始碼的時候,相關函式就可以直接跳轉到定義的地方。不知方便了多少。。。
按著步驟來,一步也不要拉下,不然後面可能會有意向不到的障礙。約摸10min左右,整個build過程結束。
3.幾個主要程式
-
Bitcoin Core.app Bitcoin客戶端圖形介面版
-
bitcoind /src/bitcoind Bitcoin簡潔命令列版,也是下一步原始碼分析的重點(不能與Bitcoin Core同事執行,如果不小心嘗試同時執行另外一個客戶端,它會提示已經有一個客戶端在執行並且自動退出)
-
bitcoin-cli /src/bitcoin-cli Bitcoind的一個功能完備的RPC客戶端,可以通過它在命令列查詢某個區塊資訊,交易資訊等
-
bitcoin-tx /src/bitcoind 比特幣交易處理模組,可以進行交易的查詢和建立
bitcoind
1.啟動與結束bitcoind
cd .../bitcoin/src
//1.啟動bitcoind,會聯網進行block的同步,180多G耗時耗記憶體
./bitcoind
//2.啟動並指定同步數
./bitcoind -maxconnections=0
//3.或者在1啟動後通過bitcoin-cli無效化當前區塊
./bitcoin-cli invalidateblock `bitcoin-cli getbestblockhash`
//4.結束
./bitcoin-cli stop
複製程式碼
注:如果突然發現你的Mac記憶體不夠用了,老鐵,一定是bitcoin乾的!Mac下預設的block同步路徑可是讓我好找,貼出來省得大家到時候懵逼不知道哪裡找:
/Users/[User]/Library/Application Support/Bitcoin/blocks
複製程式碼
2. bitcoind其他命令
./bitcoind -help可以檢視bitcoind支援的各種命令和帶參格式:
//bitcoind 命令通用格式
bitcoind [選項]
bitcoind [選項] <命令> [引數] 將命令傳送到 -server 或 bitcoind
bitcoind [選項] help 列出命令
bitcoind [選項] help <命令> 獲取該命令的幫助
//bitcoind常見命令
-conf=<檔名> 指定配置檔案(預設:bitcoin.conf)
-pid=<檔名> 指定 pid (程式 ID)檔案(預設:bitcoind.pid)
-gen 生成比特幣
-gen=0 不生成比特幣
-min 啟動時最小化
-splash 啟動時顯示啟動螢幕(預設:1)
-datadir=<目錄名> 指定資料目錄
-dbcache=<n style="word-wrap: break-word;"> 設定資料庫快取大小,單位為兆位元組(MB)(預設:25)</n>
-dblogsize=<n style="word-wrap: break-word;"> 設定資料庫磁碟日誌大小,單位為兆位元組(MB)(預設:100)</n>
-timeout=<n style="word-wrap: break-word;"> 設定連線超時,單位為毫秒</n>
-proxy=<ip:埠 style="word-wrap: break-word;"> 通過 Socks4 代理連結</ip:埠>
-dns addnode 允許查詢 DNS 並連線
-port=<埠> 監聽 <埠> 上的連線(預設:8333,測試網路 testnet:18333)
-maxconnections=<n style="word-wrap: break-word;"> 最多維護 <n style="word-wrap: break-word;">個節點連線(預設:125)</n></n>
-addnode=<ip style="word-wrap: break-word;"> 新增一個節點以供連線,並嘗試保持與該節點的連線</ip>
-connect=<ip style="word-wrap: break-word;"> 僅連線到這裡指定的節點</ip>
-irc 使用 IRC(因特網中繼聊天)查詢節點(預設:0)
-listen 接受來自外部的連線(預設:1)
-dnsseed 使用 DNS 查詢節點(預設:1)
-banscore=<n style="word-wrap: break-word;"> 與行為異常節點斷開連線的臨界值(預設:100)</n>
-bantime=<n style="word-wrap: break-word;"> 重新允許行為異常節點連線所間隔的秒數(預設:86400)</n>
-maxreceivebuffer=<n style="word-wrap: break-word;"> 最大每連線接收快取,<n style="word-wrap: break-word;">*1000 位元組(預設:10000)</n></n>
-maxsendbuffer=<n style="word-wrap: break-word;"> 最大每連線傳送快取,<n style="word-wrap: break-word;">*1000 位元組(預設:10000)</n></n>
-upnp 使用全域性即插即用(UPNP)對映監聽埠(預設:0)
-detachdb 分離貨幣塊和地址資料庫。會增加客戶端關閉時間(預設:0)
-paytxfee=<amt style="word-wrap: break-word;"> 您傳送的交易每 KB 位元組的手續費</amt>
-testnet 使用測試網路
-debug 輸出額外的除錯資訊
-logtimestamps 除錯資訊前新增[時間戳](http://8btc.com/article-165-1.html)
-printtoconsole 傳送跟蹤/除錯資訊到控制檯而不是 debug.log 檔案
-printtodebugger 傳送跟蹤/除錯資訊到偵錯程式
-rpcuser=<使用者名稱> JSON-RPC 連線使用的使用者名稱
-rpcpassword=<密碼> JSON-RPC 連線使用的密碼
-rpcport=<port style="word-wrap: break-word;"> JSON-RPC 連線所監聽的 <埠>(預設:8332)</port>
-rpcallowip=<ip style="word-wrap: break-word;"> 允許來自指定 <ip style="word-wrap: break-word;">地址的 JSON-RPC 連線</ip></ip>
-rpcconnect=<ip style="word-wrap: break-word;"> 傳送命令到執行在 <ip style="word-wrap: break-word;">地址的節點(預設:127.0.0.1)</ip></ip>
-blocknotify=<命令> 當最好的貨幣塊改變時執行命令(命令中的 %s 會被替換為貨幣塊雜湊值)
-upgradewallet 將錢包升級到最新的格式
-keypool=<n style="word-wrap: break-word;"> 將密匙池的尺寸設定為 <n style="word-wrap: break-word;">(預設:100)</n></n>
-rescan 重新掃描貨幣塊鏈以查詢錢包丟失的交易
-checkblocks=<n style="word-wrap: break-word;"> 啟動時檢查多少貨幣塊(預設:2500,0 表示全部)</n>
-checklevel=<n style="word-wrap: break-word;"> 貨幣塊驗證的級別(0-6,預設:1)</n>
**SSL 選項:**
-rpcssl 使用 OpenSSL(https)JSON-RPC 連線
-rpcsslcertificatechainfile=<檔案.cert> 伺服器證書檔案(預設:server.cert)
-rpcsslprivatekeyfile=<檔案.pem> 伺服器私匙檔案(預設:server.pem)
-rpcsslciphers=<密碼> 可接受的密碼(預設:TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)
複製程式碼
bitcoin-cli
Bitcoin Core包含的一個功能完備的RPC客戶端,可以查詢區塊,錢包,交易等各項資訊。比特幣使用的是Json-RPC介面。
1.命令示例
//獲取height為0的區塊雜湊
./src/bitcoin-cli getblockhash 0
000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
//獲取已知某雜湊的區塊具體資訊
./src/bitcoin-cli getblock 000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
{
"hash": "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f",
"confirmations": 187783,
"strippedsize": 285,
"size": 285,
"weight": 1140,
"height": 0,
"version": 1,
"versionHex": "00000001",
"merkleroot": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b",
"tx": [
"4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b"
],
"time": 1231006505,
"mediantime": 1231006505,
"nonce": 2083236893,
"bits": "1d00ffff",
"difficulty": 1,
"chainwork": "0000000000000000000000000000000000000000000000000000000100010001",
"nextblockhash": "00000000839a8e6886ab5951d76f411475428afc90947ee320161bbf18eb6048"
}
複製程式碼
2.其他命令
A、一般性的命令
//幫助指令
help ( "command" )
stop //停止bitcoin服務
getinfo //獲取當前節點資訊
ping
getnettotals
getnetworkinfo
getpeerinfo
getconnectioncount
verifychain ( checklevel numblocks )
getaddednodeinfo dns ( "node" )
addnode "node" "add|remove|onetry"
B、錢包、賬戶、地址、轉帳、發訊息
getwalletinfo //獲取錢包資訊
walletpassphrase "passphrase" timeout //解鎖錢包 密碼-多久錢包自動鎖定
walletlock //鎖定錢包
walletpassphrasechange "oldpassphrase" "newpassphrase" //更改錢包密碼
backupwallet "destination" //錢包備份
importwallet "filename" //錢包備份檔案匯入
dumpwallet "filename" //錢包恢復
listaccounts ( minconf ) //列出所有使用者
getaddressesbyaccount "account" //列出使用者所有的錢包地址
getaccountaddress "account"
getaccount "bitcoinaddress"
validateaddress "bitcoinaddress"
dumpprivkey "bitcoinaddress"
setaccount "bitcoinaddress" "account"
getnewaddress ( "account" ) //獲取新的錢包地址,由錢包地址池生成
keypoolrefill ( newsize )
importprivkey "bitcoinprivkey" ( "label" rescan ) //匯入私鑰
createmultisig nrequired ["key",...]
addmultisigaddress nrequired ["key",...] ( "account" )
getbalance ( "account" minconf ) //顯示所有經過至少minconf個確認的交易加和後的餘額
getunconfirmedbalance
//獲取account或bitcoinaddress對應收到的比特幣數量
getreceivedbyaccount "account" ( minconf )
getreceivedbyaddress "bitcoinaddress" ( minconf )
listreceivedbyaccount ( minconf includeempty )
listreceivedbyaddress ( minconf includeempty )
move "fromaccount" "toaccount" amount ( minconf "comment" )
listunspent ( minconf maxconf ["address",...] )
listlockunspent
lockunspent unlock [{"txid":"txid","vout":n},...]
getrawchangeaddress
listaddressgroupings
settxfee amount
sendtoaddress "bitcoinaddress" amount ( "comment" "comment-to" )
sendfrom "fromaccount" "tobitcoinaddress" amount ( minconf "comment" "comment-to" )
sendmany "fromaccount" {"address":amount,...} ( minconf "comment" )
signmessage "bitcoinaddress" "message"
verifymessage "bitcoinaddress" "signature" "message"
C、Tx、Block、Ming
createrawtransaction [{"txid":"id","vout":n},...] {"address":amount,...}
signrawtransaction "hexstring" ( [{"txid":"id","vout":n,"scriptPubKey":"hex","redeemScript":"hex"},...] ["privatekey1",...] sighashtype )
sendrawtransaction "hexstring" ( allowhighfees )
gettransaction "txid" //獲取簡化版交易資訊
//獲取完整交易資訊
getrawtransaction "txid" ( verbose ) //得到一個描述交易的16進位制字串
decoderawtransaction "hexstring" //解碼上面的字串
listtransactions ( "account" count from ) //獲取錢包對應的交易
listsinceblock ( "blockhash" target-confirmations )
getrawmempool ( verbose )
gettxoutsetinfo
gettxout "txid" n ( includemempool )
decodescript "hex"
getblockchaininfo
getblockcount
getbestblockhash
getblockhash index
getblock "hash" ( verbose )
getmininginfo
getdifficulty
getnetworkhashps ( blocks height )
gethashespersec
getgenerate
setgenerate generate ( genproclimit )
getwork ( "data" )
getblocktemplate ( "jsonrequestobject" )
submitblock "hexdata" ( "jsonparametersobject" )
複製程式碼
Mac下bitcoin原始碼的編譯就完成了,同時我們也瞭解了bitcoind和bitcoin-cli基本命令。萬里長征終於邁出了第一步,今天就到這裡了。
下一篇認識bitcoin原始碼整體框架和程式碼模組的功能。
網際網路顛覆世界,區塊鏈顛覆網際網路!
————————————————–20180417 23:08