This project implements an onchain Battleship game optimized for Layer 2 networks like Base. Players can create games, place ships, and battle in real-time using smart contracts. The game logic is fully implemented onchain, with state verification and anti-cheat mechanisms built into the protocol.
- Complete onchain Battleship game mechanics
- Optimized for Layer 2 performance
- Private ship placement with commit-reveal scheme
- Fair matchmaking and turn enforcement
- Upgradeable game contracts for future feature expansion
- WebSocket event subscriptions for real-time game updates
- Comprehensive test suite simulating complete game scenarios
The ZK Battleship contract system consists of the following components:
┌──────────────────────────────────────────────────────────────────────┐
│ ZK Battleship Contract System │
└──────────────────────────────────────┬───────────────────────────────┘
│
┌──────────────────────────┐│┌───────────────────────────┐
│ │││ │
│ ┌────────────────────┐ │││ ┌────────────────────┐ │
│ │ GameFactory │◄─┘│└─►│ $SHIPToken │ │
│ │ (Game Creation) │ │ │ (Rewards) │ │
│ └──────────┬─────────┘ │ └────────────────────┘ │
│ │ │ │
│ ┌──────────▼─────────┐ │ ┌────────────────────┐ │
│ │ BattleshipGameProxy│ │ │ ZKVerifier │ │
│ │ (Permanent Address)│◄──┼───┤ (Proof Validation) │ │
│ └──────────┬─────────┘ │ └────────────────────┘ │
│ │ │ │
│ │ │ ┌────────────────────┐ │
│ ┌──────────▼─────────┐ │ │ GameUpgradeManager │ │
│ │ Game Implementation│◄──┼───┤ (Upgrade Control) │ │
│ │ (Upgradeable Logic)│ │ └────────────────────┘ │
│ └──────────┬─────────┘ │ │
│ │ │ │
│ ┌──────────▼─────────┐ │ │
│ │ GameStorage │ │ │
│ │ (State Management) │ │ │
│ └────────────────────┘ │ │
│ │ │
│ Core Gameplay │ Support Systems │
└───────────────────────────┘ └─────────────────────┘
The main gameplay logic contract that implements:
- Game lifecycle management (Created -> Setup -> Active -> Completed/Cancelled)
- Move validation and state transitions
- Integration with ZK proof verification
- Access controls for players and admin functions
- Upgradeability via UUPS pattern
A simple proxy contract that follows the ERC1967 standard to:
- Provide a permanent address for each game instance
- Delegate all calls to the current implementation
- Maintain game state across upgrades
Manages game creation and serves as the entry point for players:
- Creates new game instances as proxy contracts
- Maintains registry of active games
- Manages player-to-game mappings
- Controls implementation upgrades
Adds financial incentives to gameplay:
- USDC-based betting with escrow mechanism
- Time-limited betting invites (24 hours)
- Platform fee collection (10% of winnings)
- Draw handling with full refunds
- Admin controls for emergency situations
Validates zero-knowledge proofs for game actions:
- Verifies board placement proofs
- Validates shot result proofs
- Confirms game ending proofs
Optimizes storage and retrieval of game state:
- Uses bit-packed board representation
- Compresses storage of shot history
- Provides gas-optimized data structures
The implementation uses the UUPS (Universal Upgradeable Proxy Standard) pattern:
- The proxy contract is minimal and non-upgradeable itself
- The implementation contract contains the upgrade logic
- Upgrade authorization is controlled by access roles
- Storage uses gap slots to allow future extensions
Benefits of this approach:
- Gas Efficiency: Reduced proxy deployment costs
- Security: Clear upgrade authorization controls
- Simplicity: Clean separation of concerns
The GameStorage library provides optimized on-chain storage:
-
Efficient Board Representation:
- Bit-packed ship positions using uint256
- Compressed storage of hit and shot maps
- Minimal storage requirements
-
Gas Optimization:
- Each 10x10 board fits in a single storage slot
- Coordinates are packed for efficient storage
- O(1) lookups for shot and hit checks
-
Game Creation:
- Player calls
GameFactory.createGame(opponent)
- Factory deploys new proxy with implementation
- Game initializes with both player addresses
- Player calls
-
Board Submission:
- Players generate ZK proofs of valid board layouts
- Both players call
submitBoard(commitment, proof)
- Once both boards are submitted, game moves to Active state
-
Gameplay:
- Current player calls
makeShot(x, y)
- Target player calls
submitShotResult(x, y, isHit, proof)
- Turns alternate until win condition is met
- Current player calls
-
Game Completion:
- When all ships of a player are sunk
- Player calls
verifyGameEnd(commitment, proof)
- Players can claim rewards via
claimReward()
When BattleshipBetting is deployed, players can wager on games:
-
Create Betting Invite:
- Player calls
BattleshipBetting.createInvite(stakeAmount)
- USDC stake is escrowed in the contract
- Invite expires after 24 hours if not accepted
- Player calls
-
Accept Betting Invite:
- Opponent calls
acceptInvite(inviteId)
- Matching USDC stake is escrowed
- Bet is now matched and ready for game creation
- Opponent calls
-
Game Creation:
- Backend calls
createGame(inviteId)
- Game is created through GameFactory
- Players proceed with normal gameplay
- Backend calls
-
Resolve Betting:
- Backend calls
resolveGame(gameId, winner)
- Winner receives 90% of pool (180% of their stake)
- Platform collects 10% fee
- Draws return full stakes to both players
- Backend calls
├── .github/ # GitHub Actions workflows
├── circuit/ # ZK circuit files
├── lib/ # Dependencies (managed by Foundry)
├── script/ # Deployment and operation scripts
│ ├── deploy/ # Deployment scripts
│ └── upgrade/ # Upgrade scripts
├── src/ # Smart contract source code
│ ├── access/ # Access control contracts
│ ├── interfaces/ # Interface definitions
│ ├── libraries/ # Shared libraries
│ └── proxies/ # Proxy contracts
└── test/ # Test suite
├── integration/ # Integration tests
└── unit/ # Unit tests
-
Clone this repository:
git clone https://github.com/zkripson/contracts.git cd kripson
-
Install dependencies:
forge install
-
Create a
.env
file from the example:cp .env.example .env
-
Configure your environment variables in the
.env
file.
Building the Project We use a special build script to handle the verifier contracts, which are complex and can cause stack-too-deep errors when compiled. Setup
Ensure the scripts are executable:
bashchmod +x scripts/pre-build.sh scripts/deploy.sh
Create a .env file with your deployment settings:
PRIVATE_KEY=your_private_key MEGAETH_RPC_URL=your_rpc_url
We use a special build script to handle the verifier contracts, which are complex and can cause stack-too-deep errors when compiled.
- Ensure the scripts are executable:
chmod +x scripts/pre-build.sh scripts/deploy.sh
- Create a
.env
file with your deployment settings:
# Use Cast keystore instead of private key
BASE_MAINNET_RPC_URL=your_rpc_url
BASE_MAINNET_API_KEY=your_api_key_for_verification
ADMIN_ADDRESS=your_admin_address
TREASURY_ADDRESS=your_treasury_address
USDC_ADDRESS=0x833589fcd6edb6e08f4c7c32d4f71b54bda02913
To build the project:
forge build --optimize
For a build with specific parameters:
forge build --optimize --via-ir
To deploy the core contracts:
./scripts/deploy.sh
To deploy all contracts including the betting system:
# First, set these in your .env file
USDC_ADDRESS=0x833589fcd6edb6e08f4c7c32d4f71b54bda02913 # USDC token address on Base Mainnet
TREASURY_ADDRESS=0x... # Treasury address for platform fees
ADMIN_ADDRESS=0x... # Admin address for contract management
BACKEND_ADDRESS=0x... # Backend service address
# Run deployment
./scripts/deploy.sh
The deployment script will:
-
Build all contracts with optimization
-
Deploy core contracts (SHIPToken, GameFactory, Statistics, Implementation)
-
Deploy BattleshipBetting contract if USDC_ADDRESS and TREASURY_ADDRESS are set
-
Configure all necessary permissions and roles
-
Update your .env file with deployed addresses
-
Generate deployment-config.json with all contract addresses
-
Verify contracts on Base Mainnet explorer (if API key is provided)
-
Run tests:
forge test
-
Set up your Cast keystore and ensure your
.env
file is properly configured with the Base Mainnet RPC URL. -
Run the deployment script:
./scripts/deploy.sh
-
Manual deployment with verification:
forge script scripts/deploy/Deploy.s.sol --rpc-url $BASE_MAINNET_RPC_URL --broadcast --verify --etherscan-api-key $BASE_MAINNET_API_KEY --account deployKey
Base is a secure, low-cost, builder-friendly Layer 2 solution built on Ethereum, offering:
- Fast transaction confirmations
- Low gas costs for better user experience
- Full Ethereum compatibility
- Strong security guarantees through Optimistic Rollups
- Reliable infrastructure built by Coinbase
For more details, refer to the Base documentation.
The system emits various events to track game progression:
- Game creation and state transitions
- Player actions and turn progression
- Reward distribution on game completion
You can monitor these events using standard Ethereum event listeners or Base's RPC endpoints.
This project is licensed under the MIT License - see the LICENSE file for details.