# Synor VM Host Function ABI This document describes the host functions available to Synor smart contracts. ## Overview Synor contracts are WebAssembly modules that import host functions from the `env` module. All functions use the WASM calling convention with i32/i64 parameters and return values. ## Storage Operations ### `synor_storage_read` ``` synor_storage_read(key_ptr: i32, out_ptr: i32) -> i32 ``` Reads a value from contract storage. - `key_ptr`: Pointer to a 32-byte storage key - `out_ptr`: Pointer to output buffer (must be at least 4096 bytes) - Returns: Length of data read, or -1 if key not found **Gas Cost**: 200 gas per byte read ### `synor_storage_write` ``` synor_storage_write(key_ptr: i32, value_ptr: i32, value_len: i32) -> i32 ``` Writes a value to contract storage. - `key_ptr`: Pointer to a 32-byte storage key - `value_ptr`: Pointer to value data - `value_len`: Length of value data - Returns: 0 on success, -1 if in static call **Gas Cost**: 5000 gas per byte written ### `synor_storage_delete` ``` synor_storage_delete(key_ptr: i32) -> i32 ``` Deletes a value from contract storage. - `key_ptr`: Pointer to a 32-byte storage key - Returns: 1 if key existed, 0 otherwise **Gas Refund**: 15000 gas ## Context Information ### `synor_get_caller` ``` synor_get_caller(out_ptr: i32) ``` Gets the address that called this contract. - `out_ptr`: Pointer to 34-byte output buffer ### `synor_get_address` ``` synor_get_address(out_ptr: i32) ``` Gets the contract's own address. - `out_ptr`: Pointer to 34-byte output buffer ### `synor_get_origin` ``` synor_get_origin(out_ptr: i32) ``` Gets the original transaction sender. - `out_ptr`: Pointer to 34-byte output buffer ### `synor_get_value` ``` synor_get_value() -> i64 ``` Gets the value (in sompi) sent with this call. - Returns: Amount of sompi sent ### `synor_get_calldata_size` ``` synor_get_calldata_size() -> i32 ``` Gets the size of the call data. - Returns: Size in bytes ### `synor_get_calldata` ``` synor_get_calldata(out_ptr: i32, offset: i32, length: i32) ``` Copies call data to memory. - `out_ptr`: Pointer to output buffer - `offset`: Offset into call data - `length`: Number of bytes to copy ### `synor_get_timestamp` ``` synor_get_timestamp() -> i64 ``` Gets the current block timestamp. - Returns: Unix timestamp in seconds ### `synor_get_block_height` ``` synor_get_block_height() -> i64 ``` Gets the current block height (DAA score). - Returns: Block height ### `synor_get_block_hash` ``` synor_get_block_hash(out_ptr: i32) ``` Gets the current block hash. - `out_ptr`: Pointer to 32-byte output buffer ### `synor_get_gas_remaining` ``` synor_get_gas_remaining() -> i64 ``` Gets the remaining gas for this execution. - Returns: Remaining gas units ### `synor_get_chain_id` ``` synor_get_chain_id() -> i64 ``` Gets the chain ID. - Returns: Chain ID (0 = mainnet, 1 = testnet) ## Cryptographic Operations ### `synor_sha3` ``` synor_sha3(data_ptr: i32, data_len: i32, out_ptr: i32) ``` Computes SHA3-256 hash. - `data_ptr`: Pointer to input data - `data_len`: Length of input data - `out_ptr`: Pointer to 32-byte output buffer **Gas Cost**: 30 + 6 gas per byte ### `synor_blake3` ``` synor_blake3(data_ptr: i32, data_len: i32, out_ptr: i32) ``` Computes Blake3 hash. - `data_ptr`: Pointer to input data - `data_len`: Length of input data - `out_ptr`: Pointer to 32-byte output buffer **Gas Cost**: 30 + 6 gas per byte ### `synor_verify_ed25519` ``` synor_verify_ed25519(msg_ptr: i32, msg_len: i32, sig_ptr: i32, pk_ptr: i32) -> i32 ``` Verifies an Ed25519 signature. - `msg_ptr`: Pointer to message data - `msg_len`: Length of message - `sig_ptr`: Pointer to 64-byte signature - `pk_ptr`: Pointer to 32-byte public key - Returns: 1 if valid, 0 if invalid **Gas Cost**: 3000 gas ## Events ### `synor_emit_log` ``` synor_emit_log(topics_ptr: i32, topics_count: i32, data_ptr: i32, data_len: i32) -> i32 ``` Emits a log event. - `topics_ptr`: Pointer to array of 32-byte topics - `topics_count`: Number of topics (max 4) - `data_ptr`: Pointer to event data - `data_len`: Length of event data - Returns: 0 on success, -1 if in static call **Gas Cost**: 375 gas per topic + 8 gas per data byte ## Cross-Contract Calls ### `synor_call` ``` synor_call(addr_ptr: i32, value: i64, data_ptr: i32, data_len: i32, gas: i64) -> i32 ``` Calls another contract. - `addr_ptr`: Pointer to 32-byte contract address - `value`: Amount of sompi to send - `data_ptr`: Pointer to call data - `data_len`: Length of call data - `gas`: Gas limit for the call - Returns: Length of return data, or negative error code **Gas Cost**: 700 + 3 gas per data byte ### `synor_static_call` ``` synor_static_call(addr_ptr: i32, data_ptr: i32, data_len: i32, gas: i64) -> i32 ``` Makes a read-only call to another contract. - `addr_ptr`: Pointer to 32-byte contract address - `data_ptr`: Pointer to call data - `data_len`: Length of call data - `gas`: Gas limit for the call - Returns: Length of return data, or negative error code ### `synor_delegate_call` ``` synor_delegate_call(addr_ptr: i32, data_ptr: i32, data_len: i32, gas: i64) -> i32 ``` Calls another contract in this contract's context. - `addr_ptr`: Pointer to 32-byte contract address - `data_ptr`: Pointer to call data - `data_len`: Length of call data - `gas`: Gas limit for the call - Returns: Length of return data, or negative error code ### `synor_return_data_size` ``` synor_return_data_size() -> i32 ``` Gets the size of return data from the last call. - Returns: Size in bytes ### `synor_return_data_copy` ``` synor_return_data_copy(dest_ptr: i32, offset: i32, length: i32) ``` Copies return data from the last call. - `dest_ptr`: Pointer to destination buffer - `offset`: Offset into return data - `length`: Number of bytes to copy ## Control Flow ### `synor_revert` ``` synor_revert(msg_ptr: i32, msg_len: i32) ``` Reverts execution with a message. Does not return. - `msg_ptr`: Pointer to error message (UTF-8) - `msg_len`: Length of error message ### `synor_return` ``` synor_return(data_ptr: i32, data_len: i32) ``` Sets return data for this call. - `data_ptr`: Pointer to return data - `data_len`: Length of return data ## Balance Operations ### `synor_get_balance` ``` synor_get_balance(addr_ptr: i32) -> i64 ``` Gets the balance of an address. - `addr_ptr`: Pointer to 34-byte address - Returns: Balance in sompi ### `synor_transfer` ``` synor_transfer(addr_ptr: i32, amount: i64) -> i32 ``` Transfers value to an address. - `addr_ptr`: Pointer to 34-byte address - `amount`: Amount of sompi to transfer - Returns: 0 on success, -1 if in static call or insufficient balance ## Memory Layout Contracts must export a `memory` of type WebAssembly.Memory. The minimum memory size is 1 page (64 KB), maximum is 256 pages (16 MB). ## Contract Exports Contracts must export the following functions: ``` __synor_init(params_ptr: i32, params_len: i32) -> i32 ``` Called when the contract is deployed. Returns 0 on success, negative on error. ``` __synor_call(args_ptr: i32, args_len: i32) -> i32 ``` Called for all subsequent interactions. The first 4 bytes of args are the method selector. Returns length of return data, or negative on error. ## Method Selectors Method selectors are computed as the first 4 bytes of the Blake3 hash of the method name: ```rust fn method_selector(name: &str) -> [u8; 4] { let hash = blake3::hash(name.as_bytes()); [hash[0], hash[1], hash[2], hash[3]] } ``` ## Serialization Arguments and return values are serialized using [Borsh](https://borsh.io/) encoding.