- Introduced DexExample.swift demonstrating decentralized exchange operations including spot trading, perpetual futures, liquidity provision, order book management, and portfolio tracking. - Added IbcExample.swift showcasing inter-blockchain communication operations such as cross-chain transfers, channel management, packet handling, and relayer operations. - Created ZkExample.swift illustrating zero-knowledge proof operations including circuit compilation, proof generation and verification, and trusted setup ceremonies.
353 lines
11 KiB
Kotlin
353 lines
11 KiB
Kotlin
package io.synor.examples
|
|
|
|
import io.synor.compiler.*
|
|
import io.synor.compiler.types.*
|
|
import kotlinx.coroutines.runBlocking
|
|
|
|
/**
|
|
* Synor Compiler SDK Examples for Kotlin
|
|
*
|
|
* Demonstrates smart contract compilation and analysis:
|
|
* - WASM contract compilation and optimization
|
|
* - ABI extraction and encoding
|
|
* - Contract analysis and security scanning
|
|
* - Validation and verification
|
|
*/
|
|
fun main() = runBlocking {
|
|
// Initialize client
|
|
val config = CompilerConfig(
|
|
apiKey = System.getenv("SYNOR_API_KEY") ?: "your-api-key",
|
|
endpoint = "https://compiler.synor.io/v1",
|
|
timeout = 60_000,
|
|
retries = 3,
|
|
debug = false,
|
|
defaultOptimizationLevel = OptimizationLevel.SIZE,
|
|
maxContractSize = 256 * 1024,
|
|
useWasmOpt = true,
|
|
validate = true,
|
|
extractMetadata = true,
|
|
generateAbi = true
|
|
)
|
|
|
|
val compiler = SynorCompiler(config)
|
|
|
|
try {
|
|
// Check service health
|
|
val healthy = compiler.healthCheck()
|
|
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.
|
|
*/
|
|
fun createMinimalWasm(): ByteArray {
|
|
return byteArrayOf(
|
|
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
|
|
)
|
|
}
|
|
|
|
suspend fun compileContractExample(compiler: SynorCompiler) {
|
|
println("=== Contract Compilation ===")
|
|
|
|
val wasm = createMinimalWasm()
|
|
|
|
val result = compiler.compile(
|
|
wasm,
|
|
CompileOptions(
|
|
optimizationLevel = OptimizationLevel.SIZE,
|
|
useWasmOpt = true,
|
|
validate = true,
|
|
extractMetadata = true,
|
|
generateAbi = true,
|
|
stripOptions = StripOptions(
|
|
stripDebug = true,
|
|
stripProducers = true,
|
|
stripNames = true,
|
|
stripCustom = true,
|
|
stripUnused = true,
|
|
preserveSections = emptyList()
|
|
)
|
|
)
|
|
)
|
|
|
|
println("Compilation result:")
|
|
println(" Contract ID: ${result.contractId}")
|
|
println(" Code hash: ${result.codeHash}")
|
|
println(" Original size: ${result.originalSize} bytes")
|
|
println(" Optimized size: ${result.optimizedSize} bytes")
|
|
println(" Size reduction: ${"%.1f".format(result.sizeReduction)}%")
|
|
println(" Estimated deploy gas: ${result.estimatedDeployGas}")
|
|
|
|
result.metadata?.let { metadata ->
|
|
println("\nMetadata:")
|
|
println(" Name: ${metadata.name}")
|
|
println(" Version: ${metadata.version}")
|
|
println(" SDK Version: ${metadata.sdkVersion}")
|
|
}
|
|
|
|
result.abi?.let { abi ->
|
|
println("\nABI:")
|
|
println(" Functions: ${abi.functions?.size ?: 0}")
|
|
println(" Events: ${abi.events?.size ?: 0}")
|
|
println(" Errors: ${abi.errors?.size ?: 0}")
|
|
}
|
|
|
|
println()
|
|
}
|
|
|
|
suspend fun compilationModesExample(compiler: SynorCompiler) {
|
|
println("=== Compilation Modes ===")
|
|
|
|
val wasm = createMinimalWasm()
|
|
|
|
// Development mode: fast compilation, debugging support
|
|
println("Development mode:")
|
|
val devResult = compiler.contracts.compileDev(wasm)
|
|
println(" Size: ${devResult.optimizedSize} bytes")
|
|
println(" Optimization: none")
|
|
|
|
// Production mode: maximum optimization
|
|
println("\nProduction mode:")
|
|
val prodResult = compiler.contracts.compileProduction(wasm)
|
|
println(" Size: ${prodResult.optimizedSize} bytes")
|
|
println(" Optimization: aggressive")
|
|
println(" Size savings: ${devResult.optimizedSize - prodResult.optimizedSize} bytes")
|
|
|
|
// Custom optimization levels
|
|
println("\nOptimization levels:")
|
|
val levels = listOf(
|
|
OptimizationLevel.NONE,
|
|
OptimizationLevel.BASIC,
|
|
OptimizationLevel.SIZE,
|
|
OptimizationLevel.AGGRESSIVE
|
|
)
|
|
|
|
for (level in levels) {
|
|
val result = compiler.compile(
|
|
wasm,
|
|
CompileOptions(optimizationLevel = level)
|
|
)
|
|
println(" $level: ${result.optimizedSize} bytes")
|
|
}
|
|
|
|
println()
|
|
}
|
|
|
|
suspend fun abiExample(compiler: SynorCompiler) {
|
|
println("=== ABI Operations ===")
|
|
|
|
val wasm = createMinimalWasm()
|
|
|
|
// Extract ABI from WASM
|
|
val abi = compiler.abi.extract(wasm)
|
|
println("Contract: ${abi.name}")
|
|
println("Version: ${abi.version}")
|
|
|
|
// List functions
|
|
abi.functions?.takeIf { it.isNotEmpty() }?.let { functions ->
|
|
println("\nFunctions:")
|
|
for (func in functions) {
|
|
val inputs = func.inputs?.joinToString(", ") { "${it.name}: ${it.type.typeName}" } ?: ""
|
|
val outputs = func.outputs?.joinToString(", ") { it.type.typeName } ?: "void"
|
|
val modifiers = buildList {
|
|
if (func.view) add("view")
|
|
if (func.payable) add("payable")
|
|
}.joinToString(" ")
|
|
|
|
println(" ${func.name}($inputs) -> $outputs $modifiers")
|
|
println(" Selector: ${func.selector}")
|
|
}
|
|
}
|
|
|
|
// List events
|
|
abi.events?.takeIf { it.isNotEmpty() }?.let { events ->
|
|
println("\nEvents:")
|
|
for (event in events) {
|
|
val params = event.params?.joinToString(", ") {
|
|
"${if (it.indexed) "indexed " else ""}${it.name}: ${it.type.typeName}"
|
|
} ?: ""
|
|
println(" ${event.name}($params)")
|
|
println(" Topic: ${event.topic}")
|
|
}
|
|
}
|
|
|
|
// Encode a function call
|
|
abi.functions?.firstOrNull()?.let { func ->
|
|
val encoded = compiler.abi.encodeCall(func, listOf("arg1", "arg2"))
|
|
println("\nEncoded call to ${func.name}: $encoded")
|
|
|
|
// Decode a result
|
|
val decoded = compiler.abi.decodeResult(func, encoded)
|
|
println("Decoded result: $decoded")
|
|
}
|
|
|
|
println()
|
|
}
|
|
|
|
suspend fun analysisExample(compiler: SynorCompiler) {
|
|
println("=== Contract Analysis ===")
|
|
|
|
val wasm = createMinimalWasm()
|
|
|
|
// Full analysis
|
|
val analysis = compiler.analysis.analyze(wasm)
|
|
|
|
// Size breakdown
|
|
analysis.sizeBreakdown?.let { size ->
|
|
println("Size breakdown:")
|
|
println(" Code: ${size.code} bytes")
|
|
println(" Data: ${size.data} bytes")
|
|
println(" Functions: ${size.functions} bytes")
|
|
println(" Memory: ${size.memory} bytes")
|
|
println(" Exports: ${size.exports} bytes")
|
|
println(" Imports: ${size.imports} bytes")
|
|
println(" Total: ${size.total} bytes")
|
|
}
|
|
|
|
// Function analysis
|
|
analysis.functions?.takeIf { it.isNotEmpty() }?.let { functions ->
|
|
println("\nFunction analysis:")
|
|
for (func in functions.take(5)) {
|
|
println(" ${func.name}:")
|
|
println(" Size: ${func.size} bytes")
|
|
println(" Instructions: ${func.instructionCount}")
|
|
println(" Locals: ${func.localCount}")
|
|
println(" Exported: ${func.exported}")
|
|
println(" Estimated gas: ${func.estimatedGas}")
|
|
}
|
|
}
|
|
|
|
// Import analysis
|
|
analysis.imports?.takeIf { it.isNotEmpty() }?.let { imports ->
|
|
println("\nImports:")
|
|
for (imp in imports) {
|
|
println(" ${imp.module}.${imp.name} (${imp.kind})")
|
|
}
|
|
}
|
|
|
|
// Gas analysis
|
|
analysis.gasAnalysis?.let { gas ->
|
|
println("\nGas analysis:")
|
|
println(" Deployment: ${gas.deploymentGas}")
|
|
println(" Memory init: ${gas.memoryInitGas}")
|
|
println(" Data section: ${gas.dataSectionGas}")
|
|
}
|
|
|
|
// Extract metadata
|
|
val metadata = compiler.analysis.extractMetadata(wasm)
|
|
println("\nContract metadata:")
|
|
println(" Name: ${metadata.name}")
|
|
println(" Version: ${metadata.version}")
|
|
println(" Build timestamp: ${metadata.buildTimestamp}")
|
|
|
|
// Estimate deployment gas
|
|
val gasEstimate = compiler.analysis.estimateDeployGas(wasm)
|
|
println("\nEstimated deployment gas: $gasEstimate")
|
|
|
|
println()
|
|
}
|
|
|
|
suspend fun validationExample(compiler: SynorCompiler) {
|
|
println("=== Contract Validation ===")
|
|
|
|
val wasm = createMinimalWasm()
|
|
|
|
// Full validation
|
|
val result = compiler.validation.validate(wasm)
|
|
println("Valid: ${result.valid}")
|
|
println("Exports: ${result.exportCount}")
|
|
println("Imports: ${result.importCount}")
|
|
println("Functions: ${result.functionCount}")
|
|
println("Memory pages: ${result.memoryPages}")
|
|
|
|
result.errors?.takeIf { it.isNotEmpty() }?.let { errors ->
|
|
println("\nValidation errors:")
|
|
for (error in errors) {
|
|
println(" [${error.code}] ${error.message}")
|
|
error.location?.let { println(" at $it") }
|
|
}
|
|
}
|
|
|
|
result.warnings?.takeIf { it.isNotEmpty() }?.let { warnings ->
|
|
println("\nWarnings:")
|
|
for (warning in warnings) {
|
|
println(" $warning")
|
|
}
|
|
}
|
|
|
|
// Quick validation
|
|
val isValid = compiler.validation.isValid(wasm)
|
|
println("\nQuick validation: $isValid")
|
|
|
|
// Get validation errors only
|
|
val errors = compiler.validation.getErrors(wasm)
|
|
println("Error count: ${errors.size}")
|
|
|
|
// Validate required exports
|
|
val hasRequired = compiler.validation.validateExports(
|
|
wasm,
|
|
listOf("init", "execute", "query")
|
|
)
|
|
println("Has required exports: $hasRequired")
|
|
|
|
// Validate memory constraints
|
|
val memoryValid = compiler.validation.validateMemory(wasm, maxPages = 16)
|
|
println("Memory within 16 pages: $memoryValid")
|
|
|
|
println()
|
|
}
|
|
|
|
suspend fun securityExample(compiler: SynorCompiler) {
|
|
println("=== Security Scanning ===")
|
|
|
|
val wasm = createMinimalWasm()
|
|
|
|
val security = compiler.analysis.securityScan(wasm)
|
|
|
|
println("Security score: ${security.score}/100")
|
|
|
|
security.issues?.takeIf { it.isNotEmpty() }?.let { issues ->
|
|
println("\nSecurity issues:")
|
|
val severityIcons = mapOf(
|
|
"critical" to "[CRIT]",
|
|
"high" to "[HIGH]",
|
|
"medium" to "[MED]",
|
|
"low" to "[LOW]"
|
|
)
|
|
for (issue in issues) {
|
|
val icon = severityIcons[issue.severity.lowercase()] ?: "[???]"
|
|
println("$icon [${issue.severity.uppercase()}] ${issue.type}")
|
|
println(" ${issue.description}")
|
|
issue.location?.let { println(" at $it") }
|
|
}
|
|
} ?: println("No security issues found!")
|
|
|
|
security.recommendations?.takeIf { it.isNotEmpty() }?.let { recommendations ->
|
|
println("\nRecommendations:")
|
|
for (rec in recommendations) {
|
|
println(" • $rec")
|
|
}
|
|
}
|
|
|
|
println()
|
|
}
|