package io.synor.examples; import io.synor.compiler.*; import io.synor.compiler.types.*; import java.util.List; import java.util.concurrent.CompletableFuture; /** * Synor Compiler SDK Examples for Java * * Demonstrates smart contract compilation and analysis: * - WASM contract compilation and optimization * - ABI extraction and encoding * - Contract analysis and security scanning * - Validation and verification */ public class CompilerExample { public static void main(String[] args) throws Exception { // Initialize client CompilerConfig config = CompilerConfig.builder() .apiKey(System.getenv("SYNOR_API_KEY") != null ? System.getenv("SYNOR_API_KEY") : "your-api-key") .endpoint("https://compiler.synor.io/v1") .timeout(60000) .retries(3) .debug(false) .defaultOptimizationLevel(OptimizationLevel.SIZE) .maxContractSize(256 * 1024) .useWasmOpt(true) .validate(true) .extractMetadata(true) .generateAbi(true) .build(); SynorCompiler compiler = new SynorCompiler(config); try { // Check service health boolean healthy = compiler.healthCheck().get(); System.out.println("Service healthy: " + healthy + "\n"); // Run examples compileContractExample(compiler); compilationModesExample(compiler); abiExample(compiler); analysisExample(compiler); validationExample(compiler); securityExample(compiler); } finally { compiler.close(); } } /** * Create a minimal valid WASM module for testing. */ static byte[] createMinimalWasm() { return new 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 }; } static void compileContractExample(SynorCompiler compiler) throws Exception { System.out.println("=== Contract Compilation ==="); byte[] wasm = createMinimalWasm(); CompileResult result = compiler.compile(wasm, CompileOptions.builder() .optimizationLevel(OptimizationLevel.SIZE) .useWasmOpt(true) .validate(true) .extractMetadata(true) .generateAbi(true) .stripOptions(StripOptions.builder() .stripDebug(true) .stripProducers(true) .stripNames(true) .stripCustom(true) .stripUnused(true) .preserveSections(List.of()) .build()) .build()).get(); System.out.println("Compilation result:"); System.out.println(" Contract ID: " + result.getContractId()); System.out.println(" Code hash: " + result.getCodeHash()); System.out.println(" Original size: " + result.getOriginalSize() + " bytes"); System.out.println(" Optimized size: " + result.getOptimizedSize() + " bytes"); System.out.println(" Size reduction: " + String.format("%.1f", result.getSizeReduction()) + "%"); System.out.println(" Estimated deploy gas: " + result.getEstimatedDeployGas()); if (result.getMetadata() != null) { System.out.println("\nMetadata:"); System.out.println(" Name: " + result.getMetadata().getName()); System.out.println(" Version: " + result.getMetadata().getVersion()); System.out.println(" SDK Version: " + result.getMetadata().getSdkVersion()); } if (result.getAbi() != null) { System.out.println("\nABI:"); System.out.println(" Functions: " + (result.getAbi().getFunctions() != null ? result.getAbi().getFunctions().size() : 0)); System.out.println(" Events: " + (result.getAbi().getEvents() != null ? result.getAbi().getEvents().size() : 0)); System.out.println(" Errors: " + (result.getAbi().getErrors() != null ? result.getAbi().getErrors().size() : 0)); } System.out.println(); } static void compilationModesExample(SynorCompiler compiler) throws Exception { System.out.println("=== Compilation Modes ==="); byte[] wasm = createMinimalWasm(); // Development mode: fast compilation, debugging support System.out.println("Development mode:"); CompileResult devResult = compiler.contracts().compileDev(wasm).get(); System.out.println(" Size: " + devResult.getOptimizedSize() + " bytes"); System.out.println(" Optimization: none"); // Production mode: maximum optimization System.out.println("\nProduction mode:"); CompileResult prodResult = compiler.contracts().compileProduction(wasm).get(); System.out.println(" Size: " + prodResult.getOptimizedSize() + " bytes"); System.out.println(" Optimization: aggressive"); System.out.println(" Size savings: " + (devResult.getOptimizedSize() - prodResult.getOptimizedSize()) + " bytes"); // Custom optimization levels System.out.println("\nOptimization levels:"); OptimizationLevel[] levels = { OptimizationLevel.NONE, OptimizationLevel.BASIC, OptimizationLevel.SIZE, OptimizationLevel.AGGRESSIVE }; for (OptimizationLevel level : levels) { CompileResult result = compiler.compile(wasm, CompileOptions.builder() .optimizationLevel(level) .build()).get(); System.out.println(" " + level + ": " + result.getOptimizedSize() + " bytes"); } System.out.println(); } static void abiExample(SynorCompiler compiler) throws Exception { System.out.println("=== ABI Operations ==="); byte[] wasm = createMinimalWasm(); // Extract ABI from WASM ContractAbi abi = compiler.abi().extract(wasm).get(); System.out.println("Contract: " + abi.getName()); System.out.println("Version: " + abi.getVersion()); // List functions if (abi.getFunctions() != null && !abi.getFunctions().isEmpty()) { System.out.println("\nFunctions:"); for (AbiFunction func : abi.getFunctions()) { StringBuilder inputs = new StringBuilder(); if (func.getInputs() != null) { for (int i = 0; i < func.getInputs().size(); i++) { AbiParam param = func.getInputs().get(i); if (i > 0) inputs.append(", "); inputs.append(param.getName()).append(": ").append(param.getType().getTypeName()); } } StringBuilder outputs = new StringBuilder(); if (func.getOutputs() != null && !func.getOutputs().isEmpty()) { for (int i = 0; i < func.getOutputs().size(); i++) { if (i > 0) outputs.append(", "); outputs.append(func.getOutputs().get(i).getType().getTypeName()); } } else { outputs.append("void"); } StringBuilder modifiers = new StringBuilder(); if (func.isView()) modifiers.append("view "); if (func.isPayable()) modifiers.append("payable"); System.out.println(" " + func.getName() + "(" + inputs + ") -> " + outputs + " " + modifiers); System.out.println(" Selector: " + func.getSelector()); } } // List events if (abi.getEvents() != null && !abi.getEvents().isEmpty()) { System.out.println("\nEvents:"); for (AbiEvent event : abi.getEvents()) { StringBuilder params = new StringBuilder(); if (event.getParams() != null) { for (int i = 0; i < event.getParams().size(); i++) { AbiEventParam param = event.getParams().get(i); if (i > 0) params.append(", "); if (param.isIndexed()) params.append("indexed "); params.append(param.getName()).append(": ").append(param.getType().getTypeName()); } } System.out.println(" " + event.getName() + "(" + params + ")"); System.out.println(" Topic: " + event.getTopic()); } } // Encode a function call if (abi.getFunctions() != null && !abi.getFunctions().isEmpty()) { AbiFunction func = abi.getFunctions().get(0); byte[] encoded = compiler.abi().encodeCall(func, List.of("arg1", "arg2")).get(); System.out.println("\nEncoded call to " + func.getName() + ": " + bytesToHex(encoded)); // Decode a result Object decoded = compiler.abi().decodeResult(func, encoded).get(); System.out.println("Decoded result: " + decoded); } System.out.println(); } static void analysisExample(SynorCompiler compiler) throws Exception { System.out.println("=== Contract Analysis ==="); byte[] wasm = createMinimalWasm(); // Full analysis ContractAnalysis analysis = compiler.analysis().analyze(wasm).get(); // Size breakdown if (analysis.getSizeBreakdown() != null) { SizeBreakdown size = analysis.getSizeBreakdown(); System.out.println("Size breakdown:"); System.out.println(" Code: " + size.getCode() + " bytes"); System.out.println(" Data: " + size.getData() + " bytes"); System.out.println(" Functions: " + size.getFunctions() + " bytes"); System.out.println(" Memory: " + size.getMemory() + " bytes"); System.out.println(" Exports: " + size.getExports() + " bytes"); System.out.println(" Imports: " + size.getImports() + " bytes"); System.out.println(" Total: " + size.getTotal() + " bytes"); } // Function analysis if (analysis.getFunctions() != null && !analysis.getFunctions().isEmpty()) { System.out.println("\nFunction analysis:"); for (FunctionAnalysis func : analysis.getFunctions().subList(0, Math.min(5, analysis.getFunctions().size()))) { System.out.println(" " + func.getName() + ":"); System.out.println(" Size: " + func.getSize() + " bytes"); System.out.println(" Instructions: " + func.getInstructionCount()); System.out.println(" Locals: " + func.getLocalCount()); System.out.println(" Exported: " + func.isExported()); System.out.println(" Estimated gas: " + func.getEstimatedGas()); } } // Import analysis if (analysis.getImports() != null && !analysis.getImports().isEmpty()) { System.out.println("\nImports:"); for (ImportAnalysis imp : analysis.getImports()) { System.out.println(" " + imp.getModule() + "." + imp.getName() + " (" + imp.getKind() + ")"); } } // Gas analysis if (analysis.getGasAnalysis() != null) { GasAnalysis gas = analysis.getGasAnalysis(); System.out.println("\nGas analysis:"); System.out.println(" Deployment: " + gas.getDeploymentGas()); System.out.println(" Memory init: " + gas.getMemoryInitGas()); System.out.println(" Data section: " + gas.getDataSectionGas()); } // Extract metadata ContractMetadata metadata = compiler.analysis().extractMetadata(wasm).get(); System.out.println("\nContract metadata:"); System.out.println(" Name: " + metadata.getName()); System.out.println(" Version: " + metadata.getVersion()); System.out.println(" Build timestamp: " + metadata.getBuildTimestamp()); // Estimate deployment gas long gasEstimate = compiler.analysis().estimateDeployGas(wasm).get(); System.out.println("\nEstimated deployment gas: " + gasEstimate); System.out.println(); } static void validationExample(SynorCompiler compiler) throws Exception { System.out.println("=== Contract Validation ==="); byte[] wasm = createMinimalWasm(); // Full validation ValidationResult result = compiler.validation().validate(wasm).get(); System.out.println("Valid: " + result.isValid()); System.out.println("Exports: " + result.getExportCount()); System.out.println("Imports: " + result.getImportCount()); System.out.println("Functions: " + result.getFunctionCount()); System.out.println("Memory pages: " + result.getMemoryPages()); if (result.getErrors() != null && !result.getErrors().isEmpty()) { System.out.println("\nValidation errors:"); for (ValidationError error : result.getErrors()) { System.out.println(" [" + error.getCode() + "] " + error.getMessage()); if (error.getLocation() != null) { System.out.println(" at " + error.getLocation()); } } } if (result.getWarnings() != null && !result.getWarnings().isEmpty()) { System.out.println("\nWarnings:"); for (String warning : result.getWarnings()) { System.out.println(" " + warning); } } // Quick validation boolean isValid = compiler.validation().isValid(wasm).get(); System.out.println("\nQuick validation: " + isValid); // Get validation errors only List errors = compiler.validation().getErrors(wasm).get(); System.out.println("Error count: " + errors.size()); // Validate required exports boolean hasRequired = compiler.validation().validateExports( wasm, List.of("init", "execute", "query") ).get(); System.out.println("Has required exports: " + hasRequired); // Validate memory constraints boolean memoryValid = compiler.validation().validateMemory(wasm, 16).get(); System.out.println("Memory within 16 pages: " + memoryValid); System.out.println(); } static void securityExample(SynorCompiler compiler) throws Exception { System.out.println("=== Security Scanning ==="); byte[] wasm = createMinimalWasm(); SecurityScanResult security = compiler.analysis().securityScan(wasm).get(); System.out.println("Security score: " + security.getScore() + "/100"); if (security.getIssues() != null && !security.getIssues().isEmpty()) { System.out.println("\nSecurity issues:"); for (SecurityIssue issue : security.getIssues()) { String icon; switch (issue.getSeverity().toLowerCase()) { case "critical": icon = "[CRIT]"; break; case "high": icon = "[HIGH]"; break; case "medium": icon = "[MED]"; break; case "low": icon = "[LOW]"; break; default: icon = "[???]"; } System.out.println(icon + " [" + issue.getSeverity().toUpperCase() + "] " + issue.getType()); System.out.println(" " + issue.getDescription()); if (issue.getLocation() != null) { System.out.println(" at " + issue.getLocation()); } } } else { System.out.println("No security issues found!"); } if (security.getRecommendations() != null && !security.getRecommendations().isEmpty()) { System.out.println("\nRecommendations:"); for (String rec : security.getRecommendations()) { System.out.println(" • " + rec); } } System.out.println(); } private static String bytesToHex(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (byte b : bytes) { sb.append(String.format("%02x", b)); } return sb.toString(); } }