Creating a TREZ Mining Pool: Developer's Guide
Last updated: October 2025
This guide provides an in-depth walkthrough for developers to create a mining pool that connects to the TREZ mining contract on Solana
(EUBkEwKJJnuenTnocaUHDZUaSegeWWZAFwBTqTRcQ1sJ). A mining pool allows multiple miners to combine their computational power (hashrate) to increase the chances of finding valid proof-of-work (PoW) solutions, with rewards distributed proportionally based on contributed shares. The pool server interacts with the TREZ contract to submit valid solutions via the claim_reward instruction and handles reward distribution.
The guide assumes familiarity with Python, Solana development, and the TREZ mining contract. We’ll use Python for the pool server (FastAPI + WebSockets) and provide example code for both the server and client miners. You can adapt this to other languages or frameworks.
Table of Contents
- Overview of Mining Pools
- Prerequisites
- Pool Architecture
- Setting Up the Pool Server
- Example Pool Server Code
- Miner Client Integration
- Example Miner Client Code
- Reward Distribution
- Security Considerations
- Testing and Deployment
- Scaling and Optimization
- Resources
Overview of Mining Pools
In the TREZ ecosystem, individual miners solve SHA-256 challenges to meet the dynamic difficulty (targeting ~180-second blocks) and claim rewards via claim_reward. A mining pool aggregates miners’ efforts:
- Shares: miners submit partial solutions that meet a pool-defined lower difficulty.
- Valid Solutions: when a share meets the on-chain difficulty, the pool submits it to the contract.
- Payouts: rewards (base block reward and any applicable referral bonus) are distributed by the pool based on contributed shares (e.g., PPLNS).
- Benefits: reduces variance for small miners and increases collective hashrate.
The pool connects to the TREZ contract to fetch state (challenge, difficulty) and to submit claim_reward when a full-difficulty solution is found.
Prerequisites
- Programming: Python 3.8+.
- Solana Tools:
- Solana CLI:
sh -c "$(curl -sSfL https://release.solana.com/v1.18.20/install)" - Anchor:
cargo install --git https://github.com/coral-xyz/anchor anchor-cli --locked
- Solana CLI:
- Python Dependencies: install via pip install -r requirements.txt
- TREZ Contract Details:
- Program ID:
EUBkEwKJJnuenTnocaUHDZUaSegeWWZAFwBTqTRcQ1sJ - Mint:
TREZuzaCxTVsg4U9c4MTe7dterWcLe5LA92PHG12Jez(6 decimals) - IDL:
idl/trez.json(generate with Anchor as needed)
- Program ID:
- Pool Wallet: a Solana wallet for the pool operator to submit transactions and distribute rewards.
- Server Hosting: a VPS (e.g., EC2, DigitalOcean) for running the pool server.
- Database: SQLite or Redis for tracking shares and miner stats.
Sample requirements.txt
fastapi==0.111.0
uvicorn==0.30.1
websockets==12.0
anchorpy==0.19.0
solana==0.34.3
solders==0.21.0
redis==5.0.7 # Optional, for high-scale stats
Install:
# Linux/macOS
python3 -m pip install -r requirements.txt
# Windows PowerShell
python -m pip install -r requirements.txt
Pool Architecture
- Pool Server:
- Fetches on-chain state (challenge, difficulty) from the TREZ contract.
- Assigns work to miners via WebSockets.
- Validates submitted shares (pool difficulty vs. on-chain difficulty).
- Submits valid solutions using the pool wallet via
claim_reward. - Tracks shares in a database for payout calculation.
- Miner Clients:
- Connect to the pool via WebSocket.
- Receive work (challenge, difficulty) and mine shares.
- Submit shares to the pool for credit.
- Reward Flow:
- Pool receives TREZ rewards and distributes to miners based on shares (minus optional pool fee).
Setting Up the Pool Server
- Create the Project Structure:
mkdir trez-mining-pool cd trez-mining-pool touch server.py database.py config.py - Configure the Pool (in
config.py):RPC_URL = "https://api.mainnet-beta.solana.com" PROGRAM_ID = "EUBkEwKJJnuenTnocaUHDZUaSegeWWZAFwBTqTRcQ1sJ" TREZ_MINT = "TREZuzaCxTVsg4U9c4MTe7dterWcLe5LA92PHG12Jez" POOL_WALLET_SECRET = "your_pool_wallet_secret_base58" # Securely store this! POOL_DIFFICULTY = 20 # Lower than on-chain for pool shares SHARE_WINDOW = 1000 # N for PPLNS POOL_FEE = 0.01 # 1% fee (optional) - Set Up Database (in
database.py):import sqlite3, time def init_db(): conn = sqlite3.connect('pool.db') c = conn.cursor() c.execute('''CREATE TABLE IF NOT EXISTS shares (miner TEXT, timestamp REAL, share_count INTEGER)''') conn.commit() return conn def add_share(conn, miner: str, count: int = 1): c = conn.cursor() c.execute("INSERT INTO shares VALUES (?, ?, ?)", (miner, time.time(), count)) conn.commit() def get_last_n_shares(conn, n: int): c = conn.cursor() c.execute("SELECT miner, SUM(share_count) FROM shares GROUP BY miner " "ORDER BY MAX(timestamp) DESC LIMIT ?", (n,)) return c.fetchall()
Example Pool Server Code
The FastAPI WebSocket server assigns jobs, validates shares, submits full-difficulty solutions, and accounts for payouts. Stub methods like token transfers should be implemented for production.
# server.py
import asyncio, json, time, hashlib
from fastapi import FastAPI, WebSocket
from anchorpy import Program, Provider, Wallet
from solana.rpc.async_api import AsyncClient
from solders.pubkey import Pubkey
from solders.keypair import Keypair
from config import RPC_URL, PROGRAM_ID, TREZ_MINT, POOL_WALLET_SECRET, POOL_DIFFICULTY, SHARE_WINDOW, POOL_FEE
from database import init_db, add_share, get_last_n_shares
app = FastAPI()
conn = init_db()
async def load_program():
client = AsyncClient(RPC_URL)
wallet = Wallet(Keypair.from_base58_string(POOL_WALLET_SECRET))
provider = Provider(client, wallet)
# Load IDL from file
with open("idl/trez.json", "r") as f:
idl = json.load(f)
program = Program(idl, Pubkey.from_string(PROGRAM_ID), provider)
return program, client, provider
program, client, provider = asyncio.get_event_loop().run_until_complete(load_program())
async def get_state():
state_pda = Pubkey.find_program_address([b"state"], Pubkey.from_string(PROGRAM_ID))[0]
state = await program.account["State"].fetch(state_pda)
return {
"challenge": bytes(state.challenge_number).hex(),
"difficulty": int(state.difficulty_high),
"block_count": int(state.block_count)
}
def meets_difficulty(digest: bytes, difficulty: int) -> bool:
u192 = int.from_bytes(digest[:24], "little")
return (u192 >> (192 - difficulty)) == 0
def compute_digest(challenge: bytes, miner_pk: Pubkey, block_count: int, nonce: int) -> bytes:
nonce_bytes = nonce.to_bytes(8, "little")
miner_bytes = bytes(miner_pk)
block_bytes = block_count.to_bytes(8, "little")
return hashlib.sha256(challenge + miner_bytes + block_bytes + hashlib.sha256(nonce_bytes).digest()).digest()
@app.websocket("/mine")
async def mine_ws(ws: WebSocket):
await ws.accept()
# TODO: auth the miner and set miner_address
miner_address = None
while True:
state = await get_state()
challenge = bytes.fromhex(state["challenge"])
await ws.send_json(state)
data = await ws.receive_json()
nonce = int(data["nonce"])
digest = bytes.fromhex(data["digest"])
# Pool difficulty check (share credit)
if meets_difficulty(digest, POOL_DIFFICULTY):
add_share(conn, miner_address or "unknown")
# On-chain difficulty (submit claim)
if meets_difficulty(digest, state["difficulty"]):
# TODO: call program.methods.claim_reward(...).accounts(...).rpc()
# TODO: on success, trigger payout distribution
pass
await asyncio.sleep(0.05)
async def distribute_rewards():
shares = get_last_n_shares(conn, SHARE_WINDOW)
total = sum(s[1] for s in shares) or 0
if total == 0:
return
# TODO: read pool balance, split minus POOL_FEE, transfer to miners
for miner, scount in shares:
portion = scount / total
# TODO: transfer 'portion * reward' to miner ATA (transfer_checked)
pass
Miner Client Integration
Modify your miner to connect to the pool’s WebSocket, receive work, and submit shares back when a nonce meets the pool difficulty.
Example Miner Client Code
# miner_client.py
import asyncio, json, hashlib, random, websockets
from solders.pubkey import Pubkey
POOL_URL = "ws://your-pool-server.com/mine"
MINER_PUBKEY = Pubkey.from_string("YourMinerPubkeyHere")
def meets_difficulty(digest: bytes, difficulty: int) -> bool:
u192 = int.from_bytes(digest[:24], "little")
return (u192 >> (192 - difficulty)) == 0
def compute_digest(challenge: bytes, miner_pk: Pubkey, block_count: int, nonce: int) -> bytes:
nonce_b = nonce.to_bytes(8, "little")
miner_b = bytes(miner_pk)
block_b = block_count.to_bytes(8, "little")
return hashlib.sha256(challenge + miner_b + block_b + hashlib.sha256(nonce_b).digest()).digest()
async def mine_pool():
async with websockets.connect(POOL_URL) as ws:
while True:
work = json.loads(await ws.recv())
challenge = bytes.fromhex(work["challenge"])
difficulty = int(work["difficulty"])
block_count = int(work["block_count"])
while True:
nonce = random.getrandbits(64)
digest = compute_digest(challenge, MINER_PUBKEY, block_count, nonce)
if meets_difficulty(digest, difficulty): # full-diff or just send all shares
await ws.send(json.dumps({
"nonce": nonce,
"digest": digest.hex()
}))
break # request new work
asyncio.run(mine_pool())
Reward Distribution
- PPLNS: use the last N shares to calculate payouts so miners are rewarded proportionally to recent contribution.
- Implementation: after a successful
claim_reward, sum shares in the window and performtransfer_checkedto miners’ ATAs. - Pool Fee: deduct an optional operator fee before distribution.
Security Considerations
- Authentication: sign a nonce with miners’ wallets or use API keys tied to addresses.
- Share Validation: verify digests server-side; don’t trust client difficulty checks.
- Rate Limiting: throttle connections and messages to mitigate spam/DoS.
- Key Management: protect the pool wallet (consider HSM/airgapped signing for production).
- Monitoring: log submissions, accepts/rejects, and payouts for auditability.
Testing and Deployment
- Local: run the server with
uvicorn server:app --reloadand connect test miners. - Deployment: host behind Nginx with TLS; consider Docker for portability.
- Observability: export metrics (Prometheus) and alerts for hashrate, latency, and error spikes.
Scaling and Optimization
- Redis for real-time share counters and leaderboards.
- Worker Threads/Processes for hash validation and DB writes.
- Dynamic Pool Difficulty to keep share rates stable as hashrate grows.
- Stratum-like Protocol if you need industry-standard miner compatibility.
Resources
- Solana Docs: docs.solana.com
- AnchorPy: anchorpy.readthedocs.io
- FastAPI WebSockets: fastapi.tiangolo.com/advanced/websockets
- TREZ Program:
programs/trez-mining/src/lib.rs - Reference App:
mining-app/trez_miner.py
This guide is for developers. Operating a pool involves security, compliance, and operational risks—review and audit your implementation before going live.
