Skip to main content

WASM Execution

The HCS-12 WASM execution system in the Standards SDK handles loading and executing WebAssembly modules for HashLinks actions.

WASM InterfaceDirect link to WASM Interface​

All actions must implement the WasmInterface with INFO, POST, and GET methods:

interface WasmInterface {
// Returns module metadata in deterministic JSON format
INFO(): string;

// Executes actions that modify state or submit transactions
POST(
action: string,
params: string,
network: 'mainnet' | 'testnet',
memo: string
): Promise<string>;

// Retrieves information without modifying state
GET(
action: string,
params: string,
network: 'mainnet' | 'testnet'
): Promise<string>;
}

WASM ExecutorDirect link to WASM Executor​

The SDK provides a WasmExecutor for executing WASM modules:

import { WasmExecutor } from '@hashgraphonline/standards-sdk';

// Create WASM executor
const wasmExecutor = new WasmExecutor(logger, 'testnet');

// Execute an action
const result = await wasmExecutor.execute(actionRegistration, {
method: 'POST',
params: {
action: 'transfer',
amount: 100,
to: '0.0.987654'
}
});

JavaScript Wrapper SupportDirect link to JavaScript Wrapper Support​

For wasm-bindgen generated modules, JavaScript wrappers are supported:

// Action registration with JavaScript wrapper
const actionRegistration: ActionRegistration = {
p: 'hcs-12',
op: 'register',
t_id: '0.0.123456', // WASM module topic ID
js_t_id: '0.0.123457', // JavaScript wrapper topic ID
hash: 'e3b0c442...', // INFO method result hash
wasm_hash: 'a1b2c3d4...', // WASM binary hash
js_hash: 'f5e6d7c8...', // JavaScript wrapper hash
interface_version: '0.2.95' // wasm-bindgen version
};

// Execute with JavaScript wrapper
const result = await wasmExecutor.execute(actionRegistration, {
method: 'POST',
params: {
action: 'transfer',
amount: 100,
to: '0.0.987654'
}
});

Module Info ExtractionDirect link to Module Info Extraction​

The SDK can extract module info from WASM binaries:

import { ActionBuilder, WasmValidator } from '@hashgraphonline/standards-sdk';

// Extract metadata from WASM data
const validator = new WasmValidator(logger);
const moduleInfo = await validator.extractMetadata(wasmData);

// Generate INFO hash
const infoHash = await new ActionBuilder(logger).generateInfoHash(moduleInfo);

// Generate WASM hash
const wasmHash = await new ActionBuilder(logger).generateWasmHash(wasmData);

WASM LoadingDirect link to WASM Loading​

The executor handles WASM module loading from HCS-1 topics:

// Load WASM module from topic
const wasmResult = await hrlResolver.resolve(action.t_id, {
network: 'testnet',
returnRaw: true
});

// Load JavaScript wrapper from topic
const jsResult = await hrlResolver.resolve(action.js_t_id!, {
network: 'testnet',
returnRaw: false
});

Execution ContextDirect link to Execution Context​

Actions receive execution context with network and memo information:

interface WasmExecutionContext {
method: 'INFO' | 'POST' | 'GET';
params: {
action: string;
[key: string]: any;
};
state?: Record<string, any>;
}

Result HandlingDirect link to Result Handling​

Execution results are returned in a standardized format:

interface WasmExecutionResult {
success: boolean;
data?: any;
error?: string;
gasUsed?: number;
}

// Example successful result
const successResult: WasmExecutionResult = {
success: true,
data: {
transactionId: '0.0.123456@1234567890.000000000',
newValue: 42
}
};

// Example error result
const errorResult: WasmExecutionResult = {
success: false,
error: 'Invalid parameter: amount must be positive'
};

Error HandlingDirect link to Error Handling​

The WASM executor provides comprehensive error handling:

try {
const result = await wasmExecutor.execute(actionRegistration, context);

if (result.success) {
console.log('Execution successful:', result.data);
} else {
console.error('Execution failed:', result.error);
}
} catch (error) {
console.error('WASM execution error:', error.message);
}

Memory ManagementDirect link to Memory Management​

The executor handles WASM memory management:

// Memory cleanup for cached instances
wasmExecutor.clearCache();

ValidationDirect link to Validation​

The executor validates action parameters and capabilities:

import { WasmValidator } from '@hashgraphonline/standards-sdk';

const validator = new WasmValidator(logger);
const report = await validator.validate(wasmData);
if (!report.isValid) {
console.error(report.errors);
}

Performance OptimizationDirect link to Performance Optimization​

The executor includes performance optimizations:

// Concurrent execution
const results = await Promise.all([
wasmExecutor.execute(action1, context1),
wasmExecutor.execute(action2, context2),
wasmExecutor.execute(action3, context3)
]);

// Resource cleanup
wasmExecutor.clearCache();

Security FeaturesDirect link to Security Features​

The executor includes security features for safe execution:

import { WasmValidator } from '@hashgraphonline/standards-sdk';

const validator = new WasmValidator(logger);
const report = await validator.validate(wasmData);
console.log(report.isValid, report.errors, report.warnings);

Browser SupportDirect link to Browser Support​

The executor works in both Node.js and browser environments:

WasmExecutor is browser-oriented in the current SDK implementation. In Node.js/SSR contexts it returns an execution error rather than running the module.

Best PracticesDirect link to Best Practices​

  1. Deterministic Execution: Ensure all actions are deterministic
  2. Error Handling: Handle errors gracefully and provide meaningful error messages
  3. Resource Management: Be mindful of resource usage and execution time
  4. Security: Validate all inputs and sanitize outputs
  5. Performance: Use caching for frequently executed actions
  6. Validation: Validate parameters and capabilities before execution
  7. Memory Management: Properly manage WASM memory and instances
  8. Testing: Test actions with various input scenarios