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
353 lines
9.8 KiB
Ruby
353 lines
9.8 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
#
|
|
# Synor Compiler SDK Examples for Ruby
|
|
#
|
|
# Demonstrates smart contract compilation and analysis:
|
|
# - WASM contract compilation and optimization
|
|
# - ABI extraction and encoding
|
|
# - Contract analysis and security scanning
|
|
# - Validation and verification
|
|
#
|
|
|
|
require 'synor/compiler'
|
|
|
|
class CompilerExample
|
|
def initialize(compiler)
|
|
@compiler = compiler
|
|
end
|
|
|
|
# Creates a minimal valid WASM module for testing
|
|
def create_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, # "add"
|
|
# Code section
|
|
0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b
|
|
].pack('C*')
|
|
end
|
|
|
|
def run_compile_contract_example
|
|
puts '=== Contract Compilation ==='
|
|
|
|
wasm = create_minimal_wasm
|
|
|
|
result = @compiler.compile(wasm,
|
|
optimization_level: :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: []
|
|
}
|
|
)
|
|
|
|
puts 'Compilation result:'
|
|
puts " Contract ID: #{result.contract_id}"
|
|
puts " Code hash: #{result.code_hash}"
|
|
puts " Original size: #{result.original_size} bytes"
|
|
puts " Optimized size: #{result.optimized_size} bytes"
|
|
puts " Size reduction: #{format('%.1f', result.size_reduction)}%"
|
|
puts " Estimated deploy gas: #{result.estimated_deploy_gas}"
|
|
|
|
if result.metadata
|
|
puts "\nMetadata:"
|
|
puts " Name: #{result.metadata.name}"
|
|
puts " Version: #{result.metadata.version}"
|
|
puts " SDK Version: #{result.metadata.sdk_version}"
|
|
end
|
|
|
|
if result.abi
|
|
puts "\nABI:"
|
|
puts " Functions: #{result.abi.functions.length}"
|
|
puts " Events: #{result.abi.events.length}"
|
|
puts " Errors: #{result.abi.errors.length}"
|
|
end
|
|
puts
|
|
end
|
|
|
|
def run_compilation_modes_example
|
|
puts '=== Compilation Modes ==='
|
|
|
|
wasm = create_minimal_wasm
|
|
|
|
# Development mode: fast compilation, debugging support
|
|
puts 'Development mode:'
|
|
dev_result = @compiler.contracts.compile_dev(wasm)
|
|
puts " Size: #{dev_result.optimized_size} bytes"
|
|
puts ' Optimization: none'
|
|
|
|
# Production mode: maximum optimization
|
|
puts "\nProduction mode:"
|
|
prod_result = @compiler.contracts.compile_production(wasm)
|
|
puts " Size: #{prod_result.optimized_size} bytes"
|
|
puts ' Optimization: aggressive'
|
|
puts " Size savings: #{dev_result.optimized_size - prod_result.optimized_size} bytes"
|
|
|
|
# Custom optimization levels
|
|
puts "\nOptimization levels:"
|
|
levels = [
|
|
{ level: :none, name: 'NONE' },
|
|
{ level: :basic, name: 'BASIC' },
|
|
{ level: :size, name: 'SIZE' },
|
|
{ level: :aggressive, name: 'AGGRESSIVE' }
|
|
]
|
|
|
|
levels.each do |l|
|
|
result = @compiler.compile(wasm, optimization_level: l[:level])
|
|
puts " #{l[:name]}: #{result.optimized_size} bytes"
|
|
end
|
|
puts
|
|
end
|
|
|
|
def run_abi_example
|
|
puts '=== ABI Operations ==='
|
|
|
|
wasm = create_minimal_wasm
|
|
|
|
# Extract ABI from WASM
|
|
abi = @compiler.abi.extract(wasm)
|
|
puts "Contract: #{abi.name}"
|
|
puts "Version: #{abi.version}"
|
|
|
|
# List functions
|
|
if abi.functions.any?
|
|
puts "\nFunctions:"
|
|
abi.functions.each do |func|
|
|
inputs = func.inputs.map { |p| "#{p.name}: #{p.type.type_name}" }.join(', ')
|
|
outputs = func.outputs.empty? ? 'void' : func.outputs.map { |o| o.type.type_name }.join(', ')
|
|
|
|
modifiers = []
|
|
modifiers << 'view' if func.view?
|
|
modifiers << 'payable' if func.payable?
|
|
modifier_str = modifiers.join(' ')
|
|
|
|
puts " #{func.name}(#{inputs}) -> #{outputs} #{modifier_str}"
|
|
puts " Selector: #{func.selector}"
|
|
end
|
|
end
|
|
|
|
# List events
|
|
if abi.events.any?
|
|
puts "\nEvents:"
|
|
abi.events.each do |event|
|
|
params = event.params.map do |param|
|
|
prefix = param.indexed? ? 'indexed ' : ''
|
|
"#{prefix}#{param.name}: #{param.type.type_name}"
|
|
end.join(', ')
|
|
puts " #{event.name}(#{params})"
|
|
puts " Topic: #{event.topic}"
|
|
end
|
|
end
|
|
|
|
# Encode a function call
|
|
if abi.functions.any?
|
|
func = abi.functions.first
|
|
encoded = @compiler.abi.encode_call(func, %w[arg1 arg2])
|
|
puts "\nEncoded call to #{func.name}: #{encoded}"
|
|
|
|
# Decode a result
|
|
decoded = @compiler.abi.decode_result(func, encoded)
|
|
puts "Decoded result: #{decoded}"
|
|
end
|
|
puts
|
|
end
|
|
|
|
def run_analysis_example
|
|
puts '=== Contract Analysis ==='
|
|
|
|
wasm = create_minimal_wasm
|
|
|
|
# Full analysis
|
|
analysis = @compiler.analysis.analyze(wasm)
|
|
|
|
# Size breakdown
|
|
if analysis.size_breakdown
|
|
size = analysis.size_breakdown
|
|
puts 'Size breakdown:'
|
|
puts " Code: #{size.code} bytes"
|
|
puts " Data: #{size.data} bytes"
|
|
puts " Functions: #{size.functions} bytes"
|
|
puts " Memory: #{size.memory} bytes"
|
|
puts " Exports: #{size.exports} bytes"
|
|
puts " Imports: #{size.imports} bytes"
|
|
puts " Total: #{size.total} bytes"
|
|
end
|
|
|
|
# Function analysis
|
|
if analysis.functions.any?
|
|
puts "\nFunction analysis:"
|
|
analysis.functions.first(5).each do |func|
|
|
puts " #{func.name}:"
|
|
puts " Size: #{func.size} bytes"
|
|
puts " Instructions: #{func.instruction_count}"
|
|
puts " Locals: #{func.local_count}"
|
|
puts " Exported: #{func.exported?}"
|
|
puts " Estimated gas: #{func.estimated_gas}"
|
|
end
|
|
end
|
|
|
|
# Import analysis
|
|
if analysis.imports.any?
|
|
puts "\nImports:"
|
|
analysis.imports.each do |imp|
|
|
puts " #{imp.module}.#{imp.name} (#{imp.kind})"
|
|
end
|
|
end
|
|
|
|
# Gas analysis
|
|
if analysis.gas_analysis
|
|
gas = analysis.gas_analysis
|
|
puts "\nGas analysis:"
|
|
puts " Deployment: #{gas.deployment_gas}"
|
|
puts " Memory init: #{gas.memory_init_gas}"
|
|
puts " Data section: #{gas.data_section_gas}"
|
|
end
|
|
|
|
# Extract metadata
|
|
metadata = @compiler.analysis.extract_metadata(wasm)
|
|
puts "\nContract metadata:"
|
|
puts " Name: #{metadata.name}"
|
|
puts " Version: #{metadata.version}"
|
|
puts " Build timestamp: #{metadata.build_timestamp}"
|
|
|
|
# Estimate deployment gas
|
|
gas_estimate = @compiler.analysis.estimate_deploy_gas(wasm)
|
|
puts "\nEstimated deployment gas: #{gas_estimate}"
|
|
puts
|
|
end
|
|
|
|
def run_validation_example
|
|
puts '=== Contract Validation ==='
|
|
|
|
wasm = create_minimal_wasm
|
|
|
|
# Full validation
|
|
result = @compiler.validation.validate(wasm)
|
|
puts "Valid: #{result.valid?}"
|
|
puts "Exports: #{result.export_count}"
|
|
puts "Imports: #{result.import_count}"
|
|
puts "Functions: #{result.function_count}"
|
|
puts "Memory pages: #{result.memory_pages}"
|
|
|
|
if result.errors.any?
|
|
puts "\nValidation errors:"
|
|
result.errors.each do |error|
|
|
puts " [#{error.code}] #{error.message}"
|
|
puts " at #{error.location}" if error.location
|
|
end
|
|
end
|
|
|
|
if result.warnings.any?
|
|
puts "\nWarnings:"
|
|
result.warnings.each do |warning|
|
|
puts " #{warning}"
|
|
end
|
|
end
|
|
|
|
# Quick validation
|
|
is_valid = @compiler.validation.valid?(wasm)
|
|
puts "\nQuick validation: #{is_valid}"
|
|
|
|
# Get validation errors only
|
|
errors = @compiler.validation.get_errors(wasm)
|
|
puts "Error count: #{errors.length}"
|
|
|
|
# Validate required exports
|
|
has_required = @compiler.validation.validate_exports(wasm, %w[init execute query])
|
|
puts "Has required exports: #{has_required}"
|
|
|
|
# Validate memory constraints
|
|
memory_valid = @compiler.validation.validate_memory(wasm, 16)
|
|
puts "Memory within 16 pages: #{memory_valid}"
|
|
puts
|
|
end
|
|
|
|
def run_security_example
|
|
puts '=== Security Scanning ==='
|
|
|
|
wasm = create_minimal_wasm
|
|
|
|
security = @compiler.analysis.security_scan(wasm)
|
|
|
|
puts "Security score: #{security.score}/100"
|
|
|
|
if security.issues.any?
|
|
puts "\nSecurity issues:"
|
|
security.issues.each do |issue|
|
|
icon = case issue.severity
|
|
when 'critical' then '[CRIT]'
|
|
when 'high' then '[HIGH]'
|
|
when 'medium' then '[MED]'
|
|
when 'low' then '[LOW]'
|
|
else '[???]'
|
|
end
|
|
|
|
puts "#{icon} [#{issue.severity}] #{issue.type}"
|
|
puts " #{issue.description}"
|
|
puts " at #{issue.location}" if issue.location
|
|
end
|
|
else
|
|
puts 'No security issues found!'
|
|
end
|
|
|
|
if security.recommendations.any?
|
|
puts "\nRecommendations:"
|
|
security.recommendations.each do |rec|
|
|
puts " • #{rec}"
|
|
end
|
|
end
|
|
puts
|
|
end
|
|
end
|
|
|
|
# Main execution
|
|
if __FILE__ == $PROGRAM_NAME
|
|
# Initialize client
|
|
api_key = ENV.fetch('SYNOR_API_KEY', 'your-api-key')
|
|
config = Synor::Compiler::Config.new(
|
|
api_key: api_key,
|
|
endpoint: 'https://compiler.synor.io/v1',
|
|
timeout: 60,
|
|
retries: 3,
|
|
debug: false,
|
|
default_optimization_level: :size,
|
|
max_contract_size: 256 * 1024,
|
|
use_wasm_opt: true,
|
|
validate: true,
|
|
extract_metadata: true,
|
|
generate_abi: true
|
|
)
|
|
|
|
compiler = Synor::Compiler::Client.new(config)
|
|
example = CompilerExample.new(compiler)
|
|
|
|
begin
|
|
# Check service health
|
|
healthy = compiler.health_check
|
|
puts "Service healthy: #{healthy}\n\n"
|
|
|
|
# Run examples
|
|
example.run_compile_contract_example
|
|
example.run_compilation_modes_example
|
|
example.run_abi_example
|
|
example.run_analysis_example
|
|
example.run_validation_example
|
|
example.run_security_example
|
|
rescue StandardError => e
|
|
warn "Error: #{e.message}"
|
|
exit 1
|
|
end
|
|
end
|