Overview
GatePass contracts are deployed on Polygon using Foundry, a fast and modern Ethereum development toolkit. This guide covers deploying the factory contract and creating your first event.
Make sure you have MATIC tokens in your wallet for gas fees. Even though Polygon is cheap, you’ll need ~$1-2 worth of MATIC for deployment.
Prerequisites
Install Foundry
Install Foundry (Forge, Cast, Anvil) for Solidity development curl -L https://foundry.paradigm.xyz | bash
foundryup
Clone Repository
Clone the GatePass contracts repository git clone https://github.com/yourorg/gatepass-contracts
cd gatepass-contracts/src/packages/contracts
Install Dependencies
Install OpenZeppelin and other dependencies
Configure Environment
Create a .env file with your deployment credentials cp .env.example .env
# Edit .env with your private key and RPC URL
Environment Configuration
Create a .env file in the contracts directory:
# Deployer wallet private key (without 0x prefix)
PRIVATE_KEY = your_private_key_here
# Platform fee recipient address
PLATFORM_FEE_RECIPIENT = 0xYourPlatformFeeAddress
# Network configuration
NETWORK_NAME = polygon
RPC_URL = https://polygon-rpc.com
# Polygonscan API key for verification
POLYGONSCAN_API_KEY = your_api_key_here
Never commit your .env file to version control! Add it to .gitignore immediately.
Deployment Script
The deployment script (script/Deploy.s.sol) handles:
Deploying the EventTicketFactory contract
Deploying the EventTicket implementation contract
Setting the platform fee recipient
Saving deployment information to a JSON file
Deploy.s.sol
Deploy Command
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24 ;
import "forge-std/Script.sol" ;
import "../src/EventTicketFactory.sol" ;
contract Deploy is Script {
function run () external {
uint256 deployerPrivateKey = vm. envUint ( "PRIVATE_KEY" );
address platformFeeRecipient = vm. envAddress ( "PLATFORM_FEE_RECIPIENT" );
vm. startBroadcast (deployerPrivateKey);
// Deploy the factory contract
EventTicketFactory factory = new EventTicketFactory (platformFeeRecipient);
console. log ( "EventTicketFactory deployed to:" , address (factory));
console. log ( "Implementation contract:" , factory. getImplementation ());
console. log ( "Platform fee recipient:" , factory. platformFeeRecipient ());
console. log ( "Platform fee (bps):" , factory. platformFeeBps ());
vm. stopBroadcast ();
// Write deployment info to file
string memory deploymentInfo = string (
abi . encodePacked (
"{\n" ,
' "factory": "' , vm. toString ( address (factory)), '",\n' ,
' "implementation": "' , vm. toString (factory. getImplementation ()), '",\n' ,
' "platformFeeRecipient": "' , vm. toString (platformFeeRecipient), '",\n' ,
' "platformFeeBps": ' , vm. toString (factory. platformFeeBps ()), ',\n' ,
' "network": "' , vm. envString ( "NETWORK_NAME" ), '",\n' ,
' "deployedAt": ' , vm. toString ( block .timestamp), '\n' ,
"}"
)
);
vm. writeFile ( "./deployments/latest.json" , deploymentInfo);
console. log ( "Deployment info saved to ./deployments/latest.json" );
}
}
Step-by-Step Deployment
1. Deploy Factory Contract
# Load environment variables
source .env
# Deploy to Polygon
forge script script/Deploy.s.sol:Deploy \
--rpc-url https://polygon-rpc.com \
--broadcast \
--verify \
--etherscan-api-key $POLYGONSCAN_API_KEY \
-vvvv
[⠊] Compiling...
[⠃] Compiling 25 files with 0.8.24
[⠊] Solc 0.8.24 finished in 3.45s
Compiler run successful
## Setting up 1 EVM.
==========================
Chain 137
Estimated gas price: 30.000000001 gwei
Estimated total gas used for script: 2134567
Estimated amount required: 0.064037010002134567 MATIC
##### polygon
✅ [Success] Hash: 0x1234...5678
Contract Address: 0xFactoryAddress...
Block: 12345678
Paid: 0.062 MATIC
EventTicketFactory deployed to: 0xFactoryAddress...
Implementation contract: 0xImplementationAddress...
Platform fee recipient: 0xYourPlatformFeeAddress
Platform fee (bps): 250
✅ Sequence #1 on polygon | Total Paid: 0.062 MATIC
2. Verify Deployment
After deployment, verify the contracts on Polygonscan:
forge verify-contract \
--chain-id 137 \
--num-of-optimizations 200 \
--watch \
--constructor-args $( cast abi-encode "constructor(address)" $PLATFORM_FEE_RECIPIENT ) \
--etherscan-api-key $POLYGONSCAN_API_KEY \
--compiler-version v0.8.24+commit.e11b9ed9 \
$FACTORY_ADDRESS \
src/EventTicketFactory.sol:EventTicketFactory
3. Save Deployment Info
The script automatically saves deployment information to deployments/latest.json:
{
"factory" : "0xFactoryAddress..." ,
"implementation" : "0xImplementationAddress..." ,
"platformFeeRecipient" : "0xYourPlatformFeeAddress" ,
"platformFeeBps" : 250 ,
"network" : "polygon" ,
"deployedAt" : 1710345600
}
Creating Your First Event
After deploying the factory, you can create events using the createEvent function.
Using the Deployment Script
# Set factory address in .env
echo "FACTORY_ADDRESS=0xYourFactoryAddress" >> .env
# Run create event script
forge script script/Deploy.s.sol:CreateTestEvent \
--rpc-url $RPC_URL \
--broadcast \
-vvvv
Using Cast CLI
cast send $FACTORY_ADDRESS \
"createEvent(string,string,uint256,uint256,uint256,uint256,uint256,string)" \
"My Concert" \
"CONCERT" \
1000 \
"10000000000000000" \
$( date +%s ) \
$(($( date +%s ) + 604800)) \
$(($( date +%s ) + 1209600)) \
"https://api.myevent.com/metadata/" \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY
Parameters Explained
Name of the event (e.g., “DevCon 2024”)
Symbol for the NFT tickets (e.g., “DEVCON24”)
Maximum number of tickets available (1-10000)
Price per ticket in wei (e.g., 0.01 ether = “10000000000000000”)
Unix timestamp when ticket sales begin
Unix timestamp when ticket sales end (must be before eventDate)
Unix timestamp of the actual event
Example Script
JavaScript (ethers.js)
Python (web3.py)
const { ethers } = require ( 'ethers' );
async function createEvent () {
const provider = new ethers . JsonRpcProvider ( 'https://polygon-rpc.com' );
const wallet = new ethers . Wallet ( process . env . PRIVATE_KEY , provider );
const factoryABI = [ 'function createEvent(string,string,uint256,uint256,uint256,uint256,uint256,string) returns (address)' ];
const factory = new ethers . Contract ( factoryAddress , factoryABI , wallet );
const now = Math . floor ( Date . now () / 1000 );
const tx = await factory . createEvent (
'DevCon 2024' ,
'DEVCON24' ,
1000 , // 1000 tickets
ethers . parseEther ( '0.01' ), // 0.01 MATIC per ticket
now , // Sale starts now
now + ( 7 * 24 * 60 * 60 ), // Sale ends in 7 days
now + ( 14 * 24 * 60 * 60 ), // Event in 14 days
'https://api.example.com/metadata/'
);
const receipt = await tx . wait ();
console . log ( 'Event created:' , receipt );
}
createEvent ();
Testing Deployment
Before deploying to mainnet, test on a local fork or testnet:
Local Testing with Anvil
# Start local Polygon fork
anvil --fork-url https://polygon-rpc.com
# Deploy to local fork
forge script script/Deploy.s.sol:Deploy \
--rpc-url http://127.0.0.1:8545 \
--broadcast
Run Tests
# Run all tests
forge test
# Run tests with verbosity
forge test -vvv
# Run specific test
forge test --match-test testMintTicket
# Run tests with gas reporting
forge test --gas-report
Post-Deployment
Update Frontend
Update your frontend configuration with the deployed factory address
Configure Platform Fee
Adjust platform fee if needed (default is 2.5%) cast send $FACTORY_ADDRESS \
"setPlatformFee(uint256)" \
200 \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY
Monitor Events
Set up event monitoring for EventContractDeployed events
Document Addresses
Save all contract addresses in your documentation and configuration
Troubleshooting
Insufficient funds for gas
Make sure your deployer wallet has enough MATIC. You need ~$2-3 worth for deployment. # Check balance
cast balance $DEPLOYER_ADDRESS --rpc-url $RPC_URL
Your transaction nonce is outdated. Wait for pending transactions to confirm. # Check pending transactions
cast nonce $DEPLOYER_ADDRESS --rpc-url $RPC_URL
If contract verification fails, manually verify on Polygonscan:
Go to Polygonscan
Find your contract
Click “Verify and Publish”
Select “Solidity (Standard Json-Input)”
Upload the standard JSON input from forge verify-contract
Next Steps
EventTicket Contract Learn about the EventTicket contract functionality
Factory Contract Detailed factory contract documentation