Skip to content

Sample code and reference architecture to deploy an NFT on the Ethereum blockchain using Amazon Managed Blockchain

License

Notifications You must be signed in to change notification settings

aws-samples/nft-deployment-amazon-managed-blockchain

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

29 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Deploy NFT on Ethereum using Amazon Managed Blockchain

This repository contains sample code to deploy ERC-721 smart contracts on the Ethereum blockchain network using Amazon Managed Blockchain as a geth node. It provides a reference architecture for deploying a contract, minting NFT tokens and querying token owners using serverless components

The repo is structured as follows:

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

Reference architecture

Architecture

Pre-requisites

  1. An AWS account with a VPC and a public subnet. Ensure you have permissions to make objects in the S3 bucket public
  2. AWS SAM CLI : Install the AWS SAM CLI.
  3. Node.js: Install Node.js 14, including the npm package management tool.
  4. Docker: Install Docker community edition.

Deploy Ethereum node and Serverless components

An AWS Serverless Application Model (SAM) template is used to deploy the stack

cd serverless/

sam build

....
Building codeuri: /Users/pravincv/Nft-amb-repo/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

On success completion of the build, deploy the stack

sam deploy --guided --capabilities CAPABILITY_NAMED_IAM

Input the parameter values and confirm changes to deploy

Stack Name [nft-stack]:       
AWS Region [ap-southeast-1]:   -  region where Amazon  Managed Blockchain is supported
Parameter pEmail [name@example.com]:  - email id that will receive Amazon SNS notifications 
Parameter pSubnetId [subnet-xxxxxxx]:  - public subnet where the AWS Fargate task will run
Parameter pNftBucketName [nftmetadata]: - bucket where NFT metadata will be stored
Parameter pConfirmationBlocks [50]:     - number of confirmations on the blockchain, to wait for
Parameter pClusterName [nftcluster]:    -  AWS ECS cluster name
Parameter pContainerName [rinkeby]:     -  name of container
Parameter pRepositoryName [nftrepository]: - AWS ECR where the Docker images will be stored
Parameter pIpRangeWhitelist [**.***.***.**/**]:  - IP address CIDR that is allowed to invoke the API
Parameter pNetworkId [n-ethereum-rinkeby]:      - default network is rinkeby. Can choose ropsten if desired
Parameter pInstanceType [bc.t3.large]:         - choose desired instance size
Parameter pAvailabilityZone [ap-southeast-1a]: - choose availability zone based on region
  	Confirm changes before deploy [Y/n]:           - confirm changes Y
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]:    - choose Y
Save arguments to configuration file [Y/n]: -choose Y
SAM configuration file [samconfig.toml]:  - default file to save the samconfig
SAM configuration environment [default]:   

The following resources are created on deployment

SAM

This creates the following resources

  • nftmain - AWS Lambda function that provides APIs to deploy an ERC-721 contract to the Ethereum rinkeby test network, mint a new token as well get the owner of a specified token minted. The deploy API sends out an SNS message on successful deployment of a contract
  • invokeFargateTask - This Lambda function is triggered by the AWS SNS message sent by the nftmain Lambda. On being triggered, it invokes a task that awaits until the rinkeby blockchain has confirmed the deployment confirmationBlocks (passed as an environment variable) number of times
  • ethTxnTopic - Amazon SNS topic to which nftmain Lambda published the transaction id on deployment of a contract
  • ethConfirmationTopic - Amazon SNS topic to which the task publishes a message on completing confirmationBlocks number of confirmations on the Rinkeby network
  • cluster and taskDefinition - cluster and task definition that provides the compute for the 'confirmation' logic
  • nftapi - api created and exposed via the api gateway for users to invoke HTTP POST
  • ecrRepository - repository where the docker image for the task is stored

To complete the serverless stack, create a Docker image and push to the ecrRepository by building, tagging and pushing the image as below.

cd serverless/

1. aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <account id>.dkr.ecr.<region>.amazonaws.com
    
2. docker build -t nftrepository .

3. docker tag nftrepository:latest <account>.dkr.ecr.<region><.amazonaws.com/nftrepository:latest

4. docker push <account>.dkr.ecr.<region>.amazonaws.com/nftrepository:latest
    
    

To create a transaction on the Ethereum Rinkeby network, a private-public key pair is required. Generate the private key and upload to AWS SSM Parameter Store as an encrypted string as 'ethSystemKey'. - ensure the string excludes the first 2 characters, 0x of the privatekey . Add some ethereum test tokens for the rinkeby network by entering the public key https://faucets.chain.link/rinkeby and requesting ethereum test tokens. Please note that for AWS SSM Paramter Store might not be sufficient for some cases where wallets bear real funds.

EthereumKey

Deploying a test contract, minting an NFT and checking token ownership

Now we are ready to deploy an ERC-721 smart contract to the network.

├── 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
    
└── txconfirmation
    └── index.js
    

The contract to be deployed is stored in the nftmain directory under NFTSamples.

We'll be using curl -X POST to deploy and mint the NFT. Obtain the API endpoint i.e InvokeURL from Amazon API Gateway ->APIs > Stages on the AWS Console.

cd serverless/test-events 

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

Edit the deploy.json file to fill up the needed values.

> cat deploy.json

{"requestType": "deploy",
"tokenName": "coolnft",  # name of nft
"tokenTicker": "SYMB",   # symbol
"metadataFilename": "metadata.json", # name of metadata file
 "metadata":{                #metadata associated with nft
  "description": "useful description",     
  "image": "<url of the image, preferably an IPFS hash>",
  "name": " coolnft"
}}
> curl -X POST https://<api> .execute-api.<region>.amazonaws.com/nftapi -H "Content-Type: application/json" -d @deploy.json

The deploy command returns a transaction id hash and the contract address.

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

 > cat mint.json
 
 {"requestType": "mint",
"contractAddress": "0x8A3Ce65B266E8DE37Fe7d2e4911CA4578B5a7445",   -> address of the contract address of the deployed contract
"mintAddress": "0x905b8699E611a5F1f74BF5Cc3cCa2aCd175ec0c0"        -> public key of any another wallet/address
}
 
 > curl -X POST https://<api>.execute-api.<region>.amazonaws.com/nftapi -H "Content-Type: application/json" -d @mint.json

The response contains the transaction id ash

{"Mint Tx Hash":"0x960080892462ea76a90a5a00fe88ebc5d85d0b84d75e781ca5aa14e5829a0a14"}
 > cat getowner.json
 {"requestType": "mint",
"contractAddress": "0x8A3Ce65B266E8DE37Fe7d2e4911CA4578B5a7445",   -> address of the contract address of the deployed contract
"tokenID": "0"        -> ID of the token that was minted previously
}

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

The response provides the address of the owner for whom the token was minted.

{"Owner address":"0x905b8699E611a5F1f74BF5Cc3cCa2aCd175ec0c0"}

Security

See CONTRIBUTING for more information.

License

This library is licensed under the MIT-0 License. See the LICENSE file.

About

Sample code and reference architecture to deploy an NFT on the Ethereum blockchain using Amazon Managed Blockchain

Topics

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published