synor/sdk/go/examples/compiler_example.go
Gulshan Yadav 9416d76108 Add IBC and ZK SDK examples for Rust
- Introduced `ibc_example.rs` demonstrating Inter-Blockchain Communication operations including cross-chain transfers, channel management, packet handling, and relayer operations.
- Introduced `zk_example.rs` showcasing Zero-Knowledge proof operations such as circuit compilation, proof generation and verification, and on-chain verification with multiple proving systems.
2026-01-28 14:15:51 +05:30

465 lines
12 KiB
Go

// Package main demonstrates the Synor Compiler SDK for Go
//
// This example covers smart contract compilation and analysis:
// - WASM contract compilation and optimization
// - ABI extraction and encoding
// - Contract analysis and security scanning
// - Validation and verification
package main
import (
"context"
"fmt"
"log"
"os"
"time"
"github.com/synor/sdk-go/compiler"
)
func main() {
// Initialize client
config := compiler.Config{
APIKey: getEnv("SYNOR_API_KEY", "your-api-key"),
Endpoint: "https://compiler.synor.io/v1",
Timeout: 60 * time.Second,
Retries: 3,
Debug: false,
DefaultOptimizationLevel: compiler.OptimizationSize,
MaxContractSize: 256 * 1024,
UseWasmOpt: true,
Validate: true,
ExtractMetadata: true,
GenerateABI: true,
}
client, err := compiler.NewClient(config)
if err != nil {
log.Fatalf("Failed to create client: %v", err)
}
defer client.Close()
ctx := context.Background()
// Check service health
healthy, err := client.HealthCheck(ctx)
if err != nil {
log.Printf("Health check failed: %v", err)
} else {
fmt.Printf("Service healthy: %v\n\n", healthy)
}
// Run examples
compileContractExample(ctx, client)
compilationModesExample(ctx, client)
abiExample(ctx, client)
analysisExample(ctx, client)
validationExample(ctx, client)
securityExample(ctx, client)
}
// createMinimalWasm creates a minimal valid WASM module for testing.
func createMinimalWasm() []byte {
return []byte{
0x00, 0x61, 0x73, 0x6d, // Magic: \0asm
0x01, 0x00, 0x00, 0x00, // Version: 1
// Type section
0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, 0x7f, 0x01, 0x7f,
// Function section
0x03, 0x02, 0x01, 0x00,
// Export section
0x07, 0x08, 0x01, 0x04, 0x61, 0x64, 0x64, 0x00, 0x00,
// Code section
0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b,
}
}
func compileContractExample(ctx context.Context, client *compiler.Client) {
fmt.Println("=== Contract Compilation ===")
wasm := createMinimalWasm()
result, err := client.Compile(ctx, wasm, &compiler.CompileOptions{
OptimizationLevel: compiler.OptimizationSize,
UseWasmOpt: true,
Validate: true,
ExtractMetadata: true,
GenerateABI: true,
StripOptions: &compiler.StripOptions{
StripDebug: true,
StripProducers: true,
StripNames: true,
StripCustom: true,
StripUnused: true,
PreserveSections: []string{},
},
})
if err != nil {
log.Printf("Failed to compile contract: %v", err)
return
}
fmt.Println("Compilation result:")
fmt.Printf(" Contract ID: %s\n", result.ContractID)
fmt.Printf(" Code hash: %s\n", result.CodeHash)
fmt.Printf(" Original size: %d bytes\n", result.OriginalSize)
fmt.Printf(" Optimized size: %d bytes\n", result.OptimizedSize)
fmt.Printf(" Size reduction: %.1f%%\n", result.SizeReduction)
fmt.Printf(" Estimated deploy gas: %d\n", result.EstimatedDeployGas)
if result.Metadata != nil {
fmt.Println("\nMetadata:")
fmt.Printf(" Name: %s\n", result.Metadata.Name)
fmt.Printf(" Version: %s\n", result.Metadata.Version)
fmt.Printf(" SDK Version: %s\n", result.Metadata.SDKVersion)
}
if result.ABI != nil {
fmt.Println("\nABI:")
fmt.Printf(" Functions: %d\n", len(result.ABI.Functions))
fmt.Printf(" Events: %d\n", len(result.ABI.Events))
fmt.Printf(" Errors: %d\n", len(result.ABI.Errors))
}
fmt.Println()
}
func compilationModesExample(ctx context.Context, client *compiler.Client) {
fmt.Println("=== Compilation Modes ===")
wasm := createMinimalWasm()
// Development mode: fast compilation, debugging support
fmt.Println("Development mode:")
devResult, err := client.Contracts.CompileDev(ctx, wasm)
if err != nil {
log.Printf("Failed to compile in dev mode: %v", err)
return
}
fmt.Printf(" Size: %d bytes\n", devResult.OptimizedSize)
fmt.Println(" Optimization: none")
// Production mode: maximum optimization
fmt.Println("\nProduction mode:")
prodResult, err := client.Contracts.CompileProduction(ctx, wasm)
if err != nil {
log.Printf("Failed to compile in production mode: %v", err)
return
}
fmt.Printf(" Size: %d bytes\n", prodResult.OptimizedSize)
fmt.Println(" Optimization: aggressive")
fmt.Printf(" Size savings: %d bytes\n", devResult.OptimizedSize-prodResult.OptimizedSize)
// Custom optimization levels
fmt.Println("\nOptimization levels:")
levels := []compiler.OptimizationLevel{
compiler.OptimizationNone,
compiler.OptimizationBasic,
compiler.OptimizationSize,
compiler.OptimizationAggressive,
}
for _, level := range levels {
result, err := client.Compile(ctx, wasm, &compiler.CompileOptions{
OptimizationLevel: level,
})
if err != nil {
log.Printf("Failed to compile with %s: %v", level, err)
continue
}
fmt.Printf(" %s: %d bytes\n", level, result.OptimizedSize)
}
fmt.Println()
}
func abiExample(ctx context.Context, client *compiler.Client) {
fmt.Println("=== ABI Operations ===")
wasm := createMinimalWasm()
// Extract ABI from WASM
abi, err := client.ABI.Extract(ctx, wasm)
if err != nil {
log.Printf("Failed to extract ABI: %v", err)
return
}
fmt.Printf("Contract: %s\n", abi.Name)
fmt.Printf("Version: %s\n", abi.Version)
// List functions
if len(abi.Functions) > 0 {
fmt.Println("\nFunctions:")
for _, fn := range abi.Functions {
inputs := ""
for i, input := range fn.Inputs {
if i > 0 {
inputs += ", "
}
inputs += fmt.Sprintf("%s: %s", input.Name, input.Type.TypeName)
}
outputs := "void"
if len(fn.Outputs) > 0 {
outputTypes := make([]string, len(fn.Outputs))
for i, output := range fn.Outputs {
outputTypes[i] = output.Type.TypeName
}
outputs = fmt.Sprintf("%v", outputTypes)
}
modifiers := ""
if fn.View {
modifiers += "view "
}
if fn.Payable {
modifiers += "payable"
}
fmt.Printf(" %s(%s) -> %s %s\n", fn.Name, inputs, outputs, modifiers)
fmt.Printf(" Selector: %s\n", fn.Selector)
}
}
// List events
if len(abi.Events) > 0 {
fmt.Println("\nEvents:")
for _, event := range abi.Events {
params := ""
for i, param := range event.Params {
if i > 0 {
params += ", "
}
indexed := ""
if param.Indexed {
indexed = "indexed "
}
params += fmt.Sprintf("%s%s: %s", indexed, param.Name, param.Type.TypeName)
}
fmt.Printf(" %s(%s)\n", event.Name, params)
fmt.Printf(" Topic: %s\n", event.Topic)
}
}
// Encode a function call
if len(abi.Functions) > 0 {
fn := abi.Functions[0]
encoded, err := client.ABI.EncodeCall(ctx, fn, []interface{}{"arg1", "arg2"})
if err != nil {
log.Printf("Failed to encode call: %v", err)
} else {
fmt.Printf("\nEncoded call to %s: %s\n", fn.Name, encoded)
}
// Decode a result
decoded, err := client.ABI.DecodeResult(ctx, fn, encoded)
if err != nil {
log.Printf("Failed to decode result: %v", err)
} else {
fmt.Printf("Decoded result: %v\n", decoded)
}
}
fmt.Println()
}
func analysisExample(ctx context.Context, client *compiler.Client) {
fmt.Println("=== Contract Analysis ===")
wasm := createMinimalWasm()
// Full analysis
analysis, err := client.Analysis.Analyze(ctx, wasm)
if err != nil {
log.Printf("Failed to analyze contract: %v", err)
return
}
// Size breakdown
if analysis.SizeBreakdown != nil {
fmt.Println("Size breakdown:")
fmt.Printf(" Code: %d bytes\n", analysis.SizeBreakdown.Code)
fmt.Printf(" Data: %d bytes\n", analysis.SizeBreakdown.Data)
fmt.Printf(" Functions: %d bytes\n", analysis.SizeBreakdown.Functions)
fmt.Printf(" Memory: %d bytes\n", analysis.SizeBreakdown.Memory)
fmt.Printf(" Exports: %d bytes\n", analysis.SizeBreakdown.Exports)
fmt.Printf(" Imports: %d bytes\n", analysis.SizeBreakdown.Imports)
fmt.Printf(" Total: %d bytes\n", analysis.SizeBreakdown.Total)
}
// Function analysis
if len(analysis.Functions) > 0 {
fmt.Println("\nFunction analysis:")
limit := 5
if len(analysis.Functions) < limit {
limit = len(analysis.Functions)
}
for _, fn := range analysis.Functions[:limit] {
fmt.Printf(" %s:\n", fn.Name)
fmt.Printf(" Size: %d bytes\n", fn.Size)
fmt.Printf(" Instructions: %d\n", fn.InstructionCount)
fmt.Printf(" Locals: %d\n", fn.LocalCount)
fmt.Printf(" Exported: %v\n", fn.Exported)
fmt.Printf(" Estimated gas: %d\n", fn.EstimatedGas)
}
}
// Import analysis
if len(analysis.Imports) > 0 {
fmt.Println("\nImports:")
for _, imp := range analysis.Imports {
fmt.Printf(" %s.%s (%s)\n", imp.Module, imp.Name, imp.Kind)
}
}
// Gas analysis
if analysis.GasAnalysis != nil {
fmt.Println("\nGas analysis:")
fmt.Printf(" Deployment: %d\n", analysis.GasAnalysis.DeploymentGas)
fmt.Printf(" Memory init: %d\n", analysis.GasAnalysis.MemoryInitGas)
fmt.Printf(" Data section: %d\n", analysis.GasAnalysis.DataSectionGas)
}
// Extract metadata
metadata, err := client.Analysis.ExtractMetadata(ctx, wasm)
if err != nil {
log.Printf("Failed to extract metadata: %v", err)
} else {
fmt.Println("\nContract metadata:")
fmt.Printf(" Name: %s\n", metadata.Name)
fmt.Printf(" Version: %s\n", metadata.Version)
fmt.Printf(" Build timestamp: %s\n", metadata.BuildTimestamp)
}
// Estimate deployment gas
gas, err := client.Analysis.EstimateDeployGas(ctx, wasm)
if err != nil {
log.Printf("Failed to estimate deploy gas: %v", err)
} else {
fmt.Printf("\nEstimated deployment gas: %d\n", gas)
}
fmt.Println()
}
func validationExample(ctx context.Context, client *compiler.Client) {
fmt.Println("=== Contract Validation ===")
wasm := createMinimalWasm()
// Full validation
result, err := client.Validation.Validate(ctx, wasm)
if err != nil {
log.Printf("Failed to validate contract: %v", err)
return
}
fmt.Printf("Valid: %v\n", result.Valid)
fmt.Printf("Exports: %d\n", result.ExportCount)
fmt.Printf("Imports: %d\n", result.ImportCount)
fmt.Printf("Functions: %d\n", result.FunctionCount)
fmt.Printf("Memory pages: %d\n", result.MemoryPages)
if len(result.Errors) > 0 {
fmt.Println("\nValidation errors:")
for _, e := range result.Errors {
fmt.Printf(" [%s] %s\n", e.Code, e.Message)
if e.Location != "" {
fmt.Printf(" at %s\n", e.Location)
}
}
}
if len(result.Warnings) > 0 {
fmt.Println("\nWarnings:")
for _, warning := range result.Warnings {
fmt.Printf(" %s\n", warning)
}
}
// Quick validation
isValid, err := client.Validation.IsValid(ctx, wasm)
if err != nil {
log.Printf("Failed quick validation: %v", err)
} else {
fmt.Printf("\nQuick validation: %v\n", isValid)
}
// Get validation errors only
errors, err := client.Validation.GetErrors(ctx, wasm)
if err != nil {
log.Printf("Failed to get validation errors: %v", err)
} else {
fmt.Printf("Error count: %d\n", len(errors))
}
// Validate required exports
hasRequired, err := client.Validation.ValidateExports(ctx, wasm, []string{"init", "execute", "query"})
if err != nil {
log.Printf("Failed to validate exports: %v", err)
} else {
fmt.Printf("Has required exports: %v\n", hasRequired)
}
// Validate memory constraints
memoryValid, err := client.Validation.ValidateMemory(ctx, wasm, 16)
if err != nil {
log.Printf("Failed to validate memory: %v", err)
} else {
fmt.Printf("Memory within 16 pages: %v\n", memoryValid)
}
fmt.Println()
}
func securityExample(ctx context.Context, client *compiler.Client) {
fmt.Println("=== Security Scanning ===")
wasm := createMinimalWasm()
security, err := client.Analysis.SecurityScan(ctx, wasm)
if err != nil {
log.Printf("Failed to perform security scan: %v", err)
return
}
fmt.Printf("Security score: %d/100\n", security.Score)
if len(security.Issues) > 0 {
fmt.Println("\nSecurity issues:")
severityIcons := map[string]string{
"critical": "[CRIT]",
"high": "[HIGH]",
"medium": "[MED]",
"low": "[LOW]",
}
for _, issue := range security.Issues {
icon := severityIcons[issue.Severity]
if icon == "" {
icon = "[???]"
}
fmt.Printf("%s [%s] %s\n", icon, issue.Severity, issue.Type)
fmt.Printf(" %s\n", issue.Description)
if issue.Location != "" {
fmt.Printf(" at %s\n", issue.Location)
}
}
} else {
fmt.Println("No security issues found!")
}
if len(security.Recommendations) > 0 {
fmt.Println("\nRecommendations:")
for _, rec := range security.Recommendations {
fmt.Printf(" * %s\n", rec)
}
}
fmt.Println()
}
func getEnv(key, defaultValue string) string {
if value := os.Getenv(key); value != "" {
return value
}
return defaultValue
}