Ethereumをベースに、企業向けに改良されているスマートコントラクトプラットフォーム「Quorum」を使った、“トランザクション”と“プライベートトランザクション”の発行方法を紹介する。
「スマートコントラクト」は、契約の条件確認や履行などを自動で行えることから、ブロックチェーン技術を活用したアプリケーションプラットフォームの中でも研究開発が進み、注目されている技術です。
本連載では、スマートコントラクトの概念や仕組みを整理しつつ、DApps(Decentralized Applications:分散ノード上で実行されるアプリケーション)でのスマートコントラクトのコーディング方法、企業向けアプリケーション開発の実践方法について解説しています。
前回は、Quorumの概要、サンプルの動作について説明しました。今回は2種類のトランザクション発行方法を紹介します。1つ目は「通常のトランザクション」。2つ目は「プライベートトランザクション」です。
まず、コマンドプロンプトを起動して、コントラクトをコンパイルするためのライブラリをインストールします。
$ npm install -g solc
次に、下記の内容でコントラクトを作成し、任意の場所に保存します。
// SingleNumRegister.sol pragma solidity ^0.4.0; contract SingleNumRegister { uint storedData; function set(uint x) public{ storedData = x; } function get() public constant returns (uint retVal){ return storedData; } }
コントラクトと同一の階層に移動し、下記コマンドを実行してコンパイルします。
$ cd sample-contract $ solcjs --abi --bin SingleNumRegister.sol
以下のようにabiファイルとbinファイルが出力されていればコンパイル完了です。
. ├── SingleNumRegister.sol ├── SingleNumRegister_sol_SingleNumRegister.abi └── SingleNumRegister_sol_SingleNumRegister.bin
前回の記事で構築したQuorumの仮想環境に接続します。
$ cd quorum-examples $ vagrant ssh
次に、仮想環境でQuorumを起動し、node1のコンソールを起動します。
$ cd quorum-examples/7nodes $ ./raft-start.sh $ geth attach qdata/dd1/geth.ipc
abiファイル、binファイルの中身をそれぞれコピーし、下記のコマンドをnode1のコンソールで実行します。コマンドの実行結果に戻り値が存在しない場合は、コンソールに「undefined」と表示されますが、コマンドは正常に終了しています。
> var bin = "0x<binファイルの中身>" > var abi = <abiファイルの中身>
続けて、これらの変数を用いて下記のコマンドを実行し、コントラクトをデプロイします。
> var contract = eth.contract(abi) > var myContract = contract.new({ from: eth.accounts[0], data: bin})
下記のコマンドでデプロイ結果を確認します。
> myContract
以下のような内容が表示され、addressに値が設定されていればデプロイ完了です。
{ 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: "0x87ec4e85245d901de66c09c96bd53c8146e0c12d", transactionHash: "0x7d57f2dcf0ad2d1f68d73c64db781003d2f56a2795c83d3fd3b13d46df8a72f4", allEvents: function(), get: function(), set: function() }
デプロイしたコントラクトをコールするためにトランザクションを発行します。まずは、コントラクトへアクセスするオブジェクトを生成するため、下記のコマンドをnode1のコンソールで実行します。
> var cnt = eth.contract(myContract.abi).at(myContract.address)
このオブジェクト「cnt」を用いてContractにアクセスをし、コントラクトの関数「set」を下記コマンドで呼び出します。
> cnt.set.sendTransaction(6,{from:eth.accounts[0]}) "0x99b5fddd7be35aa442596187088884e8317723207d3cbbb7d24e3e0a1dc6195c"
このコマンドを実行した際の戻り値は、トランザクションIDです。このトランザクションIDを使ってトランザクションの状態を確認します。
> eth.getTransaction("0x99b5fddd7be35aa442596187088884e8317723207d3cbbb7d24e3e0a1dc6195c")
以下のような内容が表示され、blockNumberに値が設定されていればトランザクションが確定します。
{ blockHash: "0x1eb01e3320066fe1fe3c8510ae057fdc29eb65fb9c199e9d5b62d217d8d08e2b", blockNumber: 10452, from: "0xca843569e3427144cead5e4d5999a3d0ccf92b8e", gas: 90000, gasPrice: 0, hash: "0x99b5fddd7be35aa442596187088884e8317723207d3cbbb7d24e3e0a1dc6195c", input: "0x60fe47b10000000000000000000000000000000000000000000000000000000000000006", nonce: 2, r: "0xa95a9cc1e0f849a86762268ddfeb2cee1271ca8f44efb004d09ae43d4114c569", s: "0x7903dc0c8259a41738b3932bcc3582e92707d07cecd63e805a6ea1ba67a77690", to: "0x87ec4e85245d901de66c09c96bd53c8146e0c12d", transactionIndex: 0, v: "0x1b", value: 0 }
コントラクトの関数「get」を下記コマンドで呼び出し、登録した値を参照します。
> cnt.get() 6
6と表示されれば、トランザクションの発行は完了です。完了後はexitコマンドでコンソールを閉じます。
> exit
Copyright © ITmedia, Inc. All Rights Reserved.