[アップデート] Ethereum on Amazon Managed Blockchain が GA されました
先日のアップデートで Ethereum on Amazon Managed Blockchain が GA になりました。
昨年 12 月にプレビューリリースされていた Ethereum on Amazon Managed Blockchain がいよいよ一般提供可能になりました!
Ethereum on Amazon Managed Blockchain
Ethereum スマートコントラクト
Ethereum は分散型アプリケーション(Dapp)などのスマートコントラクトによるアプリケーション構築が可能なオープンソースプロジェクトです。
Ethereum は暗号資産($ETH)としての認知度が高いと思いますが、ゲーム、不動産取引、身分証明(DID)などのサービスを Ethereum プラットフォーム上で提供することも可能です。
記憶にあたらしいところでは、昨年、暗号資産人気を後押しした分散型金融(DeFi)、分散型取引所(DEX)、ノン・ファンジブル・トークン(NFT)などはまさに Ethereum スマートコントラクトの代表格として皆さんもご存知のことかと思います。
フルマネージドな Ethereum ノード
通常、Ethereum フルノードを抱える場合、日々増加するストレージや、ネットワーク性能、ソフトウェア(Geth)のアップデートなどの運用が必要になりますが、Ethereum on Amazon Managed Blockchain ではフルマネージドサービスとして AWS に任せることができます。
利用可能な Ethereum ネットワーク
選択可能なネットワークは以下の 3 つ。
- メインネットワーク: 本番用の PoW ネットワーク。トランザクションには実際の Gas が必要になります。(最近、高騰していますね。。)
- Rinkeby テストネットワーク: テスト用の PoA ネットワーク。実際の Gas は必要ありません。
- Ropsten テストネットワーク: テスト用の PoW ネットワーク。実際の Gas は必要ありません。
上記ネットワークはいずれもパブリックネットワークです。プライベートネットワークとしての Ethereum にはまだ対応していないようです。(ネットワーク作成のメニューから見ると Coming Soon のままでした)
料金
利用可能なインスタンスタイプと料金(東京リージョン)は下記のとおりです。m5.large/t3.large
だと最小要件(2core/4GB RAM) を満たしますが、Ethereum の推奨要件(4core/+16GB RAM)だと m5.xlarge/t3.xlarge
あたりになります。
インスタンスタイプ | 時間あたり料金 |
---|---|
bc.c5.2xlarge | $0.685 |
bc.c5.4xlarge | $1.37 |
bc.c5.xlarge | $0.342 |
bc.m5.2xlarge | $0.794 |
bc.m5.4xlarge | $1.587 |
bc.m5.large | $0.198 |
bc.m5.xlarge | $0.397 |
bc.t3.large | $0.174 |
bc.t3.xlarge | $0.348 |
その他に以下の料金が発生します。
- Storage Rate $0.12 per GB-month
- Ethereum API リクエスト $0.00000488 per Request ($4.88 per million requests)
- 1 リクエストは交換されたデータサイズ 32 KB または 応答時間 500 ms のいずれかでカウントされます
利用可能なリージョン
執筆時点で利用可能なリージョンは以下のとおりです。
- 米国東部(バージニア北部)
- アジアパシフィック(ソウル)
- アジアパシフィック(東京)
- アジアパシフィック(シンガポール)
- 欧州(アイルランド)
- 欧州(ロンドン)
利用上の考慮点
ノードタイプ
執筆時点において Ethereum on Amazon Managed Blockchain で利用可能なノードは Geth フルノードのみです。以下のとおりアーカイブノードはグレーアウトになっています。
Ethereum JSON-RPC
Ethereum クライアントがノードに対してクエリやトランザクションを送信するには、JSON-RPC API をインタフェースとして利用しますが、Ethereum on Amazon Managed Blockchain のマネージドノードでは一部の Ethereum JSON-RPC メソッドはサポートされていないようです。
ざっくり調べですが、対応していないメソッドは以下のとおりです。
- eth_coinbase
- eth_mining
- eth_hashrate
- eth_accounts
- eth_sign
- eth_signTransaction
- eth_sendTransaction
- eth_getCompilers
- eth_compileLLL
- eth_compileSolidity
- eth_compileSerpent
- eth_submitWork
- eth_submitHashrate
- db_putString
- db_getString
- db_putHex
- db_getHex
- shh_post
- shh_version
- shh_newIdentity
- shh_hasIdentity
- shh_newGroup
- shh_addToGroup
- shh_newFilter
- shh_uninstallFilter
- shh_getFilterChanges
- shh_getMessages
eth_mining
が対応していないのでマイニング用途には利用できなさそうですね。
また以下ドキュメントに記載のとおり eth_sendRawTransaction
のみがサポートされていますので、トランザクションをノードに送信する前に署名する必要があります。
トランザクションの署名を必要とする eth_sendTransaction
はマネージドノードではサポートされていません。
Ethereum on Managed Blockchain only supports the
eth_sendRawTransaction
method, which requires that you create and sign the transaction before sending it to the node. Managed Blockchain does not have any way to sign transactions similar to an Ethereum wallet application.
eth_accounts
がサポートされておらずアカウント管理は出来ないので、当然 Geth クライアント(ノード)での署名を管理することも出来ない、ということでしょう。
利用可能な JSON-RPC メソッド一覧はドキュメントを参照ください。
やってみる
それでは簡単に検証してみましょう。今回の検証は以下のとおりです。
- 東京リージョン
- bc.t3.large
- 検証内容
- ノードの作成
- Ethereum JSON-RPC API コール
ノードの作成
Amazon Managed Blockchain 管理コンソールをから [ネットワークに参加] を開きます。参加するブロックチェーンネットワーク、インスタンスタイプ、ノードタイプなどを選択し [ノードの作成] をクリックします。
今回は Ropsten
テストネットワークに bc.t3.large
インスタンスのフルノードを作成します。検証ですので単一 AZ として 1 ノードのみ作成しています。
作成メニューのインフォメーションに記載のとおり、ノード作成してから利用可能になるまでは 30 分程度でした。
ノードの詳細を確認すると、WebSocket エンドポイント、HTTP エンドポイントなどが確認できます。これらは後ほど JSON-RPC API をコールする際に必要となりますので控えておきます。
ちなみに Ropsten テストネットワークに作成した直後のストレージ容量は 111 GB くらいでした。
Ethereum JSON-RPC API コール
Ethereum JSON-RPC API を呼び出すために、いくつかの方法があります。
今回は web3.js を使用して HTTP エンドポイントに API コールしてみます。
環境準備
まずノードバージョンマネージャー(nvm)と Node.js バージョン 14 以降をインストールします。EC2 や Cloud9 環境を利用の場合、以下のチュートリアルを参考にすると良いです。
$ node --version v14.16.0
バージョン 14 より前のものが表示される場合は、nvm install 14
、nvm use 14
を実行することでバージョン 14 が利用可能になります。
次に、公式ドキュメントのサンプルスクリプトを実行するための前提条件となる以下のパッケージをインストールします。
$ npm install aws-sdk $ npm install web3 $ npm install xhr2
サンプルスクリプトでは ECMAScript(ES) モジュールを使用しますので、 package.json
に以下の内容を追加します。
{ "type": "module", "dependencies": { "aws-sdk": "^2.809.0", "web3": "^1.3.0", "xhr2": "^0.2.0" } }
IAM ポリシー
Ethereum on Amazon Managed Blockchain のノードに対して Ethereum JSON-RPC を API コールするためには署名バージョン 4 の署名プロセスを利用します。
今回は検証用に作成した IAM ユーザーに AWS マネージドポリシーの AmazonManagedBlockchainConsoleFullAccess
をアタッチしました。ポリシーの内容は以下のとおりです。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "managedblockchain:*", "ec2:DescribeAvailabilityZones", "ec2:DescribeSecurityGroups", "ec2:DescribeSubnets", "ec2:DescribeVpcs", "ec2:CreateVpcEndpoint", "kms:ListAliases", "kms:DescribeKey" ], "Resource": "*" } ] }
環境変数に AWS アクセスキー/シークレットキー、エンドポイント情報などを設定します。各種エンドポイントは作成したノード情報を参照することで確認可能です。
$ export AWS_ACCESS_KEY_ID="AKXXXXXXXXXXXXXXXXXX" $ export AWS_SECRET_ACCESS_KEY="ZoXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX+" $ export AMB_HTTP_ENDPOINT="https://nd-XXXXXXXXXXXXXXXXXXXXXXXXXX.ethereum.managedblockchain.ap-northeast-1.amazonaws.com" $ export AMB_WS_ENDPOINT="wss://nd-XXXXXXXXXXXXXXXXXXXXXXXXXX.wss.ethereum.managedblockchain.ap-northeast-1.amazonaws.com"
サンプルスクリプトを実行する
公式ドキュメントを参考にサンプルスクリプトを準備します。aws-http-provider.js
は以下のとおりです。
///////////////////////////////////////////////////// // Authored by Carl Youngblood // Senior Blockchain Solutions Architect, AWS // Adapted from web3 npm package v1.3.0 // licensed under GNU Lesser General Public License // https://github.com/ethereum/web3.js ///////////////////////////////////////////////////// import AWS from 'aws-sdk'; import HttpProvider from 'web3-providers-http'; import XHR2 from 'xhr2'; export default class AWSHttpProvider extends HttpProvider { send(payload, callback) { const self = this; const request = new XHR2(); // eslint-disable-line request.timeout = self.timeout; request.open('POST', self.host, true); request.setRequestHeader('Content-Type', 'application/json'); request.onreadystatechange = () => { if (request.readyState === 4 && request.timeout !== 1) { let result = request.responseText; // eslint-disable-line let error = null; // eslint-disable-line try { result = JSON.parse(result); } catch (jsonError) { let message; if (!!result && !!result.error && !!result.error.message) { message = `[aws-ethjs-provider-http] ${result.error.message}`; } else { message = `[aws-ethjs-provider-http] Invalid JSON RPC response from host provider ${self.host}: ` + `${JSON.stringify(result, null, 2)}`; } error = new Error(message); } callback(error, result); } }; request.ontimeout = () => { callback(`[aws-ethjs-provider-http] CONNECTION TIMEOUT: http request timeout after ${self.timeout} ` + `ms. (i.e. your connect has timed out for whatever reason, check your provider).`, null); }; try { const strPayload = JSON.stringify(payload); const region = process.env.AWS_DEFAULT_REGION || 'us-east-1'; const credentials = new AWS.EnvironmentCredentials('AWS'); const endpoint = new AWS.Endpoint(self.host); const req = new AWS.HttpRequest(endpoint, region); req.method = request._method; req.body = strPayload; req.headers['host'] = request._url.host; const signer = new AWS.Signers.V4(req, 'managedblockchain'); signer.addAuthorization(credentials, new Date()); request.setRequestHeader('Authorization', req.headers['Authorization']); request.setRequestHeader('X-Amz-Date', req.headers['X-Amz-Date']); request.send(strPayload); } catch (error) { callback(`[aws-ethjs-provider-http] CONNECTION ERROR: Couldn't connect to node '${self.host}': ` + `${JSON.stringify(error, null, 2)}`, null); } } }
aws-http-provider.js
と同じディレクトリに Ethereum JSON-RPC API をコールする web3-example-http.js
を配置します。今回のサンプルスクリプトでは getNodeInfo
メソッドを実行しています。
import Web3 from 'web3'; import AWSHttpProvider from './aws-http-provider.js'; const endpoint = process.env.AMB_HTTP_ENDPOINT const web3 = new Web3(new AWSHttpProvider(endpoint)); web3.eth.getNodeInfo().then(console.log);
スクリプトを実行して以下のような結果が取得できれば正常に API コールできています。
$ node web3-example-http.js web3-shh package will be deprecated in version 1.3.5 and will no longer be supported. web3-bzz package will be deprecated in version 1.3.5 and will no longer be supported. Geth/v1.9.24-stable-cc05b050/linux-amd64/go1.15.5
以下のようなエラーが出る場合、環境変数にリージョン情報を設定することで解決できます。
UnhandledPromiseRejectionWarning: Error: Invalid JSON RPC response: {"message":"Credential should be scoped to a valid region, not 'us-east-1'. "}
export AWS_DEFAULT_REGION=ap-northeast-1
検証は以上です!
さいごに
Ethereum on Amazon Managed Blockchain が GA になりましたので試しにノードを作成してみましたが EC2 を起動すよりも簡単に Geth ノードを作成して Ethereum ネットワークに参加させることができました。
これを機にスマートコントラクト開発にチャレンジしてみるのも良いかもしれません!
ブロックチェーンといえば暗号資産(仮想通貨)の投機的なイメージばかりが先行して、なかなかアプリケーションプラットフォームとして広がりを感じることは少ないと思いますが、国外に目を向ければ Ethereum などのスマートコントラクトを利用したサービスがどんどん増えています。
今後、新たな 「Decentralized xx」(分散型 xx) という仕組みが次々に出てくることが予想されますが、国内からもそのようなユースケースが出てくることを期待したいですね!
以上!大阪オフィスの丸毛(@marumo1981)でした!