微專業-區塊鏈開發工程師 - 去除“泡沫”,迴歸區塊鏈本質
幾乎所有語言都可以編寫區塊鏈開發程式。那麼如何用JavaScript寫一個區塊鏈?以下我將要用JavaScript來建立1個簡單的區塊鏈來演示它們的內部到底是怎樣工作的。我將會稱作SavjeeCoin!
區塊鏈是由一個個所有人能夠訪問的區塊構成的公共資料庫。這好像沒有什麼特別的,不過它們有個有意思的特性:它們是無法變的。要是1個區塊被插入到區塊鏈中,除非讓剩下的另外區塊失效,不然這是不會再被更改的。
區塊鏈是由千千萬萬的區塊連線在一起的。鏈上的區塊根據某一方法容許人們檢驗到是不是有人控制了以前的一切區塊。
那麼人們怎樣保證資料的完整性呢?每一區塊都含有1個基於其內容計算出來的hash。同時也涵蓋了前1個區塊的hash。
下面是一個區塊類用JavaScript寫出去大概的模樣:
const SHA256 = require(“crypto-js/sha256”);
class Block {
constructor(index, timestamp, data, previousHash = ‘’) {
this.index = index;
this.previousHash = previousHash;
this.timestamp = timestamp;
this.data = data;
this.hash = this.calculateHash();
}
calculateHash() {
return SHA256(this.index + this.previousHash + this.timestamp + JSON.stringify(this.data)).toString();
}
}
因為JavaScript中並不支援sha256所以我引入了crypto-js庫。然後我定義了一個建構函式來初始化我區塊的屬性。每一個區塊上都被賦予了index屬性來告知我們這個區塊在整個鏈上的位置。我們同時也生成了一個時間戳,以及需要在區塊裡儲存的一些資料。最後是前一個區塊的hash。
創造一個鏈
現在我們可以在Blockchain類中將區塊連結起來了!下面是用JavaScript實現的程式碼:
class Blockchain{
constructor() {
this.chain = [this.createGenesisBlock()];
}
createGenesisBlock() {
return new Block(0, “01/01/2017”, “Genesis block”, “0”);
}
getLatestBlock() {
return this.chain[this.chain.length - 1];
}
addBlock(newBlock) {
newBlock.previousHash = this.getLatestBlock().hash;
newBlock.hash = newBlock.calculateHash();
this.chain.push(newBlock);
}
isChainValid() {
for (let i = 1; i 《 this.chain.length; i++){
const currentBlock = this.chain[i];
const previousBlock = this.chain[i - 1];
if (currentBlock.hash !== currentBlock.calculateHash()) {
return false;
}
if (currentBlock.previousHash !== previousBlock.hash) {
return false;
}
}
return true;
}
}
在建構函式裡,我通過建立一個包含創世塊的陣列來初始化整個鏈。第一個區塊是特殊的,因為它不能指向前一個區塊。我還添加了下面兩個方法:
· getLatestBlock()返回我們區塊鏈上最新的區塊。
· addBlock()負責將新的區塊新增到我們的鏈上。為此,我們將前一個區塊的hash新增到我們新的區塊中。這樣我們就可以保持整個鏈的完整性。因為只要我們變更了最新區塊的內容,我們就需要重新計算它的hash。當計算完成後,我將把這個區塊推進鏈裡(一個數組)。
最後,我建立一個isChainValid()來確保沒有人篡改過區塊鏈。它會遍歷所有的區塊來檢查每個區塊的hash是否正確。它會通過比較previousHash來檢查每個區塊是否指向正確的上一個區塊。如果一切都沒有問題它會返回true否則會返回false。
使用區塊鏈
我們的區塊鏈類已經寫完啦,可以真正的開始使用它了!
let savjeeCoin = new Blockchain();
savjeeCoin.addBlock(new Block(1, “20/07/2017”, { amount: 4 }));
savjeeCoin.addBlock(new Block(2, “20/07/2017”, { amount: 8 }));
在這裡我僅僅是建立了一個區塊鏈的例項,並且命名它為SavjeeCoin!之後我在鏈上添加了一些區塊。區塊裡可以包含任何你想要放的資料,不過在上面的程式碼裡,我選擇添加了一個帶有amount屬性的物件。
試著操作吧!
在介紹裡我曾說過區塊鏈是不可變的。一旦新增,區塊就不可能再變更了。讓我們試一下!
// 檢查是否有效(將會返回true)
console.log(‘Blockchain valid? ’ + savjeeCoin.isChainValid());
// 現在嘗試操作變更資料
savjeeCoin.chain[1].data = { amount: 100 };
// 再次檢查是否有效 (將會返回false)
console.log(“Blockchain valid? ” + savjeeCoin.isChainValid());
我會在一開始通過執行isChainValid()來驗證整個鏈的完整性。我們操作過任何區塊,所以它會返回true。
之後我將鏈上的第一個(索引為1)區塊的資料進行了變更。之後我再次檢查整個鏈的完整性,發現它返回了false。我們的整個鏈不再有效了。
其實區塊鏈的原理並不複雜,這個小例子證明了區塊鏈的工作原理。