日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

5分钟学会区块链 - 开发一条区块链 Develop BlockChain with Tendermint

發(fā)布時間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 5分钟学会区块链 - 开发一条区块链 Develop BlockChain with Tendermint 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

本文攻略:解惑區(qū)塊鏈開發(fā),學習 Tendermint,給自己造一條區(qū)塊鏈

建議玩家等級:技術小白,學生黨,初級碼農

?

閱讀此文先解鎖技能:

  • 一點點命令行基礎
  • 一點點 GO 基礎:三天包學會
  • 一點點區(qū)塊鏈知識:5分鐘學會區(qū)塊鏈 - 關于區(qū)塊鏈的一切 All About Blockchain
  • 實踐此文推薦裝備:

  • 操作系統(tǒng):macOS Sierra(Windows也沒毛病)
  • IDE:VSCode,并自動安裝一批官方建議的GO插件
  • Restful API 工具:Paw(非必需,瀏覽器也可以)
  • ?

    PART 1: Tendermint 是什么

    上篇文章我們舉了雷布斯、杰克馬、坡尼馬和強東哥打麻將共同記賬的栗子,這回PO主見他們手寫記賬這么原始,就想給這四位寫一個區(qū)塊鏈記賬APP,讓他們從此告別手寫賬本。

    既然重新造輪子這件事是不存在的,于是向大家介紹一款區(qū)塊鏈輪子叫 Tendermint(以下簡稱 TM),如果有玩家聽說過以太坊(Ethereum),這個什么坊有個分支 Ethermint 就是基于 TM 開發(fā)的,反正PO主只懂擼代碼不懂炒幣,不是很了解這到底是個什么工坊。

    好了,先來了解一下 TM 的原理,因為實在沒什么可以可視化的 UI 讓玩家們一目了然。TM 主要包含兩部分:

  • Tendermint Core:區(qū)塊鏈共識引擎。它負責兩件事情:節(jié)點之間的數據同步有序傳輸,拜占庭共識機制的實現(xiàn)。
  • ABCI:區(qū)塊鏈應用接口。它被設計成一組有接口規(guī)范的協(xié)議,目的是可以使用多種語言實現(xiàn)區(qū)塊鏈應用邏輯。
  • 那他兩到底干啥用的,說了半天好像還是不太理解,沒關系先記住他們,PO主剛開始看原文檔的時候也和各位玩家有著同樣的感受。

    ?

    PART 2: Tendermint 安裝運行

    1. 官方安裝指南

    讓我們忽略更多的理論,直接擼起袖子做程序猿最喜歡做的事情,先下載輪子,命令行輸入:

    go get github.com/Masterminds/glide go get github.com/tendermint/tendermint/cmd/tendermint

    下載過程比較長,這個輪子比較大(可能需要科學上網),下載完成后安裝,命令行輸入:

    cd $GOPATH/src/github.com/tendermint/tendermint glide install go install ./cmd/tendermint

    安裝過程也比較長,安裝完成后驗證安裝是否成功,命令行輸入:

    tendermint version abci-cli version

    截止本文的發(fā)表時間,tendermint 版本 0.15.0,abci-cli 版本 0.9.0

    ?

    2. 運行官方栗子

    官方文檔提供了兩個栗子,已經集成在了剛才的安裝里:

  • dummy:一個簡單的鍵值存儲區(qū)塊鏈應用,使用起來有點像 Redis 或 ElasticSearch。
  • counter:一個簡單的計數器區(qū)塊鏈應用,寫入區(qū)塊的數字必須遞增,否則將不被區(qū)塊接受。
  • 這里我們簡單介紹一下 dummy 這個栗子,首先啟動這個區(qū)塊鏈應用,命令行輸入:

    abci-cli dummy

    然后啟動 TM,命令行輸入:

    tendermint init tendermint node

    順利的話,可以看到 abci 和 tendermint 兩個程序連通(Connect)了,并且 tendermint 會像心跳一樣每一秒提交一個空區(qū)塊,我們接下來準備寫入有實質內容的新區(qū)塊,命令行輸入:

    curl -s 'localhost:46657/broadcast_tx_commit?tx="abcd"' curl -s 'localhost:46657/broadcast_tx_commit?tx="name=satoshi"'

    我們的區(qū)塊鏈里就有了一個記錄“abcd”的區(qū)塊和另一個記錄“name=satoshi”的區(qū)塊,如果需要對區(qū)塊鏈內容進行查詢,命令行輸入:

    curl -s 'localhost:46657/abci_query?data="name"' curl 是 Linux 常用工具,玩家可以通過網頁瀏覽器直接輸入 localhost:46657/abci_query?data="name"

    ?

    3. 探索官方工具

    最后介紹 abci-cli 這個坑人工具登場,讓我們先關閉剛才運行的 dummy 應用和 tendermint,命令行重新輸入運行 dummy:

    abci-cli dummy

    命令行再輸入:

    abci-cli console

    然后他兩連通了(Connect),此時很多玩家會困惑于這兩個都叫 abci 的家伙怎么也能互相連通,abci 到底是個什么東西?他又干了什么?讓我們通過 PART 3 來重新梳理一下我們剛才究竟都在區(qū)塊鏈里的什么地方做了些什么事。

    ?

    PART 3: Tendermint 再理解

    PO主先把官方文檔里用的最多并容易讓人混淆的名詞都羅列出來:

  • ABCI Server
  • ABCI Client
  • Tendermint Core
  • ABCI Application
  • ABCI App
  • 然后總結了三個名詞來幫助理解,下文約定統(tǒng)一使用這三個名詞:

  • ABCI:區(qū)塊鏈內部,ABCI Server,啟動后加載 ABCI Application/App,為 Tendermint 提供 Socket 服務,服務地址:tcp://localhost:46658
  • Tendermint:區(qū)塊鏈內部,ABCI Client/Tendermint Core,啟動后與 ABCI 提供的 Socket 服務創(chuàng)建 3 條連接(Connect),同時會提供 HTTP 服務給區(qū)塊鏈外部客戶端,服務地址:http://localhost:46657
  • Client:區(qū)塊鏈外部,真正的客戶端,通過 Tendermint 提供的服務對區(qū)塊鏈進行讀寫訪問
  • ?

    還是把栗子舉一舉,假設強東哥在使用我寫的的區(qū)塊鏈記賬 APP(用iOS開發(fā)的):

  • Client 就是區(qū)塊鏈記賬 APP,強東哥記錄了一條新數據 ‘Jack Pony $10’,然后保存
  • Client 會發(fā)起請求 http://localhost:46657/broadcast_tx_commit?tx="Jack Pony $10"
  • Tendermint 收到 tx="Jack Pony $10",通過 Socket 向 ABCI 發(fā)出指令 CheckTx:"Jack Pony $10"
  • ABCI 運行了我寫的 ABCI App(用GO開發(fā)的)里的 CheckTx 方法,作用是驗證 "Jack Pony $10" 是否符合數據規(guī)范,如果不符合就要通知 Temdermint 拒絕這條 tx
  • 假設 ABCI CheckTx 驗證通過后通知 Tendermint
  • Tendermint 把 "Jack Pony $10" 暫存在內存池(mempool)里,并把這條 tx 通過 P2P 網絡復制給其它 Tendermint 節(jié)點(杰克馬、坡尼馬和雷布斯各自運行的 Tendermint 節(jié)點)
  • Tendermint 發(fā)起了對 "Jack Pony $10" 這條 tx 的拜占庭共識投票,所有4個 Tendermint 節(jié)點都參與了。投票過程分三輪,第一輪預投票(PreVote),超過 2/3 認可后進入第二輪預提交(PreCommit),超過 2/3 認可后進入最后一輪正式提交(Commit)
  • Tendermint 提交(Commit)時依次向 ABCI 發(fā)送指令:BeginBlock -> DeliverTx * n次 -> EndBlock -> Commit,大致意思就是:快接受新區(qū)快 -> 正在接受區(qū)塊內容 * n條 -> 區(qū)塊內容接受完了 -> 提交到區(qū)塊鏈去吧
  • ABCI 提交(Commit)成功后會通知 Tendermint
  • 至此,區(qū)塊鏈多了一個區(qū)塊記錄了 1 條 transaction "Jack Pony $10" ,當然我們也可以記錄 n 條后再保存,那么一個區(qū)塊就會記錄 n 條 transaction
  • ?

    最后再總結幾點:

  • 說回剛才那個坑人的 abci-cli,當他運行 'abci-cli dummy' 時其實是運行了 ABCI,當他運行了 'abci-cli console' 時其實是運行了 Tendermint,所以一起運行后會進行 Socket 連接(Connect)
  • Tendermint 和 ABCI 之間的 Socket 連接有 3 條:1 條用于驗證數據(CheckTx 指令),1 條用于查詢數據(Query 指令),1 條用于共識數據(BeginBlock, DeliverTx, EndBlock, Commit 指令)
  • Tendermit 提供給 Client 的 HTTP 接口有很多,瀏覽器訪問 http://localhost:46657 就都知道了
  • 玩家也可以親自拜讀一下官方文檔
  • ?

    PART 4: 開發(fā)一條區(qū)塊鏈

    總算到了擼代碼環(huán)節(jié),我們先把項目架構整理一下:

  • ClientApp:區(qū)塊鏈記賬 APP,可以用任意語言任意平臺實現(xiàn)(iOS/Android/H5/其它),這個版本里我們用 GO 做了最簡單的控制臺命令行實現(xiàn),甚至沒有 UI 界面。
  • TendermintApp:區(qū)塊鏈服務程序,這個里面包括 Tendermint 和 ABCI 兩部分。
  • ABCI:因為是接口協(xié)議,設計上可以用任何語言去實現(xiàn),我們使用了 GO 語言。開發(fā)上主要是實現(xiàn) CheckTx, DeliverTx, Commit 等 ABCI 指令的具體邏輯
  • Tendermint:幾乎沒有需要開發(fā)的地方,前面提到了它已經為我們做了兩件事情,P2P網絡同步有序傳輸數據和拜占庭共識引擎。我們在這里就將它運行即可。
  • ?

    接下來正式擼代碼,我們主要講解一部分核心邏輯:

    1. ClientApp

    模擬了5個區(qū)塊,每個區(qū)塊記錄10條記錄,將這些記錄轉成 json 提交給 Tendermint

    blocksNumber := 5 // how many blocks transactionsPerBlock := 10 // how many transactions in each block players := []string{"Lei", "Jack", "Pony", "Richard"} // 4 players random := rand.New(rand.NewSource(time.Now().UnixNano())) json := jsoniter.ConfigCompatibleWithStandardLibraryfor i := 0; i < blocksNumber; i++ {time.Sleep(time.Second * 1)transactions := []controllers.Transaction{}for j := 0; j < transactionsPerBlock; j++ {from := players[random.Intn(len(players))]to := players[random.Intn(len(players))]for from == to {to = players[random.Intn(len(players))]}btc := float32(random.Intn(10) + 1)tran := controllers.Transaction{From: from,To: to,Bitcoin: btc,}_, _ = tran.Create()transactions = append(transactions, tran)}bytes, _ := json.Marshal(&transactions)data := strings.Replace(string(bytes), "\"", "'", -1)tx := data// tmAsync(tx)tmCommit(tx) }

    ?

    func tmCommit(tx string) {url := "http://localhost:46657/broadcast_tx_async?tx=\"" + tx + "\""txHandle(url) }

    ?

    2. Tendermint

    通過命令行運行一個定義好的 Shell 腳本,并且把運行結果打印到控制臺和日志文件中去

    f, err := os.Create("logs/tendermint.log") if err != nil {fmt.Println("Tendermint log init error:", err) } multiWriter := io.MultiWriter(f, os.Stdout)go func() {cmd := exec.Command("bash", "-c", "sh run-tm.sh")cmd.Stdout = multiWritercmd.Start() }()

    run-tm.sh 腳本內容:

    echo tendermint start tendermint init tendermint unsafe_reset_all tendermint node --consensus.create_empty_blocks=false echo tendermint end unsafe_reset_all 作用是每次重置本機的區(qū)塊鏈數據,僅供開發(fā)使用 consensus.create_empty_blocks 作用是關閉 Tendermint 自帶的每秒生成新的空區(qū)塊功能

    ?

    3. ABCI

    實現(xiàn) ABCI 指令接口,這里我們直接使用了官方栗子 dummy 應用,來保存提交的 json 記錄,并且在每個實現(xiàn)接口里做了日志打印(因篇幅有限,省略了長長的代碼)

    func (app *DummyApplication) CheckTx(tx []byte) types.ResponseCheckTx {lib.Log.Debug("CheckTx")lib.Log.Notice(string(tx))return types.ResponseCheckTx{Code: code.CodeTypeOK} }func (app *DummyApplication) DeliverTx(tx []byte) types.ResponseDeliverTx {lib.Log.Debug("DeliverTx")lib.Log.Notice(string(tx))// ...return types.ResponseDeliverTx{Code: code.CodeTypeOK, Tags: tags} }func (app *DummyApplication) Commit() types.ResponseCommit {lib.Log.Debug("Commit")// ...lib.Log.Debug("Commit Hash", hash)return types.ResponseCommit{Code: code.CodeTypeOK, Data: hash} }func (app *DummyApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) {lib.Log.Debug("Query")// ... }

    ?

    4. 編譯

    我們寫好了編譯腳本,命令行輸入:

    sh make.sh

    編譯腳本本質就是把三個運行程序編譯出來:

    go build ./TendermintApp/ABCIServer/ go build ./TendermintApp/ABCIClient/ go build -o Client ./ClientApp/

    ?

    5. 測試

    到了激動人心的一刻,我們已經離一條自造的區(qū)塊鏈很接近了。

    先運行 ABCI,命令行輸入:

    ./ABCIServer

    再運行 Tendermint,命令行輸入:

    ./ABCIClient

    可以看到 Tendermint 和 ABCI 已經有 3 個連接(Connect) Socket 握手了,表示整個區(qū)塊鏈服務已經準備就緒,最后我們只需要使用 Client 往區(qū)塊鏈里寫數據就行了,命令行輸入:

    ./Client

    把條命令理解成使用記賬 APP 記錄了 5 頁,每頁 10 條記錄,然后點擊保存后送去了區(qū)塊鏈。

    ?

    附上一張運行結果圖,大致能觀察到三個程序都已成功運行

    ?

    最終我們創(chuàng)造了一條區(qū)塊鏈,一共有 7 個區(qū)塊,2~6 號區(qū)塊各自寫有 10 條賬本記錄,第 1 和第 7 號區(qū)塊是系統(tǒng)創(chuàng)建的空區(qū)塊。

    空區(qū)塊是怎么回事?原先 PO 主也以為是 BUG,去了官方的開發(fā) issue 里了解到 Tendermint 每次收到新的 tx 或者區(qū)塊鏈 hash 值變化的時候(就是區(qū)塊鏈狀態(tài)變了)會產生一個新區(qū)塊去接受 mempool 里未被提交的新 tx,這是 Tendermint 用于正常自檢工作產生的。

    ?

    來看看這條區(qū)塊鏈長什么樣子,這里展示了 2, 3, 4 號區(qū)塊的賬本記錄

    ?

    感覺有好多$$在這小小的幾個區(qū)塊里,最后獻上本文代碼,希望各位玩家也創(chuàng)造一條屬于自己的區(qū)塊鏈。PO 主也默默去寫未完成的賬本 APP了。

    https://zhuanlan.zhihu.com/p/33154604

    總結

    以上是生活随笔為你收集整理的5分钟学会区块链 - 开发一条区块链 Develop BlockChain with Tendermint的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。