Internals

WASM smart contracts

Deploy ink! smart contracts on subtensor via pallet-contracts and the custom chain extension.

View as Markdown

Subtensor supports WebAssembly (WASM) smart contract functionality through the integration of pallet-contracts, enabling developers to deploy and execute WASM smart contracts on the network. Contracts are written in ink!, a Rust-based embedded domain-specific language (eDSL) for writing smart contracts on Substrate-based chains. For compatibility, WASM contracts can also be compiled from Solidity using Solang.

Getting Started

For general smart contract development on Subtensor, please refer to the official ink! documentation:

Subtensor-Specific Features

Chain Extension

Subtensor provides a custom chain extension that allows smart contracts to interact with Subtensor-specific functionality:

Available Functions

Function IDNameDescriptionParametersReturns
0get_stake_info_for_hotkey_coldkey_netuidQuery stake information(AccountId, AccountId, NetUid)Option<StakeInfo>
1add_stakeDelegate stake from coldkey to hotkey(AccountId, NetUid, TaoBalance)Error code
2remove_stakeWithdraw stake from hotkey back to coldkey(AccountId, NetUid, AlphaBalance)Error code
3unstake_allUnstake all TAO from a hotkey(AccountId)Error code
4unstake_all_alphaUnstake all Alpha from a hotkey(AccountId)Error code
5move_stakeMove stake between hotkeys(AccountId, AccountId, NetUid, NetUid, AlphaBalance)Error code
6transfer_stakeTransfer stake between coldkeys(AccountId, AccountId, NetUid, NetUid, AlphaBalance)Error code
7swap_stakeSwap stake allocations between subnets(AccountId, NetUid, NetUid, AlphaBalance)Error code
8add_stake_limitDelegate stake with a price limit(AccountId, NetUid, TaoBalance, TaoBalance, bool)Error code
9remove_stake_limitWithdraw stake with a price limit(AccountId, NetUid, AlphaBalance, TaoBalance, bool)Error code
10swap_stake_limitSwap stake between subnets with price limit(AccountId, NetUid, NetUid, AlphaBalance, TaoBalance, bool)Error code
11remove_stake_full_limitFully withdraw stake with optional price limit(AccountId, NetUid, Option<TaoBalance>)Error code
12set_coldkey_auto_stake_hotkeyConfigure automatic stake destination(NetUid, AccountId)Error code
13add_proxyAdd a staking proxy for the contract's account(AccountId)Error code
14remove_proxyRemove a staking proxy for the contract's account(AccountId)Error code
15get_alpha_priceQuery the current alpha price for a subnet(NetUid)u64 (price × 10⁹)
16recycle_alphaRecycle alpha stake, reducing SubnetAlphaOut (supply reduction)(AccountId, NetUid, AlphaBalance)u64 (actual amount recycled)
17burn_alphaBurn alpha stake without reducing SubnetAlphaOut (supply neutral)(AccountId, NetUid, AlphaBalance)u64 (actual amount burned)
18add_stake_recycleAtomically add stake then recycle the resulting alpha(AccountId, NetUid, TaoBalance)u64 (alpha amount recycled)
19add_stake_burnAtomically add stake then burn the resulting alpha(AccountId, NetUid, TaoBalance)u64 (alpha amount burned)
34get_subnet_registration_stateQuery whether a subnet exists and which registration generation currently owns the netuid(NetUid)SubnetRegistrationState { netuid, exists, registered_subnet_counter }
35get_coldkey_lockQuery the current rolled-forward lock state for a coldkey on a subnet(AccountId, NetUid)Option<ColdkeyLock { locked_mass: AlphaBalance, conviction_bits: u128, last_update: u64 }>
36get_stake_availabilityQuery total, locked, and currently available alpha for a coldkey on a subnet(AccountId, NetUid)StakeAvailability { netuid: NetUid, total: AlphaBalance, locked: AlphaBalance, available: AlphaBalance }
37move_stake_limitMove stake between hotkeys and subnets with a relative price limit(AccountId, AccountId, NetUid, NetUid, AlphaBalance, TaoBalance, bool)Error code

Example usage in your ink! contract:

#[ink::chain_extension(extension = 0)]
pub trait SubtensorExtension {
    type ErrorCode = SubtensorError;

    #[ink(function = 0)]
    fn get_stake_info(
        hotkey: AccountId,
        coldkey: AccountId,
        netuid: u16,
    ) -> Result<Option<StakeInfo>, SubtensorError>;
}

Error Codes

Chain extension functions that modify state return error codes as u32 values. The following codes are defined:

CodeNameDescription
0SuccessOperation completed successfully
1RuntimeErrorUnknown runtime error occurred
2NotEnoughBalanceToStakeInsufficient balance to complete stake operation
3NonAssociatedColdKeyColdkey is not associated with the hotkey
4BalanceWithdrawalErrorError occurred during balance withdrawal
5NotRegisteredHotkey is not registered in the subnet
6NotEnoughStakeToWithdrawInsufficient stake available for withdrawal
7TxRateLimitExceededTransaction rate limit has been exceeded
8SlippageTooHighPrice slippage exceeds acceptable threshold
9SubnetNotExistsSpecified subnet does not exist
10HotKeyNotRegisteredInSubNetHotkey is not registered in the specified subnet
11SameAutoStakeHotkeyAlreadySetAuto-stake hotkey is already configured
12InsufficientBalanceAccount has insufficient balance
13AmountTooLowTransaction amount is below minimum threshold
14InsufficientLiquidityInsufficient liquidity for swap operation
15SameNetuidSource and destination subnets are the same
16ProxyTooManyToo many proxies registered
17ProxyDuplicateProxy already exists
18ProxyNoSelfProxyCannot add self as proxy
19ProxyNotFoundProxy relationship not found
20CannotUseSystemAccountA system account cannot be used in this operation
21CannotBurnOrRecycleOnRootSubnetCannot burn or recycle on the root subnet
22SubtokenDisabledSubtoken is not enabled for the specified subnet

Call Filter

For security, contracts can only directly dispatch a limited set of runtime calls:

Whitelisted Calls:

  • Proxy::proxy - Execute proxy calls

All other runtime calls are restricted and cannot be dispatched from contracts.

Configuration Parameters

ParameterValueDescription
Maximum code size128 KBMaximum size of contract WASM code
Call stack depth5 framesMaximum nested contract call depth
Runtime memory1 GBMemory available during contract execution
Validator runtime memory2 GBMemory available for validators
Transient storage1 MBMaximum transient storage size

Additional Resources