use.miden::kernel_proc_offsets # NATIVE ACCOUNT PROCEDURES # ================================================================================================= #! Returns the account id. #! #! Stack: [] #! Output: [acct_id] #! #! - acct_id is the account id. export.get_id # start padding the stack push.0.0.0 exec.kernel_proc_offsets::get_account_id_offset # => [offset, 0, 0, 0] # pad the stack padw swapw padw padw swapdw # => [offset, 0, PAD(14)] syscall.exec_kernel_proc # => [acct_id, PAD(15)] # clean the stack swapdw dropw dropw swapw dropw movdn.3 drop drop drop # => [acct_id] end #! Returns the account nonce. #! #! Stack: [] #! Output: [nonce] #! #! - nonce is the account nonce. export.get_nonce # start padding the stack push.0.0.0 exec.kernel_proc_offsets::get_account_nonce_offset # => [offset, 0, 0, 0] # pad the stack padw swapw padw padw swapdw # => [offset, PAD(15)] syscall.exec_kernel_proc # => [nonce, PAD(15)] # clean the stack swapdw dropw dropw swapw dropw movdn.3 drop drop drop # => [nonce] end #! Returns the initial account hash. #! #! Stack: [] #! Output: [H] #! #! - H is the initial account hash. export.get_initial_hash # pad the stack padw padw padw push.0.0.0 # => [PAD(15)] exec.kernel_proc_offsets::get_initial_account_hash_offset # => [offset, PAD(15)] syscall.exec_kernel_proc # => [H, PAD(12)] # clean the stack swapdw dropw dropw swapw dropw # => [H] end #! Computes and returns the account hash from account data stored in memory. #! #! Stack: [] #! Output: [ACCT_HASH] #! #! - ACCT_HASH is the hash of the account data. export.get_current_hash # pad the stack padw padw padw push.0.0.0 # => [PAD(15)] exec.kernel_proc_offsets::get_current_account_hash_offset # => [offset, PAD(15)] syscall.exec_kernel_proc # => [ACCT_HASH, PAD(12)] # clean the stack swapdw dropw dropw swapw dropw # => [ACCT_HASH] end #! Increments the account nonce by the provided value. #! #! Stack: [value] #! Output: [] #! #! - value is the value to increment the nonce by. value can be at most 2^32 - 1 otherwise this #! procedure panics. export.incr_nonce # start padding the stack push.0.0 movup.2 # => [value, 0, 0] exec.kernel_proc_offsets::incr_account_nonce_offset # => [offset, value, 0, 0] # pad the stack padw swapw padw padw swapdw # => [offset, value, PAD(14)] syscall.exec_kernel_proc # => [PAD(16)] dropw dropw dropw dropw end #! Gets an item from the account storage. Panics if the index is out of bounds. #! #! Stack: [index] #! Output: [VALUE] #! #! - index is the index of the item to get. #! - VALUE is the value of the item. export.get_item push.0.0 movup.2 # => [index, 0, 0] exec.kernel_proc_offsets::get_account_item_offset # => [offset, index, 0, 0] # pad the stack padw swapw padw padw swapdw # => [offset, index, PAD(14)] syscall.exec_kernel_proc # => [VALUE, PAD(12)] # clean the stack swapdw dropw dropw swapw dropw # => [VALUE] end #! Sets an item in the account storage. Panics if the index is out of bounds. #! #! Stack: [index, V'] #! Output: [R', V] #! #! - index is the index of the item to set. #! - V' is the value to set. #! - V is the previous value of the item. #! - R' is the new storage commitment. export.set_item exec.kernel_proc_offsets::set_account_item_offset # => [offset, index, V'] # pad the stack push.0.0 movdn.7 movdn.7 padw padw swapdw # => [offset, index, V', PAD(10)] syscall.exec_kernel_proc # => [R', V, PAD(8)] # clean the stack swapdw dropw dropw # => [R', V] end #! Gets a map item from the account storage. Panics if #! - the index for the map is out of bounds, means >255 #! - the slot item at index is not a map #! #! Stack: [index, KEY] #! Output: [VALUE] #! #! - index is the index of the map where the KEY VALUE should be read. #! - KEY is the key of the item to get. #! - VALUE is the value of the item. export.get_map_item exec.kernel_proc_offsets::get_account_map_item_offset # => [offset, index, KEY] # pad the stack push.0.0 movdn.7 movdn.7 padw padw swapdw # => [offset, index, KEY, PAD(10)] syscall.exec_kernel_proc # => [VALUE, PAD(12)] # clean the stack swapdw dropw dropw swapw dropw # => [VALUE] end #! Sets a map item in the account storage. Panics if #! - the index for the map is out of bounds, means >255 #! - the slot item at index is not a map #! #! Stack: [index, KEY, VALUE] #! Output: [OLD_MAP_ROOT, OLD_MAP_VALUE] #! #! - index is the index of the map where the KEY VALUE should be set. #! - KEY is the key to set at VALUE. #! - VALUE is the value to set at KEY. #! - OLD_MAP_ROOT is the old map root. #! - OLD_MAP_VALUE is the old value at KEY. export.set_map_item exec.kernel_proc_offsets::set_account_map_item_offset # => [offset, index, KEY, VALUE] # pad the stack push.0.0 movdn.11 movdn.11 padw movdnw.3 # => [offset, index, KEY, VALUE, PAD(6)] syscall.exec_kernel_proc # => [OLD_MAP_ROOT, OLD_MAP_VALUE, PAD(8)] # clean the stack swapdw dropw dropw # => [OLD_MAP_ROOT, OLD_MAP_VALUE] end #! Sets the code of the account the transaction is being executed against. This procedure can only #! executed on regular accounts with updatable code. Otherwise, this procedure fails. #! #! Stack: [CODE_COMMITMENT] #! Output: [] #! #! - CODE_COMMITMENT is the hash of the code to set. export.set_code exec.kernel_proc_offsets::set_account_code_offset # => [offset, CODE_COMMITMENT] # pad the stack push.0.0.0 movdn.7 movdn.7 movdn.7 padw padw swapdw # => [offset, CODE_COMMITMENT, PAD(11)] syscall.exec_kernel_proc # => [PAD(16)] # clean the stack dropw dropw dropw dropw # => [] end #! Returns the balance of a fungible asset associated with a faucet_id. #! Panics if the asset is not a fungible asset. #! #! Stack: [faucet_id] #! Output: [balance] #! #! - faucet_id is the faucet id of the fungible asset of interest. #! - balance is the vault balance of the fungible asset. export.get_balance exec.kernel_proc_offsets::account_vault_get_balance_offset # => [offset, faucet_id] # pad the stack push.0.0 movdn.3 movdn.3 padw swapw padw padw swapdw # => [offset, faucet_id, PAD(14)] syscall.exec_kernel_proc # => [balance, PAD(15)] # clean the stack swapdw dropw dropw swapw dropw movdn.3 drop drop drop # => [balance] end #! Returns a boolean indicating whether the non-fungible asset is present in the vault. #! Panics if the ASSET is a fungible asset. #! #! Stack: [ASSET] #! Output: [has_asset] #! #! - ASSET is the non-fungible asset of interest #! - has_asset is a boolean indicating whether the account vault has the asset of interest export.has_non_fungible_asset exec.kernel_proc_offsets::account_vault_has_non_fungible_asset_offset # => [offset, ASSET] # pad the stack push.0.0.0 movdn.7 movdn.7 movdn.7 padw padw swapdw # => [offset, ASSET, PAD(11)] syscall.exec_kernel_proc # => [has_asset, PAD(15)] # clean the stack swapdw dropw dropw swapw dropw movdn.3 drop drop drop # => [has_asset] end #! Add the specified asset to the vault. #! #! Panics: #! - If the asset is not valid. #! - If the total value of two fungible assets is greater than or equal to 2^63. #! - If the vault already contains the same non-fungible asset. #! #! Stack: [ASSET] #! Output: [ASSET'] #! #! - ASSET' final asset in the account vault defined as follows: #! - If ASSET is a non-fungible asset, then ASSET' is the same as ASSET. #! - If ASSET is a fungible asset, then ASSET' is the total fungible asset in the account vault #! after ASSET was added to it. export.add_asset exec.kernel_proc_offsets::account_vault_add_asset_offset # => [offset, ASSET] # pad the stack push.0.0.0 movdn.7 movdn.7 movdn.7 padw padw swapdw # => [offset, ASSET, PAD(11)] syscall.exec_kernel_proc # => [ASSET', PAD(12)] # clean the stack swapdw dropw dropw swapw dropw # => [ASSET'] end #! Remove the specified asset from the vault. #! #! Panics: #! - The fungible asset is not found in the vault. #! - The amount of the fungible asset in the vault is less than the amount to be removed. #! - The non-fungible asset is not found in the vault. #! #! Stack: [ASSET] #! Output: [ASSET] #! #! - ASSET is the asset to remove from the vault. export.remove_asset exec.kernel_proc_offsets::account_vault_remove_asset_offset # => [offset, ASSET] # pad the stack push.0.0.0 movdn.7 movdn.7 movdn.7 padw padw swapdw # => [offset, ASSET, PAD(11)] syscall.exec_kernel_proc # => [ASSET, PAD(12)] # clean the stack swapdw dropw dropw swapw dropw # => [ASSET] end #! Returns a commitment to the account vault. #! #! Stack: [] #! Output: [COM] #! #! - COM is a commitment to the account vault. export.get_vault_commitment # pad the stack for syscall invocation padw padw padw push.0.0.0 # => [PAD(15)] exec.kernel_proc_offsets::get_account_vault_commitment_offset # => [offset, PAD(15)] syscall.exec_kernel_proc # => [COM, PAD(12)] # clean the stack swapdw dropw dropw swapw dropw # => [COM] end # PROCEDURES COPIED FROM KERNEL (TODO: get rid of this duplication) # ================================================================================================= # Given the most significant half of an account id, this mask defines the bits used to determine the account type. const.ACCOUNT_TYPE_U32MASK=805306368 # 0b00110000_00000000_00000000_00000000 # Bit pattern for a fungible faucet w/ immutable code, after the account type mask has been applied. const.FUNGIBLE_FAUCET_ACCOUNT=536870912 # 0b00100000_00000000_00000000_00000000 # Bit pattern for a non-fungible faucet w/ immutable code, after the account type mask has been applied. const.NON_FUNGIBLE_FAUCET_ACCOUNT=805306368 # 0b00110000_00000000_00000000_00000000 #! Returns the most significant half with the account type bits masked out. #! #! The account type can be defined by comparing this value with the following constants: #! #! - REGULAR_ACCOUNT_UPDATABLE_CODE #! - REGULAR_ACCOUNT_IMMUTABLE_CODE #! - FUNGIBLE_FAUCET_ACCOUNT #! - NON_FUNGIBLE_FAUCET_ACCOUNT #! #! Stack: [acct_id] #! Output: [acct_type] #! #! - acct_id is the account id. #! - acct_type is the account type. proc.type u32split swap drop push.ACCOUNT_TYPE_U32MASK u32and # => [acct_type] end #! Returns a boolean indicating whether the account is a fungible faucet. #! #! Stack: [acct_id] #! Output: [is_fungible_faucet] #! #! - acct_id is the account id. #! - is_fungible_faucet is a boolean indicating whether the account is a fungible faucet. export.is_fungible_faucet exec.type push.FUNGIBLE_FAUCET_ACCOUNT eq # => [is_fungible_faucet] end #! Returns a boolean indicating whether the account is a non-fungible faucet. #! #! Stack: [acct_id] #! Output: [is_non_fungible_faucet] #! #! - acct_id is the account id. #! - is_non_fungible_faucet is a boolean indicating whether the account is a non-fungible faucet. export.is_non_fungible_faucet exec.type push.NON_FUNGIBLE_FAUCET_ACCOUNT eq # => [is_non_fungible_faucet] end