use {
Asset,
AssetValue,
Bool,
NoteAssetsCommitment,
NoteAttachmentsCommitment,
NoteId,
NoteMetadata,
NoteRecipient,
NoteScriptRoot,
NoteSerialNumber,
NoteStorageCommitment,
} from miden::protocol::types
use {INPUT_NOTE_GET_ASSET_OFFSET, INPUT_NOTE_GET_ATTACHMENTS_COMMITMENT_OFFSET, INPUT_NOTE_GET_INITIAL_ASSETS_INFO_OFFSET, INPUT_NOTE_GET_METADATA_OFFSET, INPUT_NOTE_GET_NOTE_ID_OFFSET, INPUT_NOTE_GET_RECIPIENT_OFFSET, INPUT_NOTE_GET_SCRIPT_ROOT_OFFSET, INPUT_NOTE_GET_SERIAL_NUMBER_OFFSET, INPUT_NOTE_GET_STORAGE_INFO_OFFSET, INPUT_NOTE_REMOVE_ALL_ASSETS_OFFSET, INPUT_NOTE_REMOVE_ASSET_OFFSET}
from miden::protocol::kernel_proc_offsets
use miden::protocol::note_internal
# PROCEDURES
# =================================================================================================
#
# Internal shared implementations of the `miden::protocol::input_note` and
# `miden::protocol::active_note` APIs. Each procedure takes an `is_active_note` flag: 0 selects the
# input note at the specified index, 1 selects the currently active note (in which case the note
# index is ignored).
# ASSETS
# =================================================================================================
#! Writes the initial assets of the input note with the specified index or the active note,
#! depending on the provided flag, into memory starting at the specified address.
#!
#! This is the shared implementation used by both `input_note::get_initial_assets` and
#! `active_note::get_initial_assets`. See `input_note::get_initial_assets` for details on the
#! memory requirements and layout at `dest_ptr`.
#!
#! Inputs: [is_active_note, note_index, dest_ptr]
#! Outputs: [num_assets]
#!
#! Where:
#! - is_active_note is 0 for indexed access, 1 for the currently active note.
#! - note_index is the index of the input note.
#! - dest_ptr is the memory address to write the assets.
#! - num_assets is the number of assets the note was created with.
#!
#! Panics if:
#! - the note index is greater or equal to the total number of input notes.
#!
#! Invocation: exec
pub proc get_initial_assets_raw(is_active_note: Bool, note_index: u16, dest_ptr: ptr<Asset>) -> u8
exec.get_initial_assets_info_raw
# => [ASSETS_COMMITMENT, num_assets, dest_ptr]
# save num_assets for the return value
dup.4 movdn.6
# => [ASSETS_COMMITMENT, num_assets, dest_ptr, num_assets]
# write the assets stored in the advice map to the specified memory pointer
exec.note_internal::write_assets_to_memory
# => [num_assets]
end
#! Returns the initial assets information of the input note with the specified index or the
#! active note, depending on the provided flag.
#!
#! This is the shared implementation used by both `input_note::get_initial_assets_info` and
#! `active_note::get_initial_assets_info`.
#!
#! Inputs: [is_active_note, note_index]
#! Outputs: [ASSETS_COMMITMENT, num_assets]
#!
#! Where:
#! - is_active_note is 0 for indexed access, 1 for the currently active note.
#! - note_index is the index of the input note.
#! - num_assets is the number of assets the note was created with.
#! - ASSETS_COMMITMENT is a sequential hash of the assets the note was created with.
#!
#! Panics if:
#! - the note index is greater or equal to the total number of input notes.
#!
#! Invocation: exec
pub proc get_initial_assets_info_raw(
is_active_note: Bool,
note_index: u16
) -> (NoteAssetsCommitment, u8)
push.0 movdn.2
# => [is_active_note, note_index, 0]
push.INPUT_NOTE_GET_INITIAL_ASSETS_INFO_OFFSET
# => [offset, is_active_note, note_index, 0]
# pad the stack
padw swapw padw padw swapdw
# => [offset, is_active_note, note_index, pad(13)]
syscall.exec_kernel_proc
# => [ASSETS_COMMITMENT, num_assets, pad(11)]
# clean the stack
swapdw dropw dropw
repeat.3
movup.5 drop
end
# => [ASSETS_COMMITMENT, num_assets]
end
#! Returns the asset at the specified index in the input note with the specified index or the
#! active note, depending on the provided flag.
#!
#! This is the shared implementation used by both `input_note::get_asset` and
#! `active_note::get_asset`.
#!
#! Inputs: [is_active_note, asset_index, note_index]
#! Outputs: [ASSET_ID, ASSET_VALUE]
#!
#! Where:
#! - is_active_note is 0 for indexed access, 1 for the currently active note.
#! - asset_index is the index of the asset to return.
#! - note_index is the index of the input note.
#! - ASSET_ID is the asset ID of the asset at the specified index.
#! - ASSET_VALUE is the value of the asset at the specified index.
#!
#! Panics if:
#! - the note index is greater or equal to the total number of input notes.
#! - the asset index is greater or equal to the number of assets in the note.
#!
#! Invocation: exec
pub proc get_asset_raw(is_active_note: Bool, asset_index: u16, note_index: u16) -> Asset
push.INPUT_NOTE_GET_ASSET_OFFSET
# => [offset, is_active_note, asset_index, note_index]
# pad the stack
padw swapw padw padw swapdw
# => [offset, is_active_note, asset_index, note_index, pad(12)]
syscall.exec_kernel_proc
# => [ASSET_ID, ASSET_VALUE, pad(8)]
# clean the stack
swapdw dropw dropw
# => [ASSET_ID, ASSET_VALUE]
end
#! Removes an asset from the input note with the specified index or the active note, depending on
#! the provided flag.
#!
#! This is the shared implementation used by both `input_note::remove_asset` and
#! `active_note::remove_asset`.
#!
#! Inputs: [is_active_note, ASSET_ID, ASSET_VALUE, note_index]
#! Outputs: [FINAL_ASSET_VALUE]
#!
#! Where:
#! - is_active_note is 0 for indexed access, 1 for the currently active note.
#! - ASSET_ID is the asset ID of the asset to remove from the note.
#! - ASSET_VALUE is the value of the asset to remove from the note.
#! - note_index is the index of the input note.
#! - FINAL_ASSET_VALUE is the value of the asset remaining in the note after removal, which is
#! the EMPTY_WORD if the entire asset was removed.
#!
#! Panics if:
#! - is_active_note is false and the active account is not the native account.
#! - is_active_note is false and the invocation does not originate from the account context.
#! - the note index is greater or equal to the total number of input notes.
#! - the asset ID to remove is the empty word or is not a well-formed asset ID.
#! - the asset's composition is Custom (not yet supported).
#! - the asset is not present in the note.
#! - the asset is not composable and is not present in the note with the exact value.
#! - the amount of the fungible asset in the note is less than the amount to be removed.
#!
#! Invocation: exec
pub proc remove_asset_raw(
is_active_note: Bool,
asset: Asset,
note_index: u16
) -> AssetValue
push.INPUT_NOTE_REMOVE_ASSET_OFFSET
# => [offset, is_active_note, ASSET_ID, ASSET_VALUE, note_index]
# pad the stack
repeat.5
push.0 movdn.11
end
# => [offset, is_active_note, ASSET_ID, ASSET_VALUE, note_index, pad(5)]
syscall.exec_kernel_proc
# => [FINAL_ASSET_VALUE, pad(12)]
# clean the stack
swapdw dropw dropw swapw dropw
# => [FINAL_ASSET_VALUE]
end
#! Removes all remaining assets from the input note with the specified index or the active note,
#! depending on the provided flag, and writes them into memory starting at the specified address.
#!
#! This is the shared implementation used by both `input_note::remove_all_assets` and
#! `active_note::remove_all_assets`. See `input_note::remove_all_assets` for details on the
#! memory requirements and layout at `dest_ptr`.
#!
#! Inputs: [is_active_note, note_index, dest_ptr]
#! Outputs: [num_assets]
#!
#! Where:
#! - is_active_note is 0 for indexed access, 1 for the currently active note.
#! - note_index is the index of the input note.
#! - dest_ptr is the memory address to write the assets.
#! - num_assets is the number of assets removed by this procedure.
#!
#! Panics if:
#! - is_active_note is false and the active account is not the native account.
#! - is_active_note is false and the invocation does not originate from the account context.
#! - the note index is greater or equal to the total number of input notes.
#!
#! Invocation: exec
pub proc remove_all_assets_raw(is_active_note: Bool, note_index: u16, dest_ptr: ptr<Asset>) -> u8
push.0 movdn.2
# => [is_active_note, note_index, 0, dest_ptr]
push.INPUT_NOTE_REMOVE_ALL_ASSETS_OFFSET
# => [offset, is_active_note, note_index, 0, dest_ptr]
# pad the stack
padw swapw padw padw swapdw
# => [offset, is_active_note, note_index, pad(13), dest_ptr]
syscall.exec_kernel_proc
# => [ASSETS_COMMITMENT, num_assets, pad(11), dest_ptr]
# clean the stack
swapdw dropw dropw
repeat.3
movup.5 drop
end
# => [ASSETS_COMMITMENT, num_assets, dest_ptr]
# save num_assets for the return value
dup.4 movdn.6
# => [ASSETS_COMMITMENT, num_assets, dest_ptr, num_assets]
# write the removed assets stored in the advice map to the specified memory pointer
exec.note_internal::write_assets_to_memory
# => [num_assets]
end
# ACCESSORS
# =================================================================================================
#! Returns the recipient of the input note with the specified index or the active note, depending
#! on the provided flag.
#!
#! This is the shared implementation used by both `input_note::get_recipient` and
#! `active_note::get_recipient`.
#!
#! Inputs: [is_active_note, note_index]
#! Outputs: [RECIPIENT]
#!
#! Where:
#! - is_active_note is 0 for indexed access, 1 for the currently active note.
#! - note_index is the index of the input note.
#! - RECIPIENT is the commitment to the input note's script, storage, the serial number.
#!
#! Panics if:
#! - the note index is greater or equal to the total number of input notes.
#!
#! Invocation: exec
pub proc get_recipient_raw(is_active_note: Bool, note_index: u16) -> NoteRecipient
push.0 movdn.2
# => [is_active_note, note_index, 0]
push.INPUT_NOTE_GET_RECIPIENT_OFFSET
# => [offset, is_active_note, note_index, 0]
# pad the stack
padw swapw padw padw swapdw
# => [offset, is_active_note, note_index, pad(13)]
syscall.exec_kernel_proc
# => [RECIPIENT, pad(12)]
# clean the stack
swapdw dropw dropw swapw dropw
# => [RECIPIENT]
end
#! Returns the metadata of the input note with the specified index or the active note, depending
#! on the provided flag.
#!
#! This is the shared implementation used by both `input_note::get_metadata` and
#! `active_note::get_metadata`.
#!
#! Inputs: [is_active_note, note_index]
#! Outputs: [METADATA]
#!
#! Where:
#! - is_active_note is 0 for indexed access, 1 for the currently active note.
#! - note_index is the index of the input note.
#! - METADATA is the metadata of the specified input note.
#!
#! Panics if:
#! - the note index is greater or equal to the total number of input notes.
#!
#! Invocation: exec
pub proc get_metadata_raw(is_active_note: Bool, note_index: u16) -> NoteMetadata
push.0 movdn.2
# => [is_active_note, note_index, 0]
push.INPUT_NOTE_GET_METADATA_OFFSET
# => [offset, is_active_note, note_index, 0]
# pad the stack
padw swapw padw padw swapdw
# => [offset, is_active_note, note_index, pad(13)]
syscall.exec_kernel_proc
# => [METADATA, pad(12)]
# clean the stack
swapdw dropw dropw swapw dropw
# => [METADATA]
end
#! Returns the inputs commitment and length of the input note with the specified index or the
#! active note, depending on the provided flag.
#!
#! This is the shared implementation used by both `input_note::get_storage_info` and
#! `active_note::get_storage`.
#!
#! Inputs: [is_active_note, note_index]
#! Outputs: [NOTE_STORAGE_COMMITMENT, num_storage_items]
#!
#! Where:
#! - is_active_note is 0 for indexed access, 1 for the currently active note.
#! - note_index is the index of the input note.
#! - NOTE_STORAGE_COMMITMENT is the inputs commitment of the specified input note.
#! - num_storage_items is the number of input values of the specified input note.
#!
#! Panics if:
#! - the note index is greater or equal to the total number of input notes.
#!
#! Invocation: exec
pub proc get_storage_info_raw(is_active_note: Bool, note_index: u16) -> (NoteStorageCommitment, u16)
push.0 movdn.2
# => [is_active_note, note_index, 0]
push.INPUT_NOTE_GET_STORAGE_INFO_OFFSET
# => [offset, is_active_note, note_index, 0]
# pad the stack
padw swapw padw padw swapdw
# => [offset, is_active_note, note_index, pad(13)]
syscall.exec_kernel_proc
# => [NOTE_STORAGE_COMMITMENT, num_storage_items, pad(11)]
# clean the stack
swapdw dropw dropw
repeat.3
movup.5 drop
end
# => [NOTE_STORAGE_COMMITMENT, num_storage_items]
end
#! Returns the script root of the input note with the specified index or the active note,
#! depending on the provided flag.
#!
#! This is the shared implementation used by both `input_note::get_script_root` and
#! `active_note::get_script_root`.
#!
#! Inputs: [is_active_note, note_index]
#! Outputs: [SCRIPT_ROOT]
#!
#! Where:
#! - is_active_note is 0 for indexed access, 1 for the currently active note.
#! - note_index is the index of the input note.
#! - SCRIPT_ROOT is the script root of the specified input note.
#!
#! Panics if:
#! - the note index is greater or equal to the total number of input notes.
#!
#! Invocation: exec
pub proc get_script_root_raw(is_active_note: Bool, note_index: u16) -> NoteScriptRoot
push.0 movdn.2
# => [is_active_note, note_index, 0]
push.INPUT_NOTE_GET_SCRIPT_ROOT_OFFSET
# => [offset, is_active_note, note_index, 0]
# pad the stack
padw swapw padw padw swapdw
# => [offset, is_active_note, note_index, pad(13)]
syscall.exec_kernel_proc
# => [SCRIPT_ROOT, pad(12)]
# clean the stack
swapdw dropw dropw swapw dropw
# => [SCRIPT_ROOT]
end
#! Returns the serial number of the input note with the specified index or the active note,
#! depending on the provided flag.
#!
#! This is the shared implementation used by both `input_note::get_serial_number` and
#! `active_note::get_serial_number`.
#!
#! Inputs: [is_active_note, note_index]
#! Outputs: [SERIAL_NUMBER]
#!
#! Where:
#! - is_active_note is 0 for indexed access, 1 for the currently active note.
#! - note_index is the index of the input note.
#! - SERIAL_NUMBER is the serial number of the specified input note.
#!
#! Panics if:
#! - the note index is greater or equal to the total number of input notes.
#!
#! Invocation: exec
pub proc get_serial_number_raw(is_active_note: Bool, note_index: u16) -> NoteSerialNumber
push.0 movdn.2
# => [is_active_note, note_index, 0]
push.INPUT_NOTE_GET_SERIAL_NUMBER_OFFSET
# => [offset, is_active_note, note_index, 0]
# pad the stack
padw swapw padw padw swapdw
# => [offset, is_active_note, note_index, pad(13)]
syscall.exec_kernel_proc
# => [SERIAL_NUMBER, pad(12)]
# clean the stack
swapdw dropw dropw swapw dropw
# => [SERIAL_NUMBER]
end
#! Returns the ID of the input note with the specified index or the active note, depending on the
#! provided flag.
#!
#! This is the shared implementation used by both `input_note::get_note_id` and
#! `active_note::get_note_id`.
#!
#! Inputs: [is_active_note, note_index]
#! Outputs: [NOTE_ID]
#!
#! Where:
#! - is_active_note is 0 for indexed access, 1 for the currently active note.
#! - note_index is the index of the input note.
#! - NOTE_ID is the ID of the specified input note, cached by the transaction prologue.
#!
#! Panics if:
#! - the note index is greater or equal to the total number of input notes.
#!
#! Invocation: exec
pub proc get_note_id_raw(is_active_note: Bool, note_index: u16) -> NoteId
push.0 movdn.2
# => [is_active_note, note_index, 0]
push.INPUT_NOTE_GET_NOTE_ID_OFFSET
# => [offset, is_active_note, note_index, 0]
# pad the stack
padw swapw padw padw swapdw
# => [offset, is_active_note, note_index, pad(13)]
syscall.exec_kernel_proc
# => [NOTE_ID, pad(12)]
# clean the stack
swapdw dropw dropw swapw dropw
# => [NOTE_ID]
end
# ATTACHMENTS
# =================================================================================================
#! Returns the commitment over all attachments of the input note with the specified index or the
#! active note, depending on the provided flag.
#!
#! This is the shared implementation used by both `input_note::get_attachments_commitment` and
#! `active_note::get_attachments_commitment`.
#!
#! Inputs: [is_active_note, note_index]
#! Outputs: [ATTACHMENTS_COMMITMENT]
#!
#! Where:
#! - is_active_note is 0 for indexed access, 1 for the currently active note.
#! - note_index is the index of the input note.
#! - ATTACHMENTS_COMMITMENT is the commitment to all attachments of the note, or the EMPTY_WORD if
#! the note does not have any attachments.
#!
#! Panics if:
#! - the note index is greater or equal to the total number of input notes.
#!
#! Invocation: exec
pub proc get_attachments_commitment_raw(
is_active_note: Bool,
note_index: u16
) -> NoteAttachmentsCommitment
push.0 movdn.2
# => [is_active_note, note_index, 0]
push.INPUT_NOTE_GET_ATTACHMENTS_COMMITMENT_OFFSET
# => [offset, is_active_note, note_index, 0]
padw swapw padw padw swapdw
# => [offset, is_active_note, note_index, pad(13)]
syscall.exec_kernel_proc
# => [ATTACHMENTS_COMMITMENT, pad(12)]
# clean the stack, keeping only the commitment
swapdw dropw dropw swapw dropw
# => [ATTACHMENTS_COMMITMENT]
end