蒼時弦也
蒼時弦也
資深軟體工程師
發表於

在 2018 年我所知道的區塊鏈

上週同事突然在公司的聊天群組中討論起區塊鏈到底是不是屬於分散式系統(Distributed System)因為去年年底爆紅的關係,我也稍微了解了一下區塊鏈的運作,就被同事說會不會晚上就有文章出來了。

雖然不是當天晚上就在寫,不過了解區塊鏈的運作倒是很有幫助我們冷靜下來對應這個新名詞。

起源

其實最開始是跟同事有買了一些 BTC/ETH 來放著,在 2018 年底爆紅之後發現加密貨幣被當作金融商品在操作,而自己對他一點都不了解,反而沒有抓住恰當的時機,所以就開始研究他的可能性。

不過我感覺,搞懂了只會讓你想趕快賣掉而已

新技術?

因為不了解,所以我們會會認為他是一種全新的技術。實際上其實完全不是,都是靠「已知」的技術來實現的。也因為這樣,區塊鏈在運作起來還算是可靠的,因為有很多已知的問題都被研究過,而且使用的都是經過好幾年檢驗沒問題的技術。

所以,與其說是新技術,不如看作是一種新概念會比較恰當,在比特幣開始使用的 Proof of Work(工作證明)機制,經過長時間的驗證後,發現是一種有效的方法,所以才會被認同跟使用。

區塊跟鏈

從工程師的角度去看區塊鏈這個東西,大概會先連結到 Linked List 這種結構。實際上很明顯的,所謂的區塊鏈就是一種 Linked List 的資料結構,將一個接著一個的 Block(區塊)來練接起來。

所以,實際上一個區塊鏈很難實作嗎?其實不算困難。

要製作出簡單的區塊連結構,大概會像這樣。

 1# Ruby
 2
 3class Block
 4  def initialize(prev, data)
 5    @prev = prev
 6    @data = data
 7  end
 8end
 9
10class Chain
11  GENESIS = Block.new(nil, '')
12
13  def initialize
14    @blocks = [GENESIS]
15  end
16
17  def add(data)
18    @blocks.push(Block.new(@blocks.last, data))
19  end
20end
21
22chain = Chain.new
23chain.add('Hello World')

不過,光靠這些事不足以構成完善的區塊鏈本身。

產生區塊

如果光是像前面所述的去生成新的區塊,很明顯的是沒有被驗證的。那就代表說任何人都可以隨意的去產生新的區塊,而且這並不是我們所期望的結果。

所以要放入 PoW(Proof of Work)這樣的機制在裡面,用來檢驗產生區塊是否合理。

於是,產生一個區塊的流程被拆分為幾個階段。

Untitled Diagram (1).png

簡單來看,我們在原本直接產生區塊鏈的機制中,增加了一個叫做「工作證明」的動作,先讓作為礦工(節點)的角色耗費一定資源來進行運算,等到達成條件之後,再送給其他人檢查,如果結果都相同,那麼就接受這次的區塊打包,反之則拒絕讓對方重新開始。

工作證明

為了要證明工作,我們必須讓所有人都可以快速的取得相同的結果。但是證明者需要花費對應的資源才能取得結果,而其他人則需要可以用最短的時間內檢驗。

這時候加密演算法(Cryptography)剛好就可以解決這個問題。為了符合這個條件,我們需要先對區塊鏈的「區塊」本身做一些結構上的調整,這樣我們才能夠去驗證。

1class Block
2  def initialize(prev, hash, data)
3    @prev = prev
4    @parent = hash
5    @data = data
6  end
7end

簡單來說,我們要先對區塊中的「區塊資料」先做一次加密的動作,獲得一個 Hash 值,來確保每一個區塊的資料是有一致性的。比較常見的案例,就是在下載檔案時會提供一個叫做 MD5 的 Hash 值,讓我們來驗證跟提供者提供的檔案是相同的。

基於這樣的原理,我們就可以透過這個 Hash 值來確認跟其他節點的區塊對應到的是相同的一個。

不過為了要證明工作,所以整個網路會一起提出一個問題,然後由所有參與運算的節點一起來處理。例如我們使用 MD5 來進行運算,會得到一個 32 個字元長度的字串。

那麼題目就可能會是「前三個字必須是 000」的題目」不過,因為原本只對資料做 Hash 是不可能改變結果的,所以我們會再加入一個叫做 proof 的資料欄位。

原本我們的 Hash 值可能會是 md5(data) 改變為 md5(proof + data) 這樣的計算,如此一來運算節點只需要一直修改 proof 的值來達到 Hash 結果為 000 開頭,那麼就算是完成工作證明了。

接下來提交給其他節點,他們只要執行 md5(proof + data) 就可以馬上驗證這個區塊是否為正確的區塊。

出題目的情況其實就是挖礦時的難度調整,當大家都很容易算出來的時候,就會調整題目的難度,讓他更難以嘗試出來。

像這樣透過產生隨機字串去試到成功為止這件事情,就跟「挖礦」的行為很像,這也就是為什麼我們會用「挖礦」和「礦工」來形容。

至於像是比特幣有 51% 攻擊問題,礙於篇幅就不多做討論。

儲存問題

不過,隨著儲存的資料增長,每次更新都需要下載非常大量的交易紀錄,對一般使用者來說其實是一種負擔。所以我們再次利用密碼學的特性,將節點分成 Full Node 和 Light Node 兩種,前者會保存完整的資料,而後者則在有需要時才到網路上詢問其他節點。

以比特幣的情況來看,他採用了 Merkle Tree(默克爾樹)這個機制,我們將一個 Key-Value 儲存的資料,透過加密演算法,產生為一個 Hash 不斷合併後會得到一個最終的 Root Hash 作為參考,而這樣的機制可以讓我們在 Light Node 中只需要保存 Root Hash 就可以了。

透過這樣的機制,我們也得以在像是手機運行錢包,否則手機可能會連過往的交易資料都沒辦法完整儲存。

Merkle Tree 的父結點會是子結點的資料相加後的 Hash 值,然後不斷合併後達到跟節點。

受限的功能

經過前面的解說,我們已經大致上的對區塊鏈的基本雛形有一個了解。簡單的來回推這些機制,其實會發現就是為了要儲存「可信且一致」的資料,所以才會有著「分散式帳本」這樣的名稱。

我們從 CAP 的定理來看,一般的資料庫大多會將 Consistence (一致性)的要求降低,來加快資料儲存的速度。但是在區塊鏈的世界,對一致性的要求是 100% 的,也讓我們在這些取捨中,失去的運算的速度。

這也是為什麼加密貨幣沒辦法做非常及時的交易,而每秒的處理量也無法達到一些金融應用的標準。

用簡單的角度去看區塊鏈,其實就是一套 NoSQL 資料庫。但是他本身有著非常好的一致性,一但資料被寫入之後就不會和其他人有所差異。

不過一個可信的區塊鏈就必須建立在下面幾種條件都建立的情況下:

  • 適當的加密演算法
  • 足夠多的使用者(Proof of Work)

這也是目前比特幣目前最大的優勢所在,因為大部分的礦工都參與這個區塊鏈,對檢查資料一致來說是非常嚴格的(不過還有 51% 攻擊問題)

可能的應用

透過前面這些情報,其實我們會發現基本上在區塊鏈是基於「儲存資料」的前提下運作的。像是以太坊在區塊鏈上提供了圖靈完備的機制,我們放一段可執行的程式碼是可行的。這也構成了 DApp 和 Token(代幣)體系得以實現。

不過回到可應用的層面,因為我們都是在操作這些儲存的資料,能做的事情其實並不多。而跟這些特性相符的事情,又更少了。

適應性最高的就是加密貨幣的應用,也就是資產類型的管理和轉移。另一方面則是力用擁有圖靈完備機能的區塊鏈,在鏈上進行一些操作。

如此一來,加密貨幣的應用就顯而易見了。也因此,發展方向不外乎就是基於區塊鏈的一致性特性來輔助管理,所以才會有像是醫療、物聯網等等應用,用來追蹤資訊的變化跟脈絡。

另一方面則是強化區塊鏈本身,所以才會有側鏈、新的工作證明機制等等方法的提出,或者去開發全新的區塊鏈來改善等等。

反思

從技術的角度去觀察區塊鏈本身,其實會發現「能做的事情不多」也就是為什麼大家都在等待所謂的「殺手級應用」出現。

至於像是交易所、ICO 這類應用,只能說是在商業上的成功。至於該怎麼使用區塊鏈來改善生活,到目前為止都還沒有看到一個明確的方向。

這也是為什麼文章一開始會認為「搞懂了反而想賣掉」的原因,作為投資理財的角度,加密貨幣確實是這幾年值得一試的金融商品。但是從技術面來看,到目前為止都還沒有非常明朗的結果,也因為這樣,就代表說加密貨幣一直有資金流入,但是卻一直沒有實質上的產出。

這就跟泡沫化的跡象一樣,他很熱門但是還沒有實質的用途。

這才是大家擔心的泡沫,不過即使泡沫破了,工程師們大概還是會在這個方向上繼續努力。所以該買加密貨幣嗎?

作為研究用圖,或者期待哪一天工程師們可以找到正確得應用方案,那麼在「可接受的範圍內」買一點放著,偶爾可以拿來嘗試一些有趣的應用(Ex. 加密貓)之類的,倒是不錯。

不過到這邊為止,我想大家應該是可以很冷靜的看待區塊鏈了吧!