Quorum example触ってみる

#はじめに
エンタープライズ向けEthereumのQuorumを触ってみます。
公式の[quorum examples](https://github.com/jpmorganchase/quorum-examples)を使います。

#Quorumとは

Quorumについては[こちらの資料](https://scrapbox.io/layerx/Quorum)をみると良いです。

#動かしてみる
##セットアップ
[Virtual Box](https://www.virtualbox.org/wiki/Downloads)と[Vagrant](https://www.vagrantup.com/downloads.html)がインストールされていることが必須

```
$ git clone https://github.com/jpmorganchase/quorum-examples
$ vagrant up
$ vagrant ssh
```

##node起動

```
$ cd examples/7nodes/
$ ./raft-init.sh
$ ./raft-start.sh
```

##private transactionを試してみる

　```SimpleStorage```コントラクトをnode1からnode7に送ります.トランザクションの送信オプションに```privateFor```がつけられていてこれはnode1とnode7にしか知り得ないようになっています.


```
$ ./runscript.sh private-contract.js
Contract transaction send: TransactionHash: 0x9e31af66669a6602307481bf2ebff2893f9d571effa11e50760e85686414a972 waiting to be mined...
true
```

node1としてgethコンソール入り, トランザクションを確認します
node1として入るには```geth attach ipc:qdata/dd1/geth.ipc```
node4として入るには```geth attach ipc:qdata/dd4/geth.ipc```
node7として入るには```geth attach ipc:qdata/dd7/geth.ipc```
を実行します.

```
$ geth attach ipc:qdata/dd1/geth.ipc
> eth.getTransaction("0x9e31af66669a6602307481bf2ebff2893f9d571effa11e50760e85686414a972")
{
  blockHash: "0x5e31602616f28c2f2bd6075d0de08eace32a68804289179d36536d1f224d6f75",
  blockNumber: 1,
  from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
  gas: 4700000,
  gasPrice: 0,
  hash: "0x9e31af66669a6602307481bf2ebff2893f9d571effa11e50760e85686414a972",
  input: "0x2bfd82f5cbc0666eec01e8d7faaf158e5e42b0f41c7fbf33ec20182cc29adce7863431c029ad2be5f0e9c396ac24dbe01d86c1395b688ef9edb46e58daf6ee03",
  nonce: 0,
  r: "0x854a01efdba6cb5bc5624793fd2b891b7ab97d17858f98f19e6507c9a6b9dc61",
  s: "0x412224a2d04ca3c7853533a8c7b461a08c75d972ac8e5024c44473ad37706aac",
  to: null,
  transactionIndex: 0,
  v: "0x26",
  value: 0
}
```

パラメータ```v```が```0x26```になっています. プライベートトランザクションは```v```が```0x26```か```0x27```になります.

次に、コントラクトのステートを見てみます.
このコントラクトは初期化時に```x```に```42```を代入しているので, node1と7は```x```が```42```になっているはずです. 逆に他のノードが```x```をみると```0```になっているはずです.

eth.getTransactionReceipt(txHash)を実行するとコントラクトアドレスがわかります.

```
> eth.getTransactionReceipt("0x9e31af66669a6602307481bf2ebff2893f9d571effa11e50760e85686414a972")
{
  blockHash: "0x5e31602616f28c2f2bd6075d0de08eace32a68804289179d36536d1f224d6f75",
  blockNumber: 1,
  contractAddress: "0x1932c48b2bf8102ba33b4a6b545c32236e342f34",
  cumulativeGasUsed: 0,
  from: "0xed9d02e382b34818e88b88a309c7fe71e65f419d",
  gasUsed: 0,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  status: "0x1",
  to: null,
  transactionHash: "0x9e31af66669a6602307481bf2ebff2893f9d571effa11e50760e85686414a972",
  transactionIndex: 0
}
```

```
> var address = "0x1932c48b2bf8102ba33b4a6b545c32236e342f34"
> var abi = [{"constant":true,"inputs":[],"name":"storedData","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"x","type":"uint256"}],"name":"set","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"get","outputs":[{"name":"retVal","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"initVal","type":"uint256"}],"type":"constructor"}];
> var private = eth.contract(abi).at(address)
```

node1として実行すると

```
> private.get()
42
```
node4として実行すると

```
> private.get()
0
```
node7として実行すると

```
> private.get()
42
```

が返ってきます.

##コントラクトを変更して試してみる
こんな感じのコントラクトに送金するコントラクトでプライベートトランザクションを試します

```
pragma solidity >=0.4.22 <0.6.0;

contract Bank {
    mapping(address => uint256) public UserToAmount;
    
    function deposit() payable public {
        UserToAmount[msg.sender] += msg.value;
    }
    
    function withdraw(uint256 amount) public {
        require(UserToAmount[msg.sender] >= amount);
        UserToAmount[msg.sender] -= amount;
        msg.sender.transfer(amount);
    }
}
```

```:ABI
[
	{
		"constant": false,
		"inputs": [],
		"name": "deposit",
		"outputs": [],
		"payable": true,
		"stateMutability": "payable",
		"type": "function"
	},
	{
		"constant": false,
		"inputs": [
			{
				"name": "amount",
				"type": "uint256"
			}
		],
		"name": "withdraw",
		"outputs": [],
		"payable": false,
		"stateMutability": "nonpayable",
		"type": "function"
	},
	{
		"constant": true,
		"inputs": [
			{
				"name": "",
				"type": "address"
			}
		],
		"name": "UserToAmount",
		"outputs": [
			{
				"name": "",
				"type": "uint256"
			}
		],
		"payable": false,
		"stateMutability": "view",
		"type": "function"
	}
]
```

```:bytecode
"608060405234801561001057600080fd5b50610275806100206000396000f3fe608060405260043610610051576000357c0100000000000000000000000000000000000000000000000000000000900480632e1a7d4d14610056578063d0e30db014610091578063ebfb4d531461009b575b600080fd5b34801561006257600080fd5b5061008f6004803603602081101561007957600080fd5b8101908080359060200190929190505050610100565b005b6100996101e3565b005b3480156100a757600080fd5b506100ea600480360360208110156100be57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050610231565b6040518082815260200191505060405180910390f35b806000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561014d57600080fd5b806000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501580156101df573d6000803e3d6000fd5b5050565b346000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550565b6000602052806000526040600020600091509050548156fea165627a7a72305820a406a09d0c1ed38eca8e89b9ab68ee75f667463a5bf92f87749eac7058143a240029"
```
保留

#まとめ
プライベートトランザクションを使用すると対象となるノード以外でもトランザクションの存在は確認できる.
コントラクトなどのステートには対象のノードしかアクセスできない感じ.