Skip to Content

TAKO SDK Reference

The tako_sdk crate provides all the functions needed to build smart contracts on TOS Network.

Installation

Add to your Cargo.toml:

[dependencies] tako-sdk = { git = "https://github.com/tos-network/tako", branch = "main" }

Import in your contract:

use tako_sdk::*;

Constants

/// Success return code pub const SUCCESS: u64 = 0; /// Generic error return code pub const ERROR: u64 = 1;

Core Functions

Environment

get_tx_sender

Get the address of the transaction sender.

pub fn get_tx_sender() -> [u8; 32];

Example:

let sender = get_tx_sender();

get_caller

Get the immediate caller (may differ from tx_sender in CPI).

pub fn get_caller() -> [u8; 32];

get_contract_hash

Get the current contract’s address.

pub fn get_contract_hash() -> [u8; 32];

get_call_value

Get the TOS amount sent with this call.

pub fn get_call_value() -> u64;

Example:

let amount = get_call_value(); if amount == 0 { return ERR_NO_VALUE; }

get_block_number

Get the current block number.

pub fn get_block_number() -> u64;

get_block_hash

Get the current block hash.

pub fn get_block_hash() -> [u8; 32];

get_timestamp

Get the current block timestamp.

pub fn get_timestamp() -> u64;

Input/Output

get_input_data

Read the input data for this contract call.

pub fn get_input_data(buffer: &mut [u8]) -> u32;

Returns: Number of bytes written to buffer.

Example:

let mut input = [0u8; 1024]; let len = get_input_data(&mut input); // Parse opcode and parameters let opcode = input[0]; let params = &input[1..len as usize];

set_return_data

Set the return data for this call.

pub fn set_return_data(data: &[u8]) -> Result<(), u64>;

Example:

let balance = get_balance(&account); let result = balance.to_le_bytes(); set_return_data(&result)?;

Storage

storage_read

Read data from contract storage.

pub fn storage_read(key: &[u8], buffer: &mut [u8]) -> u32;

Returns: Number of bytes read (0 if key not found).

Example:

const COUNTER_KEY: &[u8] = b"counter"; let mut buffer = [0u8; 8]; let len = storage_read(COUNTER_KEY, &mut buffer); let value = if len == 8 { u64::from_le_bytes(buffer) } else { 0 // Default value };

storage_write

Write data to contract storage.

pub fn storage_write(key: &[u8], value: &[u8]) -> Result<(), u64>;

Cost: 20,000 compute units per write.

Example:

let value = 42u64; storage_write(b"my_key", &value.to_le_bytes())?;

Transfers

transfer

Transfer TOS to another address.

pub fn transfer(recipient: &[u8; 32], amount: u64) -> Result<(), u64>;

Example:

let recipient = get_tx_sender(); let reward = 100_000000; // 1 TOS (8 decimals) transfer(&recipient, reward)?;

transfer_from_contract

Transfer TOS from contract balance.

pub fn transfer_from_contract(recipient: &[u8; 32], amount: u64) -> Result<(), u64>;

Logging

log

Log a message (for debugging and events).

pub fn log(message: &str);

Cost: 100 compute units.

Example:

log("Transfer successful");

log_u64

Log up to 5 u64 values.

pub fn log_u64(a: u64, b: u64, c: u64, d: u64, e: u64);

Example:

log_u64(amount, from_balance, to_balance, 0, 0);

Hashing

blake3_hash

Compute Blake3 hash of data.

pub fn blake3_hash(data: &[u8]) -> [u8; 32];

Example:

let data = b"hello world"; let hash = blake3_hash(data);

keccak256

Compute Keccak256 hash (Ethereum compatible).

pub fn keccak256(data: &[u8]) -> [u8; 32];

Cross-Program Invocation (CPI)

cpi_call

Call another contract.

pub fn cpi_call( target: &[u8; 32], input: &[u8], return_buffer: &mut [u8], ) -> Result<u32, u64>;

Returns: Number of bytes written to return_buffer.

Example:

let target_contract = [...]; // 32-byte contract address let input = [OP_BALANCE_OF, ...]; // Call data let mut return_data = [0u8; 8]; let len = cpi_call(&target_contract, &input, &mut return_data)?; let balance = u64::from_le_bytes(return_data);

VRF (Verifiable Random Function)

vrf_random

Generate a verifiable random number.

pub fn vrf_random(seed: &[u8]) -> Result<VRFOutput, u64>;

Returns:

pub struct VRFOutput { pub random: [u8; 32], // Random output pub pre_output: [u8; 32], // Pre-output for verification pub proof: [u8; 64], // VRF proof }

Cost: 10,000 compute units.

Example:

let seed = get_block_hash(); let output = vrf_random(&seed)?; // Use first byte for game logic let roll = output.random[0] % 100;

vrf_verify

Verify a VRF proof.

pub fn vrf_verify( public_key: &[u8; 32], input: &[u8; 32], pre_output: &[u8; 32], proof: &[u8; 64], ) -> Result<(), u64>;

vrf_public_key

Get the VRF public key for this block.

pub fn vrf_public_key() -> Result<[u8; 32], u64>;

Referral System

tos_has_referrer

Check if user has bound a referrer.

pub fn tos_has_referrer(user: &[u8; 32]) -> Result<bool, u64>;

Cost: 500 compute units.

tos_get_referrer

Get user’s direct referrer.

pub fn tos_get_referrer(user: &[u8; 32]) -> Result<[u8; 32], u64>;

Cost: 500 compute units.

get_uplines

Get multiple levels of uplines.

pub fn get_uplines( user: &[u8; 32], levels: u8, ) -> Result<([[u8; 32]; 20], u8), u64>;

Returns: Tuple of (uplines array, count of valid uplines).

Cost: 500 + 200×N compute units.

Example:

let (uplines, count) = get_uplines(&buyer, 3)?; for i in 0..count as usize { let upline = &uplines[i]; // Distribute reward to upline }

tos_get_team_size

Get total team size (cached).

pub fn tos_get_team_size(user: &[u8; 32]) -> Result<u64, u64>;

Cost: 500 compute units.

Team Volume

add_team_volume

Add volume to upline chain.

pub fn add_team_volume( user: &[u8; 32], asset: &[u8; 32], amount: u64, levels: u8, ) -> Result<(), u64>;

Cost: 1,000 + 500×levels compute units.

get_team_volume

Get total team volume for user-asset pair.

pub fn get_team_volume( user: &[u8; 32], asset: &[u8; 32], ) -> Result<u64, u64>;

Cost: 500 compute units.

get_direct_volume

Get direct referral volume only.

pub fn get_direct_volume( user: &[u8; 32], asset: &[u8; 32], ) -> Result<u64, u64>;

get_zone_volumes

Get each direct referral’s team volume.

pub fn get_zone_volumes( user: &[u8; 32], asset: &[u8; 32], limit: u8, ) -> Result<ZoneVolumesResult, u64>;

Error Codes

Common error codes returned by SDK functions:

CodeMeaning
0Success
1Generic error
100Invalid argument
101Buffer too small
102Storage read failed
103Storage write failed
104Transfer failed
105Insufficient balance
106CPI call failed
107VRF failed

Complete Example

#![no_std] #![no_main] use tako_sdk::*; const KEY_BALANCE: u8 = 0x10; fn get_balance(account: &[u8; 32]) -> u64 { let mut key = [0u8; 33]; key[0] = KEY_BALANCE; key[1..33].copy_from_slice(account); let mut buffer = [0u8; 8]; let len = storage_read(&key, &mut buffer); if len == 8 { u64::from_le_bytes(buffer) } else { 0 } } fn set_balance(account: &[u8; 32], amount: u64) { let mut key = [0u8; 33]; key[0] = KEY_BALANCE; key[1..33].copy_from_slice(account); let _ = storage_write(&key, &amount.to_le_bytes()); } #[no_mangle] pub extern "C" fn entrypoint() -> u64 { let sender = get_tx_sender(); let deposit = get_call_value(); if deposit > 0 { let current = get_balance(&sender); let new_balance = current.saturating_add(deposit); set_balance(&sender, new_balance); log("Deposit successful"); } SUCCESS } #[panic_handler] fn panic(_info: &core::panic::PanicInfo) -> ! { loop {} }
Last updated on