synor/sdk/c/examples/compiler_example.c
Gulshan Yadav cf5130d9e4 feat(sdk): Add comprehensive examples for C, C++, C#, and Ruby SDKs
Add example code demonstrating all SDK services (Crypto, DEX, ZK, IBC,
Compiler) for the remaining languages:

- C SDK (5 examples): Using synor_* C API with explicit memory management
- C++ SDK (5 examples): Modern C++17 with RAII and designated initializers
- C# SDK (5 examples): Async/await patterns with .NET conventions
- Ruby SDK (5 examples): Ruby idioms with blocks and symbols

Each example covers:
- Crypto: Hybrid signatures, mnemonics, Falcon, SPHINCS+, KDF, hashing
- DEX: Markets, spot trading, perpetuals, liquidity, portfolio
- ZK: Circuits, Groth16, PLONK, STARK, recursive proofs, ceremonies
- IBC: Chains, channels, transfers, packets, relayer, monitoring
- Compiler: Compilation, optimization, ABI, analysis, validation, security
2026-01-28 14:44:04 +05:30

553 lines
20 KiB
C

/**
* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <synor/compiler.h>
// Helper function to create a minimal valid WASM module for testing
void create_minimal_wasm(uint8_t** wasm, size_t* wasm_len) {
static const uint8_t minimal_wasm[] = {
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
};
*wasm_len = sizeof(minimal_wasm);
*wasm = (uint8_t*)malloc(*wasm_len);
memcpy(*wasm, minimal_wasm, *wasm_len);
}
void compile_contract_example(synor_compiler_t* compiler) {
printf("=== Contract Compilation ===\n");
synor_error_t err;
uint8_t* wasm;
size_t wasm_len;
create_minimal_wasm(&wasm, &wasm_len);
synor_compile_options_t options = {
.optimization_level = SYNOR_OPTIMIZATION_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
}
};
synor_compile_result_t* result = NULL;
err = synor_compile(compiler, wasm, wasm_len, &options, &result);
free(wasm);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to compile contract\n");
return;
}
printf("Compilation result:\n");
printf(" Contract ID: %s\n", synor_compile_result_get_contract_id(result));
printf(" Code hash: %s\n", synor_compile_result_get_code_hash(result));
printf(" Original size: %zu bytes\n", synor_compile_result_get_original_size(result));
printf(" Optimized size: %zu bytes\n", synor_compile_result_get_optimized_size(result));
printf(" Size reduction: %.1f%%\n", synor_compile_result_get_size_reduction(result));
printf(" Estimated deploy gas: %lu\n", synor_compile_result_get_estimated_deploy_gas(result));
// Get metadata if available
synor_contract_metadata_t* metadata = synor_compile_result_get_metadata(result);
if (metadata) {
printf("\nMetadata:\n");
printf(" Name: %s\n", synor_metadata_get_name(metadata));
printf(" Version: %s\n", synor_metadata_get_version(metadata));
printf(" SDK Version: %s\n", synor_metadata_get_sdk_version(metadata));
}
// Get ABI if available
synor_contract_abi_t* abi = synor_compile_result_get_abi(result);
if (abi) {
printf("\nABI:\n");
printf(" Functions: %zu\n", synor_abi_get_function_count(abi));
printf(" Events: %zu\n", synor_abi_get_event_count(abi));
printf(" Errors: %zu\n", synor_abi_get_error_count(abi));
}
synor_compile_result_free(result);
printf("\n");
}
void compilation_modes_example(synor_compiler_t* compiler) {
printf("=== Compilation Modes ===\n");
synor_error_t err;
uint8_t* wasm;
size_t wasm_len;
create_minimal_wasm(&wasm, &wasm_len);
// Development mode: fast compilation, debugging support
printf("Development mode:\n");
synor_compile_result_t* dev_result = NULL;
err = synor_contracts_compile_dev(compiler, wasm, wasm_len, &dev_result);
if (err == SYNOR_OK) {
printf(" Size: %zu bytes\n", synor_compile_result_get_optimized_size(dev_result));
printf(" Optimization: none\n");
}
// Production mode: maximum optimization
printf("\nProduction mode:\n");
synor_compile_result_t* prod_result = NULL;
err = synor_contracts_compile_production(compiler, wasm, wasm_len, &prod_result);
if (err == SYNOR_OK) {
printf(" Size: %zu bytes\n", synor_compile_result_get_optimized_size(prod_result));
printf(" Optimization: aggressive\n");
if (dev_result) {
printf(" Size savings: %zu bytes\n",
synor_compile_result_get_optimized_size(dev_result) -
synor_compile_result_get_optimized_size(prod_result));
}
synor_compile_result_free(prod_result);
}
if (dev_result) synor_compile_result_free(dev_result);
// Custom optimization levels
printf("\nOptimization levels:\n");
synor_optimization_level_t levels[] = {
SYNOR_OPTIMIZATION_NONE,
SYNOR_OPTIMIZATION_BASIC,
SYNOR_OPTIMIZATION_SIZE,
SYNOR_OPTIMIZATION_AGGRESSIVE
};
const char* level_names[] = {"NONE", "BASIC", "SIZE", "AGGRESSIVE"};
for (int i = 0; i < 4; i++) {
synor_compile_options_t options = {
.optimization_level = levels[i]
};
synor_compile_result_t* result = NULL;
err = synor_compile(compiler, wasm, wasm_len, &options, &result);
if (err == SYNOR_OK) {
printf(" %s: %zu bytes\n", level_names[i],
synor_compile_result_get_optimized_size(result));
synor_compile_result_free(result);
}
}
free(wasm);
printf("\n");
}
void abi_example(synor_compiler_t* compiler) {
printf("=== ABI Operations ===\n");
synor_error_t err;
uint8_t* wasm;
size_t wasm_len;
create_minimal_wasm(&wasm, &wasm_len);
// Extract ABI from WASM
synor_contract_abi_t* abi = NULL;
err = synor_abi_extract(compiler, wasm, wasm_len, &abi);
free(wasm);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to extract ABI\n");
return;
}
printf("Contract: %s\n", synor_abi_get_name(abi));
printf("Version: %s\n", synor_abi_get_version(abi));
// List functions
size_t func_count = synor_abi_get_function_count(abi);
if (func_count > 0) {
printf("\nFunctions:\n");
for (size_t i = 0; i < func_count; i++) {
synor_abi_function_t* func = synor_abi_get_function(abi, i);
char inputs[256] = "";
size_t input_count = synor_abi_function_get_input_count(func);
for (size_t j = 0; j < input_count; j++) {
synor_abi_param_t* param = synor_abi_function_get_input(func, j);
char temp[64];
snprintf(temp, sizeof(temp), "%s: %s%s",
synor_abi_param_get_name(param),
synor_abi_param_get_type_name(param),
j < input_count - 1 ? ", " : "");
strncat(inputs, temp, sizeof(inputs) - strlen(inputs) - 1);
}
char outputs[128] = "void";
size_t output_count = synor_abi_function_get_output_count(func);
if (output_count > 0) {
outputs[0] = '\0';
for (size_t j = 0; j < output_count; j++) {
synor_abi_param_t* param = synor_abi_function_get_output(func, j);
char temp[64];
snprintf(temp, sizeof(temp), "%s%s",
synor_abi_param_get_type_name(param),
j < output_count - 1 ? ", " : "");
strncat(outputs, temp, sizeof(outputs) - strlen(outputs) - 1);
}
}
char modifiers[32] = "";
if (synor_abi_function_is_view(func)) strcat(modifiers, "view ");
if (synor_abi_function_is_payable(func)) strcat(modifiers, "payable");
printf(" %s(%s) -> %s %s\n",
synor_abi_function_get_name(func), inputs, outputs, modifiers);
printf(" Selector: %s\n", synor_abi_function_get_selector(func));
}
}
// List events
size_t event_count = synor_abi_get_event_count(abi);
if (event_count > 0) {
printf("\nEvents:\n");
for (size_t i = 0; i < event_count; i++) {
synor_abi_event_t* event = synor_abi_get_event(abi, i);
char params[256] = "";
size_t param_count = synor_abi_event_get_param_count(event);
for (size_t j = 0; j < param_count; j++) {
synor_abi_event_param_t* param = synor_abi_event_get_param(event, j);
char temp[64];
snprintf(temp, sizeof(temp), "%s%s: %s%s",
synor_abi_event_param_is_indexed(param) ? "indexed " : "",
synor_abi_event_param_get_name(param),
synor_abi_event_param_get_type_name(param),
j < param_count - 1 ? ", " : "");
strncat(params, temp, sizeof(params) - strlen(params) - 1);
}
printf(" %s(%s)\n", synor_abi_event_get_name(event), params);
printf(" Topic: %s\n", synor_abi_event_get_topic(event));
}
}
// Encode a function call
if (func_count > 0) {
synor_abi_function_t* func = synor_abi_get_function(abi, 0);
const char* args[] = {"arg1", "arg2"};
uint8_t* encoded;
size_t encoded_len;
err = synor_abi_encode_call(compiler, func, args, 2, &encoded, &encoded_len);
if (err == SYNOR_OK) {
printf("\nEncoded call to %s: ", synor_abi_function_get_name(func));
for (size_t i = 0; i < encoded_len && i < 20; i++) {
printf("%02x", encoded[i]);
}
printf("...\n");
// Decode a result
char** decoded;
size_t decoded_count;
err = synor_abi_decode_result(compiler, func, encoded, encoded_len,
&decoded, &decoded_count);
if (err == SYNOR_OK) {
printf("Decoded result: ");
for (size_t i = 0; i < decoded_count; i++) {
printf("%s%s", decoded[i], i < decoded_count - 1 ? ", " : "");
}
printf("\n");
synor_string_array_free(decoded, decoded_count);
}
free(encoded);
}
}
synor_abi_free(abi);
printf("\n");
}
void analysis_example(synor_compiler_t* compiler) {
printf("=== Contract Analysis ===\n");
synor_error_t err;
uint8_t* wasm;
size_t wasm_len;
create_minimal_wasm(&wasm, &wasm_len);
// Full analysis
synor_contract_analysis_t* analysis = NULL;
err = synor_analysis_analyze(compiler, wasm, wasm_len, &analysis);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to analyze contract\n");
free(wasm);
return;
}
// Size breakdown
synor_size_breakdown_t* size = synor_analysis_get_size_breakdown(analysis);
if (size) {
printf("Size breakdown:\n");
printf(" Code: %zu bytes\n", synor_size_breakdown_get_code(size));
printf(" Data: %zu bytes\n", synor_size_breakdown_get_data(size));
printf(" Functions: %zu bytes\n", synor_size_breakdown_get_functions(size));
printf(" Memory: %zu bytes\n", synor_size_breakdown_get_memory(size));
printf(" Exports: %zu bytes\n", synor_size_breakdown_get_exports(size));
printf(" Imports: %zu bytes\n", synor_size_breakdown_get_imports(size));
printf(" Total: %zu bytes\n", synor_size_breakdown_get_total(size));
}
// Function analysis
size_t func_count = synor_analysis_get_function_count(analysis);
if (func_count > 0) {
printf("\nFunction analysis:\n");
for (size_t i = 0; i < 5 && i < func_count; i++) {
synor_function_analysis_t* func = synor_analysis_get_function(analysis, i);
printf(" %s:\n", synor_function_analysis_get_name(func));
printf(" Size: %zu bytes\n", synor_function_analysis_get_size(func));
printf(" Instructions: %zu\n", synor_function_analysis_get_instruction_count(func));
printf(" Locals: %zu\n", synor_function_analysis_get_local_count(func));
printf(" Exported: %s\n", synor_function_analysis_is_exported(func) ? "true" : "false");
printf(" Estimated gas: %lu\n", synor_function_analysis_get_estimated_gas(func));
}
}
// Import analysis
size_t import_count = synor_analysis_get_import_count(analysis);
if (import_count > 0) {
printf("\nImports:\n");
for (size_t i = 0; i < import_count; i++) {
synor_import_analysis_t* imp = synor_analysis_get_import(analysis, i);
printf(" %s.%s (%s)\n",
synor_import_analysis_get_module(imp),
synor_import_analysis_get_name(imp),
synor_import_analysis_get_kind(imp));
}
}
// Gas analysis
synor_gas_analysis_t* gas = synor_analysis_get_gas_analysis(analysis);
if (gas) {
printf("\nGas analysis:\n");
printf(" Deployment: %lu\n", synor_gas_analysis_get_deployment_gas(gas));
printf(" Memory init: %lu\n", synor_gas_analysis_get_memory_init_gas(gas));
printf(" Data section: %lu\n", synor_gas_analysis_get_data_section_gas(gas));
}
synor_analysis_free(analysis);
// Extract metadata
synor_contract_metadata_t* metadata = NULL;
err = synor_analysis_extract_metadata(compiler, wasm, wasm_len, &metadata);
if (err == SYNOR_OK) {
printf("\nContract metadata:\n");
printf(" Name: %s\n", synor_metadata_get_name(metadata));
printf(" Version: %s\n", synor_metadata_get_version(metadata));
printf(" Build timestamp: %s\n", synor_metadata_get_build_timestamp(metadata));
synor_metadata_free(metadata);
}
// Estimate deployment gas
uint64_t gas_estimate;
err = synor_analysis_estimate_deploy_gas(compiler, wasm, wasm_len, &gas_estimate);
if (err == SYNOR_OK) {
printf("\nEstimated deployment gas: %lu\n", gas_estimate);
}
free(wasm);
printf("\n");
}
void validation_example(synor_compiler_t* compiler) {
printf("=== Contract Validation ===\n");
synor_error_t err;
uint8_t* wasm;
size_t wasm_len;
create_minimal_wasm(&wasm, &wasm_len);
// Full validation
synor_validation_result_t* result = NULL;
err = synor_validation_validate(compiler, wasm, wasm_len, &result);
if (err == SYNOR_OK) {
printf("Valid: %s\n", synor_validation_result_is_valid(result) ? "true" : "false");
printf("Exports: %zu\n", synor_validation_result_get_export_count(result));
printf("Imports: %zu\n", synor_validation_result_get_import_count(result));
printf("Functions: %zu\n", synor_validation_result_get_function_count(result));
printf("Memory pages: %zu\n", synor_validation_result_get_memory_pages(result));
// Print errors
size_t error_count = synor_validation_result_get_error_count(result);
if (error_count > 0) {
printf("\nValidation errors:\n");
for (size_t i = 0; i < error_count; i++) {
synor_validation_error_t* error = synor_validation_result_get_error(result, i);
printf(" [%s] %s\n",
synor_validation_error_get_code(error),
synor_validation_error_get_message(error));
const char* location = synor_validation_error_get_location(error);
if (location) {
printf(" at %s\n", location);
}
}
}
// Print warnings
size_t warning_count = synor_validation_result_get_warning_count(result);
if (warning_count > 0) {
printf("\nWarnings:\n");
for (size_t i = 0; i < warning_count; i++) {
printf(" %s\n", synor_validation_result_get_warning(result, i));
}
}
synor_validation_result_free(result);
}
// Quick validation
bool is_valid;
err = synor_validation_is_valid(compiler, wasm, wasm_len, &is_valid);
printf("\nQuick validation: %s\n", is_valid ? "true" : "false");
// Get validation errors only
synor_validation_error_list_t* errors = NULL;
err = synor_validation_get_errors(compiler, wasm, wasm_len, &errors);
if (err == SYNOR_OK) {
printf("Error count: %zu\n", synor_validation_error_list_count(errors));
synor_validation_error_list_free(errors);
}
// Validate required exports
const char* required[] = {"init", "execute", "query"};
bool has_required;
err = synor_validation_validate_exports(compiler, wasm, wasm_len,
required, 3, &has_required);
printf("Has required exports: %s\n", has_required ? "true" : "false");
// Validate memory constraints
bool memory_valid;
err = synor_validation_validate_memory(compiler, wasm, wasm_len, 16, &memory_valid);
printf("Memory within 16 pages: %s\n", memory_valid ? "true" : "false");
free(wasm);
printf("\n");
}
void security_example(synor_compiler_t* compiler) {
printf("=== Security Scanning ===\n");
synor_error_t err;
uint8_t* wasm;
size_t wasm_len;
create_minimal_wasm(&wasm, &wasm_len);
synor_security_scan_result_t* security = NULL;
err = synor_analysis_security_scan(compiler, wasm, wasm_len, &security);
free(wasm);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to scan contract\n");
return;
}
printf("Security score: %d/100\n", synor_security_scan_get_score(security));
size_t issue_count = synor_security_scan_get_issue_count(security);
if (issue_count > 0) {
printf("\nSecurity issues:\n");
for (size_t i = 0; i < issue_count; i++) {
synor_security_issue_t* issue = synor_security_scan_get_issue(security, i);
const char* severity = synor_security_issue_get_severity(issue);
const char* icon;
if (strcmp(severity, "critical") == 0) icon = "[CRIT]";
else if (strcmp(severity, "high") == 0) icon = "[HIGH]";
else if (strcmp(severity, "medium") == 0) icon = "[MED]";
else if (strcmp(severity, "low") == 0) icon = "[LOW]";
else icon = "[???]";
printf("%s [%s] %s\n", icon,
synor_security_issue_get_severity(issue),
synor_security_issue_get_type(issue));
printf(" %s\n", synor_security_issue_get_description(issue));
const char* location = synor_security_issue_get_location(issue);
if (location) {
printf(" at %s\n", location);
}
}
} else {
printf("No security issues found!\n");
}
size_t rec_count = synor_security_scan_get_recommendation_count(security);
if (rec_count > 0) {
printf("\nRecommendations:\n");
for (size_t i = 0; i < rec_count; i++) {
printf(" • %s\n", synor_security_scan_get_recommendation(security, i));
}
}
synor_security_scan_result_free(security);
printf("\n");
}
int main(int argc, char** argv) {
synor_error_t err;
// Initialize client
synor_compiler_config_t config = {
.api_key = getenv("SYNOR_API_KEY") ? getenv("SYNOR_API_KEY") : "your-api-key",
.endpoint = "https://compiler.synor.io/v1",
.timeout_ms = 60000,
.retries = 3,
.debug = false,
.default_optimization_level = SYNOR_OPTIMIZATION_SIZE,
.max_contract_size = 256 * 1024,
.use_wasm_opt = true,
.validate = true,
.extract_metadata = true,
.generate_abi = true
};
synor_compiler_t* compiler = NULL;
err = synor_compiler_init(&config, &compiler);
if (err != SYNOR_OK) {
fprintf(stderr, "Failed to initialize compiler client: %s\n", synor_error_string(err));
return 1;
}
// Check service health
bool healthy;
err = synor_compiler_health_check(compiler, &healthy);
printf("Service healthy: %s\n\n", healthy ? "true" : "false");
// Run examples
compile_contract_example(compiler);
compilation_modes_example(compiler);
abi_example(compiler);
analysis_example(compiler);
validation_example(compiler);
security_example(compiler);
// Cleanup
synor_compiler_free(compiler);
return 0;
}