How to index token transfers with GhostGraph
Introduction
In this guide, you will create an ERC20 token on Monad Testnet and index its transfers with GhostGraph. You'll learn how to:
- Deploy a basic ERC20 token contract
- Test the contract locally
- Deploy to Monad Testnet
- Set up event tracking with GhostGraph
Prerequisites
Before starting, ensure you have:
- Node.js installed (v16 or later)
- Git installed
- Foundry installed
- Some MONAD testnet tokens (for gas fees)
- Basic knowledge of Solidity and ERC20 tokens
Project Setup
First, clone the starter repository:
git clone https://github.com/chrischang/cat-token-tutorial.gitcd cat-token-tutorial
CatToken Contract Implementation
The src/CatToken.sol
contract implements a basic ERC20 token with a fixed supply. Here's the code:
CatToken.sol
12345678910111213141516
// SPDX-License-Identifier: MITpragma solidity ^0.8.19;import "@openzeppelin/contracts/token/ERC20/ERC20.sol";contract CatToken is ERC20 {/*** @dev Constructor that gives msg.sender all existing tokens.* Initial supply is 1 billion tokens.*/constructor() ERC20("CatToken", "CAT") {// Mint initial supply of 1 billion tokens to deployer// This will emit a Transfer event that GhostGraph can index_mint(msg.sender, 1_000_000_000 * 10 ** decimals());}}
This implementation:
- Creates a token with name "CatToken" and symbol "CAT"
- Mints 1 billion tokens to the deployer's address
- Uses OpenZeppelin's battle-tested ERC20 implementation
Testing the Contract
Navigate to the test file test/CatToken.t.sol
:
CatToken.t.sol
123456789101112131415161718192021222324252627282930
// SPDX-License-Identifier: MITpragma solidity ^0.8.19;import "forge-std/Test.sol";import "../src/CatToken.sol";contract CatTokenTest is Test {CatToken public token;address public owner;address public user;function setUp() public {owner = address(this);user = address(0x1);token = new CatToken();}function testInitialSupply() public view {assertEq(token.totalSupply(), 1_000_000_000 * 10**18);assertEq(token.balanceOf(owner), 1_000_000_000 * 10**18);}function testTransfer() public {uint256 amount = 1_000_000 * 10**18;token.transfer(user, amount);assertEq(token.balanceOf(user), amount);assertEq(token.balanceOf(owner), 999_000_000 * 10**18);}}
Run the tests:
forge test -vv
Deployment Setup
1. Create a .env
file:
cp .env.example .env
2. Add your credentials to .env
file:
PRIVATE_KEY=your_private_key_hereMONAD_TESTNET_RPC=https://testnet-rpc.monad.xyz
3. Create deployment script script/DeployCatToken.s.sol
:
DeployCatToken.s.sol
12345678910111213141516171819
// SPDX-License-Identifier: MITpragma solidity ^0.8.19;import "forge-std/Script.sol";import "../src/CatToken.sol";contract DeployCatToken is Script {function run() external {// Retrieve private key from environmentuint256 deployerPrivateKey = vm.envUint("PRIVATE_KEY");vm.startBroadcast(deployerPrivateKey);CatToken token = new CatToken();vm.stopBroadcast();// Log the token address - this will be needed for GhostGraph indexing and submit transactionsconsole.log("CatToken deployed to:", address(token));}}
Deploying CatToken on Monad Testnet
1. Load environment variables:
source .env
2. Deploy the contract:
forge script script/DeployCatToken.s.sol \--rpc-url $MONAD_TESTNET_RPC \--broadcast
Save the deployed contract address for the next steps.
Remember to add TOKEN_ADDRESS
into your .env
file
You should now have
PRIVATE_KEY=your_private_key_hereMONAD_TESTNET_RPC=https://testnet-rpc.monad.xyzTOKEN_ADDRESS=0x...