Go Smart Contract Template
A Go-based smart contract client for Dragonchain Prime that connects via gRPC.
Prerequisites
- Go 1.21 or later
- Protocol Buffers compiler (
protoc) - Go protobuf plugins
Installing Tools
# Install protoc (Ubuntu/Debian)
sudo apt install -y protobuf-compiler
# Install protoc (macOS)
brew install protobuf
# Install Go protobuf plugins
make tools
Quick Start
-
Copy this template to create your smart contract:
cp -r go /path/to/my-smart-contract cd /path/to/my-smart-contract -
Initialize your Go module and update package names:
go mod init github.com/your-org/your-project make fix-package-name -
Generate the protobuf code:
make proto -
Configure your connection by editing
config.yaml:server_address: "your-dragonchain-server:50051" smart_contract_id: "your-smart-contract-id" api_key: "your-api-key" -
Implement your smart contract logic in
process.goby modifying theProcessfunction. -
Build and run:
make build ./smart-contract -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.go:
func Process(ctx context.Context, txJSON string, envVars, secrets map[string]string) ProcessResult {
// Parse the transaction
var tx Transaction
if err := json.Unmarshal([]byte(txJSON), &tx); err != nil {
return ProcessResult{Error: fmt.Errorf("failed to parse transaction: %w", err)}
}
// Access transaction data
txnId := tx.Header.TxnId
txnType := tx.Header.TxnType
payload := tx.Payload
// Access environment variables
scName := envVars["SMART_CONTRACT_NAME"]
dcID := envVars["DRAGONCHAIN_ID"]
// Access secrets
mySecret := secrets["SC_SECRET_MY_SECRET"]
// Implement your logic here
result := map[string]any{
"status": "success",
"data": "your result data",
}
return ProcessResult{
Data: result,
OutputToChain: true, // Set to true to persist result on chain
Error: nil,
}
}
Transaction Structure
The Transaction struct in process.go matches the Dragonchain transaction format:
type Transaction struct {
Version string `json:"version"`
Header TransactionHeader `json:"header"`
Payload map[string]any `json:"payload"`
}
type TransactionHeader struct {
Tag string `json:"tag"`
DcId string `json:"dc_id"`
TxnId string `json:"txn_id"`
BlockId string `json:"block_id"`
TxnType string `json:"txn_type"`
Timestamp string `json:"timestamp"`
Invoker string `json:"invoker"`
}
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 map with keys prefixed by SC_SECRET_.
Project Structure
.
├── main.go # Client infrastructure (do not modify)
├── process.go # Your smart contract logic (modify this)
├── proto/
│ └── remote_sc.proto # gRPC service definition
├── config.yaml # Configuration file
├── go.mod # Go module definition
├── Makefile # Build commands
└── README.md # This file
File Descriptions
process.go- Contains theProcessfunction where you implement your smart contract logic. This is the only file you need to modify for most use cases.main.go- Contains the gRPC client infrastructure, connection handling, and worker pool. You typically don't need to modify this file.
Make Commands
make proto # Generate Go code from proto files
make build # Build the binary
make run # Run with default config
make test # Run tests
make clean # Remove build artifacts
make tools # Install required tools
make deps # Download dependencies
make fix-package-name # Update package name based on go.mod
Concurrent Processing
The client uses a worker pool pattern to process multiple transactions concurrently. The number of workers is configurable via num_workers in the config file.
Error Handling
- Return errors from the
Processfunction to report failures to the server - The client automatically handles reconnection on connection failures
- Logs are captured and sent back with the response
License
[Your License Here]