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
415 lines
14 KiB
C#
415 lines
14 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
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using Synor.Compiler;
|
|
|
|
namespace Synor.Examples;
|
|
|
|
public class CompilerExample
|
|
{
|
|
private readonly SynorCompiler _compiler;
|
|
|
|
public CompilerExample(SynorCompiler compiler)
|
|
{
|
|
_compiler = compiler;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a minimal valid WASM module for testing
|
|
/// </summary>
|
|
private 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, (byte)'a', (byte)'d', (byte)'d', 0x00, 0x00,
|
|
// Code section
|
|
0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b
|
|
};
|
|
}
|
|
|
|
public async Task RunCompileContractExample()
|
|
{
|
|
Console.WriteLine("=== Contract Compilation ===");
|
|
|
|
var wasm = CreateMinimalWasm();
|
|
|
|
var result = await _compiler.CompileAsync(wasm, new CompileOptions
|
|
{
|
|
OptimizationLevel = OptimizationLevel.Size,
|
|
UseWasmOpt = true,
|
|
Validate = true,
|
|
ExtractMetadata = true,
|
|
GenerateAbi = true,
|
|
StripOptions = new StripOptions
|
|
{
|
|
StripDebug = true,
|
|
StripProducers = true,
|
|
StripNames = true,
|
|
StripCustom = true,
|
|
StripUnused = true,
|
|
PreserveSections = new List<string>()
|
|
}
|
|
});
|
|
|
|
Console.WriteLine("Compilation result:");
|
|
Console.WriteLine($" Contract ID: {result.ContractId}");
|
|
Console.WriteLine($" Code hash: {result.CodeHash}");
|
|
Console.WriteLine($" Original size: {result.OriginalSize} bytes");
|
|
Console.WriteLine($" Optimized size: {result.OptimizedSize} bytes");
|
|
Console.WriteLine($" Size reduction: {result.SizeReduction:F1}%");
|
|
Console.WriteLine($" Estimated deploy gas: {result.EstimatedDeployGas}");
|
|
|
|
if (result.Metadata != null)
|
|
{
|
|
Console.WriteLine("\nMetadata:");
|
|
Console.WriteLine($" Name: {result.Metadata.Name}");
|
|
Console.WriteLine($" Version: {result.Metadata.Version}");
|
|
Console.WriteLine($" SDK Version: {result.Metadata.SdkVersion}");
|
|
}
|
|
|
|
if (result.Abi != null)
|
|
{
|
|
Console.WriteLine("\nABI:");
|
|
Console.WriteLine($" Functions: {result.Abi.Functions.Count}");
|
|
Console.WriteLine($" Events: {result.Abi.Events.Count}");
|
|
Console.WriteLine($" Errors: {result.Abi.Errors.Count}");
|
|
}
|
|
Console.WriteLine();
|
|
}
|
|
|
|
public async Task RunCompilationModesExample()
|
|
{
|
|
Console.WriteLine("=== Compilation Modes ===");
|
|
|
|
var wasm = CreateMinimalWasm();
|
|
|
|
// Development mode: fast compilation, debugging support
|
|
Console.WriteLine("Development mode:");
|
|
var devResult = await _compiler.Contracts.CompileDevAsync(wasm);
|
|
Console.WriteLine($" Size: {devResult.OptimizedSize} bytes");
|
|
Console.WriteLine(" Optimization: none");
|
|
|
|
// Production mode: maximum optimization
|
|
Console.WriteLine("\nProduction mode:");
|
|
var prodResult = await _compiler.Contracts.CompileProductionAsync(wasm);
|
|
Console.WriteLine($" Size: {prodResult.OptimizedSize} bytes");
|
|
Console.WriteLine(" Optimization: aggressive");
|
|
Console.WriteLine($" Size savings: {devResult.OptimizedSize - prodResult.OptimizedSize} bytes");
|
|
|
|
// Custom optimization levels
|
|
Console.WriteLine("\nOptimization levels:");
|
|
var levels = new (OptimizationLevel Level, string Name)[]
|
|
{
|
|
(OptimizationLevel.None, "NONE"),
|
|
(OptimizationLevel.Basic, "BASIC"),
|
|
(OptimizationLevel.Size, "SIZE"),
|
|
(OptimizationLevel.Aggressive, "AGGRESSIVE")
|
|
};
|
|
|
|
foreach (var (level, name) in levels)
|
|
{
|
|
var result = await _compiler.CompileAsync(wasm, new CompileOptions
|
|
{
|
|
OptimizationLevel = level
|
|
});
|
|
Console.WriteLine($" {name}: {result.OptimizedSize} bytes");
|
|
}
|
|
Console.WriteLine();
|
|
}
|
|
|
|
public async Task RunAbiExample()
|
|
{
|
|
Console.WriteLine("=== ABI Operations ===");
|
|
|
|
var wasm = CreateMinimalWasm();
|
|
|
|
// Extract ABI from WASM
|
|
var abi = await _compiler.Abi.ExtractAsync(wasm);
|
|
Console.WriteLine($"Contract: {abi.Name}");
|
|
Console.WriteLine($"Version: {abi.Version}");
|
|
|
|
// List functions
|
|
if (abi.Functions.Count > 0)
|
|
{
|
|
Console.WriteLine("\nFunctions:");
|
|
foreach (var func in abi.Functions)
|
|
{
|
|
var inputs = string.Join(", ", func.Inputs.ConvertAll(p => $"{p.Name}: {p.Type.TypeName}"));
|
|
var outputs = func.Outputs.Count == 0
|
|
? "void"
|
|
: string.Join(", ", func.Outputs.ConvertAll(o => o.Type.TypeName));
|
|
|
|
var modifiers = new List<string>();
|
|
if (func.View) modifiers.Add("view");
|
|
if (func.Payable) modifiers.Add("payable");
|
|
var modifierStr = modifiers.Count > 0 ? string.Join(" ", modifiers) : "";
|
|
|
|
Console.WriteLine($" {func.Name}({inputs}) -> {outputs} {modifierStr}");
|
|
Console.WriteLine($" Selector: {func.Selector}");
|
|
}
|
|
}
|
|
|
|
// List events
|
|
if (abi.Events.Count > 0)
|
|
{
|
|
Console.WriteLine("\nEvents:");
|
|
foreach (var evt in abi.Events)
|
|
{
|
|
var paramParts = new List<string>();
|
|
foreach (var param in evt.Params)
|
|
{
|
|
var prefix = param.Indexed ? "indexed " : "";
|
|
paramParts.Add($"{prefix}{param.Name}: {param.Type.TypeName}");
|
|
}
|
|
Console.WriteLine($" {evt.Name}({string.Join(", ", paramParts)})");
|
|
Console.WriteLine($" Topic: {evt.Topic}");
|
|
}
|
|
}
|
|
|
|
// Encode a function call
|
|
if (abi.Functions.Count > 0)
|
|
{
|
|
var func = abi.Functions[0];
|
|
var encoded = await _compiler.Abi.EncodeCallAsync(func, new[] { "arg1", "arg2" });
|
|
Console.WriteLine($"\nEncoded call to {func.Name}: {encoded}");
|
|
|
|
// Decode a result
|
|
var decoded = await _compiler.Abi.DecodeResultAsync(func, encoded);
|
|
Console.WriteLine($"Decoded result: {decoded}");
|
|
}
|
|
Console.WriteLine();
|
|
}
|
|
|
|
public async Task RunAnalysisExample()
|
|
{
|
|
Console.WriteLine("=== Contract Analysis ===");
|
|
|
|
var wasm = CreateMinimalWasm();
|
|
|
|
// Full analysis
|
|
var analysis = await _compiler.Analysis.AnalyzeAsync(wasm);
|
|
|
|
// Size breakdown
|
|
if (analysis.SizeBreakdown != null)
|
|
{
|
|
var size = analysis.SizeBreakdown;
|
|
Console.WriteLine("Size breakdown:");
|
|
Console.WriteLine($" Code: {size.Code} bytes");
|
|
Console.WriteLine($" Data: {size.Data} bytes");
|
|
Console.WriteLine($" Functions: {size.Functions} bytes");
|
|
Console.WriteLine($" Memory: {size.Memory} bytes");
|
|
Console.WriteLine($" Exports: {size.Exports} bytes");
|
|
Console.WriteLine($" Imports: {size.Imports} bytes");
|
|
Console.WriteLine($" Total: {size.Total} bytes");
|
|
}
|
|
|
|
// Function analysis
|
|
if (analysis.Functions.Count > 0)
|
|
{
|
|
Console.WriteLine("\nFunction analysis:");
|
|
foreach (var func in analysis.Functions.GetRange(0, Math.Min(analysis.Functions.Count, 5)))
|
|
{
|
|
Console.WriteLine($" {func.Name}:");
|
|
Console.WriteLine($" Size: {func.Size} bytes");
|
|
Console.WriteLine($" Instructions: {func.InstructionCount}");
|
|
Console.WriteLine($" Locals: {func.LocalCount}");
|
|
Console.WriteLine($" Exported: {func.Exported}");
|
|
Console.WriteLine($" Estimated gas: {func.EstimatedGas}");
|
|
}
|
|
}
|
|
|
|
// Import analysis
|
|
if (analysis.Imports.Count > 0)
|
|
{
|
|
Console.WriteLine("\nImports:");
|
|
foreach (var imp in analysis.Imports)
|
|
{
|
|
Console.WriteLine($" {imp.Module}.{imp.Name} ({imp.Kind})");
|
|
}
|
|
}
|
|
|
|
// Gas analysis
|
|
if (analysis.GasAnalysis != null)
|
|
{
|
|
var gas = analysis.GasAnalysis;
|
|
Console.WriteLine("\nGas analysis:");
|
|
Console.WriteLine($" Deployment: {gas.DeploymentGas}");
|
|
Console.WriteLine($" Memory init: {gas.MemoryInitGas}");
|
|
Console.WriteLine($" Data section: {gas.DataSectionGas}");
|
|
}
|
|
|
|
// Extract metadata
|
|
var metadata = await _compiler.Analysis.ExtractMetadataAsync(wasm);
|
|
Console.WriteLine("\nContract metadata:");
|
|
Console.WriteLine($" Name: {metadata.Name}");
|
|
Console.WriteLine($" Version: {metadata.Version}");
|
|
Console.WriteLine($" Build timestamp: {metadata.BuildTimestamp}");
|
|
|
|
// Estimate deployment gas
|
|
var gasEstimate = await _compiler.Analysis.EstimateDeployGasAsync(wasm);
|
|
Console.WriteLine($"\nEstimated deployment gas: {gasEstimate}");
|
|
Console.WriteLine();
|
|
}
|
|
|
|
public async Task RunValidationExample()
|
|
{
|
|
Console.WriteLine("=== Contract Validation ===");
|
|
|
|
var wasm = CreateMinimalWasm();
|
|
|
|
// Full validation
|
|
var result = await _compiler.Validation.ValidateAsync(wasm);
|
|
Console.WriteLine($"Valid: {result.Valid}");
|
|
Console.WriteLine($"Exports: {result.ExportCount}");
|
|
Console.WriteLine($"Imports: {result.ImportCount}");
|
|
Console.WriteLine($"Functions: {result.FunctionCount}");
|
|
Console.WriteLine($"Memory pages: {result.MemoryPages}");
|
|
|
|
if (result.Errors.Count > 0)
|
|
{
|
|
Console.WriteLine("\nValidation errors:");
|
|
foreach (var error in result.Errors)
|
|
{
|
|
Console.WriteLine($" [{error.Code}] {error.Message}");
|
|
if (!string.IsNullOrEmpty(error.Location))
|
|
{
|
|
Console.WriteLine($" at {error.Location}");
|
|
}
|
|
}
|
|
}
|
|
|
|
if (result.Warnings.Count > 0)
|
|
{
|
|
Console.WriteLine("\nWarnings:");
|
|
foreach (var warning in result.Warnings)
|
|
{
|
|
Console.WriteLine($" {warning}");
|
|
}
|
|
}
|
|
|
|
// Quick validation
|
|
var isValid = await _compiler.Validation.IsValidAsync(wasm);
|
|
Console.WriteLine($"\nQuick validation: {isValid}");
|
|
|
|
// Get validation errors only
|
|
var errors = await _compiler.Validation.GetErrorsAsync(wasm);
|
|
Console.WriteLine($"Error count: {errors.Count}");
|
|
|
|
// Validate required exports
|
|
var hasRequired = await _compiler.Validation.ValidateExportsAsync(wasm, new[] { "init", "execute", "query" });
|
|
Console.WriteLine($"Has required exports: {hasRequired}");
|
|
|
|
// Validate memory constraints
|
|
var memoryValid = await _compiler.Validation.ValidateMemoryAsync(wasm, 16);
|
|
Console.WriteLine($"Memory within 16 pages: {memoryValid}");
|
|
Console.WriteLine();
|
|
}
|
|
|
|
public async Task RunSecurityExample()
|
|
{
|
|
Console.WriteLine("=== Security Scanning ===");
|
|
|
|
var wasm = CreateMinimalWasm();
|
|
|
|
var security = await _compiler.Analysis.SecurityScanAsync(wasm);
|
|
|
|
Console.WriteLine($"Security score: {security.Score}/100");
|
|
|
|
if (security.Issues.Count > 0)
|
|
{
|
|
Console.WriteLine("\nSecurity issues:");
|
|
foreach (var issue in security.Issues)
|
|
{
|
|
var icon = issue.Severity switch
|
|
{
|
|
"critical" => "[CRIT]",
|
|
"high" => "[HIGH]",
|
|
"medium" => "[MED]",
|
|
"low" => "[LOW]",
|
|
_ => "[???]"
|
|
};
|
|
|
|
Console.WriteLine($"{icon} [{issue.Severity}] {issue.Type}");
|
|
Console.WriteLine($" {issue.Description}");
|
|
if (!string.IsNullOrEmpty(issue.Location))
|
|
{
|
|
Console.WriteLine($" at {issue.Location}");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Console.WriteLine("No security issues found!");
|
|
}
|
|
|
|
if (security.Recommendations.Count > 0)
|
|
{
|
|
Console.WriteLine("\nRecommendations:");
|
|
foreach (var rec in security.Recommendations)
|
|
{
|
|
Console.WriteLine($" • {rec}");
|
|
}
|
|
}
|
|
Console.WriteLine();
|
|
}
|
|
|
|
public static async Task Main(string[] args)
|
|
{
|
|
// Initialize client
|
|
var apiKey = Environment.GetEnvironmentVariable("SYNOR_API_KEY") ?? "your-api-key";
|
|
var config = new CompilerConfig
|
|
{
|
|
ApiKey = apiKey,
|
|
Endpoint = "https://compiler.synor.io/v1",
|
|
Timeout = TimeSpan.FromSeconds(60),
|
|
Retries = 3,
|
|
Debug = false,
|
|
DefaultOptimizationLevel = OptimizationLevel.Size,
|
|
MaxContractSize = 256 * 1024,
|
|
UseWasmOpt = true,
|
|
Validate = true,
|
|
ExtractMetadata = true,
|
|
GenerateAbi = true
|
|
};
|
|
|
|
var compiler = new SynorCompiler(config);
|
|
var example = new CompilerExample(compiler);
|
|
|
|
try
|
|
{
|
|
// Check service health
|
|
var healthy = await compiler.HealthCheckAsync();
|
|
Console.WriteLine($"Service healthy: {healthy}\n");
|
|
|
|
// Run examples
|
|
await example.RunCompileContractExample();
|
|
await example.RunCompilationModesExample();
|
|
await example.RunAbiExample();
|
|
await example.RunAnalysisExample();
|
|
await example.RunValidationExample();
|
|
await example.RunSecurityExample();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Console.Error.WriteLine($"Error: {ex.Message}");
|
|
Environment.Exit(1);
|
|
}
|
|
}
|
|
}
|