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
-
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
-
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.
-
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
- Open MetaMask and click the network selector dropdown.
- Click Add Network → Add a network manually.
- 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
- Click Save and switch to the Plasma Testnet.
Get Testnet Tokens
- Copy your wallet address from MetaMask.
- Visit gas.zip/faucet/plasma.
- Enter your address and request testnet tokens.
- Wait for the transaction to complete (should appear in MetaMask within a few seconds).
Set Up Environment Variables
-
Grab your account’s private key from MetaMask.
-
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
-
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;
}
}
-
Compile the contract:
This should output something like:
Downloading compiler 0.8.28
Downloading compiler 0.8.28
Compiled 2 Solidity files successfully (evm target: paris).
Testing
-
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");
});
});
-
Run the tests:
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
-
First, make a scripts
directory:
-
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);
});
-
Deploy the contract:
npx hardhat run scripts/deploy.js --network plasmaTestnet
This should output something like:
Deploying SimpleStorage...
SimpleStorage deployed to: 0xaa4FB2A8eD6953A4e57b8097BAf048d7919e6262
-
Make a note of the deployed to:
address. This is the address of your contract on the Plasma testnet.
Verify Deployment
- Copy the contract address.
- Visit the Plasma testnet explorer.
- Search for your contract address to view the deployment transaction.
Troubleshooting
Issue | Resolution |
---|
Gas estimation errors | Ensure wallet has sufficient XPL |
Network connection errors | Verify RPC URL and testnet availability |
Private key errors | Ensure .env is configured correctly (no 0x prefix if required) |
Explorer delay | Wait a few minutes; explorer may be syncing |