Amazon Web Services ブログ

AWS のプライベート Ethereum ブロックチェーンネットワークに、スマートコントラクトをデプロイする

ブロックチェーンは、信頼できる中央機関がなくても、複数の関係機関が分散的にデータをトランザクションおよび共有する必要があるような場合に使用することができます。このブログ記事では、ブロックチェーンを使って、スマートコントラクトをデプロイする方法について説明します。

ブロックチェーンネットワークには、誰でも参加できるパブリック、またはネットワークが既知の参加者たちに制限されている許可型があります。パブリックネットワークの例としては、パブリック Ethereum ネットワークが挙げられます。このネットワークでは、誰でもトランザクションを行ったり、トランザクション履歴を表示したり、ピアノードを作成しネットワークに参加させたりして、ネットワークを維持します。

許可型ネットワークの例としては、国境を越える資産の転送 (信用状など) を相互に行おうとする銀行や輸出業者のコンソーシアムが知られています。このネットワークの例では、調整役の中央機関がなくても機能します。ブロックチェーンの詳細については、AWS ウェブページのブロックチェーンを参照してください。

ブロックチェーンテクノロジーは、イミュータブル (不変) な台帳データベース、コンセンサスメカニズム、およびスマートコントラクトの実行環境という 3 つの主となるコンポーネントで構成されています。ブロックチェーンネットワークの各メンバーは、台帳データベースのコピーを所有しているため、トランザクション履歴を個別に検証できます。台帳データベースには 2 つのコンポーネントがあり、1 つは暗号上不変なトランザクション履歴をすべて保持するジャーナルで、もう 1 つはこれらのトランザクションから派生したデータの現在の状態を示すワールドステートです。

「ブロックチェーン」とは、ジャーナルのデータ構造のことです。このデータ構造では、トランザクションを「ブロック」にまとめ、これらのブロックの「チェーン」を作成します。これは、新しい各ブロックに前のブロックの暗号化ハッシュを格納することによって行われます。このアプローチは、台帳に不変の特性を与えます。

スマートコントラクトは、ブロックチェーンネットワーク内の自己実行型アプリケーションです。スマートコントラクトに関する主なユースケースとしては、中央当局の介入を避けながら、透明性があり、かつ紛争のない方法でお金や財産、株式、または何か価値のあるものを交換する場合などがあります。たとえば、ある商品の所有権がその商品の代金を支払った人全員に移転するとコントラクトが定めている場合、単にそのコントラクトに提示価格を送信します。その後、台帳は次のブロックのトランザクションで自動的に更新され、新しい所有者としてあなたを反映します。

スマートコントラクトを使って、住宅ローン、債券、証券などの金融商品の条件をプログラムすることもできます。あるいは、サプライチェーンを通じた商品の追跡や支払いを簡単に行うことも可能です。契約を必要とするものなら何でも、スマートコントラクトを利用することができます。

11 月に、AWS はオープンソースフレームワークの Ethereum および Hyperledger Fabric を使用した、新しいサービス、Amazon Managed Blockchain を開始し、スケーラブルなブロックチェーンネットワークを簡単に作成および管理できるようになりました。このサービスは現在プレビュー版で、Hyperledger Fabric をサポートしており、Ethereum のサポートももうすぐ開始される予定です。Amazon Managed Blockchain の詳細については、Amazon Managed Blockchain の製品ページを参照してください。

このブログ記事では、Ethereum のスマートコントラクトを作成し、デプロイする方法を解説しています。Amazon Managed Blockchain プレビュー版で Ethereum のサポートが開始される前に、AWS Blockchain Templates を使ったプライベート Ethereum ネットワークを作成します。プライベート Ethereum ネットワークでは、スマートコントラクトをパブリック Ethereum ネットワークにデプロイする前にテストしたり、既知のメンバーたちでネットワークを構築することができます。今後の記事では、Amazon Managed Blockchain の Ethereum ネットワーク上で、こうした例を実行する方法を紹介する予定です。

このブログ記事では、プライベート Ethereum ネットワークとやり取りできるよう Ethereum Wallet GUI をインストールおよび設定し、スマートコントラクトをデプロイしテストする方法を紹介します。これを行うには、Microsoft Windows Bastion Host に新しいノードをデプロイしてから、このノードを Amazon ECS でホストされているプライベート Ethereum ブロックチェーンネットワークに接続し同期します。コンソーシアムに新しいメンバーを追加して、複数の主体または会社が分散した同じ台帳から読み書きできるようにすると考えてください。

次の図は、Windows Bastion Host を含んだ AWS Blockchain Templates を示しています。

前提条件

この記事では、AWS Blockchain Templates、Ethereum、Solidity、およびスマートコントラクトに精通していることを前提としています。

AWS Blockchain Templates を使用すると、一般的なオープンソースフレームワークを使用して、ブロックチェーンネットワークを迅速かつ簡単に作成およびデプロイすることが可能となります。Solidity とは、スマートコントラクトを実装するコントラクト指向のハイレベルな言語です。C++、Python、JavaScript の影響を受けており、Ethereum Virtual Machine (EVM) を対象として設計されています。

次のドキュメントでは、この記事で説明する手順を実行する際に役立つ背景知識を提供しています。

AWS Blockchain Templates を使用して、Ethereum ネットワークを構築する

前の図が表す環境を構築するために、次の AWS CloudFormation テンプレートをデプロイします。これを行うと、内部の Application Load Balancer によって公開される次のウェブサービスを使用して、Amazon ECS 上にプライベート Ethereum ブロックチェーンネットワークが構築されます。

  • Ethereum Network Status – Ethereum ネットワークの状態を監視するためのウェブベースのアプリケーション。
  • Ethereum Explorer – Ethereum 用ブロックエクスプローラー。
  • Ethereum JSON-RPC – ステートレスで軽量なリモート手続き呼び出し (RPC) プロトコル。

Ethereum Network Status のページでは、ネットワークの健全性とアクティビティを表示でき、Ethereum Explorer のページでは生成されたブロックとその内容を表示できます。JSON-RPC URL を使用すれば、ブロックチェーンネットワークにリモート接続し、リモートで手続き呼び出しを発行できます。このブログ記事では、リモート呼び出しを発行するのではなく、ネットワークにノードを追加し、そのノードに対してコマンドを発行しています。Windows Bastion Host を使用して、新しいノードであるクライアントソフトウェアを実行し、ブロックチェーンに接続してスマートコントラクトをデプロイします。

以下に示す CloudFormation テンプレートでは、あらかじめ設定されたデフォルトとプライベートブロックチェーンとやり取りするために必要なソフトウェアも使用して、Private Ethereum Network をデプロイしています。

: これらのテンプレートは、前述のアーキテクチャー図に示されているように完全な環境を構築します。基本レベルの Ethereum テンプレートは、もともとは AWS ウェブページ「AWS Blockchain Templates の使用開始」からのものです。デフォルトのブロックチェーンパラメータを変更したい場合は、オリジナルのソーステンプレートを参照してください。

ステップ 1: CloudFormation テンプレートをデプロイする

初めに、この Amazon S3 バケットから CloudFormation テンプレートをデプロイします。これで、ブログ投稿で手順を進める際に利用する、設定済みのデフォルトと関連ソフトウェアを含む Private Ethereum Blockchain ネットワークがインストールされます。

テンプレートをデプロイしたら、Remote Desktop Protocol (RDP) を使用して、Windows Bastion Host にログインします。このインスタンスは VPC 内にあるため、クライアントツールを使ってプライベートネットワークと通信できます。

注: Bastion Host に接続できない場合は、関連付けられているセキュリティグループの入力ルールを調べて、RDP トラフィックの送信元 IP アドレスと一致することを確認してください。

Windows Bastion Host には、ブロックチェーンへの接続に使用する 2 つのクライアントツールがプレインストールされています。

  • Ethereum Wallet – Ethereum 上に構築されたイーサかつ他の CryptoAsset を保持および保護し、スマートコントラクトを作成、デプロイ、使用することも可能にする Ethereum GUI。
  • geth – Go で実装される完全な Ethereum ノードを実行するためのコマンドラインインターフェース。JavaScript ランタイム環境を提供する対話式コンソールの geth を起動すれば、JavaScript API を公開してノードとやり取りすることができます。

コマンドを実行する

参照しやすいように、実行するコマンドの完全なリストが次のパスに用意されています。C:\Users\Administrator\EthereumPrivate\commands.txt

次の PowerShell コマンドを使って、commands.txt ファイルを開きます。

PowerShell_ISE -file .\EthereumPrivate\commands.txt

PowerShell_ISE を使用してファイルを表示および編集するのは、Notepad.exe がファイルコンテンツの形式を変更するためです。

注: PowerShell_ISE 内で geth コマンドを実行しないでください。標準の PowerShell インターフェース内でのみ実行してください。

次のスクリーンショットは、commands.txt ファイルにアクセスする例を示しています。

ノードを同期する

Ethereum Wallet と geth は RPC を使用してリモートノードに接続できますが、安全に行えるようには設計されていません。たとえば、HTTP 経由で接続しているときにアカウントのロックを解除すると、geth は HTTP 経由でプレーンテキストのパスワードをリモートノードに送信します。そのため、ネットワークに参加するローカル geth ノードを実行します。

ステップ 2: ジェネシスブロックを確認する

すべてのブロックチェーンは、ジェネシスブロックから始まります。デフォルト設定で初めて geth を実行すると、メインネットのジェネシスブロックがデータベースにコミットされます。プライベートネットワークの場合、通常は別のジェネシスブロックが必要です。

C:\Users\Administrator\EthereumPrivate というフォルダが作成され、そこにプライベートブロックチェーンファイルを格納します。このフォルダの中に、genesis.json というファイルがあります。このファイルは、AWS Blockchain Templates を使って構築したプライベートネットワークと互換性のあるジェネシスブロックを作成するために使用されます。これで、ノードを Amazon ECS 上でホストされているプライベートネットワークと同期させることができます。

ファイルを開き、その内容を確認してください。そうすると、次のように表示されるでしょう。

{
"config":{
"chainId":1234,
"homesteadBlock":0,
"eip155Block":0,
"eip158Block":0},
"nonce":"0x0000000000000001",
"mixhash":"0x0000000000000000000000000000000000000000000000000000000000000000",
"difficulty":"0x1",
"coinbase":"0x0000000000000000000000000000000000000000",
"timestamp":"0x00",
"parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
"gasLimit":"0x7a1200",

"alloc":{
"0x0ADfCCa4B2a1132F82488546AcA086D7E24EA324":
{"balance":"1000000000000000000000"},

"0x0bd5EebDC3E53973dDF236D43906C776a5fE3784":
{"balance":"1000000000000000000000"},

"0x9537cb86f5a03C8CCB52c44b49757861eCA0004b":
{"balance":"1000000000000000000000"},

"0x1Fbc353788338F902630E5494aD7FaC7dF8dBb29":
{"balance":"1000000000000000000000"},

"0x5ccBe3B9B15eFB62bB2696051091Ee7C1Eb4c7E6":
{"balance":"1000000000000000000000"}

}
}

注: CloudFormation のデプロイ中にデフォルト値を「Ethereum Network ID」や「Initial List of Accounts」などに変更した場合は、必ずジェネシスファイルにも同じ変更を加えてください。

ステップ 3: 静的ノードマッピングを作成する

静的ノードマッピングは、ネットワーク内で他のどのノードと通信するかをノードに指示します。これを行うためのファイルは既に作成されていますが、編集する必要があります。

このセットアップでは、Amazon ECS でタスクとして現在実行されているものとして、静的ノードを設定します。これで、ローカルノードは AWS でホストされているものと同じネットワークに参加できます。

Windows Bastion Server 上の、次のファイルディレクトリを参照します。

C:\Users\Administrator\EthereumPrivate\geth\

このディレクトリで static-nodes.json というファイルを開き、Amazon DynamoDB テーブルから次のノード情報を入力します。

注: 使用中の環境に必要な IP 情報については、AWS Blockchain Templates によって「CloudFormation スタック名」を含む名前で作成された DynamoDB テーブルを参照してください。

次のスクリーンショットは、Ethereum ノードと IP 情報を示しています。

[
"enode://<id>@<ip address>:30303",
"enode://<id>@<ip address>:30303",
"enode://<id>@<ip address>:30303"
]

管理者アカウントで Windows にログイン中と仮定します。実行を成功させるためにも、このブログ記事で説明している手順をよく理解してから、管理者以外の代替ユーザーを設定することをお勧めします。

ファイル static-nodes.json を編集するには、次の PowerShell コマンドを実行します。

PowerShell_ISE -file .\EthereumPrivate\geth\static-nodes.json

CloudFormation スタックのデプロイの一環として、作成した DynamoDB テーブルで enode ID とそれに付随する IP アドレスを検索します。さらに、static-node.json ファイルに必要な変更を加えます。ファイルを閉じる前に、必ず変更を保存してください。

これで、環境に関連した対応する設定情報を含むファイルが見つかるはずです。ファイルはこちらにあります。

C:\Users\Administrator\EthereumPrivate\geth\static-nodes.json

注: 以下に示す構成ファイルは例ですので、使用しないでください。

Static-nodes.json ファイルの例を以下に示します。

[
"enode://18c1c4869d9e54b75ce968c1726b4ada18732ab5b577c2d0a35d85384e03def3e61a948dd0a1ba968d675c849df36e36cd5c9b15b66239974525551a40433406@10.0.40.135:30303",
"enode://681867148e14ee9c6f1fb839e9f0674651e3e27eb1f1e15d3b2ae7e3de1640e6af3441cc06ea686db7f75b07a2294d95c6e4555400f9a698ca1cbafdebde4d8e@10.0.30.154:30303",
"enode://8ac49be3a5da121ca7dffd74e613a2d490771d0328da05f8c686192d6dbf8f9055e5935101498451a48c13d7e0b94063e812e1f2e56b07a01a6035dfbda80234@10.0.40.52:30303"
]

ステップ 4: Ethereum クライアントを初期化する

Genesis.jsonstatic-nodes.json ファイルを配置したので、次に Ethereum クライアントを初期化します。

まず、genesis.json で定義されているジェネシスブロックを使用するように geth クライアントを初期化する必要があります。 これを行うには、PowerShell を開き、次のコマンドを実行します。

geth --datadir C:\Users\Administrator\EthereumPrivate init C:\Users\Administrator\EthereumPrivate\genesis.json

注: PowerShell_ISE 内で geth コマンドを実行しないでください。標準の PowerShell インターフェース内でのみ実行してください。


ステップ 5: geth を開始する

ジェネシスブロックとピアノードが構成されました。Ethereum クライアントを起動し、プライベートネットワークと通信するように設定します。これを行うには、次のコマンドを実行します。

geth --datadir C:\Users\Administrator\EthereumPrivate —networkid 1234

注: PowerShell_ISE 内で geth コマンドを実行しないでください。標準の PowerShell インターフェース内でのみ実行してください。

ステップ 6: Ethereum Wallet アプリを使用して、ネットワークとやり取りする

ネットワークとやり取りするには、まず Etherem Wallet アプリを開きます。

Wallet はキーとそれに関連するイーサ、コントラクト、およびトークンの保存ができる場所です。実際には、資産は自身のマシンではなく、ブロックチェーンに保存されています。

パブリックキーに資産を割り当てることができます。プライベートキーは、コントラクトを作成したり、コントラクトとやり取りしたり、さらには他者に資産を送るトランザクションに署名するのに使用されます。

デスクトップに Ethereum Wallet のアイコンが表示されているはずです。このアイコンをダブルクリックして、アプリを開きます。これでプライベート Ethereum ネットワークに接続でき、次のようなスクリーンが表示されます。

Private-Net が、1234 などの非パブリックネットワーク ID を使用していることを示します。

ステップ 7: アカウントを追加する

トランザクションとスマートコントラクトのテストを開始するため、アカウントを追加します。アカウントはパスワードで保護されたキーで、イーサ、安全な Ethereum ベースのトークンまたはコインを保持したり、コントラクトを管理します。

Ethereum Wallet で、[File][New Account] と進み、パスワードを入力して [Enter] を押します。パスワードを確認して、[Enter] を押します。これでアカウントが作成されました。

ステップ 8: マイニングを開始する

マイニングとは、数学的問題を解くことで、ネットワークへのブロックを確認するプロセスのことです。

プルーフオブワークでは、前のブロックハッシュ、タイムスタンプ、トランザクション、およびナンス値を組み合わせて、先頭に一定数のゼロが並ぶハッシュを生成するのが目的です。ネットワークのメンバーは全員、最初の 3 つの変数を持っているため、望ましい結果を生み出すナンス値を見つけるのは基本的に早いもの勝ちです。答えを見つけた最初のノードは、確認のためにそれをネットワークにブロードキャストします。他のノードが答えを確認した後、ブロックはコミットされ、イーサはマイナーに報酬を与えます。

パブリック Ethereum ネットワークでのマイニングは、GPU を使用する場合にのみ実行可能であり、OpenCL または CUDA 対応の ethminer インスタンスが必要なため、複雑な作業です。ただし、プライベートネットワークの設定では、単一の CPU マイナーインスタンスで実用的な目的には十分す。1 つのインスタンスで、大量のリソースを必要とせずに、正しい間隔で安定したブロックのストリームを生成できます。

イーサのマイニングを開始し、スマートコントラクトの作成などのトランザクションに使用できる資金を作ります。これを行うには、別の PowerShell ウィンドウを開き、geth attach ipc:\\.\pipe\geth.ipc で geth インスタンスにアタッチする必要があります。これでコマンドを実行できるようになります。

ステップ 9: 登録したアカウントを確認する

Eth.accounts と入力し、登録したアカウントを表示します。

Ethereum Wallet で作成したアカウントと同じアカウントが表示されるはずです。

ステップ 10: 2 つのスレッドでマイニングを始める

miner.start(2) と入力し、2 つのスレッドでマイニングを開始します。

これで Ethereum Wallet 内のアカウントが、マイニングでイーサを集め始めます。

ステップ 11: スマートコントラクトを作成、デプロイおよびテストする

次のステップは、スマートコントラクトの作成です。

Ethereum エコシステムのトークンは、硬貨、ロイヤリティポイント、ゴールド証明書、IOU、ゲームのアイテムなど、代替可能なあらゆる取引可能商品を表しています。トークンはすべて、標準的な基本機能をいくつか実装しています。このため、トークンは Ethereum Wallet や他のクライアント、または同じ標準を使用するコントラクトと、即座に互換性を持ちます。

それでは、トークンまたはコインをデプロイする基本的なコントラクトを構築しましょう。楽しくするために、MattCoin という基本的な自分の通貨を作ります。MattCoin ではなく、他の名前に自由に変更して構いません。作業が楽しくなるだけでなく、自分の暗号通貨も持っていることを友人たちに自慢することもできます。

このコントラクトをデプロイするには、Ethereum Wallet の [CONTRACTS] をクリックしてから、[DEPLOY NEW CONTRACT] を選択します。

以下は、MattCoin を構築するためにデプロイするコントラクトのコードです。 このコードを [SOLIDITY CONTRACT SOURCE CODE] セクションに貼り付けます。次に、デプロイするコントラクトと作成する最初のトークン数を選択します。次に、[DEPLOY] をクリックして、アカウントで作成したパスワードを入力します。

このコードで、簡単なコインまたはトークンのためのスマートコントラクトを作成できます。まず、すべての可能性のある Ethereum アドレスのマッピングを作成し、それらを均衡にします。変数は、任意のアドレスが MattCoin の値を保持できるようにします。次に、コンストラクタで、最初のトークンの供給全体をコントラクトの作成者に渡すように指定します。最後に、transfer という関数を定義します。これで、ある Ethereum アドレスから別のアドレスに MattCoin を送信することができるようになります。

pragma solidity ^0.4.18;
contract MattCoin {
    (これで、すべてが均衡な配列を作成できます)
    mapping (address => uint256) public balanceOf;

    (コントラクトの作成者への最初のトークン供給で、コントラクトを初期化します)
    constructor(
        uint256 initialSupply
        ) public {
        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
    }

    (コインを送信します)
    function transfer(address _to, uint256 _value) public {
        require(balanceOf[msg.sender] >= _value);           // Check if the sender has enough
        require(balanceOf[_to] + _value >= balanceOf[_to]); // Check for overflows
        balanceOf[msg.sender] -= _value;                    // Subtract from the sender
        balanceOf[_to] += _value;                           // Add the same to the recipient
    }
}

これでコントラクトが作成されました。次のブロックにマイニングされたら、プロセスは終了します。

コントラクトを作成したら、それをクリックして Balance of のフィールドにアカウントアドレスを入力します。そうすると、コントラクトで作成した金額と同じ残高が表示されます。

トークンを別の Ethereum アカウントに送信するのをテストしたい場合は、まず 2 つ目のアカウントを作成します。次に、transfer 関数を選択し、to address に転送するトークン数を指定して、[EXECUTE] をクリックします。

トランザクションに署名するため、もう一度パスワードを入力するように求められます。

トランザクションが送信されたら、to address の値を Balance of フィールドに入力すると、このアドレスに送信した金額が表示されます。

結論

これで自分のプライベート Ethereum ネットワークをセットアップし、最初のスマートコントラクトをデプロイしました。Ethereum 用 AWS Blockchain Template を使用することで、簡単にブロックチェーンプロジェクトを開始し、ユースケースのテストを実施できるようになります。今度は、誰か他のメンバーがこのネットワークに参加したり、Ethereum Wallet のようなスマートコントラクトを使用して GUI を使用したりすることに関心がないか、検討してみましょう。


著者について

Matt Taylor は、IT インフラストラクチャのアーキテクチャと配信の経験がある AWS パートナーソリューションアーキテクトです。AWS パートナーに AWS 製品およびサービスに関するコンサルティングを行い、お客様の問題を最善の方法で解決できるよう支援しています。余暇には、ブロックチェーンのテクノロジーについて学んだり、アプリケーションや業界で将来最も影響を持つのはどこかなどを考えて過ごします。

 

 

 

Pierre Liddle は、セキュリティの運用やエンジニアリングからアーキテクチャおよびリスク管理まで、幅広い経験を積んできました。そして現在は、彼の知識をふんだんに活用して、AWS のお客様をサポートしています。セキュリティに重点的に取り組む AWS エンタープライズソリューションアーキテクトとして、AWS のお客様がリスクを管理し、セキュリティ要件を満たす安全なワークロードを設計できるよう支援しています。