200行のコードへのブロックチェーンの実装

↓「マイニングをしているノードだけがホントのフルノードだ。他のフルノードは伝播を遅くしているだけ」 by ロジャー さすがに、これは、本気でいっているのでしょうか。ビッグブロックを実現したい立場に頑ななあまり、信用を失うのは得策ではないとおもうのですが・・。
飼い猫ぴっぴとも話したけど基本的にはトランザクションをブロックにつめてブロックチェーンで管理すれば良いはずで、認証系のトランザクションだけでもそうすれば特権的なノードを作らずに済んでみんなハッピーなのになーとか考えている
mstdonもブロックチェーンもなんでもそうだけれど、複数ノードがある中でフルメッシュでリアルタイムに大規模データをバカスカやりとりするなんてインフラ的に大変な仕事なので、どれだけ管理者のいない世界を実現しても結局集権的な取引所は生まれるものだと思うよ
マストドン、ブロックチェーンみたいに自分がノード(サーバー)になることもできるのか。小さい村が乱立する感じでおもしろい。
自律分散ネットワークで信用の置けるノードを接続。。。許可型ブロックチェーンを作ろうとしているのか #bc2017s
「Rippleでは台帳技術を採用してはいるものの、特定のノードの集合が、新しく台帳に追記される情報の候補を承認すれば合意が形成される仕組みになっています。この点がブロックチェーンの定義1)にある「不特定多数のノード」という点に反するため、」
USAFノードの中のbitcoindを0.14.1にアップデート作業。これ、小型コンピュータだと、5時間くらいかかるのね・・ それからブロックチェーンのデータをUSBにコピーして、それを差し込んで起動チェック。なかなかセットアップがめんどうなんですが、すぐ動く状態でおとどけします

ブロックチェーンの基本的な概念は非常にシンプルです。分散型データベースで、順序付けられたレコードのリストが連続的に増加していきます。しかしシンプルとは言え、ブロックチェーンやそれを使うことで解決しようとしている問題について話をする際に、頭を悩まされることがよくあります。これは、ビットコインイーサリアムといった、一般にもよく知られているブロックチェーンベースのプロジェクトでよく聞かれる話です。「ブロックチェーン」は、取引スマートコントラクト、または暗号通貨といったコンセプトと強い結びつきがあります。

そのため、本来シンプルであるべきブロックチェーンの理解がより困難になってしまっています。抜け目のないソースコードであれば尚更です。
そこで、NaiveChainという、200行のJavascripitに実装した、非常にシンプルなブロックチェーンを紹介したいと思います。

ブロックの構造

まず行うべき作業は、ブロックの構造を決めることです。可能な限りシンプルにするため、最低限必要となる、インデックス、タイムスタンプ、データ、ハッシュ値、そして1つ前のブロックのハッシュ値のみを構造に含めます。


チェーンの安全性を維持するために、ブロックの中には、1つ前のブロックのハッシュ値が含まれていなくてはなりません。

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();  };  

ブロックの生成

ブロックを生成するには、1つ前のブロックのハッシュ値を知っていなければならず、その上で、その他、必要なコンテンツ(インデックス、ハッシュ値、データ、タイムスタンプ)を作成します。ブロックデータは、エンドユーザによって提供されます。

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;   };  

最長チェーンを選択

どんな場合でも、チェーンには明確なブロックのセットが1つでなくてはなりません。矛盾する点(例えば、2つのノードがどちらもブロック番号72を生成している)があった場合、ブロックの数が多いチェーンを選択します。


注釈:当初の矛盾点、解決済み、最長チェーンが優位

 var replaceChain = (newBlocks) => {       if (isValidChain(newBlocks) && newBlocks.length > blockchain.length) {           console.log('Received blockchain is valid. Replacing current blockchain with received blockchain');           blockchain = newBlocks;           broadcast(responseLatestMsg());       } else {           console.log('Received blockchain invalid');       }   };  

他のノードとの連絡

ノードに不可欠なのは、ブロックチェーンを他のノードと共有、また同期する点です。以下は、ネットワークが常に同期されるために必要なルールです。

  • ノードが新しいブロックを生成したら、ネットワークへと送信する。
  • ノードが新しいピアに連結したら、最新のブロックに対してクエリを行う。
  • ノードが、最新として知られるブロックのインデックスよりも大きいインデックスのブロックに出くわしたら、最新のチェーンにそのブロックを追加するか、全ブロックチェーンに対してクエリを行う。


(上から下、左から右の順)
注釈:
ノード1はノード2と連結し、同期する
最新のブロックにクエリを行う
最新のブロックを送信する
全てのブロックに対してクエリを行う
全てのブロックを送信する

ノード1がブロックを生成し、送信する
最新のブロックを送信する
最新のブロックを送信する
最新のブロックを送信する

ノードが表示されているプロトコルに従う際の一般的な連絡の流れ。

自動的にピアを発見するプロトコルは使用されていないので、ピアの場所(URL)は手動で追加しなくてはなりません。

ノードの制御

何らかの方法で、ユーザはノードを制御する必要があります。これはHTTPサーバを設定することで可能です。

var initHttpServer = () => {     var app = express();     app.use(bodyParser.json());      app.get('/blocks', (req, res) => res.send(JSON.stringify(blockchain)));     app.post('/mineBlock', (req, res) => {         var newBlock = generateNextBlock(req.body.data);         addBlock(newBlock);         broadcast(responseLatestMsg());         console.log('block added: ' + JSON.stringify(newBlock));         res.send();     });     app.get('/peers', (req, res) => {         res.send(sockets.map(s => s._socket.remoteAddress + ':' + s._socket.remotePort));     });     app.post('/addPeer', (req, res) => {         connectToPeers([req.body.peer]);         res.send();     });     app.listen(http_port, () => console.log('Listening http on port: ' + http_port)); }; 

以下の方法で、ユーザはノードとの情報交換が可能となります。

  • 全てのブロックを記載する。
  • ユーザから与えられたコンテントを基に新しいブロックを作成する。
  • ピアを記載するか追加する。

ノードを制御する最も単純な方法は、cRULなどを使用することです。

ノードから全てのブロックを取得する

curl http://localhost:3001/blocks

アーキテクチャ

ノードは、2つのWebサーバを露出することに注意してください。1つは、ノードを制御するためのユーザ向けのサーバ(HTTPサーバ)、もう1つは、ノード同士のピア・ツー・ピア連絡用サーバ(Websocket HTTPサーバ)です。


(上から下、左から右の順)
注釈:
ブロックチェーン
HTTPインターフェース、ノードの制御用
Websocketインターフェース、他のノードとのP2P連絡用

NaiveChainの主なコンポーネント

まとめ

NavieChainは、デモンストレーションおよび学習目的で作成されました。このブロックチェーンには「マイニング」アルゴリズム(プルーフ・オブ・ワークプルーフ・オブ・ステーク)は含まれていないので、パブリックネットワークで使用することはできませんが、ブロックチェーンを動かすための基本的な機能は実装されています。

技術的な詳細を知りたい方は、GitHubレポジトリをご覧ください。

  • コメント

    1. 匿名希望
      2017/04/21(金) 23:24:34

      ↓「マイニングをしているノードだけがホントのフルノードだ。他のフルノードは伝播を遅くしているだけ」 by ロジャー
      さすがに、これは、本気でいっているのでしょうか。ビッグブロックを実現したい立場に頑ななあまり、信用を失うのは得策ではないとおもうのですが・・。

    2. 匿名希望
      2017/04/21(金) 23:24:34

      飼い猫ぴっぴとも話したけど基本的にはトランザクションをブロックにつめてブロックチェーンで管理すれば良いはずで、認証系のトランザクションだけでもそうすれば特権的なノードを作らずに済んでみんなハッピーなのになーとか考えている

    3. 匿名希望
      2017/04/21(金) 23:24:34

      mstdonもブロックチェーンもなんでもそうだけれど、複数ノードがある中でフルメッシュでリアルタイムに大規模データをバカスカやりとりするなんてインフラ的に大変な仕事なので、どれだけ管理者のいない世界を実現しても結局集権的な取引所は生まれるものだと思うよ

    4. 匿名希望
      2017/04/21(金) 23:24:34

      マストドン、ブロックチェーンみたいに自分がノード(サーバー)になることもできるのか。小さい村が乱立する感じでおもしろい。

    5. 匿名希望
      2017/04/21(金) 23:24:34

      自律分散ネットワークで信用の置けるノードを接続。。。許可型ブロックチェーンを作ろうとしているのか #bc2017s

    記事に戻る

関連記事