This guide covers environment setup, contract deployment, and interaction with Plasma’s EVM compatible testnet using Hardhat. It assumes basic familiarity with Ethereum tooling and smart contract development.

Prerequisites

  • Node.js 16+
  • Basic knowledge of Ethereum development
  • Browser wallet (e.g., MetaMask)

Environment Setup

Use Hardhat to build and deploy contracts.

Hardhat Setup

  1. Create a new project directory and initialize:

    mkdir my-plasma-project
    cd my-plasma-project
    npm init -y
    npm install --save-dev hardhat @nomicfoundation/hardhat-toolbox
    npm install dotenv
    npx hardhat init
    
  2. Follow the steps to create a JavaScript project. Save the project wherever you want. You likely don’t need a .gitignore file for this quickstart.

  3. Configure hardhat.config.js for Plasma testnet:

    require("@nomicfoundation/hardhat-toolbox");
    require("dotenv").config();
    
    /** @type import('hardhat/config').HardhatUserConfig */
    module.exports = {
      solidity: "0.8.28",
      networks: {
        plasmaTestnet: {
          url: process.env.RPC_ENDPOINT
          chainId: 9746,
          accounts: [process.env.PRIVATE_KEY] // We'll set this up next.
        }
      }
    };
    

Wallet & Testnet Setup

Add Plasma Testnet to MetaMask

  1. Open MetaMask and click the network selector dropdown.
  2. Click Add NetworkAdd a network manually.
  3. Enter these details:
    • Network Name: Plasma Testnet
    • New RPC URL: https://testnet-rpc.plasma.to
    • Chain ID: 9746
    • Currency Symbol: XPL
    • Block Explorer URL: https://testnet.plasmascan.to
  4. Click Save and switch to the Plasma Testnet.

Get Testnet Tokens

  1. Copy your wallet address from MetaMask.
  2. Visit gas.zip/faucet/plasma.
  3. Enter your address and request testnet tokens.
  4. Wait for the transaction to complete (should appear in MetaMask within a few seconds).

Set Up Environment Variables

  1. Grab your account’s private key from MetaMask.

  2. Create a .env file in your project root:

    PRIVATE_KEY=your_private_key_here
    RPC_ENDPOINT=https://testnet-rpc.plasma.to
    

Never commit your private key or mnemonic to version control. Add .env to your .gitignore file.

Write a Simple Smart Contract

  1. Create a basic storage contract contracts/SimpleStorage.sol:

    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.19;
    
    contract SimpleStorage {
        string private storedData;
        
        event DataStored(string data);
        
        constructor() {
            storedData = "Hello, Plasma!";
        }
        
        function setData(string memory data) public {
            storedData = data;
            emit DataStored(data);
        }
        
        function getData() public view returns (string memory) {
            return storedData;
        }
    }
    
  2. Compile the contract:

    npx hardhat compile
    

    This should output something like:

    Downloading compiler 0.8.28
    Downloading compiler 0.8.28
    Compiled 2 Solidity files successfully (evm target: paris).
    

Testing

  1. Create a test script test/SimpleStorage.js:

    const { expect } = require("chai");
    
    describe("SimpleStorage", function () {
      let simpleStorage;
    
      beforeEach(async function () {
        const SimpleStorage = await ethers.getContractFactory("SimpleStorage");
        simpleStorage = await SimpleStorage.deploy();
        await simpleStorage.waitForDeployment();
      });
    
      it("Should return the initial greeting", async function () {
        expect(await simpleStorage.getData()).to.equal("Hello, Plasma!");
      });
    
      it("Should update the stored data", async function () {
        await simpleStorage.setData("Updated data");
        expect(await simpleStorage.getData()).to.equal("Updated data");
      });
    });
    
  2. Run the tests:

    npx hardhat test
    

    This should output something like:

    Lock
      Deployment
        ✔ Should set the right unlockTime (454ms)
        ✔ Should set the right owner
        ✔ Should receive and store the funds to lock
        ✔ Should fail if the unlockTime is not in the future
      Withdrawals
        Validations
          ✔ Should revert with the right error if called too soon
          ✔ Should revert with the right error if called from another account
          ✔ Shouldn't fail if the unlockTime has arrived and the owner calls it
        Events
          ✔ Should emit an event on withdrawals
        Transfers
          ✔ Should transfer the funds to the owner
    
    SimpleStorage
      ✔ Should return the initial greeting
      ✔ Should update the stored data
    
    
    11 passing (541ms)
    

Deploy to Plasma Testnet

  1. First, make a scripts directory:

    mkdir scripts
    
  2. Next, create a script to deploy the contract scripts/deploy.js:

    async function main() {
      const SimpleStorage = await ethers.getContractFactory("SimpleStorage");
      
      console.log("Deploying SimpleStorage...");
      const simpleStorage = await SimpleStorage.deploy();
      await simpleStorage.waitForDeployment();
      
      const address = await simpleStorage.getAddress();
      console.log("SimpleStorage deployed to:", address);
    }
    
    main()
      .then(() => process.exit(0))
      .catch((error) => {
        console.error(error);
        process.exit(1);
      });
    
  3. Deploy the contract:

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

    This should output something like:

    Deploying SimpleStorage...
    SimpleStorage deployed to: 0xaa4FB2A8eD6953A4e57b8097BAf048d7919e6262
    
  4. Make a note of the deployed to: address. This is the address of your contract on the Plasma testnet.

Verify Deployment

  1. Copy the contract address.
  2. Visit the Plasma testnet explorer.
  3. Search for your contract address to view the deployment transaction.

Troubleshooting

IssueResolution
Gas estimation errorsEnsure wallet has sufficient XPL
Network connection errorsVerify RPC URL and testnet availability
Private key errorsEnsure .env is configured correctly (no 0x prefix if required)
Explorer delayWait a few minutes; explorer may be syncing