Deploy a Smart Contract on Polygon Mainnet with AMB Access and Hardhat Ignition

7 minute read
Content level: Foundational
2

Learn how to deploy a smart contract on Polygon Mainnet with Amazon Managed Blockchain (AMB) Access and Hardhat Ignition

Introduction

In this tutorial, you'll learn how to create, compile, and deploy a simple smart contract on Polygon Mainnet using Amazon Managed Blockchain (AMB) Access. Hardhat Ignition is a declarative system that is utilized to handle the compilation and deployment of smart contracts. This tutorial is ideal for developers beginning their journey in blockchain development.

Note

In line with Polygon's deprecation of Mumbai announced on March 27 2024, we will cease support of AMB Access Mumbai on April 15 2024. AMB Access Polygon Mainnet will continue to be available as Public Preview. We will continue evaluating support for Amoy Testnet in AMB Access. Please contact us if you would like to learn more.

Prerequisites
  • Node.js (version 18 or above)
  • A text editor (such as Visual Studio Code)
  • Basic knowledge of Polygon and smart contracts
  • Installation of the AWS Command Line Interface (CLI).
    • Run the command aws configure to set the variables for your IAM User’s Access Key ID, Secret Access Key, and Region.
      • Ensure that this User has the appropriate IAM permissions for AMB Access Polygon. For this tutorial, you can use the AmazonManagedBlockchainFullAccess managed policy.

Step 1: Setting up the project

  1. Create a new directory for your project and change into it by running the following command in your terminal:
mkdir HelloWorldContract && cd HelloWorldContract
  1. Run the following command to initialize a new Node.js project:
npm init -y
  1. Install Hardhat Ignition and other necessary dependencies by running this command:
npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-ignition-ethers web3 @aws-sdk/client-managedblockchain dotenv
  1. Set up a Hardhat project by executing this command. Choose the option, Create an empty hardhat.config.js:
npx hardhat init

Step 2: Write the Smart Contract

  1. Create a contracts directory containing a file named HelloWorld.sol at the root of your project with the following command:
mkdir contracts && touch contracts/HelloWorld.sol
  1. Copy the following code into the HelloWorld.sol file:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract HelloWorld {
    string public greeting;

    constructor() {
        greeting = "Hello, World!";
    }

    function setGreeting(string memory _greeting) public {
        greeting = _greeting;
    }

    function getGreeting() public view returns (string memory) {
        return greeting;
    }
}

Step 3: Environment variables setup

The following script automates the following tasks:

  1. Retrieval or creation of an AMB Polygon Mainnet Accessor token.
    • The script first checks for any existing Polygon Mainnet Accessor tokens in your AWS account. If an available token is found, it will be reused. Otherwise, a new Accessor token will be created.
  2. Configuration of an AMB Access Polygon Mainnet endpoint with your Accessor token.
    • Your configured endpoint will allow you to make JSON-RPC calls to Polygon Mainnet with web3.js.

Warning: Never share or expose your account’s private key or Accessor token publicly. It is important to note that the hardhat.config.js file is utilizing a locally stored private key and should not be used in production environments, as it poses a security risk.

Create a new file (e.g init.js) in the root of your directory and copy the following code:

const fs = require('fs').promises;
const { Web3 } = require('web3');
const { ManagedBlockchainClient, CreateAccessorCommand, ListAccessorsCommand, GetAccessorCommand } = require("@aws-sdk/client-managedblockchain");

const network = "POLYGON_MAINNET";

async function getExistingAccessor(client) {
    try {
        const response = await client.send(new ListAccessorsCommand({ NetworkType: network }));

        for (const accessor of response.Accessors) {
            if (accessor.Status === "AVAILABLE") {
                const accessorResponse = await client.send(new GetAccessorCommand({ AccessorId: accessor.Id }));
                return accessorResponse.Accessor;
            }
        }
    } catch (error) {
        console.error('Error retrieving existing Accessor. Please double check your AWS credentials.', error);
        throw error;
    }
    return null;
}

async function createAccessor() {
    const client = new ManagedBlockchainClient();
    const existingAccessor = await getExistingAccessor(client);

    if (existingAccessor) {
        console.log('Using existing Accessor token.');
        return {
            billingToken: existingAccessor.BillingToken
        };
    }
    else {
        console.log('Creating a new Accessor token.');
    }

    try {
        const input = {
            AccessorType: "BILLING_TOKEN",
            NetworkType: network,
        };
        const command = new CreateAccessorCommand(input);
        const response = await client.send(command);
        return {
            billingToken: response.BillingToken,
        };
    } catch (error) {
        console.error('Error creating Accessor token:', error);
        throw error;
    }
}

async function main() {
    try {
        console.log('Creating or retrieving AMB Access Polygon Accessor token...');
        const accessor = await createAccessor();
        const accessEndpoint = `https://mainnet.polygon.managedblockchain.us-east-1.amazonaws.com?billingtoken=${accessor.billingToken}`;
        const account = 'YOUR-PRIVATE-KEY';
        const dataToSave = `PRIVATE_KEY=${account}\nAMB_ACCESS_POLYGON_MAINNET=${accessEndpoint}`;
        await fs.writeFile('.env', dataToSave);
        console.log('Accessor token created or retrieved. Details saved to .env file.');
    } catch (error) {
        console.error('Setup failed:', error);
    }
}

main();

Execute the script by running:

node init.js

Your endpoint for AMB Access Polygon has been securely stored in a generated .env file.

Note: Modify the placeholder PRIVATE_KEY variable in the .env file. Make sure that your private key starts with the 0x prefix.

Step 4: Create the Hardhat Ignition Module

  1. Setup the deployment module directory in the root of your project with the following command:
mkdir -p ignition/modules && touch ignition/modules/DeployHelloWorld.js
  1. Copy the following code into the DeployHelloWorld.js file:
const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules");

module.exports = buildModule("DeployHelloWorld", (m) => {
    const helloWorld = m.contract("HelloWorld", []);

    return { helloWorld };
});
  1. Replace the hardhat.config.js file contents with the following code:
require("dotenv").config();
require("@nomicfoundation/hardhat-ignition-ethers");

module.exports = {
  solidity: "0.8.19",
  networks: {
    polygon: {
      url: process.env.AMB_ACCESS_POLYGON_MAINNET,
      // ONLY USE AN ACCOUNT ON MAINNET THAT HAS A SMALL AMOUNT OF FUNDS
      accounts: [process.env.PRIVATE_KEY]
    },
  },
  ignition: {
    timeBeforeBumpingFees: 1000,
    maxFeeBumps: 100,
    blockPollingInterval: 20000
  },
};

Step 6: Compile and deploy your smart contract

  1. Run the following command to compile and deploy your smart contract:
npx hardhat ignition deploy ignition/modules/DeployHelloWorld.js --network polygon
  1. Save your contract’s address in the .env file:
CONTRACT_ADDRESS=your-contract-address
  1. By running the following command, you will be taken to the contract page on the Polygon blockchain explorer:
source .env && open https://polygonscan.com/address/$CONTRACT_ADDRESS

With the successful deployment of your smart contract, explore Interact with your Smart Contract on Polygon Mainnet with Amazon Managed Blockchain (AMB) Access to learn how to read from and write data to your contract.

Optional: Verifying your contract on Polygon Scan

Important: If your smart contract's code is identical to the one used in this tutorial and has not been altered, automatic verification may occur. This is due to there being an existing similar contract on Polygon Mainnet.

If the contract was modified from the example or you want to verify it yourself, then follow the instructions below

  1. You first need to obtain an API Key by visiting the Polygon Scan website.
  2. If you're not registered, create an account, or log in if you already have one.
  3. In the account dashboard, go to the "API Keys" section.
  4. Click on "Add" to generate a new API key.
  5. Name your key for easy identification, such as "AMB Access Hardhat". After creation, the API key will be listed on the page.
  6. In your project's root directory, locate your .env file.
  7. Add a new variable named VERIFY_KEY and assign your Polygon Scan API key as its value:
VERIFY_KEY=your-polygon-scan-api-key

Integrate the VERIFY_KEY from your .env file into the hardhat.config.js file to use it with Polygon Scan:

require("dotenv").config();
require("@nomicfoundation/hardhat-ignition-ethers");

module.exports = {
  solidity: "0.8.19",
  networks: {
    polygon: {
      url: process.env.AMB_ACCESS_POLYGON_MAINNET,
      // ONLY USE AN ACCOUNT ON MAINNET THAT HAS A SMALL AMOUNT OF FUNDS
      accounts: [process.env.PRIVATE_KEY]
    },
  },
  ignition: {
    timeBeforeBumpingFees: 10 * 1000,
    maxFeeBumps: 100,
    blockPollingInterval: 20000
  },
  etherscan: {
    apiKey: process.env.VERIFY_KEY,
  },
};

Run the following command to verify your smart contract:

npx hardhat ignition verify chain-137

Conclusion

This tutorial guided you through the deployment of a smart contract on Polygon Mainnet, utilizing Amazon Managed Blockchain (AMB) Access Polygon and Hardhat Ignition. Remember to prioritize security, especially with private keys and your Accessor token.

Please leave a comment below if you have any questions. If you would like to learn more about AMB Access Polygon, you can refer to the documentation.

profile pictureAWS
EXPERT
published 3 months ago1262 views