如何防止一個帳本被篡改
在設計一個理想的DLT時,其實最核心就三個問題:如何設計出一個好的帳本?如何讓此帳本上的資料無法是無法被篡改的?如何讓每個不信任的節點之間對這個帳本有一個共識?
第一個問題其實就是在談UTXO模型與Account模型;第二個問題在談Hash跟非對稱加密;第三個在談各種Proof of 某某。第二個問題(本篇)與第三個問題會獨立出一篇,而第一個問題則會直接放到介紹比特幣與以太坊的內容當中。讓我們先專注在這問題上:已經有個的帳本,也就是一筆資料在哪邊時,該如何做到不讓它被隨意的竄改呢?
[ Hash函數 ]
- SHA256 Hash是一個函數,厲害的地方是可以把任意長度的Input轉換成一個固定長度,稱作Hash值的Output
- Hash值、Hash Value、雜湊值、或有時侯直接簡稱為Hash,它們指的都是同一個東西。
- Hash函數有個特性:當Input有些微的差異,Output就會差很多,並且是毫無邏輯可言的,也就是說,如果想要獲得特定的Hash值,只能靠一直亂猜。
- SHA256的全稱是Secure Hash Algorithm 256,256指的是,這個產生的Output長度,固定都是256 bits。在16進位(0 ~ F)之下,也就是一個長度為64位元的字串。
- 在區塊鏈的語境之下,Input就是各式各樣的資料(Data);在分散式帳本(DLT)的語境之下,Input就更明確為帳本資料(Ledger),也就是,誰給了誰多少錢的一筆筆資料。
[ Block ]
- 每一個Block會有五個元素:#Block(第幾個區塊)、Nonce(一個隨機數)、Data、Previous Hash值、Hash值。
- 把前四項包在一起,能視為一個Input,通過Hash函數,我們可以得到第五項的這個Hash值。Input在只更動Nonce的條件下,讓Output(Hash值)的前六位為零,這個「湊出符合條件的Nonce」的過程我們稱之為挖礦。礦工指的就是這個去買計算機拿去進行挖礦的人。
- 第一個湊出正確答案的人,會把結果廣播給其他人知道。在其他人都驗證沒問題之後,大家會把這個驗證過的Block接到自己原先的鏈上。而那個第一個算出正確答案的人能拿到一筆獎勵。(把這句話的「人」全都替換成「節點」比較準確,但你懂我意思的)
- Blockchain顧名思義,就是很多個Block接起來,下一個Block的Previous Hash值會是上一個Block的Hash值。
- 例如有一條鏈已經接了五個Blocks了,你去稍微更動第二個Block的任何資料,則後面所有的Hash值都會一連串的隨之改變。
- 當然,你可以暴力去再去算出符合條件的Nonce值,讓二三四五的Hash值都符合上面要求的規則(前六位為零),但是,結尾的Block上的Hash值會跟其他人電腦上的不一樣,這樣別人就知道你動過前面的東西。
- 想更動越之前的Data,難度更高,因為需要更強的算力使其變成最長鏈。
- 以上的這套系統,創造了一個防止他人竄改歷史Data的系統。
- 不能更動與防止竄改是兩個概念:不能更動是設計上直接不能有任何改變,防止竄改指的是可以改動,但我去改動的話,大家都會知道,無法偷偷來。
[ 轉帳資料 ]
- 即使一個完整的帳本是受到防篡改保護的,但由於帳本內的一筆筆交易,是由一個個有可能作惡的使用者所發起的,衍伸的就會產生以下三個問題:一是怎麼知道看到「A給B發錢」的請求時,A手上是真的有錢,而不是一時口嗨;二是如何避免雙重支付(Double-spending),也就是俗稱的雙花攻擊;三是怎麼確認這個發錢的請求,確實是由我本人發起的。不然我就能亂喊Musk給我一個億之類的(他肯定有xDD)。
- 第一個問題好解決,就是一路往前追朔到最前面的區塊,當然,這有點沒效率,替代的解決方式就是,用一個資料庫去存最後的狀態,有點像帳戶餘額的概念。
- 第二個問題由UTXO模型本身就能避免。UTXO的內容我們放到談比特幣的時候一起講。
- 第三個問題是透過公鑰密碼學(Public-Key Cryptography, PKC)來解決,它是一種同時使用公鑰與私鑰的機制,其核心內容為非對稱加密與數字簽名。
- 首先要有個觀念:世界上所有的加密方法都只是讓密碼變很難猜罷了,如果有人硬是要花時間窮舉的話,理論上肯定還是猜的到。好的加密方法指的是,別人需要窮舉很久。而一種密碼方法被破解,指的是,有人找到一個比窮舉還要有效率的解法。例如窮舉需要猜10000次,有人找到個算法,去猜9000次就能肯定得到答案的話,那麼這個加密演算法算是被破解了。
- 對稱加密,意思是加密的過程中,只使用單個密鑰(例如AES)。與之相對的,非對稱加密會同時有私鑰(private key)與公鑰(public key),其密鑰也會比較長。雖然在加密與解密的過程上需要更多的計算資源,但相對的也比較難被破解。
- 最常見的非對稱加密算法是RSA算法,名字來源於它的三位發明者:Rivest、Shamir以及Adleman。而比特幣跟以太坊用的都是另一種稱為ECDSA的算法,也屬於非對稱加密家族的一個成員。
- 私鑰與公鑰是一組的,但是具有方向性:知道私鑰,也就知道與之相對的公鑰,但反之並不成立。私鑰像是私人印章,而公鑰能確認這個蓋過章的東西是不是贗品。
- 加密的過程:給訊息、給私鑰,可以產生數位簽章(message signature)。這過程可以理解為幫一段訊息蓋章,跟去銀行填匯款單時,要蓋印章或簽名是一個道理。
- 解密的過程:給訊息、給公鑰、給數位簽章,就能確認訊息是不是由本人發出。
- 公鑰就是錢包地址。(詳細來說會有一點差異,但你懂的,這不影響理解)
- 回到最一開始的問題,每個人在發出一筆交易例如「A匯給B 100鎂」這訊息時,會A用自己的私鑰,給這訊息產生一個數位簽章,使得他人任意改動交易的內容時,即使Nonce值是對的,透過數位簽章也能看出有問題。
強烈建議到這個網站上面去實際玩玩看,這demo是目前看過最好最直覺的區塊鏈展示,沒有之一的那種。這一套防止篡改的手段,你會發現這有點像是個套娃:在交易資料時,就先有一個數位簽章的驗證程序,然後在最外面整個帳本還有一個Nonce跟Hash值的驗證。三個區塊練基本問題之中,目前回答了第二個問題,下一篇我們會來講如何產生共識這個問題。Be Happy & Stay Tuned,我們回頭見!