/** * Synor Compiler SDK Examples for C++ * * Demonstrates smart contract compilation and analysis: * - WASM contract compilation and optimization * - ABI extraction and encoding * - Contract analysis and security scanning * - Validation and verification */ #include #include #include #include using namespace synor::compiler; // Helper function to create a minimal valid WASM module for testing std::vector create_minimal_wasm() { return { 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 }; } void compile_contract_example(SynorCompiler& compiler) { std::cout << "=== Contract Compilation ===" << std::endl; auto wasm = create_minimal_wasm(); auto result = compiler.compile(wasm, { .optimization_level = OptimizationLevel::Size, .use_wasm_opt = true, .validate = true, .extract_metadata = true, .generate_abi = true, .strip_options = { .strip_debug = true, .strip_producers = true, .strip_names = true, .strip_custom = true, .strip_unused = true, .preserve_sections = {} } }); std::cout << "Compilation result:" << std::endl; std::cout << " Contract ID: " << result.contract_id() << std::endl; std::cout << " Code hash: " << result.code_hash() << std::endl; std::cout << " Original size: " << result.original_size() << " bytes" << std::endl; std::cout << " Optimized size: " << result.optimized_size() << " bytes" << std::endl; std::cout << " Size reduction: " << std::fixed << std::setprecision(1) << result.size_reduction() << "%" << std::endl; std::cout << " Estimated deploy gas: " << result.estimated_deploy_gas() << std::endl; if (result.metadata()) { std::cout << "\nMetadata:" << std::endl; std::cout << " Name: " << result.metadata()->name() << std::endl; std::cout << " Version: " << result.metadata()->version() << std::endl; std::cout << " SDK Version: " << result.metadata()->sdk_version() << std::endl; } if (result.abi()) { std::cout << "\nABI:" << std::endl; std::cout << " Functions: " << result.abi()->functions().size() << std::endl; std::cout << " Events: " << result.abi()->events().size() << std::endl; std::cout << " Errors: " << result.abi()->errors().size() << std::endl; } std::cout << std::endl; } void compilation_modes_example(SynorCompiler& compiler) { std::cout << "=== Compilation Modes ===" << std::endl; auto wasm = create_minimal_wasm(); // Development mode: fast compilation, debugging support std::cout << "Development mode:" << std::endl; auto dev_result = compiler.contracts().compile_dev(wasm); std::cout << " Size: " << dev_result.optimized_size() << " bytes" << std::endl; std::cout << " Optimization: none" << std::endl; // Production mode: maximum optimization std::cout << "\nProduction mode:" << std::endl; auto prod_result = compiler.contracts().compile_production(wasm); std::cout << " Size: " << prod_result.optimized_size() << " bytes" << std::endl; std::cout << " Optimization: aggressive" << std::endl; std::cout << " Size savings: " << (dev_result.optimized_size() - prod_result.optimized_size()) << " bytes" << std::endl; // Custom optimization levels std::cout << "\nOptimization levels:" << std::endl; std::vector> levels = { {OptimizationLevel::None, "NONE"}, {OptimizationLevel::Basic, "BASIC"}, {OptimizationLevel::Size, "SIZE"}, {OptimizationLevel::Aggressive, "AGGRESSIVE"} }; for (const auto& [level, name] : levels) { auto result = compiler.compile(wasm, {.optimization_level = level}); std::cout << " " << name << ": " << result.optimized_size() << " bytes" << std::endl; } std::cout << std::endl; } void abi_example(SynorCompiler& compiler) { std::cout << "=== ABI Operations ===" << std::endl; auto wasm = create_minimal_wasm(); // Extract ABI from WASM auto abi = compiler.abi().extract(wasm); std::cout << "Contract: " << abi.name() << std::endl; std::cout << "Version: " << abi.version() << std::endl; // List functions if (!abi.functions().empty()) { std::cout << "\nFunctions:" << std::endl; for (const auto& func : abi.functions()) { std::string inputs; for (size_t i = 0; i < func.inputs().size(); ++i) { const auto& param = func.inputs()[i]; if (i > 0) inputs += ", "; inputs += param.name() + ": " + param.type().type_name(); } std::string outputs; if (func.outputs().empty()) { outputs = "void"; } else { for (size_t i = 0; i < func.outputs().size(); ++i) { if (i > 0) outputs += ", "; outputs += func.outputs()[i].type().type_name(); } } std::string modifiers; if (func.view()) modifiers += "view "; if (func.payable()) modifiers += "payable"; std::cout << " " << func.name() << "(" << inputs << ") -> " << outputs << " " << modifiers << std::endl; std::cout << " Selector: " << func.selector() << std::endl; } } // List events if (!abi.events().empty()) { std::cout << "\nEvents:" << std::endl; for (const auto& event : abi.events()) { std::string params; for (size_t i = 0; i < event.params().size(); ++i) { const auto& param = event.params()[i]; if (i > 0) params += ", "; if (param.indexed()) params += "indexed "; params += param.name() + ": " + param.type().type_name(); } std::cout << " " << event.name() << "(" << params << ")" << std::endl; std::cout << " Topic: " << event.topic() << std::endl; } } // Encode a function call if (!abi.functions().empty()) { const auto& func = abi.functions().front(); auto encoded = compiler.abi().encode_call(func, {"arg1", "arg2"}); std::cout << "\nEncoded call to " << func.name() << ": " << encoded << std::endl; // Decode a result auto decoded = compiler.abi().decode_result(func, encoded); std::cout << "Decoded result: " << decoded << std::endl; } std::cout << std::endl; } void analysis_example(SynorCompiler& compiler) { std::cout << "=== Contract Analysis ===" << std::endl; auto wasm = create_minimal_wasm(); // Full analysis auto analysis = compiler.analysis().analyze(wasm); // Size breakdown if (analysis.size_breakdown()) { const auto& size = *analysis.size_breakdown(); std::cout << "Size breakdown:" << std::endl; std::cout << " Code: " << size.code() << " bytes" << std::endl; std::cout << " Data: " << size.data() << " bytes" << std::endl; std::cout << " Functions: " << size.functions() << " bytes" << std::endl; std::cout << " Memory: " << size.memory() << " bytes" << std::endl; std::cout << " Exports: " << size.exports() << " bytes" << std::endl; std::cout << " Imports: " << size.imports() << " bytes" << std::endl; std::cout << " Total: " << size.total() << " bytes" << std::endl; } // Function analysis if (!analysis.functions().empty()) { std::cout << "\nFunction analysis:" << std::endl; for (size_t i = 0; i < std::min(analysis.functions().size(), size_t(5)); ++i) { const auto& func = analysis.functions()[i]; std::cout << " " << func.name() << ":" << std::endl; std::cout << " Size: " << func.size() << " bytes" << std::endl; std::cout << " Instructions: " << func.instruction_count() << std::endl; std::cout << " Locals: " << func.local_count() << std::endl; std::cout << " Exported: " << (func.exported() ? "true" : "false") << std::endl; std::cout << " Estimated gas: " << func.estimated_gas() << std::endl; } } // Import analysis if (!analysis.imports().empty()) { std::cout << "\nImports:" << std::endl; for (const auto& imp : analysis.imports()) { std::cout << " " << imp.module() << "." << imp.name() << " (" << imp.kind() << ")" << std::endl; } } // Gas analysis if (analysis.gas_analysis()) { const auto& gas = *analysis.gas_analysis(); std::cout << "\nGas analysis:" << std::endl; std::cout << " Deployment: " << gas.deployment_gas() << std::endl; std::cout << " Memory init: " << gas.memory_init_gas() << std::endl; std::cout << " Data section: " << gas.data_section_gas() << std::endl; } // Extract metadata auto metadata = compiler.analysis().extract_metadata(wasm); std::cout << "\nContract metadata:" << std::endl; std::cout << " Name: " << metadata.name() << std::endl; std::cout << " Version: " << metadata.version() << std::endl; std::cout << " Build timestamp: " << metadata.build_timestamp() << std::endl; // Estimate deployment gas auto gas_estimate = compiler.analysis().estimate_deploy_gas(wasm); std::cout << "\nEstimated deployment gas: " << gas_estimate << std::endl; std::cout << std::endl; } void validation_example(SynorCompiler& compiler) { std::cout << "=== Contract Validation ===" << std::endl; auto wasm = create_minimal_wasm(); // Full validation auto result = compiler.validation().validate(wasm); std::cout << "Valid: " << (result.valid() ? "true" : "false") << std::endl; std::cout << "Exports: " << result.export_count() << std::endl; std::cout << "Imports: " << result.import_count() << std::endl; std::cout << "Functions: " << result.function_count() << std::endl; std::cout << "Memory pages: " << result.memory_pages() << std::endl; if (!result.errors().empty()) { std::cout << "\nValidation errors:" << std::endl; for (const auto& error : result.errors()) { std::cout << " [" << error.code() << "] " << error.message() << std::endl; if (!error.location().empty()) { std::cout << " at " << error.location() << std::endl; } } } if (!result.warnings().empty()) { std::cout << "\nWarnings:" << std::endl; for (const auto& warning : result.warnings()) { std::cout << " " << warning << std::endl; } } // Quick validation bool is_valid = compiler.validation().is_valid(wasm); std::cout << "\nQuick validation: " << (is_valid ? "true" : "false") << std::endl; // Get validation errors only auto errors = compiler.validation().get_errors(wasm); std::cout << "Error count: " << errors.size() << std::endl; // Validate required exports bool has_required = compiler.validation().validate_exports(wasm, {"init", "execute", "query"}); std::cout << "Has required exports: " << (has_required ? "true" : "false") << std::endl; // Validate memory constraints bool memory_valid = compiler.validation().validate_memory(wasm, 16); std::cout << "Memory within 16 pages: " << (memory_valid ? "true" : "false") << std::endl; std::cout << std::endl; } void security_example(SynorCompiler& compiler) { std::cout << "=== Security Scanning ===" << std::endl; auto wasm = create_minimal_wasm(); auto security = compiler.analysis().security_scan(wasm); std::cout << "Security score: " << security.score() << "/100" << std::endl; if (!security.issues().empty()) { std::cout << "\nSecurity issues:" << std::endl; for (const auto& issue : security.issues()) { std::string icon; std::string severity = issue.severity(); if (severity == "critical") icon = "[CRIT]"; else if (severity == "high") icon = "[HIGH]"; else if (severity == "medium") icon = "[MED]"; else if (severity == "low") icon = "[LOW]"; else icon = "[???]"; std::cout << icon << " [" << issue.severity() << "] " << issue.type() << std::endl; std::cout << " " << issue.description() << std::endl; if (!issue.location().empty()) { std::cout << " at " << issue.location() << std::endl; } } } else { std::cout << "No security issues found!" << std::endl; } if (!security.recommendations().empty()) { std::cout << "\nRecommendations:" << std::endl; for (const auto& rec : security.recommendations()) { std::cout << " • " << rec << std::endl; } } std::cout << std::endl; } int main(int argc, char** argv) { // Initialize client const char* api_key = std::getenv("SYNOR_API_KEY"); CompilerConfig config{ .api_key = api_key ? api_key : "your-api-key", .endpoint = "https://compiler.synor.io/v1", .timeout = std::chrono::seconds(60), .retries = 3, .debug = false, .default_optimization_level = OptimizationLevel::Size, .max_contract_size = 256 * 1024, .use_wasm_opt = true, .validate = true, .extract_metadata = true, .generate_abi = true }; SynorCompiler compiler(config); try { // Check service health bool healthy = compiler.health_check(); std::cout << "Service healthy: " << (healthy ? "true" : "false") << std::endl << std::endl; // Run examples compile_contract_example(compiler); compilation_modes_example(compiler); abi_example(compiler); analysis_example(compiler); validation_example(compiler); security_example(compiler); } catch (const std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; return 1; } return 0; }