2020年3月16日 星期一

用 dart 語言產生一個簡單的區塊鏈

先寫一個 pubspec.yaml 檔案用來下載 package:crypto, 接著開啟終端機執行 pub get 就可:
// pubspec.yaml
name: blockchain
version: 0.0.1
description: >-
  A super simple example of blockchain
author: masontseng
environment:
  sdk: '>=2.6.0 <3.0.0'
dependencies:
  crypto: ^2.1.4

編輯主程式 main.dart, 接著開啟終端機執行 dart main.dart 看執行結果:
// main.dart
import 'dart:convert';
import 'package:crypto/crypto.dart';
class Block {
    final int nonce, index, timestamp;
    final String data, pre_hash;
    get plain  => "${nonce}-${index}-${data}-${timestamp}-[${pre_hash}]";
    get hash  => sha256.convert(utf8.encode(plain)).toString( );
    get dump => print("${plain} [${hash}]");
    factory Block.genesis( ) => Block(0, 0, "genesisBlock", 1584332296607000, "0");
    Block(this.nonce, this.index, this.data, this.timestamp, this.pre_hash);
}
class BlockChain {
    var field = [ ]; //field of blockchain is a matrix
    set blockchain(var temp) {
      if(temp.length <= field.length) return;
      if(temp[0].data != field[0].data) return;
      for (var i = 1; i < field.length; i++) if (! isBlockValid(temp[i], field[i - 1])) return;
      for (var i = field.length; i < temp.length; i++) if (! isBlockValid(temp[i], temp[i - 1])) return;
      field = temp;
    }  
    get blockchain => field;
    get dump { for (var i = 0; i < field.length; i++) field[i].dump; }   
    Block powMineBlock(String eData, {int nonce=0}){
      final lastblock = field[field.length - 1];
      final timeNow = DateTime.now( ).microsecondsSinceEpoch;
      return Block(nonce, lastblock.index + 1, eData, timeNow, lastblock.hash);
    }
    void addBlock(String e) => field.add(powMineBlock(e, nonce: 1));
    bool isBlockValid(Block block, Block pre) =>
      block.index    == pre.index + 1  &&
      block.pre_hash == pre.hash
    bool isValid( ) {
      for (var i = 1; i < field.length; i++) if (! isBlockValid(field[i], field[i - 1])) return false;
      return true;
    }
    BlockChain( ) {  field.add(Block.genesis( )); }
}
main( ){
  final c = BlockChain( );
  for(int i=1; i<10; i++)  c.addBlock("extendBlock${i}");
  c.dump;
  print(c.isValid( ));

  final d = BlockChain( );
  d.blockchain = c.blockchain;
  d.dump;
  print(d.isValid( ));
}
後記:
1. 理解 proof of work (pow): 是一個群體共識決(交易方法),他是針對一個數學問題,很容易驗證但很難找到答案,或許只能用嘗試錯誤法,有點類似樂透的方式猜出答案,但不管如何,只要能解答讓大部分的人同意並形成的共識決,最後將結果紀錄於區塊鏈內,解題者就可獲取報酬,缺點是要浪費電腦的計算力
2. 理解 proof of stake (pos): 也是一個群體共識決(交易方法),交易發行者針對交易行為事先在網路上廣播,擬參與交易認證者事先以一定比例(賭注/持有者資金)資金注入系統,該筆資金將在網路中暫時封鎖無法交易,有點類似價金履約保證的概念當作履約保證金,此封鎖的資金稱為 stake,擬入區塊鏈的區塊就由該履約保證者提出並上呈網路供公眾確認.最後一旦交易完成並進入區塊鏈,提出履約保證者就能獲得一定比例的報酬作為手續費,封鎖的資金也同時解凍,但若違反規則,也會獲得懲罰,像是沒收保證金等等. pos 解決了耗費電腦運算的麻煩,但隨之而來的是要解決 nas(Nothing At Stake)的問題.

沒有留言:

張貼留言

使用 pcie 轉接器連接 nvme SSD

之前 AM4 主機板使用 pcie ssd, 但主機板故障了沒辦法上網, 只好翻出以前買的 FM2 舊主機板, 想辦法讓老主機復活, 但舊主機板沒有 nvme 的界面, 因此上網買了 pcie 轉接器用來連接 nvme ssd, 遺憾的是 grub2 bootloader 無法識...