BTC original source code(C++) initial 架構分析 (1)


Posted by Kled on 2021-12-09

主要內容參考 比特幣知乎解讀

本篇文章主要解讀比特幣v0.1的代碼, 看看最原始的加密貨幣是怎麼創造出來的
如果對比特幣的原理還不太理解的, 可以參考先前的文章 BTC White Paper解讀

比特幣架構分析

bitcoin 架構

  • src : 代碼文件夾
  • bitcoin.exe : 比特幣錢包clinet運行程序
  • libeay32.dll : openssl動態連結庫
  • mingwm10.dll : mingw動態連結庫
  • license.txt : 版本說明
  • readme.txt : 程式說明

上面的結構可以看出來幾點

  1. 比特幣使用到了openssl密碼庫 (libeay32.dll)
  2. 編譯這隻程式bitcoin.exe時使用了MinGW編譯器 (mingwm10.dll)
  3. 此版本為測試版本 (ALPHA版本), 可在windows上運行, port為8333 (readme.txt)
  4. 通過Generate Coins選項可以解決難題, 成功解決一個難題將創建一個新區塊並得到比特幣做為報酬 (readme.txt)

比特幣source code架構分析

makefile
readme
一樣先從readme開始看起

  1. 首先是編譯, 可以看到IDE是用Micronsoft Visual C++ 6.0, 編譯器是MinGW

    MinGW : MinGW,又稱mingw32,是將GCC編譯器和GNU Binutils移植到Win32平台下的產物,包括一系列標頭檔、庫和可執行檔

  2. 編譯過程使用了四個依賴, Openssl, wxWidgets, Berkeley DB, Boost以及相關的版本訊息與編譯方法

比特幣錢包分析

分析到source code之前, 可以看到不是.h就是.cpp, 另外有一個uiproject.fbp比較特別, 這就是比特幣錢包的ui, 使用wxFormBuilder做的wxWidgets的UI設計(wxWidgets是跨平台的Ui設計), 要打開必須要安裝wxFormBuilder

透過wxFormBuilder生成uibase.cpp, uibase.h作為ui的interface, 並且透過ui.cpp, ui.h繼承wxApp實現邏輯層, 並透過IMPLEMENT_APP(CMyApp)啟動比特幣程序
CMyApp

編譯Bitcoin錢包程式

程式編譯過程

Openssl

作為一個基於密碼學的安全開發包, OpenSSL提供的功能相當強大和全面, 囊括了主要的密碼算法, 常用的密鑰和證書封裝管理功能以及SSL協議,並提供了豐富的應用程序供測試或其它目的使用

Boost

Boost庫簡介:
Boost庫是為C++語言標準庫提供擴展的一些C++程序庫的總稱。它由Boost社區組織開發、維護的。其目的是為C++程序員提供免費、同行審查的、可移植的程序庫。

Boost庫中與比特幣源碼相關的子庫:

Signals2庫:

Signals2是基於Boost的另一個signals庫, 實現了線程安全的觀察者模式, 在Signals2中,所謂的觀察者模式被稱為信號/插槽(signals and slots)

簡而言之, 它是一種函數回調機制, 定義signal類型數據, 把執行代碼放在單獨放在函數中, 美其名曰slot, 一個signal可以關聯多個slot, 當signal發出的時候, 所有關聯它的slot都會被調用

比特幣中涉及Qt編程, 而Signals/slots機制是Qt編程的核心機制, 要理解Qt編程就必須對Signals/slots有所了解

Thread庫:

Thread庫顧名思義就是線程庫, boost和其他語言一樣提供互斥鎖來解決, 特別的是boost還提供了互斥類, 比特幣源碼中多線程處理rpc請求的代碼中有很多涉及Thread庫。

Chrono庫:

Chrono是Boost庫中用於時間處理的庫, 主要包含三個概念時間段(duration), 時間點(time_point)和時鐘(clock)

Test庫:

  用來給代碼做單元測試, 白盒測試, 其實際過程大致為:給定輸入, 得到輸出, 判斷是否和預期的輸出相同

Boost庫的優點:

  1. 它是一個開源庫, 吸取了很多開發人員的智慧
  2. 它沿用了STL的思想
  3. 使用簡單, 不依賴其他庫
  4. 多Boost開發人員都在C ++標準委員會, 也就是說, Boost的許多部分很有可能被加入到下一個C++標準庫中

wxWidgets

wxWidgets是一種C++構架庫, 簡單來說就是一個免費、開源、跨平台的用戶圖形界面開發庫
其中包含了構建圖形界面所需的類,能夠快速解決繁瑣的圖形界面開發需求

Berkeley DB

BerkeleyDB(簡稱為BDB)是一個嵌入式數據庫, 它適合管理海量的、簡單的數據。由於Berkeley DB庫的特點, 它在比特幣源碼bitcoin-0.1.0中作為數據存儲媒介被大量使用

比特幣整體架構

架構
根據前面所說, 比特幣在ui.cpp定義了CMyApp中的OnInit作為入口函數

跳過前面的wxWidget設定
第一步驟就是ParseParameters用來對argc, argv輸入的參數做parsing

全局變量初始化

LoadAddresses(), 讀取addr.txt和addr.dat中比特幣節點的地址
LoadBlockIndex(), 讀取blkindex.dat中的數據
LoadWallet(), 讀取wallet.dat的錢包地址

UI初始化

最後透過下面初始化UI

pframeMain = new CMainFrame(NULL);
pframeMain->Show();

網路初始化

透過StartNode(strErrors)啟動當前節點, 使該節點監聽8333, 而後創建4個線程
ThreadIRCSeed, ThreadSocketHandler, ThreadOpenConnections, ThreadMessageHandler

啟動礦工線程

如果fGenerateBitcoins有打開的話, 就會啟動礦工線程ThreadBitcoinMiner

交易發起

是在ui.cpp裡面的CSendDialog::OnButtonSend(wxCommandEvent& event)實現的

  • 實例化交易對象
  • 交易金額檢驗 : 格式檢驗, 餘額檢驗
  • 調用AddressToHash160()函數, 得到收款人public key (hash160), 並將創建鎖定腳本
  • SendMoney()函數
    -- 構建交易CreateTransaction
    -- 提交交易CommitTransactionSpent
    -- 接受交易wtxNew.AcceptTransaction
    -- 廣播交易wtxNew.RelayWalletTransaction

地址管理

地址管理分為當前節點管理和外部節點地址管理, 都存在addr.dat中
當前節點存放在ui.h的CYourAddressDialog Class中, 包含新建, 重命名, 複製
收款方的節點存放在CAddressBookDialog Class中

以上就是比特幣initial的架構部分


補充C++ compiler
msvc : 使用的是VS的編譯器
MinGW : 主要適用於跨平台開發
MinGW版本比較麻煩, 需要自己安裝對應的library(cmake, opencv)

兩者是很好用的編譯工具,但是他們兼容的並不好。當你的項目使用MinGW編譯的使用,想要用一個MSVC編譯生成的庫時就會有問題。使用MinGW編譯項目的時候,所使用的Lib也要是MinGW編譯的。
如果你只是開發Window平台的軟件時,最好用Qt MSVC組合,這樣可以使用大量的第三方lib,還有很多的構建指令,畢竟window上MSVC才是王道。
msvc的側重點是對C++標準的支持以及對Windows SDK的支持,而不是對C語言的支持


如果喜歡文章, 不妨按下喜歡訂閱支持

如果真的想支持我進行創作與實踐計畫, 也可以進行打賞
BTC (BTC) : 1LFRBqvWR9GGizBzoFddkb5xRpAzKRVoDC
BTC (BSC) : 0xe1cda3eb778d1751af17feac796a4bbe4dbca815
BTC (ERC20) : 0xe1cda3eb778d1751af17feac796a4bbe4dbca815
USDT (TRC20) : TT7wgKuYoHwfRy3vCr38Qy3gnS3JJ1aKvn

如果想使用幣安, 可以使用我的推薦連結可以節省手續費10%
或使用推薦碼 : A5YRMD2T


#blockchain #BTC #比特幣 #加密貨幣 #虛擬貨幣 #幣安 #Binance #sourcecode







Related Posts

[第一週] 認識  Git  及常用指令整理

[第一週] 認識 Git 及常用指令整理

Python基礎入門 | Lambda Function

Python基礎入門 | Lambda Function

重新認識Vue.js

重新認識Vue.js


Comments