# Python Smart Contract Template A Python-based smart contract client for Dragonchain Prime that connects via gRPC. ## Prerequisites - Python 3.10 or later - pip ## Quick Start 1. **Copy this template** to create your smart contract: ```bash cp -r python /path/to/my-smart-contract cd /path/to/my-smart-contract ``` 2. **Set up the environment**: ```bash make setup source venv/bin/activate ``` Or without make: ```bash python3 -m venv venv source venv/bin/activate pip install -r requirements.txt ``` 3. **Generate the protobuf code**: ```bash make proto ``` 4. **Configure your connection** by editing `config.yaml`: ```yaml server_address: "your-dragonchain-server:50051" smart_contract_id: "your-smart-contract-id" api_key: "your-api-key" ``` 5. **Implement your smart contract logic** in `process.py` by modifying the `process` function. 6. **Run**: ```bash python main.py --config config.yaml ``` ## Configuration | Field | Description | Default | |-------|-------------|---------| | `server_address` | gRPC server address | Required | | `smart_contract_id` | Your smart contract ID | Required | | `api_key` | API key for authentication | Required | | `use_tls` | Enable TLS encryption | `false` | | `tls_cert_path` | Path to TLS certificate | - | | `num_workers` | Concurrent transaction processors | `10` | | `reconnect_delay_seconds` | Delay between reconnection attempts | `5` | | `max_reconnect_attempts` | Max reconnect attempts (0 = infinite) | `0` | ## Implementing Your Smart Contract Edit the `process` function in `process.py`: ```python def process( tx_json: str, env_vars: dict[str, str], secrets: dict[str, str], ) -> ProcessResult: # Parse the transaction tx = Transaction.from_json(tx_json) # Access transaction data txn_id = tx.header.txn_id txn_type = tx.header.txn_type payload = tx.payload # Access environment variables sc_name = env_vars.get("SMART_CONTRACT_NAME") dc_id = env_vars.get("DRAGONCHAIN_ID") # Access secrets my_secret = secrets.get("SC_SECRET_MY_SECRET") # Implement your logic here result = { "status": "success", "data": "your result data", } return ProcessResult( data=result, output_to_chain=True, # Set to True to persist result on chain error=None, ) ``` ### Transaction Structure The `Transaction` class in `process.py` matches the Dragonchain transaction format: ```python @dataclass class Transaction: version: str header: TransactionHeader payload: dict[str, Any] @dataclass class TransactionHeader: tag: str dc_id: str txn_id: str block_id: str txn_type: str timestamp: str invoker: str ``` ### Available Environment Variables | Variable | Description | |----------|-------------| | `TZ` | Timezone | | `ENVIRONMENT` | Deployment environment | | `INTERNAL_ID` | Internal identifier | | `DRAGONCHAIN_ID` | Dragonchain ID | | `DRAGONCHAIN_ENDPOINT` | Dragonchain API endpoint | | `SMART_CONTRACT_ID` | This smart contract's ID | | `SMART_CONTRACT_NAME` | This smart contract's name | | `SC_ENV_*` | Custom environment variables | ### Secrets Secrets are provided in the `secrets` dict with keys prefixed by `SC_SECRET_`. ## Project Structure ``` . ├── main.py # Client infrastructure (do not modify) ├── process.py # Your smart contract logic (modify this) ├── proto/ │ └── remote_sc.proto # gRPC service definition ├── config.yaml # Configuration file ├── requirements.txt # Python dependencies ├── Makefile # Build commands └── README.md # This file ``` ### File Descriptions - **`process.py`** - Contains the `process` function where you implement your smart contract logic. This is the only file you need to modify for most use cases. - **`main.py`** - Contains the gRPC client infrastructure, connection handling, and worker pool. You typically don't need to modify this file. ## Make Commands ```bash make setup # Create venv and install dependencies make proto # Generate Python code from proto files make run # Run with default config make test # Run tests make clean # Remove generated files and venv make deps # Install dependencies (no venv) make format # Format code with black and isort ``` ## Concurrent Processing The client uses a thread pool to process multiple transactions concurrently. The number of workers is configurable via `num_workers` in the config file. ## Error Handling - Return errors from the `process` function via `ProcessResult.error` to report failures - The client automatically handles reconnection on connection failures - Logs are captured and sent back with the response ## Docker Example `Dockerfile`: ```dockerfile FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . RUN python -m grpc_tools.protoc \ -I./proto \ --python_out=. \ --grpc_python_out=. \ proto/remote_sc.proto CMD ["python", "main.py", "--config", "config.yaml"] ``` ## License [Your License Here]