一個簡單的區塊鏈

Gb16978發表於2022-07-19

區塊鏈的基礎概念很簡單:一個分散式資料庫,儲存一個不斷加長的 list,list 中包含著許多有序的記錄。然而,在通常情況下,當我們談到區塊鏈的時候也會談起使用區塊鏈來解決的問題,這兩者很容易混淆。像流行的比特幣和以太坊這樣基於區塊鏈的專案就是這樣。“區塊鏈”這個術語通常和像交易、智慧合約、加密貨幣這樣的概念緊緊聯絡在一起。


這就令理解區塊鏈變得不必要得複雜起來,特別是當你想理解原始碼的時候。下面我將透過 200 行 JS 實現的超級簡單的區塊鏈來幫助大家理解它,我給這段程式碼起名為 NaiveChain。


塊結構


第一個邏輯步驟是決定塊結構。為了保證事情儘可能的簡單,我們只選擇最必要的部分:index(下標)、timestamp(時間戳)、data(資料)、hash(雜湊值)和 previous hash(前置雜湊值)。


這個塊中必須能找到前一個塊的雜湊值,以此來保證整條鏈的完整性。


class Block {


  constructor(index, previousHash, timestamp, data, hash) {


    this.index = index;


    this.previousHash = previousHash.toString();


    this.timestamp = timestamp;


    this.data = data;


    this.hash = hash.toString();


  }


}


塊雜湊


為了儲存完整的資料,必須雜湊區塊。


SHA-256會對塊的內容進行加密,記錄這個值應該和“挖礦”毫無關係,因為這裡不需要解決工作量證明的問題。


var calculateHash = (index, previousHash, timestamp, data) => {


  return CryptoJS.SHA256(index + previousHash + timestamp + data).toString();


};


塊的生成


要生成一個塊,必須知道前一個塊的雜湊值,然後創造其餘所需的內容(= index, hash, data and timestamp)。塊的data部分是由終端使用者所提供的。


var generateNextBlock = (blockData) => {


  var previousBlock = getLatestBlock();


  var nextIndex = previousBlock.index + 1;


  var nextTimestamp = new Date().getTime() / 1000;


  var nextHash = calculateHash(nextIndex, previousBlock.hash, nextTimestamp, blockData);


  return new Block(nextIndex, previousBlock.hash, nextTimestamp, blockData, nextHash);


};


塊的儲存


記憶體中的Javascript陣列被用於儲存區塊鏈。區塊鏈的第一個塊通常被稱為“起源塊”,是硬編碼的。


var getGenesisBlock = () => {


  return new Block(0, "0", 1465154705, "my genesis block!!", "816534932c2b7154836da6afc367695e6337db8a921823784c14378abed4f7d7");


};


 


var blockchain = [getGenesisBlock()];


確認塊的完整性


在任何時候都必須能確認一個區塊或者一整條鏈的區塊是否完整。在我們從其他節點接收到新的區塊,並需要決定接受或拒絕它們時,這一點尤為重要。


var isValidNewBlock = (newBlock, previousBlock) => {


  if (previousBlock.index + 1 !== newBlock.index) {


    console.log('invalid index');


    return false;


  } else if (previousBlock.hash !== newBlock.previousHash) {


    console.log('invalid previoushash');


    return false;


  } else if (calculateHashForBlock(newBlock) !== newBlock.hash) {


    console.log('invalid hash: ' + calculateHashForBlock(newBlock) + ' ' + newBlock.hash);


    return false;


  }


  return true;


};

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70019421/viewspace-2906362/,如需轉載,請註明出處,否則將追究法律責任。

相關文章