LoginSignup
2
2

More than 1 year has passed since last update.

Amazon Managed Blockchain で Simple NFT Marketplace を触ってみた

Posted at

はじめに

前回の記事では、Amazon Managed Blockchain で Ethereum Node を作り、簡単な動作確認を行いました。今回は、独自のスマートコントラクトをデプロイする方法を学んでいきます。

aws-samples に、「Simple NFT Marketplace」という名前の GitHub リポジトリがあり、ここでサンプルコードが公開されています。日本語の説明もあり、わかりやすいのでこれを試していきたいと思います。
https://github.com/aws-samples/simple-nft-marketplace

この「Simple NFT Marketplace」を実施することで、以下の点が学習できます

  • スマートコントラクトをデプロイする
    • Amazon Managed Blockchain でつくった Ethereum Node を使って Goerli ネットワークにデプロイする
  • デプロイしたスマートコントラクトを、Lambda から呼び出す
  • フロントエンドは、API Gateway と Lambda を経由して、スマートコントラクトを利用する

システム構成図

こんな感じのシステム構成を作っていくリポジトリになっています。シンプルな NFT ベースのマーケットプレイスの内容となっています。それではすすめていきましょう。

image-20220506200243263.png

Amazon Managed Blockchain で Ethereum Node の準備

aws-samples で公開されている GitHub のリポジトリを clone します。

git clone https://github.com/aws-samples/simple-nft-marketplace.git

前回の記事で作成した、Goerli ネットワークの Ethereum Node を使っていきます。

image-20220506202509699.png

2つの Endpoint はを後の手順で使うため、メモをしておきます。

image-20220506202710846.png

Contract のデプロイ

Ethereum では、スマートコントラクトとして独自のプログラムコードを動かすことが出来ます。Ethereum の場合は、Solidityと呼ばれる言語でスマートコントラクトのコードが書かれています。

今回は、リポジトリの中に Solidity で書かれているプログラムコードが準備されているので、これを使ってデプロイを進めていきます。Solidy で書かれているスマートコントラクトのコードはこちらです。
https://github.com/aws-samples/simple-nft-marketplace/blob/main/contract/contracts/SimpleERC721.sol

contractディレクトリに移動します。

cd simple-nft-marketplace/contract/

必要なモジュールをインストールします

npm install

npm install で定義されている依存関係はこちらです。hardhat ツールも定義されています。
https://github.com/aws-samples/simple-nft-marketplace/blob/main/contract/package.json

hardhat を使って、Solidity で書かれたコードをコンパイルします。artifactscache というディレクトリが作成されたら完了です。

npx hardhat compile

hardhat コマンドを使って、Amazon Managed Blockchain で作った Ethereum Node を使ってスマートコントラクトをデプロイします。Amazon Managed Blockchain の Node を使ってデプロイするときには、AWS が提供している仕組みの「Signature Version 4 (SigV4)」の署名が必要です。

今回の構成の場合は、デプロイツールの hardhat コマンドをカスタマイズする hardhat.config.js ファイルで、署名を行っている構成になっているようです。
https://github.com/aws-samples/simple-nft-marketplace/blob/main/contract/hardhat.config.js#L33

環境変数に、Node の HTTP Endpoint を指定します

export AMB_HTTP_ENDPOINT=nd-76uz24bmarcszofd6lvqm22eea.ethereum.managedblockchain.ap-northeast-1.amazonaws.com

続いて、Contract をデプロイする Owner のアカウントを作成します。以下のコマンドを実行してください。

npx hardhat account

実行例

> npx hardhat account
Address 0x75b57583CF3Ad7808C7659865aD1fE2c4EB723Aa
PrivateKey 0x111111secret111111

出力の Address はトークンの送付に必要になるアドレスで、PrivateKey は Transaction の署名に必要な秘密鍵です。AddressPrivateKey から生成されるので、1 対 1 の関係です。この AddressPrivateKey は後続の手順で必要になるので、必ずどこかに転記しておいてください。

Contract を Testnet である Goerli にデプロイするにあたって、手数料の Gas を支払う必要があります。そのため、上記で作成した Address に ETH を付与する必要があります。Goerli はテストネットなので、動作確認をしやすくするために、ETH を付与しているサイトがあります。たとえば 次の URL にアクセスして、Address を入力すると 0.05 Ether を入手できます。

image-20220506204640035.png

環境変数として、先ほど作成した Account に紐づく秘密鍵を設定します

export PRIVATE_KEY=0x111111secret111111

引き続き、Amazon Managed Blockchain に接続するための AWS IAM の権限設定を行います。新規で IAM ユーザーを作成する場合は、AmazonManagedBLockchainFullAccess ポリシーをアタッチしてください。AWS Access Key ID と AWS Secret Access Key を以下のように環境変数に設定します。

export AWS_ACCESS_KEY_ID=xxxxxxxxx
export AWS_SECRET_ACCESS_KEY=yyyyyyyyy
export AWS_DEFAULT_REGION="ap-northeast-1"

以下のコマンドで、コントラクトをデプロイします。--network amb と指定しているので、正しく署名が行われている形です。

npx hardhat run --network amb scripts/deploy-amb.js

実行例

  • Goerli ネットワークにデプロイしたスマートコントラクトに、アドレスが付与されています。
  • 0x07eCA4Fdda923601351F3D7989d13Ea2B9125acf
> npx hardhat run --network amb scripts/deploy-amb.js
Adding https:// prefix to AMB_HTTP_ENDPOINT
Adding https:// prefix to AMB_HTTP_ENDPOINT
Contract deployed at 0x07eCA4Fdda923601351F3D7989d13Ea2B9125acf

Etherscan のページ上で、Goerli ネットワークのアドレスに紐づく Contract の情報を確認可能です。Contract Create のイベントを確認できます。

image-20220508154317085.png

Lambda のデプロイ

スマートコントラクトをデプロイすることが出来たので、それを呼びだす Lambda 周辺の AWS サービスをデプロイしていきます。

以下のディレクトリに移動します。

cd simple-nft-marketplace/provision/

環境変数で利用するリージョンを設定します。

export AWS_DEFAULT_REGION="ap-northeast-1"

必要なモジュールをインストールします

npm install

/lambda ディレクトリでも同様にモジュールのインストールが必要です。以下のコマンドを実行してください。

cd lambda; npm install; cd -;

続いて、Contract をコンパイルした生成物 (前の手順で作成したもの) を /lambda/contracts にコピーします。以下のコマンドを実行してください。

cp ../contract/artifacts/contracts/SimpleERC721.sol/SimpleERC721.json lambda/contracts/.

続いて、CDK プロジェクトをビルドします。以下のコマンドを実行してください。

npm run build

続いて、必要な環境変数を設定します。Amazon Managed Blockchain のエンドポイントとデプロイした Contract のアドレスを設定します。

export AMB_HTTP_ENDPOINT=https://nd-76uz24bmarcszofd6lvqm22eea.ethereum.managedblockchain.ap-northeast-1.amazonaws.com
export CONTRACT_ADDRESS=0x07eCA4Fdda923601351F3D7989d13Ea2B9125acf

最後に、デプロイを実施します。以下のコマンドを実行してください。自分の環境では、約 6 分ほどかかりました。

cdk deploy SimpleNftMarketplaceStack

自動デプロイされた AWS サービスの主要なものを抜粋

  • Lambda Functions
  • DynamoDB
  • API Gateway
  • S3 Bucket
  • Cognito

実行例

 ✅  SimpleNftMarketplaceStack

✨  Deployment time: 347.71s

Outputs:
SimpleNftMarketplaceStack.NftApiEndpoint = https://uqtnh9wj8i.execute-api.ap-northeast-1.amazonaws.com/prod/
SimpleNftMarketplaceStack.NftApiEndpoint8C6C6AD5 = https://uqtnh9wj8i.execute-api.ap-northeast-1.amazonaws.com/prod/
SimpleNftMarketplaceStack.UserPoolClientId = secret
SimpleNftMarketplaceStack.UserPoolId = ap-northeast-1_Tkv3OnQDj

Lambda がどのように Contract を呼びだしているのか

Lambda のデプロイが出来たので、どのように Lamnda Function が Ethereum のコントラクトを呼びだしているのかを見ていきます。Ethereum は勉強中のため、誤りが無いように気を付けていますが、もし誤りがあったらすいません。

まず、スマートコントラクトを npx hardhat compile のコマンドでコンパイルしたときに、/contract/artifacts/contracts/SimpleERC721.sol/SimpleERC721.json のファイルが生成されました。これは、コントラクトがどのようなメソッドや引数を持っているのか、インターフェースを定義しているファイルになっています。このファイルは、Contract Application Binary Interface(ABI) に関連するファイルになっています。ABI については、次の Blog がわかりやすいです。
https://y-nakajo.hatenablog.com/entry/2019/05/14/182854

Lambda Function の共通的なライブラリとして、context.ts ファイルがあります。このファイルの中で、コンパイル時に生成された SimpleERC721.jsonファイルを読み込んでいます。それが次のコードの部分です。
https://github.com/aws-samples/simple-nft-marketplace/blob/main/provision/lambda/lib/context.ts#L6

その後に、ABI を使ったオブジェクトを生成しています。
https://github.com/aws-samples/simple-nft-marketplace/blob/main/provision/lambda/lib/context.ts#L33

実際に Ethereum ネットワークにトランザクションを流す関数はこちらです。この関数の中で、先ほどの contest.ts を import しています。
https://github.com/aws-samples/simple-nft-marketplace/blob/main/provision/lambda/purchaseJob.ts#L1

const tx = contract.methods.purchase(paramsJob.tokenId); のコードで、スマートコントラクトのメソッドである purchase を呼びだしています。
https://github.com/aws-samples/simple-nft-marketplace/blob/main/provision/lambda/purchaseJob.ts#L18

その purchase メソッドは、Solidy 言語によって以下のコードがあり、このインターフェースを使って呼び出しています。
https://github.com/aws-samples/simple-nft-marketplace/blob/main/contract/contracts/SimpleERC721.sol#L62

かなり細かい部分になるので、また興味のある時に見直してもらえると良いと思います。

フロントエンドの動作確認

スマートコントラクトと、それを呼びだす Lambda などを準備できました。次にフロントエンド側を用意していきます。以下のディレクトリに移動します。

cd simple-nft-marketplace/marketplace/

ヒアドキュメントを使って、以下のファイルを作成します。環境に合わせて値を変更してください。

cat <<EOF > .env.local
VUE_APP_AWS_REGION=ap-northeast-1
VUE_APP_API_ENDPOINT=https://uqtnh9wj8i.execute-api.ap-northeast-1.amazonaws.com/prod
VUE_APP_USER_POOL_ID=ap-northeast-1_Tkv3OnQDj
VUE_APP_USER_POOL_WEB_CLIENT_ID=secret
EOF

続いて、以下のコマンドを実行して、必要なモジュールをインストールします。

npm install

最後に、以下のコマンドを実行して、ローカルでフロントエンドを起動テストします。localhost:8080 でリッスンします。

npm run serve

ブラウザの http://localhost:8080 にアクセスしてください。サイトが表示されていれば成功です。

image-20220506213025604.png

Create account で、Cognito のユーザーを作成します

image-20220506213106628.png

メールに code が届くので入力

image-20220506213308389.png

右上の Account を押す

image-20220506220058719.png

新たに作成したユーザーに、Goerli ネットワークのアカウントが作成されています。

image-20220506220137984.png

フロントエンドのデプロイ

ローカルで動作確認が出来たので、このフロントエンドを CloudFront + S3 にデプロイします。以下のディレクトリに移動します。

cd simple-nft-marketplace/marketplace/

build

npm run build

さらに、以下のディレクトリに移動します。

cd simple-nft-marketplace/provision/

環境変数を設定

export AWS_DEFAULT_REGION="ap-northeast-1"

フロントエンドをデプロイします。

cdk deploy SimpleNftMarketplaceFrontendStack

実行例

  • CloudFront の URL が Output に表示されます。
Outputs:
SimpleNftMarketplaceFrontendStack.CfnEndpoint = https://yoursite.cloudfront.net

✨  Total time: 325.95s

実際にアクセスしてみると、正常にフロントエンドが表示されます。

image-20220506220058719.png

NFT の作成

デプロイしたフロントエンドをつかって、NFT を作成することができます。ただ、作成するためには ETH が必要です。初期状態では、Balance (ETH) が 0 なので、新たに付与します。Account ページで、その Account の Address をメモっておきます。

image-20220506220137984.png

再び以下サイトで付与できます。
URL : https://goerlifaucet.com/

0.05 Eth が付与されました。

image-20220508123619605.png

NFT の作成として、Create NFT を押します。

image-20220508133810616.png

以下のパラメータを入れて、Create を押します。

  • NFT として紐づける画像をアップロード
  • NFT のトークンとしてのタイトルと説明を入れる

image-20220508134039817.png

NFT が作成できました。この NFT に対して、値段も付けられます。

image-20220508134209791.png

NFT を作成したことにより、Accout の ETH が減っています。

image-20220508134306869.png

検証を通じてわかったこと

  • フロントエンドから直接 Amazon Managed Blockchain の Ethereum Node にリクエストを投げるのは推奨されていないため、Lambda などのコンピュートリソースを間に挟むことを検討すると良い。

    • 以下の AWS Document にも記載があり

    • https://docs.aws.amazon.com/ja_jp/managed-blockchain/latest/ethereum-dev/ethereum-json-rpc.html#supported-json-rpc

    • The Signature Version 4 signing process requires credentials associated with an AWS account. Some examples in this section export these sensitive credentials to the shell environment of the client. Only use these examples on a client running in a trusted context. Do not use these examples in an untrusted context, such as in a web browser or mobile app. Client credentials should never be embedded in user-facing applications. To expose an Ethereum node on Managed Blockchain to anonymous users visiting from trusted web domains, you can set up a separate endpoint in Amazon API Gateway backed by a Lambda function that forwards requests to your node using the proper IAM credentials.

  • スマートコントラクトは、Amazon Managed Blockchain を介して、Ethereum Netwotk にデプロイが出来る

    • デプロイしたスマートコントラクトにもアドレスが付与されており、ネットワーク上で利用可能となる
  • スマートコントラクトを外部のプログラムから呼び出す際には、Contract Application Binary Interface(ABI) を利用して呼び出す

参考URL

Goerli Etherscan
https://goerli.etherscan.io/

AWS Samples
https://github.com/aws-samples/simple-nft-marketplace

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2