web3.jsでgethにアクセスする

やっとできたぜゲスゲスゲス…

ゲスをつなげるとなんかやばみがあることがわかったところでWeb3.jsの1.0.0の情報がとても少ないので書いておきます。公式はこちら。
web3.js - Ethereum JavaScript API — web3.js 1.0.0 documentation

とりあえずweb3をインストールする

$ sudo npm install web3

すでにGethが入っているならこれだけで最新版のWeb3は入ります。Web3.jsの0.x.xと1.0.0はかなり違うみたいなのでふるいやつを使いたい場合は注意。

gethサーバーでrpcを有効にする

詳しくはこちらを参照。
qiita.com

開発モードでRPCを有効にします

$ geth --dev --datadir . --gasprice 1 --rpc --rpcapi "eth,net,web3,personal"

rpcapiはとりあえずpersonalも含めておいたがとりあえず動かすだけならいらないかも。

javaScriptを書く

1.0.0のドキュメントにもあるのだが、まずweb3のインスタンスを作ってプロバイダをセットし、そのごIPCプロバイダを設定してコネクションオープンにする。ここがよくわからなかった。なおgeth.ipcはスタートしているGethサーバーが使っているgeth.ipcを使おう(当たり前だね、、、

今回はdatadirをカレントディレクトリにしているがデフォルトにした場合は/home/user/.ethereum/geth.ipcかな

//モジュールごとに必要…というわけではないみたいなのだがgethのオプションで指定していない場合はつけておいたほうが良いのかもというかrpcapiオプションいらないのか?
var Eth = require("web3-eth");
var eth = new Eth("http://localhost:8545");
eth.setProvider("ws://localhost:8546");

var Web3 = require("web3");
//IPC providerを設定する場合は不要。
//var web3 = new Web3("http://localhost:8545");
//web3.setProvider("ws://localhost:8546");

var net = require("net");
var web3 = new Web3(new Web3.providers.IpcProvider("/home/users/test/geth.ipc", net));

web3.eth.defaultAccount = "0xアドレス";
console.log(web3.eth.defaultAccount);

//とりあえず標準出力で結果を出力するためにconsole.logをコールバックに指定
var accounts = web3.eth.getAccounts().then(console.log);
var isMining = web3.eth.isMining().then(console.log);

ぐっとUIが作りやすくなったけどJSよく知らんのよね…


ついでにスマートコントラクトを動かすところまで書くことにしました(というかようやくわかった

Solidityでスマートコントラクトの実装をする

とりあえずget/setの簡単なやつをサンプルにしてみる。

pragma solidity ^0.4.0;
contract Storage {
    uint storedData;

    function set(uint x) public {  
        storedData = x;
    }

    function get() public constant returns (uint) {
        return storedData;
    }
}

Solidityのコードをコンパイルする

これと書いたのと同じ
Ubuntu17でSolidityでスマートコントラクトをする - TOUS LES HOMMES

だがnpmでsolcをインストールしてnode上で使えるようにする方法もあるみたい。まぁこれでも読んどいてや
medium.com

とりあえずabiとbinaryを取得します。

web3jsのコードを書く

var Web3 = require("web3");
var net = require("net");
var web3 = new Web3(new Web3.providers.IpcProvider("/path/geth.iipc", net));

var bin = "0x...."; //コンパイルの結果を貼り付ける
var abi = [{"constnt":false, ...}]; //コピペした場合はこんな感じに。
//var abi = require("./storage.json"); //ファイルに書き出して読み込ませてもよい。
var contract = new web3.eth.Contract(abi);

var accounts = web3.eth.getAccounts().then(function(result, error)
{
    console.log(result[0]); //eth.accounts[0]のアドレス
    var from_address = result[0];
    contract.deploy({data:bin})   /*dataオプションは必須*/
    .send({from: from_address, gas:1000000, gasPrice: "1000000"})  /*sendTransactionでブロックチェーンに登録される*/
    .then(function(x)
    {
        console.log(x.options.address);  //成功していればアドレスが降ってくる
        contract.options.address = x.options.address;   //これをやらないと使えない
        contract.method.get().call({from: from_address}, function(error, y){ console.log(y); }); //Readする場合はcallを使う。戻り値が欲しい時はコールバック関数を指定。このときは初期値のままなのでgetした値は0
        contract.method.set(1).send({from: from_address}) /*Writeする場合はsendを使う。この場合getしたときの戻り値が1になるようにした*/
        .then(function(z)
        {
            contract.method.get().call({from: from_address}, function(error, y){ console.log(y); }); //実行すると戻り値が1になっていることを確認できる
        });
    });
});

こりゃひどい。JSのコーディングパターンとかないのか。あとEvent使えるようにならないとダメぽいですねぇ…

Ubuntu17でSolidityでスマートコントラクトをする

ざっくりすぎるタイトルである。そもそも「スマートコントラクトをする」という表現は正しいのか?
ともあれHyperledger FabricはGo言語でちょっと本腰入れてやらないといけないし、Hyperledger Irohaはスマートコントラクトがまだ実装されていないそうなので、もう少し簡単に試せるEthereum Solidityで感覚を掴んでいくことにします。 

http://solidity.readthedocs.io/en/latest/index.html

SolidityはC++, Python, JavaScriptに寄せた記述方式になっているので、モダンで高級な言語が眩しい化石エンジニアでもとっつきやすそうです。

インストール

必要なものは

  • Ethereumのクライアント
  • solidity

クライアントは簡単のためGethを使います(なんでもいい

$ sudo add-apt-repository -y ppa:ethereum/ethereum
$ sudo apt-get update
$ sudo apt-get install ethereum
$ sudo apt-get install solidity

gethを動かす

gethノードを開発モードで立ち上げる

$ mkdir ~/test     
$ cd ~/test
$ geth --dev --dtadir .

とりあえずメインのアカウントに大量のEthereumが付与され、テストで使えるようになります。devオプションをつけた場合、マイニングが行われるのはアカウント間の送金が発生するときだけとのことなので、トランザクションを実行した後に必ず送金処理が必要なことに注意しましょう。
参考:https://github.com/ethereum/go-ethereum/issues/15646

gethコンソールを開く

別のターミナルを開いてコンソールとして使用します。

$ geth attach geth.ipc
Welcome to the Geth JavaScript console!

instance: Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1
coinbase: 0x16e6395ae580d15a3fb6ed98b6bbdd73d42cb96d
 at block: 27(Thu, 08 Feb 2018 18:50:03 JST)
  datadir: /home/user/test
modules: admin:1.0 clique:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0

>
||<  


ここにあるmodulesっていうのがすでにあるインスタンス。ためしに打ち込んでみます。
>||
> admin
{
  datadir: "/home/user/test",
  nodeInfo: {
	enode: "enode://ec271ee7f939f4780ec23230417f4ed2e54f3906123818cf5328f83bba7cf66e7ae0e12d052dd7f7b3f73278660287e3724bbf71e540d1d85003a85cdc31f210@[::]:40771?discport=0",
	id: "ec271ee7f939f4780ec23230417f4ed2e54f3906123818cf5328f83bba7cf66e7ae0e12d052dd7f7b3f73278660287e3724bbf71e540d1d85003a85cdc31f210",
	ip: "::",
	listenAddr: "[::]:40771",
	name: "Geth/v1.7.3-stable-4bb3c89d/linux-amd64/go1.9.1",
	ports: {
  	discovery: 0,
  	listener: 40771
	},
	protocols: {
  	eth: {
    	difficulty: 55,
    	genesis: "0x3b64127031ee4640b0ec10ca369e1d5b442336e7a47aa714c39f692d43f36f43",
    	head: "0xa961a0bb3552403d6ed6e4b3080b8d6465d50a7db48abe414d09ef90b40f5c93",
    	network: 1
  	},
  	shh: {
    	maxMessageSize: 1048576,
    	minimumPoW: 0.2,
    	version: "5.0"
  	}
	}
  },
  peers: [],
  addPeer: function(),
  exportChain: function(),
  getDatadir: function(callback),
  getNodeInfo: function(callback),
  getPeers: function(callback),
  importChain: function(),
  removePeer: function(),
  sleep: function github.com/ethereum/go-ethereum/console.(*bridge).Sleep-fm(),
  sleepBlocks: function github.com/ethereum/go-ethereum/console.(*bridge).SleepBlocks-fm(),
  startRPC: function(),
  startWS: function(),
  stopRPC: function(),
  stopWS: function()
}

adminインスタンスの持ってる変数やら関数やらが見れます。が、どうやって使うのかはよくわからない…昔のが残っていることもあり、使えないのも結構ある。ドキュメントを読むかソースコードを読むしかない。

ちなみに残高を見ると

> eth.getBalance(eth.accounts[0])
1.15792089237316195423570985008687907853269984665640564039457584007911129021018e+77

大金持ちです。テスト用なので最初から大量の付与してくれているみたいです。eth.accounts[0]は自動で作成されるアカウントで、coinbaseとして設定されています。

アカウントを作成する

> personal.newAccount()

パスフレーズが要求されるけど、テスト用でプライベートなので特に設定しなくても良いです(設定しても良い
アドレスっぽい文字列が表示されればOK。

アカウントをアンロックする

> personal.unlockAccount(eth.accounts[0])
true
> personal.unlockAccount(eth.accounts[1])
true

パスフレーズを求められるけど、アカウント作成のときに使ったやつを入れればOK.

gasPriceを設定する

Ethの仕様なのかSolidityの仕様なのかまだちゃんと読んでないので知らないが、SmartContractを実行するのにgasPriceという手数料が課される模様。開発者モードではデフォルトが0なので、本番環境でアレ?ってならないようにとりあえず0より大きな数を設定しておきます。

> miner.setGasPrice(1)
true

gethノードを実行しているターミナルの方でpriceがアップデートされてればたぶんOK。

マイニングを開始する

> miner.start()
null

開発者モードのときはとりあえずWARNが表示され、"Block sealing failed"って言われるが特に気にしなくてよい。

ようやくSolidityです

まずソースコードを書きます

とりあえず公式ドキュメントのサンプルプログラムを動かしてみます。

pragma solidity ^0.4.0;            //includeみたいなもの。他のファイルも同様に読み込める

contract SimpleStorage {           //クラス的なやつ
    uint storedData;               //変数

    function set(uint x) public {  //メソッド。public, private など公開範囲が設定できるほか、
        storedData = x;        //payableとかreturnの型とかも設定できる。
    }

    function get() public constant returns (uint) {
        return storedData;
    }
}

写経(コピペ)したらtest.solという名前で保存します。とりあえずなんか安心する見た目ですね。

コンパイルする

コンパイルコマンドラインから。Remix使ってもいいけどとりあえず導入がめんどくさいし大した手間でもないので。
コンパイルは新しいターミナルを開いてから。

$ cd ~/test
$ solc --bin --abi --gas test.sol

コンパイルに成功するとbinとabiと消費されるgas評価が出力される(bin, abi, gasオプションを指定しているから)。

======= test.sol:Storage =======
Gas estimation:
construction:
   88 + 42200 = 42288
external:
   get():    416
   set(uint256):    20178
Binary:
6060604052341561000f57600080fd5b60d38061001d6000396000f3006060604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c14606e575b600080fd5b3415605857600080fd5b606c60048080359060200190919050506094565b005b3415607857600080fd5b607e609e565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a72305820c9facaea60dbb669543e6b5fdcca2f1aa9f3a32dfc313f846d4bc9d9482ba8460029
Contract JSON ABI
[{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]

結構バスバスgasを消費するようです。Setのほうがコストが高いんだなぁ。

gathノードでSolidityアプリケーションを動かす

アナクロな方法でSolidityアプリケーションをGethに認識させます(デプロイします)。
ここからの作業はgethコンソールで。

> test_bin="0x6060604052341561000f57600080fd5b60d38061001d6000396000f3006060604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c14606e575b600080fd5b3415605857600080fd5b606c60048080359060200190919050506094565b005b3415607857600080fd5b607e609e565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a72305820c9facaea60dbb669543e6b5fdcca2f1aa9f3a32dfc313f846d4bc9d9482ba8460029"

> test_abi=[{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]

コンパイルの結果のところからBinaryとJson ABIをコピペして貼り付けるのです。Binaryは0xをつけてダブルクオテーションでくくること。

準備ができたのでインスタンスを作成します。

> test_contract = eth.contract(test_abi)
> test_inst = test_contract.new({from: eth.accounts[0], data: test_bin, gas: 1000000 })
{
  abi: [{
  	constant: false,
  	inputs: [{...}],
  	name: "set",
  	outputs: [],
  	payable: false,
  	stateMutability: "nonpayable",
  	type: "function"
  }, {
  	constant: true,
  	inputs: [],
  	name: "get",
  	outputs: [{...}],
  	payable: false,
  	stateMutability: "view",
  	type: "function"
  }],
  address: undefined,
  transactionHash: "0x6b2690deca3d191dde77ec4e88f51192437023feb684219b0b51d4409aa7e209"
}

これでインスタンスは作成されたけど、まだブロックチェーンには登録されていません。addressがundefinedです。登録するためにEthを動かします。

> eth.sendTransaction({ from: eth.accounts[0], to: eth.accounts[1], value:1000000 })

おもむろにインスタンスを見てみます

> test_inst
{
  abi: [{
  	constant: false,
  	inputs: [{...}],
  	name: "set",
  	outputs: [],
  	payable: false,
  	stateMutability: "nonpayable",
  	type: "function"
  }, {
  	constant: true,
  	inputs: [],
  	name: "get",
  	outputs: [{...}],
  	payable: false,
  	stateMutability: "view",
  	type: "function"
  }],
  address: "0x948cf5dfb747c974e2ac90168bc537a62efc28d4",
  transactionHash: "0x6b2690deca3d191dde77ec4e88f51192437023feb684219b0b51d4409aa7e209",
  allEvents: function(),
  get: function(),
  set: function()
}

addressにアドレスが設定されているのでOKです。早速get/setを使ってみます。read-onlyのメソッドを呼ぶ時はメソッド名.call()、引数がある場合はメソッド名.sendTransaction(引数、{from: 送信アカウント名} )とするらしいです。

> test_inst.get.call()
0
> test_inst.set.sendTransaction(1, {from: eth.accounts[0]})
16進数
> test_inst.get.call()
1

ちなみにeth.getBalance(eth.accounts[1])とすると適度にEth(というかwei)が消費されています
デリゲートも使えるみたいなんで自由度高いですね。

Hyperledger Irohaをビルドする

やっぱgoとかわかんない(パッケージ関連が特に)のでC++でEnjoy!することにしました。IrohaはC++のHyperledgerで日本人が主体で開発をしているらしい…

github.com
しょっぱなからFind out Moreのリンクがことごとく切れてて瀕死なのだが…まぁいいや。
基本的な手順はこちらから。

cmakeのバージョンがチガウ…

$ sudo apt-get install cmake build-essential wget xsltproc autoconf automake libtool shtool unzip libssl-dev default-jdk
$ cd ~
$ git clone https://github.com/hyperledger/iroha.git
$ cd iroha
$ export IROHA_HOME=$(pwd)
$ mkdir build
$ cd build
$ cmake ..

libpqがないというエラーがでるので追加する。

$ sudo apt-get install libpq-dev postgresql
$ export LIBPQ_DIR=/usr/lib/postgresql/9.5
$ export LIBRARY_PATH=/usr/lib/postgresql/9.5/lib

気を取り直してやりなおし

$ cd ../
$ rm -rf build
$ mkdir build
$ cd build
$ cmake ..

今度は成功する

$ make

google.protobuf.Empty is not definedのようなエラーが出る。
github.com

3.3.0をダウンロードする(めんどくさいのでtarで落とす)
https://github.com/google/protobuf/releases

$ tar zxvf protobuf-3.3.0.tar.gz
$ ./autogen.sh
$ ./configure
$ make 
$ sudo make install
$ rm -rf schema/*.{cc,h}
$ rm -rf ../external
$ cd ../
$ rm -rf build
$ mkdir build
$ cd build
$ cmake ..
$ make

できた…かな? なんかgtestで止まってる…

Hyperledger Fabric - Introduction(下)

Hyperledger Fabricとは?

Linux Foundationは、業界間のブロックチェーン技術を発展させるため、2015年にHyperledgerを設立しました。標準となるブロックチェーンの策定だけでなく、コミュニティプロセスを通じて、オープンな開発と長期的な主要規格の採用を促進する知的財産権を持ったブロックチェーン技術の共同開発を促進するためです。

Hyperledger Fabricは、Hyperledgerのブロックチェーンプロジェクトの1つです。他のブロックチェーン技術と同様、帳票を持ち、スマートな契約を使用し、参加者が取引を管理するシステムです。

Hyperledger Fabricと他のブロックチェーンシステムの違いは、privateと許可の概念があることです。Hyperledger Fabricは、ネットワークに参加する未知のIDを許可するようなオープン制のシステム(このような場合はトランザクションの検証とセキュアなネットワークを保証するProof of Workのようなプロトコルが必要)のではありません。Hyperledger Fabricネットワークのメンバーはメンバシップサービスプロバイダ(MSP)で登録をしなければなりません。

Hyperledger Fabricには、プラグインを追加することもできます。プラグインをしようすれば、複数のフォーマットで帳票のデータを保存することができ、コンセンサスのメカニズムを入れ替えたり、別のMSPをサポートしたりすることができます。

Hyperledger Fabricでは、チャネルを作成する機能も提供しています。つまり、取引帳票を分割して作成し、グループごとに運用することが可能なのです。この機能は競合にデータを公開したくない参加者や、すべての取引を公開したくない参加者――たとえばある顧客には特別価格を提示しているが、別の顧客にはしない場合など――には非常に重要なオプションとなるでしょう。2人の参加者が1つのチャネルを作成し、それ以外の参加者に公開しなかった場合、チャンネルの帳票は二人の参加者だけに公開されます。

共有帳票

Hyperbelger Fabricは二つのコンポーネント、ワールドステートとトランザクションログからなる帳票サブシステムを持っています。各参加者は、参加者が所属するすべてのHyperledger Fabricネットワークの帳票コピーを保持します。
ワールドステートコンポーネントはある時刻における帳票の状態を記述したものです。いわゆる帳票のデータベースです。トランザクションログコンポーネントはワールドステートの現在の値をもたらしたすべての取引を記録します。つまりワールドステートの更新履歴というわけです。つまり帳票はワールドステートデータベースとトランザクションログ履歴の組み合わせということなのです。

帳票はワールドステートと交換可能なデータストアを保有しています。デフォルトではLevelDBキーバリューストアデータベースで作成されています。トランザクションログはプラグインである必要はありません。ブロックチェーンネットワークで使用された帳票データベースの更新前後の値を記録しておくだけで良いからです。

スマートコントラクト

Hyperledger Fabricスマートコントラクトはチェーンコードで書かれており、アプリケーションが帳票とやり取りする必要があるときにブロックチェーンの外部のアプリケーションから呼び出されます。 ほとんどの場合、チェーンコードは、帳票のデータベースコンポーネントとワールドステート(クエリなど)と相互作用しますが、トランザクションログは使用しません。
チェーンコードはいくつかのプログラミング言語で実装できます。 現在のところはJavaとGo言語が使用できますが、今後のリリースで追加される予定です。

プライバシー

BtoB(Business-to-Business)ネットワーク参加者は共有される情報量に非常に敏感になることがあります。その他のネットワークではプライバシーは最優先事項ではありません。
Hyperledger Fabricは、チャンネルを使用したプライバシーを主要な運用要件としたネットワークとそうでないネットワークの両方をサポートします。

コンセンサス

ネットワーク内で発生するトランザクションは、それがたとえ異なる参加者間のものであったとしても全て順番に帳票に書き込まれなければなりません。そのためにはトランザクションの順序が立証されている必要があり、また帳票にあやまって(もしくは悪意を持って)挿入された悪いトランザクションを排除する方法が導入されていなければなりません。
すでにコンピュータサイエンスの分野では研究が行われており、幾つかの方法が提唱されていますが、それぞれにトレードオフとなる点が存在します。たとえばPBFT(Practical Byzantine Fault Tolerance)は、衝突が起こった場合に各コピーの整合性を保つように複製されたファイル同士が通信するメカニズムを持っています。一方、Bitcoinでは、マイニングと呼ばれるプロセスを通じて順序付けが行われます。マイニングでは競合するコンピュータはそれぞれのプロセスが算出した結果に基づいて順序を定義する暗号化問題を解くことで順序を決定します。

Hyperledger Fabricは、ネットワークを開始する人が参加者間の関係性をもっともよく表すコンセンサスメカニズムを選択できるよう設計されました。プライバシーの観点と同様、高度に関係性を構造化したネットワークから、ピアツーピアまでネットワークの種類は多様です。
現在、我々はSOLO、Kafkaを含むHyperledger Fabricのコンセンサスメカニズムについて学び、近い将来別の文書でSBFT(Simplified Byzantine Fault Tolerance)への拡張を発表する予定です。

Hyperledger Fabric - Introduction(上)

Blockchainのプラットフォームでまぁそこそこ知名度あるでしょう…という感じなのだが意外と日本語訳がない。のでやっとく。Bitcoinから切り離されてLinux Foundationで開発されている。未来だ!未来が来たぞ!

Introduction — hyperledger-fabricdocs master documentation

Introduction

Hyperledger Fabricは、高度な機密性、復元力、柔軟性、スケーラビリティを提供するモジュラーアーキテクチャで構成される分散型帳票ソリューションのプラットフォームです。異なるコンポーネントプラグインで拡張できるような実装をサポートしており、エコシステムやネットワーク全体にまたがる複雑さに対応できるように設計されています。
Hyperledger Fabricは、独自の柔軟性と拡張性のあるアーキテクチャを提供しており、ブロックチェーンソリューションとは区別されます。エンタープライズブロックチェーンの未来を計画するにあたってもっとも大切なのは、十分に検証されたオープンソースアーキテクチャを使用することです。Hyperledger Fabricがあなたの出発点です。
初心者ユーザはまず、ブロックチェーンがいったいなんなのか、そしてHyperledger Fabricにはどんな機能とコンポーネントがあるのか、他のブロックチェーンとはどこが異なるのかを理解するためにIntroductionを一読することをおすすめします。
だいたい理解できたら――もしくはBlockChainとHyperledger Fabricについてすでに理解している場合はGetting Startedに進み、デモや技術的仕様、APIなどを調べましょう。

Blockchainとは?

分散型帳票(A Distributed Ledger)

ブロックチェーンネットワークの肝は、ネットワーク上で発生するすべてのトランザクションを記録した分散帳票です。
ブロックチェーン帳票はしばしば分散型と呼ばれますが、これはメンテナンスに協力するネットワーク参加者によって複製されるためです。分散と協力が、リアルな世界でのものやサービスを交換するビジネス手法と等価となる強力な特徴なのは明らかです。
さらに分散型で協調的であることに加え、ブロックチェーンでは情報の記録のみを行います。一旦帳票に追加されたトランザクションは、一意性を保証する暗号化技術を使っているため変更ができません。この不変性は情報の出どころを特定しやすくします。情報がある事象以後変化していないことが明らかであれば、履歴をたどるだけで良いからです。この性質から、ブロックチェーンは証明システムと呼ばれることもあります。

スマートコントラクト

情報の一貫した更新と、全体的な帳票機能(トランザクション、クエリなど)を可能にするために、ブロックチェーンネットワークでは帳票へのアクセス制御を行うスマートコントラクトを使用しています。
スマートコントラクトは単なる情報のカプセル化に使用されるキー・メカニズムというだけでなく、ネットワーク全体をシンプルに保つための機構でもあります。スマートコントラクトは参加者に特定の側面のトランザクションを自動で実行できるようにも記述されています。

たとえば、スマートコントラクトは到着時期によって変化する商品のシッピングコストを記述することができます。両当事者で同意した条件に従って、商品が受け取られると自動的に帳票に書かれているとおりの適切な資金が受け渡されるのです。

コンセンサス

帳票はトランザクションが適切な参加者に酔って承認されたときにのみ更新されなければなりません。また、ある帳票が更新されたら、他の帳票も同じ順序で同じトランザクションを更新しなければなりません。これを確実なものにするため、ネットワーク上で帳票のトランザクションを同期させるプロセスをコンセンサスと呼びます。
我々はこの章以後に帳票、スマートコントラクト、コンセンサスの詳細を説明しますが、今の段階ではBlockchainとはスマートコントラクトによって更新され、コンセンサスと呼ばれるプロセスを通じて継続的に同期される、共有・複製されたトランザクションシステムだと思っていれば十分です。

なぜブロックチェーンは有用なのか?

現在の(一般的な)記録システム

現在の業務ネットワークはビジネスの記録が保存されるようになって以来、ほとんど進化していません。ビジネスネットワークのメンバーはお互いに取引を行いますが、彼らは彼らのトランザクションに従って別々に記録をメンテナンスしています。そして彼らが取引したものは、たとえそれが16世紀のフランダースタペストリーであっても、現代の有価証券であってもそれぞれの場合において売買したことと、所有権が明らかでなければなりませんし、商取引は立証されていなければなりません。

現代の技術によってこれらのプロセスは、石や紙からハードドライブやクラウドプラットフォームへうつりました。しかし、基本的な構造は変わっていません。ネットワーク参加者のIDを管理する統一されたシステムは存在しません。もし仮に実現したとしても、有価証券の売買に数日を要します(その間に世界では数兆ドルの取引がおこなわれます)。契約はサインが必要ですし、手動で行われなければなりません。またこのようなシステムのそれぞれのデータベースには単一の情報が格納されているため、単一障害点が存在していることになります(障害が発生した場合に、すべてのシステムが止まります)。
ビジビリティと信頼性が明らかに必要とされているにも関わらず、今でもまだ情報へのアプローチ方法は十分ではなく、記録システムをビジネスネットワーク全体にまたがって構築するのは不可能です。

ブロックチェーンの特徴

もし仮にビジネスネットワークが、ネズミの巣のような「近代的な」取引システムと評される非効率なシステムのかわりに、ネットワーク上のIDによって確立され、取引を実行し、データを保管する標準的な方法があったとしたら? もし仮に一旦行われたら二度と変更されることのない、信頼のおける取引のリストを元に資産のでどころを確定できるとしたら?
そうすると、ビジネスのネットワークはこのようになります(中央に認証する機関を置く必要がなくなります)

これがブロックチェーンネットワークです。このネットワークの参加者は全員帳票を複製して所有します。帳票の情報はシェアされるだけでなく、更新のプロセスも共有します。現代のシステムのように参加者がプライベートなやり方でプライベートな帳票を更新するわけではありません。ブロックチェーンシステムでは方法も帳票の更新も共有します。
共有された帳票をつかってビジネスネットワーク上で協調することができるようになると、ブロックチェーンネットワークは時間とコストとリスク――これはプライベートな情報そのものです――を削減し、信頼性とビジビリティを向上させることができます。
あなたはもう、ブロックチェーンがいったいどんなもので、なぜ有用なのかがわかったことと思います。他にも色々と重要なことはありますが、それらは情報の共有とプロセスの基本的なアイデアにもとづいています。


あとでもうちょっとこなれた訳にするかも。後半は後日。Hyperledgerとはなにかというはなしになるみたいです。

HyperledgerをUbuntu上でビルドする

公式ドキュメントが色々と不親切なので書いておく。

ちなみに公式はこちら。
Prerequisites — hyperledger-fabricdocs master documentation

VMにUbuntu16をインストールする

インストール方法はISOイメージダウンロードしてマウントするだけなので省略します。余計なパッケージはインストールせず、素の状態でいれます。
インストール後、起動したらapt-geet updateに失敗するので、

$ sudo apt-get upgrade
$ sudo reboot

rootパスワードを設定する

Hyperledgerのビルドはrootじゃないと失敗するっぽいので。

$ sudo su -
# sudo passwd root

パスワードを設定する。

必要なパッケージをインストールする

とりあえずいれとくやつ

$ sudo apt-get install vim build-essential git ssh

Goをインストールする

Getting Started - The Go Programming Language

Goの公式を見に行くほうが早いが。ひとまず公式からアーカイブファイル(tar.gz)をダウンロードする。

$ tar -C /usr/local -xvzf go1.9.linux-amd64.tar.gz
$ ls /usr/local/go/bin

あればOK。パスを設定する

vi ~/.bashrc

でひらいて末尾に

export GOPATH=/home/ユーザ名/go_root
export GOROOT=/usr/local/go
export PATH=$PATH:/usr/local/go/bin

と記述して保存。rootでも同じ事をするのを忘れないように。

その後、

$ mkdir -p ~/go_root
$ source ~/.bashrc

GOはこれでおわり。

Docker CEをインストールする

Dockerはちゃんとドキュメント書いてくれてるのでその通りすればいい。

$ sudo apt-get install linux-image-extra-$(uname -r) linux-image-exra-virtual
$ sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg  | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88

問題ないことを確認する

$ sudo add-apt-repository "deb [arch=amd64] https://download.docker..com/linux/ubuntu $(lsb_release -cs) stable"
$ sudo apt-get update

レポジトリ追加したらupdateを忘れない。

$ sudo apt-get install docker-ce
$ sudo docker run hello-world

エラーが出なければOK

docker-composeをインストール

$ sudo curl -L https://github.com/docker/compose/releases/download/1.16.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose
$ docker-compose --version

1.16.1って表示されればOK。

pipをインストールする

Installation — pip 9.0.1 documentation
この通りやれば問題ない。
get-pip.pyをダウンロードする。

$ sudo apt-get install python python-dev python3-dev
$ sudo python get-pip.py

書き込む場所的にsudoつけないとだめみたい。

PIPから必要なパッケージをインストールする

$ sudo pip install --upgrade
$ sudo pip install behave nose
$ sudo pip install -I flask==0.10.1 python-dateutil==2.2 pytz==2014.3 pyyaml==3.10 couchdb==1.0 flask-cors==2.0.1 requests==2.4.3 pyOpenSSL==16.2.0 pysha3==1.0b1 grpcio==1.0.4

python-dev, python3-devをインストールしてないとここでエラーが出るので注意。

Hyperledgerのソースコードをビルドする

$ mkdir -p $GOPATH/src/github.com/hyperledger
$ cd $GOPATH/src/github.com/hypkerledger
$ git clone https://github.com/hyperledger/fabric.git

ほんとはGerritからクローンしたいのだが、Linux Foundation IDがなぜかEmptyになってしまっておりできない…なのでReadonlyのレポジトリから取得。

$ cd fabric

ここからはroot権限で実行する

$ su -p
$ make dist-clean all


Apache-2.0ライセンスがどうのこうのというエラーが出る場合は

$ make dist-clean peer orderer peer-docker orderer-docker tools-docker configtxgen cryptogen

でやる。詳しくは
stackoverflow.com

最後に忘れずにパスを追加する

fabric/build/binの下に色々できているのでPATHに追加する。.bashrcに追加するのが早いと思う

export PATH=$PATH:/usr/local/go/bin:$GO_PATH/src/github.com/hyperledger/fabric/build/bin

groongaの管理画面が更新されない問題

C-APIからテーブルを作ったり消したりインサートしたりモゴモゴしたりしていると、ローカルのgroongaサーバは正しく動いているのに、ブラウザから管理画面を見たときにカラムがずれてたり値が全部0になってたりすることがある。groonga-httpdを再起動すれば直るので、これはキャッシュの問題だな…

まあでも毎回groonga-httpdを再起動すればいいといえるような頻度ではない(ものすごく頻度が高い)のでC-APIから解決する。

grn_obj* db = grn_ctx_db(&ctx);
grn_db_touch(ctx, db);

でOK!
なはずなんだが、それでも時々ずれてることがある。うーん、なんだろうなー