// 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 }