Newer
Older
// data passed to the supervisor will lead to a trap. This is not documented explicitly
// for every function.
Sasha Gryaznov
committed
#[define_env(doc)]
pub mod env {
/// Set the value at the given key in the contract storage.
/// See [`pallet_contracts_uapi::HostFn::set_storage`]
Sasha Gryaznov
committed
#[prefixed_alias]
fn set_storage(
Alexander Theißen
committed
ctx: _,
memory: _,
key_ptr: u32,
value_ptr: u32,
value_len: u32,
) -> Result<(), TrapReason> {
Alexander Theißen
committed
ctx.set_storage(memory, KeyType::Fix, key_ptr, value_ptr, value_len).map(|_| ())
/// Set the value at the given key in the contract storage.
/// See [`pallet_contracts_uapi::HostFn::set_storage_v1`]
#[version(1)]
Sasha Gryaznov
committed
#[prefixed_alias]
fn set_storage(
Alexander Theißen
committed
ctx: _,
memory: _,
key_ptr: u32,
value_ptr: u32,
value_len: u32,
) -> Result<u32, TrapReason> {
Alexander Theißen
committed
ctx.set_storage(memory, KeyType::Fix, key_ptr, value_ptr, value_len)
/// Set the value at the given key in the contract storage.
/// See [`pallet_contracts_uapi::HostFn::set_storage_v2`]
Sasha Gryaznov
committed
#[prefixed_alias]
fn set_storage(
Alexander Theißen
committed
ctx: _,
memory: _,
key_ptr: u32,
key_len: u32,
value_ptr: u32,
value_len: u32,
) -> Result<u32, TrapReason> {
ctx.set_storage(memory, KeyType::Var(key_len), key_ptr, value_ptr, value_len)
/// Clear the value at the given key in the contract storage.
/// See [`pallet_contracts_uapi::HostFn::clear_storage`]
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn clear_storage(ctx: _, memory: _, key_ptr: u32) -> Result<(), TrapReason> {
ctx.clear_storage(memory, KeyType::Fix, key_ptr).map(|_| ())
/// Clear the value at the given key in the contract storage.
/// See [`pallet_contracts_uapi::HostFn::clear_storage_v1`]
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn clear_storage(ctx: _, memory: _, key_ptr: u32, key_len: u32) -> Result<u32, TrapReason> {
ctx.clear_storage(memory, KeyType::Var(key_len), key_ptr)
/// Retrieve the value under the given key from storage.
/// See [`pallet_contracts_uapi::HostFn::get_storage`]
Sasha Gryaznov
committed
#[prefixed_alias]
fn get_storage(
Alexander Theißen
committed
ctx: _,
memory: _,
key_ptr: u32,
out_ptr: u32,
out_len_ptr: u32,
) -> Result<ReturnErrorCode, TrapReason> {
Alexander Theißen
committed
ctx.get_storage(memory, KeyType::Fix, key_ptr, out_ptr, out_len_ptr)
/// Retrieve the value under the given key from storage.
/// See [`pallet_contracts_uapi::HostFn::get_storage_v1`]
Sasha Gryaznov
committed
#[prefixed_alias]
fn get_storage(
Alexander Theißen
committed
ctx: _,
memory: _,
key_ptr: u32,
key_len: u32,
out_ptr: u32,
out_len_ptr: u32,
) -> Result<ReturnErrorCode, TrapReason> {
ctx.get_storage(memory, KeyType::Var(key_len), key_ptr, out_ptr, out_len_ptr)
/// Checks whether there is a value stored under the given key.
/// See [`pallet_contracts_uapi::HostFn::contains_storage`]
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn contains_storage(ctx: _, memory: _, key_ptr: u32) -> Result<u32, TrapReason> {
ctx.contains_storage(memory, KeyType::Fix, key_ptr)
/// Checks whether there is a value stored under the given key.
/// See [`pallet_contracts_uapi::HostFn::contains_storage_v1`]
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn contains_storage(ctx: _, memory: _, key_ptr: u32, key_len: u32) -> Result<u32, TrapReason> {
ctx.contains_storage(memory, KeyType::Var(key_len), key_ptr)
/// Retrieve and remove the value under the given key from storage.
/// See [`pallet_contracts_uapi::HostFn::take_storage`]
Sasha Gryaznov
committed
#[prefixed_alias]
fn take_storage(
Alexander Theißen
committed
ctx: _,
memory: _,
key_ptr: u32,
key_len: u32,
out_ptr: u32,
out_len_ptr: u32,
) -> Result<ReturnErrorCode, TrapReason> {
let charged = ctx.charge_gas(RuntimeCosts::TakeStorage(ctx.ext.max_value_size()))?;
ensure!(
key_len <= <<E as Ext>::T as Config>::MaxStorageKeyLen::get(),
Error::<E::T>::DecodingFailed
);
Alexander Theißen
committed
let key = ctx.read_sandbox_memory(memory, key_ptr, key_len)?;
if let crate::storage::WriteOutcome::Taken(value) = ctx.ext.set_storage(
&Key::<E::T>::try_from_var(key).map_err(|_| Error::<E::T>::DecodingFailed)?,
None,
true,
)? {
ctx.adjust_gas(charged, RuntimeCosts::TakeStorage(value.len() as u32));
Alexander Theißen
committed
ctx.write_sandbox_output(memory, out_ptr, out_len_ptr, &value, false, already_charged)?;
} else {
ctx.adjust_gas(charged, RuntimeCosts::TakeStorage(0));
Ok(ReturnErrorCode::KeyNotFound)
}
/// Transfer some value to another account.
/// See [`pallet_contracts_uapi::HostFn::transfer`].
Sasha Gryaznov
committed
#[prefixed_alias]
fn transfer(
Alexander Theißen
committed
ctx: _,
memory: _,
_value_len: u32,
) -> Result<ReturnErrorCode, TrapReason> {
ctx.charge_gas(RuntimeCosts::Transfer)?;
let callee: <<E as Ext>::T as frame_system::Config>::AccountId =
Alexander Theißen
committed
ctx.read_sandbox_memory_as(memory, account_ptr)?;
let value: BalanceOf<<E as Ext>::T> = ctx.read_sandbox_memory_as(memory, value_ptr)?;
let result = ctx.ext.transfer(&callee, value);
Alexander Theißen
committed
match result {
Ok(()) => Ok(ReturnErrorCode::Success),
Alexander Theißen
committed
Err(err) => {
let code = Runtime::<E>::err_into_return_code(err)?;
Ok(code)
Alexander Theißen
committed
}
/// Make a call to another contract.
///
/// # Note
///
/// The values `_callee_len` and `_value_len` are ignored because the encoded sizes of those
/// types are fixed through [`codec::MaxEncodedLen`]. The fields exist for backwards
/// compatibility. Consider switching to the newest version of this function.
Sasha Gryaznov
committed
#[prefixed_alias]
fn call(
Alexander Theißen
committed
ctx: _,
memory: _,
callee_ptr: u32,
gas: u64,
value_ptr: u32,
input_data_ptr: u32,
input_data_len: u32,
output_ptr: u32,
output_len_ptr: u32,
) -> Result<ReturnErrorCode, TrapReason> {
ctx.call(
Alexander Theißen
committed
memory,
CallFlags::ALLOW_REENTRY,
Sasha Gryaznov
committed
CallType::Call {
callee_ptr,
value_ptr,
deposit_ptr: SENTINEL,
weight: Weight::from_parts(gas, 0),
},
input_data_ptr,
input_data_len,
output_ptr,
output_len_ptr,
)
}
/// Make a call to another contract.
/// See [`pallet_contracts_uapi::HostFn::call_v1`].
Sasha Gryaznov
committed
#[version(1)]
#[prefixed_alias]
fn call(
ctx: _,
memory: _,
flags: u32,
callee_ptr: u32,
gas: u64,
value_ptr: u32,
input_data_ptr: u32,
input_data_len: u32,
output_ptr: u32,
output_len_ptr: u32,
) -> Result<ReturnErrorCode, TrapReason> {
Sasha Gryaznov
committed
ctx.call(
memory,
CallFlags::from_bits(flags).ok_or(Error::<E::T>::InvalidCallFlags)?,
CallType::Call {
callee_ptr,
value_ptr,
deposit_ptr: SENTINEL,
weight: Weight::from_parts(gas, 0),
},
input_data_ptr,
input_data_len,
output_ptr,
output_len_ptr,
)
/// Make a call to another contract.
/// See [`pallet_contracts_uapi::HostFn::call_v2`].
Sasha Gryaznov
committed
#[version(2)]
#[unstable]
Sasha Gryaznov
committed
fn call(
Alexander Theißen
committed
ctx: _,
memory: _,
flags: u32,
Sasha Gryaznov
committed
ref_time_limit: u64,
proof_size_limit: u64,
deposit_ptr: u32,
input_data_len: u32,
output_ptr: u32,
output_len_ptr: u32,
) -> Result<ReturnErrorCode, TrapReason> {
ctx.call(
Alexander Theißen
committed
memory,
CallFlags::from_bits(flags).ok_or(Error::<E::T>::InvalidCallFlags)?,
Sasha Gryaznov
committed
CallType::Call {
callee_ptr,
value_ptr,
deposit_ptr,
weight: Weight::from_parts(ref_time_limit, proof_size_limit),
},
Yarik Bratashchuk
committed
input_data_ptr,
input_data_len,
output_ptr,
output_len_ptr,
)
Yarik Bratashchuk
committed
/// Execute code in the context (storage, caller, value) of the current contract.
/// See [`pallet_contracts_uapi::HostFn::delegate_call`].
Sasha Gryaznov
committed
#[prefixed_alias]
fn delegate_call(
Alexander Theißen
committed
ctx: _,
memory: _,
Yarik Bratashchuk
committed
flags: u32,
code_hash_ptr: u32,
input_data_ptr: u32,
input_data_len: u32,
output_ptr: u32,
output_len_ptr: u32,
) -> Result<ReturnErrorCode, TrapReason> {
Yarik Bratashchuk
committed
ctx.call(
Alexander Theißen
committed
memory,
CallFlags::from_bits(flags).ok_or(Error::<E::T>::InvalidCallFlags)?,
CallType::DelegateCall { code_hash_ptr },
input_data_ptr,
input_data_len,
output_ptr,
output_len_ptr,
)
/// Instantiate a contract with the specified code hash.
/// See [`pallet_contracts_uapi::HostFn::instantiate`].
///
/// # Note
///
/// The values `_code_hash_len` and `_value_len` are ignored because the encoded sizes
Sasha Gryaznov
committed
/// of those types are fixed through [`codec::MaxEncodedLen`]. The fields exist
Sasha Gryaznov
committed
/// for backwards compatibility. Consider switching to the newest version of this function.
Sasha Gryaznov
committed
#[prefixed_alias]
fn instantiate(
Alexander Theißen
committed
ctx: _,
memory: _,
code_hash_ptr: u32,
_code_hash_len: u32,
gas: u64,
value_ptr: u32,
_value_len: u32,
input_data_ptr: u32,
input_data_len: u32,
address_ptr: u32,
address_len_ptr: u32,
output_ptr: u32,
output_len_ptr: u32,
salt_ptr: u32,
salt_len: u32,
) -> Result<ReturnErrorCode, TrapReason> {
ctx.instantiate(
Alexander Theißen
committed
memory,
Sasha Gryaznov
committed
Weight::from_parts(gas, 0),
SENTINEL,
value_ptr,
input_data_ptr,
input_data_len,
address_ptr,
address_len_ptr,
output_ptr,
output_len_ptr,
salt_ptr,
salt_len,
)
}
/// Instantiate a contract with the specified code hash.
/// See [`pallet_contracts_uapi::HostFn::instantiate_v1`].
Sasha Gryaznov
committed
#[version(1)]
#[prefixed_alias]
fn instantiate(
ctx: _,
memory: _,
code_hash_ptr: u32,
gas: u64,
value_ptr: u32,
input_data_ptr: u32,
input_data_len: u32,
address_ptr: u32,
address_len_ptr: u32,
output_ptr: u32,
output_len_ptr: u32,
salt_ptr: u32,
salt_len: u32,
) -> Result<ReturnErrorCode, TrapReason> {
Sasha Gryaznov
committed
ctx.instantiate(
memory,
code_hash_ptr,
Weight::from_parts(gas, 0),
SENTINEL,
value_ptr,
input_data_ptr,
input_data_len,
address_ptr,
address_len_ptr,
output_ptr,
output_len_ptr,
salt_ptr,
salt_len,
)
/// Instantiate a contract with the specified code hash.
/// See [`pallet_contracts_uapi::HostFn::instantiate_v2`].
Sasha Gryaznov
committed
#[version(2)]
#[unstable]
Sasha Gryaznov
committed
fn instantiate(
Alexander Theißen
committed
ctx: _,
memory: _,
Sasha Gryaznov
committed
ref_time_limit: u64,
proof_size_limit: u64,
deposit_ptr: u32,
input_data_len: u32,
address_ptr: u32,
address_len_ptr: u32,
output_ptr: u32,
output_len_ptr: u32,
salt_ptr: u32,
salt_len: u32,
) -> Result<ReturnErrorCode, TrapReason> {
Alexander Theißen
committed
memory,
Sasha Gryaznov
committed
Weight::from_parts(ref_time_limit, proof_size_limit),
deposit_ptr,
value_ptr,
input_data_ptr,
input_data_len,
address_ptr,
address_len_ptr,
output_ptr,
output_len_ptr,
salt_ptr,
salt_len,
)
/// Remove the calling account and transfer remaining balance.
/// See [`pallet_contracts_uapi::HostFn::terminate`].
///
/// # Note
///
/// The value `_beneficiary_len` is ignored because the encoded sizes
/// this type is fixed through `[`MaxEncodedLen`]. The field exist for backwards
/// compatibility. Consider switching to the newest version of this function.
Sasha Gryaznov
committed
#[prefixed_alias]
fn terminate(
Alexander Theißen
committed
ctx: _,
memory: _,
beneficiary_ptr: u32,
_beneficiary_len: u32,
) -> Result<(), TrapReason> {
Alexander Theißen
committed
ctx.terminate(memory, beneficiary_ptr)
/// Remove the calling account and transfer remaining **free** balance.
/// See [`pallet_contracts_uapi::HostFn::terminate_v1`].
#[version(1)]
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn terminate(ctx: _, memory: _, beneficiary_ptr: u32) -> Result<(), TrapReason> {
ctx.terminate(memory, beneficiary_ptr)
/// Stores the input passed by the caller into the supplied buffer.
/// See [`pallet_contracts_uapi::HostFn::input`].
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn input(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::InputBase)?;
if let Some(input) = ctx.input_data.take() {
Alexander Theißen
committed
ctx.write_sandbox_output(memory, out_ptr, out_len_ptr, &input, false, |len| {
Some(RuntimeCosts::CopyToContract(len))
Alexander Theißen
committed
})?;
ctx.input_data = Some(input);
Alexander Theißen
committed
Ok(())
Err(Error::<E::T>::InputForwarded.into())
/// Cease contract execution and save a data buffer as a result of the execution.
/// See [`pallet_contracts_uapi::HostFn::return_value`].
fn seal_return(
Alexander Theißen
committed
ctx: _,
memory: _,
flags: u32,
data_ptr: u32,
data_len: u32,
) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::Return(data_len))?;
Alexander Theißen
committed
Err(TrapReason::Return(ReturnData {
Alexander Theißen
committed
data: ctx.read_sandbox_memory(memory, data_ptr, data_len)?,
Alexander Theißen
committed
}))
/// Stores the address of the caller into the supplied buffer.
/// See [`pallet_contracts_uapi::HostFn::caller`].
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn caller(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::Caller)?;
let caller = ctx.ext.caller().account_id()?.clone();
Alexander Theißen
committed
Ok(ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
false,
already_charged,
Alexander Theißen
committed
)?)
/// Checks whether a specified address belongs to a contract.
/// See [`pallet_contracts_uapi::HostFn::is_contract`].
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn is_contract(ctx: _, memory: _, account_ptr: u32) -> Result<u32, TrapReason> {
Sasha Gryaznov
committed
ctx.charge_gas(RuntimeCosts::IsContract)?;
let address: <<E as Ext>::T as frame_system::Config>::AccountId =
Alexander Theißen
committed
ctx.read_sandbox_memory_as(memory, account_ptr)?;
Sasha Gryaznov
committed
Ok(ctx.ext.is_contract(&address) as u32)
Sasha Gryaznov
committed
/// Retrieve the code hash for a specified contract address.
/// See [`pallet_contracts_uapi::HostFn::code_hash`].
Sasha Gryaznov
committed
#[prefixed_alias]
fn code_hash(
Alexander Theißen
committed
ctx: _,
memory: _,
account_ptr: u32,
out_ptr: u32,
out_len_ptr: u32,
) -> Result<ReturnErrorCode, TrapReason> {
ctx.charge_gas(RuntimeCosts::CodeHash)?;
let address: <<E as Ext>::T as frame_system::Config>::AccountId =
Alexander Theißen
committed
ctx.read_sandbox_memory_as(memory, account_ptr)?;
if let Some(value) = ctx.ext.code_hash(&address) {
ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
&value.encode(),
false,
already_charged,
)?;
} else {
Ok(ReturnErrorCode::KeyNotFound)
}
/// Retrieve the code hash of the currently executing contract.
/// See [`pallet_contracts_uapi::HostFn::own_code_hash`].
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn own_code_hash(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::OwnCodeHash)?;
let code_hash_encoded = &ctx.ext.own_code_hash().encode();
Ok(ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
code_hash_encoded,
false,
already_charged,
)?)
}
/// Checks whether the caller of the current contract is the origin of the whole call stack.
/// See [`pallet_contracts_uapi::HostFn::caller_is_origin`].
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn caller_is_origin(ctx: _, _memory: _) -> Result<u32, TrapReason> {
Sasha Gryaznov
committed
ctx.charge_gas(RuntimeCosts::CallerIsOrigin)?;
Ok(ctx.ext.caller_is_origin() as u32)
Sasha Gryaznov
committed
/// Checks whether the caller of the current contract is root.
/// See [`pallet_contracts_uapi::HostFn::caller_is_root`].
#[unstable]
fn caller_is_root(ctx: _, _memory: _) -> Result<u32, TrapReason> {
ctx.charge_gas(RuntimeCosts::CallerIsRoot)?;
Ok(ctx.ext.caller_is_root() as u32)
}
/// Stores the address of the current contract into the supplied buffer.
/// See [`pallet_contracts_uapi::HostFn::address`].
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn address(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::Address)?;
Alexander Theißen
committed
Ok(ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
&ctx.ext.address().encode(),
false,
already_charged,
Alexander Theißen
committed
)?)
/// Stores the price for the specified amount of gas into the supplied buffer.
/// See [`pallet_contracts_uapi::HostFn::weight_to_fee`].
Sasha Gryaznov
committed
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
#[prefixed_alias]
fn weight_to_fee(
ctx: _,
memory: _,
gas: u64,
out_ptr: u32,
out_len_ptr: u32,
) -> Result<(), TrapReason> {
let gas = Weight::from_parts(gas, 0);
ctx.charge_gas(RuntimeCosts::WeightToFee)?;
Ok(ctx.write_sandbox_output(
memory,
out_ptr,
out_len_ptr,
&ctx.ext.get_weight_price(gas).encode(),
false,
already_charged,
)?)
}
/// Stores the price for the specified amount of weight into the supplied buffer.
/// See [`pallet_contracts_uapi::HostFn::weight_to_fee_v1`].
Sasha Gryaznov
committed
#[version(1)]
#[unstable]
Sasha Gryaznov
committed
fn weight_to_fee(
Alexander Theißen
committed
ctx: _,
memory: _,
Sasha Gryaznov
committed
ref_time_limit: u64,
proof_size_limit: u64,
out_ptr: u32,
out_len_ptr: u32,
) -> Result<(), TrapReason> {
Sasha Gryaznov
committed
let weight = Weight::from_parts(ref_time_limit, proof_size_limit);
ctx.charge_gas(RuntimeCosts::WeightToFee)?;
Alexander Theißen
committed
Ok(ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
Sasha Gryaznov
committed
&ctx.ext.get_weight_price(weight).encode(),
false,
already_charged,
)?)
}
/// Stores the weight left into the supplied buffer.
/// See [`pallet_contracts_uapi::HostFn::gas_left`].
Sasha Gryaznov
committed
#[prefixed_alias]
fn gas_left(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::GasLeft)?;
let gas_left = &ctx.ext.gas_meter().gas_left().ref_time().encode();
Ok(ctx.write_sandbox_output(
memory,
out_ptr,
out_len_ptr,
gas_left,
false,
already_charged,
Alexander Theißen
committed
)?)
Sasha Gryaznov
committed
/// Stores the amount of weight left into the supplied buffer.
/// See [`pallet_contracts_uapi::HostFn::gas_left_v1`].
Sasha Gryaznov
committed
#[version(1)]
#[unstable]
Alexander Theißen
committed
fn gas_left(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::GasLeft)?;
Sasha Gryaznov
committed
let gas_left = &ctx.ext.gas_meter().gas_left().encode();
Alexander Theißen
committed
Ok(ctx.write_sandbox_output(
memory,
out_ptr,
out_len_ptr,
gas_left,
false,
already_charged,
)?)
Sasha Gryaznov
committed
/// Stores the *free* balance of the current account into the supplied buffer.
/// See [`pallet_contracts_uapi::HostFn::balance`].
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn balance(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::Balance)?;
Alexander Theißen
committed
Ok(ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
&ctx.ext.balance().encode(),
false,
already_charged,
Alexander Theißen
committed
)?)
/// Stores the value transferred along with this call/instantiate into the supplied buffer.
/// See [`pallet_contracts_uapi::HostFn::value_transferred`].
Sasha Gryaznov
committed
#[prefixed_alias]
fn value_transferred(
Alexander Theißen
committed
ctx: _,
memory: _,
out_ptr: u32,
out_len_ptr: u32,
) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::ValueTransferred)?;
Alexander Theißen
committed
Ok(ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
&ctx.ext.value_transferred().encode(),
false,
already_charged,
Alexander Theißen
committed
)?)
/// Stores a random number for the current block and the given subject into the supplied buffer.
///
/// The value is stored to linear memory at the address pointed to by `out_ptr`.
/// `out_len_ptr` must point to a u32 value that describes the available space at
/// `out_ptr`. This call overwrites it with the size of the value. If the available
/// space at `out_ptr` is less than the size of the value a trap is triggered.
///
Sasha Gryaznov
committed
/// The data is encoded as `T::Hash`.
Sasha Gryaznov
committed
#[prefixed_alias]
Sasha Gryaznov
committed
fn random(
Alexander Theißen
committed
ctx: _,
memory: _,
subject_ptr: u32,
subject_len: u32,
out_ptr: u32,
out_len_ptr: u32,
) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::Random)?;
if subject_len > ctx.ext.schedule().limits.subject_len {
return Err(Error::<E::T>::RandomSubjectTooLong.into())
Alexander Theißen
committed
let subject_buf = ctx.read_sandbox_memory(memory, subject_ptr, subject_len)?;
Ok(ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
&ctx.ext.random(&subject_buf).0.encode(),
false,
already_charged,
/// Stores a random number for the current block and the given subject into the supplied buffer.
///
/// The value is stored to linear memory at the address pointed to by `out_ptr`.
/// `out_len_ptr` must point to a u32 value that describes the available space at
/// `out_ptr`. This call overwrites it with the size of the value. If the available
/// space at `out_ptr` is less than the size of the value a trap is triggered.
///
/// The data is encoded as (T::Hash, frame_system::pallet_prelude::BlockNumberFor::<T>).
///
/// # Changes from v0
///
/// In addition to the seed it returns the block number since which it was determinable
/// by chain observers.
///
/// # Note
///
/// The returned seed should only be used to distinguish commitments made before
/// the returned block number. If the block number is too early (i.e. commitments were
/// made afterwards), then ensure no further commitments may be made and repeatedly
/// call this on later blocks until the block number returned is later than the latest
/// commitment.
#[version(1)]
Sasha Gryaznov
committed
#[prefixed_alias]
Sasha Gryaznov
committed
fn random(
Alexander Theißen
committed
ctx: _,
memory: _,
subject_ptr: u32,
subject_len: u32,
out_ptr: u32,
out_len_ptr: u32,
) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::Random)?;
if subject_len > ctx.ext.schedule().limits.subject_len {
return Err(Error::<E::T>::RandomSubjectTooLong.into())
Alexander Theißen
committed
let subject_buf = ctx.read_sandbox_memory(memory, subject_ptr, subject_len)?;
Alexander Theißen
committed
Ok(ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
&ctx.ext.random(&subject_buf).encode(),
false,
already_charged,
Alexander Theißen
committed
)?)
/// Load the latest block timestamp into the supplied buffer
/// See [`pallet_contracts_uapi::HostFn::now`].
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn now(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::Now)?;
Alexander Theißen
committed
Ok(ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
&ctx.ext.now().encode(),
false,
already_charged,
Alexander Theißen
committed
)?)
/// Stores the minimum balance (a.k.a. existential deposit) into the supplied buffer.
/// See [`pallet_contracts_uapi::HostFn::minimum_balance`].
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn minimum_balance(
ctx: _,
memory: _,
out_ptr: u32,
out_len_ptr: u32,
) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::MinimumBalance)?;
Alexander Theißen
committed
Ok(ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
&ctx.ext.minimum_balance().encode(),
false,
already_charged,
Alexander Theißen
committed
)?)
/// Stores the tombstone deposit into the supplied buffer.
///
/// The value is stored to linear memory at the address pointed to by `out_ptr`.
/// `out_len_ptr` must point to a u32 value that describes the available space at
/// `out_ptr`. This call overwrites it with the size of the value. If the available
/// space at `out_ptr` is less than the size of the value a trap is triggered.
///
Sasha Gryaznov
committed
/// There is no longer a tombstone deposit. This function always returns `0`.
Sasha Gryaznov
committed
#[prefixed_alias]
Sasha Gryaznov
committed
fn tombstone_deposit(
Alexander Theißen
committed
ctx: _,
memory: _,
out_ptr: u32,
out_len_ptr: u32,
) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::Balance)?;
let deposit = <BalanceOf<E::T>>::zero().encode();
Alexander Theißen
committed
Ok(ctx.write_sandbox_output(
memory,
out_ptr,
out_len_ptr,
&deposit,
false,
already_charged,
)?)
/// Was used to restore the given destination contract sacrificing the caller.
///
/// # Note
///
/// The state rent functionality was removed. This is stub only exists for
Sasha Gryaznov
committed
#[prefixed_alias]
Sasha Gryaznov
committed
fn restore_to(
Alexander Theißen
committed
ctx: _,
memory: _,
_rent_allowance_len: u32,
_delta_count: u32,
) -> Result<(), TrapReason> {
Sasha Gryaznov
committed
ctx.charge_gas(RuntimeCosts::DebugMessage(0))?;
/// Was used to restore the given destination contract sacrificing the caller.
///
/// # Note
///
/// The state rent functionality was removed. This is stub only exists for
#[version(1)]
Sasha Gryaznov
committed
#[prefixed_alias]
Sasha Gryaznov
committed
fn restore_to(
Alexander Theißen
committed
ctx: _,
memory: _,
_dest_ptr: u32,
_code_hash_ptr: u32,
_rent_allowance_ptr: u32,
_delta_ptr: u32,
_delta_count: u32,
) -> Result<(), TrapReason> {
Sasha Gryaznov
committed
ctx.charge_gas(RuntimeCosts::DebugMessage(0))?;
/// Was used to set rent allowance of the contract.
///
/// # Note
///
/// The state rent functionality was removed. This is stub only exists for
Sasha Gryaznov
committed
#[prefixed_alias]
Sasha Gryaznov
committed
fn set_rent_allowance(
Alexander Theißen
committed
ctx: _,
memory: _,
_value_ptr: u32,
_value_len: u32,
) -> Result<(), TrapReason> {
Sasha Gryaznov
committed
ctx.charge_gas(RuntimeCosts::DebugMessage(0))?;
/// Was used to set rent allowance of the contract.
///
/// # Note
///
/// The state rent functionality was removed. This is stub only exists for
#[version(1)]
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn set_rent_allowance(ctx: _, _memory: _, _value_ptr: u32) -> Result<(), TrapReason> {
Sasha Gryaznov
committed
ctx.charge_gas(RuntimeCosts::DebugMessage(0))?;
/// Was used to store the rent allowance into the supplied buffer.
///
/// # Note
///
/// The state rent functionality was removed. This is stub only exists for
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn rent_allowance(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::Balance)?;
let rent_allowance = <BalanceOf<E::T>>::max_value().encode();
Alexander Theißen
committed
Ok(ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
&rent_allowance,
false,
already_charged,
Alexander Theißen
committed
)?)
/// Deposit a contract event with the data buffer and optional list of topics.
/// See [pallet_contracts_uapi::HostFn::deposit_event]
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
#[prefixed_alias]
fn deposit_event(
ctx: _,
memory: _,
topics_ptr: u32,
topics_len: u32,
data_ptr: u32,
data_len: u32,
) -> Result<(), TrapReason> {
let num_topic = topics_len
.checked_div(sp_std::mem::size_of::<TopicOf<E::T>>() as u32)
.ok_or("Zero sized topics are not allowed")?;
ctx.charge_gas(RuntimeCosts::DepositEvent { num_topic, len: data_len })?;
if data_len > ctx.ext.max_value_size() {
return Err(Error::<E::T>::ValueTooLarge.into())
}
let topics: Vec<TopicOf<<E as Ext>::T>> = match topics_len {
0 => Vec::new(),
_ => ctx.read_sandbox_memory_as_unbounded(memory, topics_ptr, topics_len)?,
};
// If there are more than `event_topics`, then trap.
if topics.len() > ctx.ext.schedule().limits.event_topics as usize {
return Err(Error::<E::T>::TooManyTopics.into())
}
let event_data = ctx.read_sandbox_memory(memory, data_ptr, data_len)?;
ctx.ext.deposit_event(topics, event_data);
Ok(())
}
/// Stores the current block number of the current contract into the supplied buffer.
/// See [`pallet_contracts_uapi::HostFn::block_number`].
Sasha Gryaznov
committed
#[prefixed_alias]
Alexander Theißen
committed
fn block_number(ctx: _, memory: _, out_ptr: u32, out_len_ptr: u32) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::BlockNumber)?;
Alexander Theißen
committed
Ok(ctx.write_sandbox_output(
Alexander Theißen
committed
memory,
out_ptr,
out_len_ptr,
&ctx.ext.block_number().encode(),
false,
already_charged,
Alexander Theißen
committed
)?)
/// Computes the SHA2 256-bit hash on the given input buffer.
/// See [`pallet_contracts_uapi::HostFn::hash_sha2_256`].
Sasha Gryaznov
committed
#[prefixed_alias]
fn hash_sha2_256(
Alexander Theißen
committed
ctx: _,
memory: _,
input_ptr: u32,
input_len: u32,
output_ptr: u32,
) -> Result<(), TrapReason> {
ctx.charge_gas(RuntimeCosts::HashSha256(input_len))?;
Alexander Theißen
committed
Ok(ctx.compute_hash_on_intermediate_buffer(
memory, sha2_256, input_ptr, input_len, output_ptr,
)?)
/// Computes the KECCAK 256-bit hash on the given input buffer.
/// See [`pallet_contracts_uapi::HostFn::hash_keccak_256`].
Sasha Gryaznov
committed
#[prefixed_alias]
fn hash_keccak_256(
Alexander Theißen
committed
ctx: _,
memory: _,
input_ptr: u32,
input_len: u32,
output_ptr: u32,
) -> Result<(), TrapReason> {