iT邦幫忙

2023 iThome 鐵人賽

DAY 16
0
Web 3

從 區塊鏈 到 去中心化應用程式(DApp)系列 第 16

區塊鏈建立: 區塊運算 之 礦工與他們的領導者

  • 分享至 

  • xImage
  •  

區塊運算 之 礦工與他們的領導者

專案 GitHub 位置: https://github.com/weiawesome/block-chain_go

區塊運算中最核心的部分 便是 礦工

而所謂挖礦就是去找 Nonce 以符合區塊難度

不過基於現代多核心的處理器
完全可以運用這優勢 去進行平行運算
此處便是透過 Goroutine 的方式同時開啟多個運算單位

另外再透過一個 領導者 領導 礦工們運作

此處分為以下幾點敘述

  1. 礦工領導者的設計
  2. 礦工們的設計

完成的範圍便是 礦工管理者礦工們

礦工管理者

Channel 名稱 Channel 類型 地點
MinersBlockChannel 刷新區塊
SuccessBlockChannel 礦工們
minersChannels 礦工們
MinersSuccessBlockChannel 接收驗證區塊

礦工們

Channel 名稱 Channel 類型 地點
minersChannels 礦工管理者
SuccessBlockChannel 礦工管理者

礦工領導者的設計

檔案位置: "./service/miners_leader/miners_leader.go"

func MinerLeader(Miners int, MinersBlockChannel chan blockchain.Block, MinersSuccessBlockChannel chan blockchain.Block) {
	var minersChannels []chan blockchain.Block
	SuccessBlockChannel := make(chan blockchain.Block)
	Lower := uint32(0)
	Upper := ^uint32(0)
	nonceRange := (Upper - Lower + 1) / uint32(Miners)
	for i := 0; i < Miners; i++ {
		minerChannel := make(chan blockchain.Block)
		go miners.Miner(Lower, Lower+uint32(i)*nonceRange, minerChannel, SuccessBlockChannel)
		minersChannels = append(minersChannels, minerChannel)
	}
	for {
		select {
		case mb := <-MinersBlockChannel:
			for _, channel := range minersChannels {
				channel <- mb
			}
		case sb := <-SuccessBlockChannel:
			MinersSuccessBlockChannel <- sb
		}
	}
}
  1. 首先在建立時 根據礦工數量
    建立相對應 Goroutine 與 Channel 和 分配計算範圍
  2. 當收到新區塊時 通知所有礦工有新區塊
  3. 當收到計算完成的區塊時 通知接收驗證區塊 進行驗證與廣播

礦工們的設計

檔案位置: "./service/miners/miners.go"

func Miner(Lower uint32, Upper uint32, MinerBlockChannel chan blockchain.Block, SuccessBlockChannel chan blockchain.Block) {
	for {
		select {
		case b := <-MinerBlockChannel:
			if len(b.BlockTransactions) <= 1 && conseous.MineEmpty == false {
				continue
			}

			i := Lower
			flag := false
			for {
				select {
				case nb := <-MinerBlockChannel:
					i = Lower - 1
					b = nb
				default:
					b.BlockTop.Nonce = i
					b.ComputeBlockHash()

					if b.CheckDifficulty() {
						SuccessBlockChannel <- b
						flag = true
						break
					}
					i++
					if i == Upper {
						flag = true
						break
					}
				}
				if flag {
					break
				}
			}
		default:
			continue
		}
	}
}

根據所限定的範圍去尋找 Nonce 以符合區塊難度

另外此處有一個設定 MineEmpty 代表是否要挖空的區塊
(像是在比特幣當中 若是區塊內無交易 則獎勵減半)

因此透過這個設計 就可以設定這個區塊鏈是否會挖掘空區塊

  1. 當收到新區塊時 開始計算
  2. 當計算時 收到新區塊 重新計算
  3. 當計算完成時 通知礦工領導者 並且停止運算等待新區塊

結言

在市面上 會常常聽聞使用 GPU 挖礦

究其原由 就是因為 GPU 本身設計模式

GPU 相較於 CPU 有非常多的核心

CPU 可能 6核、9核 但 GPU 可以到上千核心
不過就單個核心計算能力 CPU 大於 GPU

因此 GPU 適用於 多點同時得簡單運算(如圖像、深度學習運算...
而 CPU 則做為 電腦核心使用

希望透過此處能夠理解

  1. 礦工領導者與礦工們的定位與服務
  2. 平行運算 Goroutine 與 Channel 的應用

下回預告

目前對於區塊運算就告一段落了!

其實邏輯上現在區塊鏈已經能成功運作起來了
包括 建立節點、連接節點、傳輸訊息、計算區塊...

不過目前對於 提交交易 或是 查詢區塊...的服務
需要提供一個接口

因此是時候來建立 API (應用程序接口)

下回 "區塊鏈建立: 區塊鏈API 相關接口"


上一篇
區塊鏈建立: 區塊運算 之 區塊的流向
下一篇
區塊鏈建立: 區塊鏈 API 相關接口
系列文
從 區塊鏈 到 去中心化應用程式(DApp)30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言