Amazon Web Services ブログ

Amazon Managed BlockchainでNFTをデプロイしてみよう

このブログは、Pravinchandra Varma と Forrest Colyer によって書かれた Mint and deploy NFTs to the Ethereum blockchain using Amazon Managed Blockchainを翻訳したものです。

Web 3.0プロトコルの実用化により、分散型金融(DeFi)およびデジタル資産のトークン化の分野ではパブリックおよびプライベートなブロックチェーン上で爆発的なアプリケーションの普及が進んでいます。ノンファンジブルトークン(NFT)は、デジタル資産の所有権と真正性の証明を提供する方法として、ますます人気が高まっています。多くの大企業、特に大規模な知的財産を保有する企業は、NFTの形でデジタルアイテム、収集品、コンテンツ、モーメントを用いた新しい顧客体験や製品提供の構築を目指しています。

ファンジビリティとは、ある資産を同じ種類の別の資産と等価に交換できることを指します。例えば米ドル紙幣は、1ドルを別の1ドル紙幣と交換することができ、どのドル紙幣でも価値は同じです。一方、ノンファンジブルな資産は、例えば野球カードのような収集品のように、ユニーク性と希少性に基づいて異なる方法で評価されます。

NFTの作成は必要な機能を備えたスマートコントラクトを Ethereumネットワークのようなパブリックブロックチェーンにデプロイすることで実現する必要があります。現在ERC-721を含む複数のNFTスマートコントラクトのスタンダードがあり、このブログでデプロイ方法を学びます。

Amazon Managed Blockchainを使用すると、NFT開発者はブロックチェーントランザクションの中継やブロックチェーンデータの状態をクエリしたりするためのEthereumノードの運用や保守を心配することなく、スマートコントラクト開発に集中することができます。

NFTの概要

Managed Blockchainを使ったNFTの構築とEthereumへのデプロイを実演する前に、NFTの重要なコンセプトとアプリケーションをおさらいしておきます。

Ethereum NFTの最も一般的な標準はERC-721で、ウォレット、ブローカー、またはオークションアプリケーションがあらゆるNFTで動作することを可能にするインターフェースを規定しています。その他の有名な標準には、ファンジブルトークンのためのERC-20とセミファンジブルトークンのためのERC-1155があります。Ethereumでは、トークンはSolidityで書かれたスマートコントラクトであり、NFT開発者は、トークン所有者がさまざまな方法でスマートコントラクトを利用できるようにカスタマイズすることができます。

NFTには以下のような幅広いユースケースがあります:

  • デジタルアート – NFTアート市場は、2021年第3四半期までに35億ドル以上の売上を記録しています。サザビーズのようなオークションハウスがNFT専用のマーケットプレイスを立ち上げています。
  • スポーツ記念品 – NFTは、物理的なカードコレクションのようなデジタル収集品を完全にデジタルなフォーマットで表現することができます。スポーツ団体は、スポーツの象徴的な瞬間をNFTとしてトークン化することで、ファンのエンゲージメントを高めることができます。
  • ゲーム – ブロックチェーンを利用したゲームやゲーム内でのコレクターズアイテムの購入は、ゲーム会社の収益源として成長しています。
  • イベントチケット – アーティストやイベント運営者は、不正防止のためのチケットや、思い出深い過去のコンサート体験を一箇所に閲覧できる場所を提供することで、ファンとの関係を深めることができます。
  • サプライチェーン – サプライチェーンの様々なタッチポイントにおけるトレーサビリティ、透明性、および所有権の証明を改善することで、企業がESG報告要件を満たすために役立ちます。
  • 特許 – 流動性の低い知的財産を特許所有者がトークン化し、出所と真正性を保証した上で取引できるようにすることができます。

ソリューションの概要

このリファレンスアーキテクチャでは、NFTの作成者がERC-721のスマートコントラクトをEthereum Rinkebyテストネットにデプロイし、NFTをミントします。

この例では、NFT作成者はManaged Blockchainで動作するEthereumのGeth ノードを介してEthereumのテストネットであるRinkebyで取引を行います。NFTの作成を開始するには、JSON RPCリクエストを Amazon API Gateway REST API エンドポイントに送信し、そのエンドポイントはリクエストをAWS Lambdaに転送します。
プロキシとして構成された Lambda は、デプロイ、ミントとトークンの所有権を取得するロジックを実装しています。このロジックはリクエストを Managed Blockchain HTTP エンドポイントに転送し、署名されたトランザクションをEthereum ブロックチェーンに送信します。ネットワークに送信されたトランザクションはネットワークトラフィックと支払われたガス料金に応じて、確認されるまでに何分もかかる場合があります。トランザクションが取り消されるリスクがないように、ブロックチェーン上で確認が完了するまでの一定数のブロックが進行するまで追加で待つ(設定可能なパラメータ)ことを推奨します。Lambdaのタイムアウトを回避するために、 AWS Fargate タスクがブロックチェーンをポーリングし、必要な数のブロックが進行したことをチェックします。チェックが完了すると、Fargateは Amazon Simple Notification Service (Amazon SNS)のメールメッセージをNFT作成者に送信します。
以下の手順でソリューションをデプロイします:

  1. 事前環境セットアップ
  2. Ethereumノード、API Gateway、Lambda、Fargate、SNSトピック、Amazon Simple Storage Service (Amazon S3)バケットを含む、NFT を発行するための仕組みの構築
  3. JSON RPCコマンドの送信、スマートコントラクトのデプロイとトークンのミント

コードのリポジトリはGitHubで公開されています。

事前環境準備

このチュートリアルでは、以下の前提条件を満たしている必要があります。

まずGitHubリポジトリをクローンして開始します。

git clone https://github.com/aws-samples/nft-deployment-amazon-managed-blockchain.git

Ethereumノードとサーバレスコンポーネントのデプロイ

AWS Serverless Application Model (AWS SAM)のテンプレートを使ってスタックをデプロイしていきます。

├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── images
└── serverless

cd serverless/

sam build

....
Building codeuri: serverless/lambdas/nftmain runtime: nodejs14.x metadata: {} architecture: x86_64 functions: ['nftmain']
Running NodejsNpmBuilder:NpmPack
Running NodejsNpmBuilder:CopyNpmrc
Running NodejsNpmBuilder:CopySource
Running NodejsNpmBuilder:NpmInstall
Running NodejsNpmBuilder:CleanUpNpmrc

Build Succeeded

ビルドが完了したら、スタックをデプロイします:

sam deploy --guided --capabilities CAPABILITY_NAMED_IAM

パラメータ値を入力して変更を確認したらデプロイします:

Stack Name [nft-stack]: #スタックの名前 
AWS Region [ap-southeast-1]: # AWSリージョン Parameter pEmail [name@example.com]: # Amazon SNSメッセージを受信するメールアドレス 
Parameter pSubnetId [subnet-xxxxxxx]: # AWS Fargate taskが動作するパブリックサブネットのID 
Parameter pNftBucketName [nftmetadata]: # NFTメタデータを格納するバケット 
Parameter pConfirmationBlocks [50]: # トランザクション待機のための確認回数 
Parameter pClusterName [nftcluster]: # Amazon ECSクラスターの名前 
Parameter pContainerName [rinkeby]: # コンテナの名前 Parameter pRepositoryName [nftrepository]: # ECR用のDockerイメージ名
Parameter pIpRangeWhitelist [**.**.**.**/**]: # ホワイトリスト指定時はIP CIDRブロックを記載 
Parameter pNetworkId [n-ethereum-rinkeby]:   # デフォルトネットワークはRinkeby 
Parameter pInstanceType [bc.t3.large]: # 希望するインスタンスサイズ 
Parameter pAvailabilityZone [ap-southeast-1a]:# リージョンに基づいたAZを指定 

Confirm changes before deploy [Y/n]: # 変更を確認する Y 
Allow SAM CLI IAM role creation [Y/n]: # Yを選択(SAMにテンプレート内のリソースに接続するロールの作成権限が必要です) 
Save arguments to configuration file [Y/n]: # Yを選択 
SAM configuration file [samconfig.toml]: # samconfigのデフォルト名 
SAM configuration environment [default]: 

AWS SAMのデプロイにより後のスクリーンショットに示すように、 AWS CloudFormation スタックのチェンジセットが作成されます。

デプロイすると以下のリソースが作成されます。:

  • Ethereumノード – Rinkebyテストネットワークに接続されたManaged Blockchain Ethereumノード。
  • nftMetadataBucket – NFTのメタデータファイルを格納するS3バケット。
  • Nftmain – Ethereum Rinkeby テストネットワークに ERC-721 コントラクトをデプロイし、新しいトークンをミントし、ミントされた指定トークンの所有者を取得するための API を提供する Lambda 関数です。コントラクトのデプロイに成功すると、SNSメッセージが公開されます。
  • invokeFargateTask – このLambda関数は、nftmain Lambda関数によってPublishされたSNSメッセージによってトリガされます。これは、Rinkeby ブロックチェーンがコントラクトデプロイメントトランザクションを一定のブロック数に進行するまで(ただし設定可能)待機する Fargate タスクを起動します。デフォルトの確認回数は50回に設定されています。
  • ethTxnTopic – コントラクトのデプロイに成功した際に、nftmain関数がトランザクションIDを発行するSNSのトピック。
  • ethConfirmationTopic – Rinkebyネットワーク上で50ブロック進んだことの確認が完了した時に、Fargateタスクがメッセージを発行するSNSトピック。
  • cluster and taskDefinition – Confirmation Blockの計算を提供するFargateクラスタとタスクの定義。
  • Nftapi – NFTクリエーターがJSON RPCリクエストを送信するためのAPI Gateway REST APIエンドポイント。
  • ecrRepository – Dockerイメージを保存するための Amazon Elastic Container Registry (Amazon ECR)

Dockerイメージの作成とAmazon ECRへのPush

デプロイを完了するには、以下のイメージをビルド、タグ付け、プッシュしてDockerイメージを作成し、Amazon ECRにプッシュします:

aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account id>.dkr.ecr.<region>.amazonaws.com
docker build -t nftrepository .
docker tag nftrepository:latest <account>.dkr.ecr.<region>.amazonaws.com/nftrepository:latest
docker push <account>.dkr.ecr.<region>.amazonaws.com/nftrepository:latest

トランザクションに署名するための秘密鍵の作成

Ethereum Rinkebyネットワークでトランザクションを作成するには、秘密鍵と公開鍵のペアが必要です。このような場合は一般的な Ethereum ライブラリである Web3Ethersを使用して、プログラム的に独自の Ethereum ウォレットを作成することができます。
このウォレットは実際の資金で使用しないように特に注意してください。
秘密鍵を生成し AWS Systems Manager パラメータストアethSystemKeyという名前で暗号化された文字列としてアップロードします。秘密鍵の最初の2文字、0xを除いたセキュアな文字列値にします。

Rinkeby faucetに公開鍵を渡してテストトークンをリクエストすることで、Rinkeby ネットワークの少量のテスト用の通貨を得ます。特に秘密鍵には注意が必要で、AWS Systems Manager は、場合によっては実際の資金を保有するウォレットとして適切でない可能性があります。注意:上記のRinkeby faucetからテスト用の通貨をリクエストするのが難しい場合、Chainlink Faucet を使って少量のテストネットイーサを取得することができます。

テストコントラクトのデプロイ、NFTのミント、トークン所有権のチェック

これで、ERC-721スマートコントラクトをネットワークにデプロイする準備が整いました。
デプロイされるコントラクトは、NFTSamples: の下のnftmainディレクトリに格納されています。

.
├── NFTSamples
│   ├── build
│   │   └── NFT_BaseURI.json
│   └── contracts
│       ├── NFTSample.sol
│       └── NFT_BaseURI.sol
├── aws-web3-http-provider.js
├── deploy_contract.js
├── get_owner.js
├── index.js
├── mint_nft.js
├── package-lock.json
├── package.json
└── utils.js

NFTのデプロイとミントには、curl -X POSTを使用します。API Gatewayのコンソールから、APIページのStagesの下にあるAPIエンドポイント(InvokeURL)を取得します。

cd serverless/test-events 

serverless/test-events
├── deploy.json
├── getowner.json
└── mint.json

1. deploy.json ファイルを編集し、NFT メタデータの値を入力します:

cat deploy.json

{
"requestType": "deploy",
"tokenName": "coolnft",
"tokenTicker": "SYMB",
"metadataFilename": "metadata.json",
"metadata": {
       "description": "useful descriptiom",
       "image": "<url of the image, eg. an IPFS URL hash>",
       "name": " My cool nft"
      }
}

2. Rinkebyのネットワークにコントラクトを展開します:

curl -X POST https://<api>.execute-api.<region>.amazonaws.com/nftapi -H "Content-Type: application/json" -d @deploy.json

deploy 呼び出しは、トランザクション ID のハッシュとコントラクトアドレスを返します:

{"Transaction id":"0x6b2af81c34055b678e5a8ae401f508fcbf950341df7e55e7372e80f75faf8afc","ContractAddress":"0x8A3Ce65B266E8DE37Fe7d2e4911CA4578B5a7445"}

3. deployコマンドで返されたコントラクトアドレスを操作してトークンをミントします。

mintAddress はトークンの所有権が移転される公開鍵/ウォレットアドレスです。

cat mint.json

{"requestType": "mint",
"contractAddress": "0x8A3Ce65B266E8DE37Fe7d2e4911CA4578B5a7445",
"mintAddress": "0x905b8699E611a5F1f74BF5Cc3cCa2aCd175ec0c0"
}

curl -X POST https://<api>.execute-api.<region>.amazonaws.com/nftapi -H "Content-Type: application/json" -d @mint.json

レスポンスにはトランザクション ID のハッシュ値が含まれます:

{"Mint Tx Hash":"0x960080892462ea76a90a5a00fe88ebc5d85d0b84d75e781ca5aa14e5829a0a14"}

4. ミントされたトークンの所有者のアドレスを取得します:

 cat getowner.json

{"requestType": "mint",
"contractAddress": "0x8A3Ce65B266E8DE37Fe7d2e4911CA4578B5a7445”, 
"tokenID": "0"
}

curl -X POST https://<api>.execute-api.<region>.amazonaws.com/nftapi -H "Content-Type: application/json" -d @getowner.json

トークンをミントした所有者のアドレスが応答されます:

{"Owner address":"0x905b8699E611a5F1f74BF5Cc3cCa2aCd175ec0c0"}

環境のクリーンナップ

完了したら、今後の課金を避けるため、展開したリソースを削除します:

  1. nftmetadata S3バケットを空にします
  2. スタックで作成された Amazon Elastic Container Service (Amazon ECS) リポジトリ内のすべてのDockerイメージを削除します。
  3. パラメータストアから ethSystemKey パラメータを削除します。
  4. 最後にデプロイされたスタックを削除します。
> cd serverless
> sam delete nft-stack

まとめ

この投稿では、Amazon Managed Blockchain を使用して、NFT 用の ERC-721 スマートコントラクトを Ethereum ブロックチェーン上にデプロイする手順を説明しました。このアーキテクチャでは、NFTの作成者のためのバックエンド処理の仕組みを取り扱いました。

今後の記事では、NFTクリエイターがお客様とやり取りするための分散型アプリケーションとNFTストアのフロントエンドをセットアップする方法を紹介する予定です。

このブログは、パートナーソリューションアーキテクトの毛利元三が翻訳しました。原文はこちらです。