PyCircleSim is a Python framework for simulating and analyzing the Circles protocol through agent-based modeling.
- Introduction
- Installation & Setup
- Project Structure
- Framework Components
- Configuration
- Running Simulations
- Analysis & Monitoring
Circles is a decentralized Universal Basic Income (UBI) protocol built on Gnosis Chain. Each participant mints their own personal currency token, with value flowing through trust relationships between participants.
PyCircleSim enables:
- Creating test networks with multiple types of agents
- Modeling realistic trust relationship formation
- Simulating token minting and trading behaviors
- Collecting comprehensive data for analysis
- Testing different scenarios and configurations
- Python 3.10+
- Git
- Foundry for blockchain simulation
- GnosisScan API key
- Install Foundry:
curl -L https://foundry.paradigm.xyz | bash
foundryup
- Install Ape and plugins:
pip install eth-ape
ape plugins install solidity foundry etherscan
- Clone and install PyCircleSim:
git clone <repository-url>
cd pyCircleSim
python -m venv circles_env
source circles_env/bin/activate # On Windows: circles_env\Scripts\activate
pip install -e .
- Configure environment:
# Create .env file with:
GNOSISSCAN_API_KEY=your_api_key_here
- Create Ape config (
ape-config.yaml
):
name: Circles-Chain-Simulator
plugins:
- name: solidity
- name: foundry
- name: etherscan
foundry:
fork:
gnosis:
mainnet_fork:
upstream_provider: https://rpc.gnosischain.com
gnosis:
default_network: mainnet-fork
mainnet_fork:
default_provider: foundry
- Fetch ABIs:
python src/protocols/abis/fetch_abis.py
- Generate contract interfaces:
python src/contract_generator/generator.py src/protocols/abis/rings/0x3D61f0A272eC69d65F5CFF097212079aaFDe8267.json
- Generate action types:
python src/framework/agents/actions_generator/generate_actions.py
PyCircleSim is organized into a clean, modular structure that separates core framework components from protocol-specific implementations and simulation configurations.
pyCircleSim/
├── scripts/ # Entry point scripts
└── src/ # Main source code
├── contract_generator/ # Contract interface generation
├── framework/ # Core framework components
├── protocols/ # Protocol implementations
└── simulations/ # Simulation configurations
contract_generator/
├── generator.py # Main generator script
└── templates/ # Jinja2 templates
├── basic_strategies.py.j2 # Strategy template
├── client.py.j2 # Client interface template
├── handler.py.j2 # Action handler template
└── interface_init.py.j2 # Init file template
framework/
├── agents/ # Agent system
│ ├── action_registry.py # Action registration
│ ├── actions_generator/ # Action type generation
│ ├── agent_manager.py # Agent coordination
│ ├── balance.py # Balance tracking
│ ├── base_agent.py # Base agent class
│ ├── profile.py # Agent profiles
│ └── types.py # Type definitions
├── core/ # Core simulation
│ ├── network_builder.py # Network initialization
│ └── network_evolver.py # Network evolution
├── data/ # Data collection
│ ├── collector.py # Main collector
│ ├── duckdb/ # Database components
│ │ ├── queries/ # SQL queries
│ │ └── schema/ # Database schema
│ └── event_logging/ # Event system
└── logging/ # Logging system
protocols/
├── abis/ # Contract ABIs
│ ├── balancer_v2/ # Balancer V2 ABIs
│ ├── balancer_v3/ # Balancer V3 ABIs
│ ├── circles/ # Circles Protocol ABIs
│ ├── fjord/ # Fjord Protocol ABIs
│ ├── rings/ # Rings Protocol ABIs
│ └── tokens/ # Token ABIs
├── handler_strategies/ # Protocol strategies
│ ├── base.py # Base strategy
│ ├── ringshub/ # Rings strategies
│ └── wxdai/ # WXDAI strategies
└── interfaces/ # Protocol interfaces
├── ringshub/ # Rings interface
└── wxdai/ # WXDAI interface
duckdb/
├── queries/ # SQL queries
│ ├── get_agent_profile.sql # Agent queries
│ ├── get_event_stats.sql # Event statistics
│ ├── get_events.sql # Event retrieval
│ ├── insert_agent.sql # Agent insertion
│ └── insert_event.sql # Event logging
└── schema/ # Database schema
├── agent_actions.up.sql # Actions table
├── agents.up.sql # Agents table
├── events.up.sql # Events table
└── network_stats.up.sql # Statistics table
- BaseAgent: Foundation for network participants
- Agent Profiles: Behavior and constraint definitions
- Action Handlers: Contract interaction management
- Agent Manager: Agent coordination and tracking
- Action Registry: Available action catalog
- Event Logger: Comprehensive event tracking
- Balance Tracker: Token balance monitoring
- Data Collector: Central storage system
- Event Handler: Contract event processing
- Network Builder: Initial network construction
- Network Evolver: Ongoing network changes
- Base Strategy: Strategy foundation interface
- Basic Strategies: Default behaviors
- Sybil Strategies: Attack pattern implementations
- Custom Strategies: Specialized behavior framework
- Contract Clients: Blockchain interaction layer
- Event Decoders: Event processing system
- Transaction Management: Transaction handling system
- Network Configuration: Simulation-wide settings
- Agent Configuration: Agent behavior parameters
- Protocol Configuration: Protocol-specific settings
size: 20 # Network size
trust_density: 0.1 # Target trust density
batch_size: 10 # Processing batch size
iterations: 100 # Number of iterations
blocks_per_iteration: 100 # Blocks per iteration
block_time: 5 # Seconds per block
strategies:
ringshub: 'basic' # or 'sybil'
wxdai: 'basic'
gas_limits:
registerHuman: 500000
trust: 300000
registerGroup: 1000000
agent_distribution:
honest_user: 10
group_creator: 1
profiles:
honest_user:
description: "Regular network participant"
base_config:
target_account_count: 1
max_daily_actions: 20
risk_tolerance: 0.3
available_actions:
- action: "ringshub_PersonalMint"
probability: 0.8
cooldown_blocks: 2
- action: "ringshub_Trust"
probability: 0.5
cooldown_blocks: 1
ape run scripts/cli.py simulate rings \
--network-config config/rings_config.yaml \
--agent-config config/agent_config.yaml
ape run scripts/cli.py simulate rings \
--network-config config/rings_config.yaml \
--agent-config config/agent_config.yaml \
--network-size 100 \
--batch-size 20 \
--iterations 500 \
--blocks-per-iteration 200 \
--fast-mode
Available options:
--network-size
: Override network size--batch-size
: Override batch size--iterations
: Override iteration count--blocks-per-iteration
: Override blocks per iteration--fast-mode/--no-fast-mode
: Toggle database storage
Results are stored in DuckDB (rings_simulation.duckdb
). Example usage:
from src.framework.data import DataCollector
collector = DataCollector()
# Export to CSV
collector.export_to_csv("analysis_results")
# Get event statistics
stats = collector.get_event_stats(simulation_run_id=1)
# Query specific events
events = collector.get_events(
event_name="Trust",
start_time=datetime(2024, 1, 1),
limit=1000
)
MIT License