referrerpolicy=no-referrer-when-downgrade

pallet_revive_uapi/
host.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14use crate::{CallFlags, Result, ReturnFlags, StorageFlags};
15use pallet_revive_proc_macro::unstable_hostfn;
16
17#[cfg(target_arch = "riscv64")]
18mod riscv64;
19
20/// Implements [`HostFn`] when compiled on supported architectures (RISC-V).
21pub enum HostFnImpl {}
22
23/// Defines all the host apis available to contracts.
24pub trait HostFn: private::Sealed {
25	/// Stores the address of the current contract into the supplied buffer.
26	///
27	/// # Parameters
28	///
29	/// - `output`: A reference to the output data buffer to write the address.
30	fn address(output: &mut [u8; 20]);
31
32	/// Get the contract immutable data.
33	///
34	/// Traps if:
35	/// - Called from within the deploy export.
36	/// - Called by contracts that didn't set immutable data by calling `set_immutable_data` during
37	///   their constructor execution.
38	///
39	/// # Parameters
40	/// - `output`: A reference to the output buffer to write the immutable bytes.
41	fn get_immutable_data(output: &mut &mut [u8]);
42
43	/// Set the contract immutable data.
44	///
45	/// It is only valid to set non-empty immutable data in the constructor once.
46	///
47	/// Traps if:
48	/// - Called from within the call export.
49	/// - Called more than once.
50	/// - The provided data was empty.
51	///
52	/// # Parameters
53	/// - `data`: A reference to the data to be stored as immutable bytes.
54	fn set_immutable_data(data: &[u8]);
55
56	/// Stores the **reducible** balance of the current account into the supplied buffer.
57	///
58	/// # Parameters
59	///
60	/// - `output`: A reference to the output data buffer to write the balance.
61	fn balance(output: &mut [u8; 32]);
62
63	/// Stores the **reducible** balance of the supplied address into the supplied buffer.
64	///
65	/// # Parameters
66	///
67	/// - `addr`: The target address of which to retreive the free balance.
68	/// - `output`: A reference to the output data buffer to write the balance.
69	fn balance_of(addr: &[u8; 20], output: &mut [u8; 32]);
70
71	/// Returns the [EIP-155](https://eips.ethereum.org/EIPS/eip-155) chain ID.
72	fn chain_id(output: &mut [u8; 32]);
73
74	/// Returns the price per ref_time, akin to the EVM
75	/// [GASPRICE](https://www.evm.codes/?fork=cancun#3a) opcode.
76	fn gas_price() -> u64;
77
78	/// Returns the base fee, akin to the EVM
79	/// [BASEFEE](https://www.evm.codes/?fork=cancun#48) opcode.
80	fn base_fee(output: &mut [u8; 32]);
81
82	/// Returns the call data size.
83	fn call_data_size() -> u64;
84
85	/// Call (possibly transferring some amount of funds) into the specified account.
86	///
87	/// # Parameters
88	///
89	/// - `flags`: See [`CallFlags`] for a documentation of the supported flags.
90	/// - `callee`: The address of the callee. Should be decodable as an `T::AccountId`. Traps
91	///   otherwise.
92	/// - `ref_time_limit`: how much *ref_time* Weight to devote to the execution.
93	/// - `proof_size_limit`: how much *proof_size* Weight to devote to the execution.
94	/// - `deposit`: The storage deposit limit for instantiation. Passing `None` means setting no
95	///   specific limit for the call, which implies storage usage up to the limit of the parent
96	///   call.
97	/// - `value`: The value to transfer into the contract.
98	/// - `input`: The input data buffer used to call the contract.
99	/// - `output`: A reference to the output data buffer to write the call output buffer. If `None`
100	///   is provided then the output buffer is not copied.
101	///
102	/// # Errors
103	///
104	/// An error means that the call wasn't successful output buffer is returned unless
105	/// stated otherwise.
106	///
107	/// - [CalleeReverted][`crate::ReturnErrorCode::CalleeReverted]: Output buffer is returned.
108	/// - [CalleeTrapped][`crate::ReturnErrorCode::CalleeTrapped]
109	/// - [TransferFailed][`crate::ReturnErrorCode::TransferFailed]
110	/// - [OutOfResources][`crate::ReturnErrorCode::OutOfResources]
111	fn call(
112		flags: CallFlags,
113		callee: &[u8; 20],
114		ref_time_limit: u64,
115		proof_size_limit: u64,
116		deposit: &[u8; 32],
117		value: &[u8; 32],
118		input_data: &[u8],
119		output: Option<&mut &mut [u8]>,
120	) -> Result;
121
122	/// Same as [HostFn::call] but receives the one-dimensional EVM gas argument.
123	///
124	/// Adds the EVM gas stipend for non-zero value calls.
125	///
126	/// If gas is `u64::MAX`, the call will run with uncapped limits.
127	fn call_evm(
128		flags: CallFlags,
129		callee: &[u8; 20],
130		gas: u64,
131		value: &[u8; 32],
132		input_data: &[u8],
133		output: Option<&mut &mut [u8]>,
134	) -> Result;
135
136	/// Stores the address of the caller into the supplied buffer.
137	///
138	/// If this is a top-level call (i.e. initiated by an extrinsic) the origin address of the
139	/// extrinsic will be returned. Otherwise, if this call is initiated by another contract then
140	/// the address of the contract will be returned.
141	///
142	/// If there is no address associated with the caller (e.g. because the caller is root) then
143	/// it traps with `BadOrigin`.
144	///
145	/// # Parameters
146	///
147	/// - `output`: A reference to the output data buffer to write the caller address.
148	fn caller(output: &mut [u8; 20]);
149
150	/// Stores the origin address (initator of the call stack) into the supplied buffer.
151	///
152	/// If there is no address associated with the origin (e.g. because the origin is root) then
153	/// it traps with `BadOrigin`. This can only happen through on-chain governance actions or
154	/// customized runtimes.
155	///
156	/// # Parameters
157	///
158	/// - `output`: A reference to the output data buffer to write the origin's address.
159	fn origin(output: &mut [u8; 20]);
160
161	/// Retrieve the code hash for a specified contract address.
162	///
163	/// # Parameters
164	///
165	/// - `addr`: The address of the contract.
166	/// - `output`: A reference to the output data buffer to write the code hash.
167	///
168	/// # Note
169	///
170	/// If `addr` is not a contract but the account exists then the hash of empty data
171	/// `0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470` is written,
172	/// otherwise `zero`.
173	fn code_hash(addr: &[u8; 20], output: &mut [u8; 32]);
174
175	/// Returns the code size for a specified contract address.
176	///
177	/// # Parameters
178	///
179	/// - `addr`: The address of the contract.
180	///
181	/// # Note
182	///
183	/// If `addr` is not a contract the `output` will be zero.
184	fn code_size(addr: &[u8; 20]) -> u64;
185
186	/// Execute code in the context (storage, caller, value) of the current contract.
187	///
188	/// Reentrancy protection is always disabled since the callee is allowed
189	/// to modify the callers storage. This makes going through a reentrancy attack
190	/// unnecessary for the callee when it wants to exploit the caller.
191	///
192	/// # Parameters
193	///
194	/// - `flags`: See [`CallFlags`] for a documentation of the supported flags.
195	/// - `address`: The address of the code to be executed. Should be decodable as an
196	///   `T::AccountId`. Traps otherwise.
197	/// - `ref_time_limit`: how much *ref_time* Weight to devote to the execution.
198	/// - `proof_size_limit`: how much *proof_size* Weight to devote to the execution.
199	/// - `deposit_limit`: The storage deposit limit for delegate call. Passing `None` means setting
200	///   no specific limit for the call, which implies storage usage up to the limit of the parent
201	///   call.
202	/// - `input`: The input data buffer used to call the contract.
203	/// - `output`: A reference to the output data buffer to write the call output buffer. If `None`
204	///   is provided then the output buffer is not copied.
205	///
206	/// # Errors
207	///
208	/// An error means that the call wasn't successful and no output buffer is returned unless
209	/// stated otherwise.
210	///
211	/// - [CalleeReverted][`crate::ReturnErrorCode::CalleeReverted]: Output buffer is returned.
212	/// - [CalleeTrapped][`crate::ReturnErrorCode::CalleeTrapped]
213	/// - [OutOfResources][`crate::ReturnErrorCode::OutOfResources]
214	fn delegate_call(
215		flags: CallFlags,
216		address: &[u8; 20],
217		ref_time_limit: u64,
218		proof_size_limit: u64,
219		deposit_limit: &[u8; 32],
220		input_data: &[u8],
221		output: Option<&mut &mut [u8]>,
222	) -> Result;
223
224	/// Same as [HostFn::delegate_call] but receives the one-dimensional EVM gas argument.
225	///
226	/// If gas is `u64::MAX`, the call will run with uncapped limits.
227	fn delegate_call_evm(
228		flags: CallFlags,
229		address: &[u8; 20],
230		gas: u64,
231		input_data: &[u8],
232		output: Option<&mut &mut [u8]>,
233	) -> Result;
234
235	/// Deposit a contract event with the data buffer and optional list of topics. There is a limit
236	/// on the maximum number of topics specified by `event_topics`.
237	///
238	/// There should not be any duplicates in `topics`.
239	///
240	/// # Parameters
241	///
242	/// - `topics`: The topics list. It can't contain duplicates.
243	fn deposit_event(topics: &[[u8; 32]], data: &[u8]);
244
245	/// Retrieve the value under the given key from storage.
246	///
247	/// The key length must not exceed the maximum defined by the `pallet-revive` parameter.
248	///
249	/// # Parameters
250	/// - `key`: The storage key.
251	/// - `output`: A reference to the output data buffer to write the storage entry.
252	///
253	/// # Errors
254	///
255	/// [KeyNotFound][`crate::ReturnErrorCode::KeyNotFound]
256	fn get_storage(flags: StorageFlags, key: &[u8], output: &mut &mut [u8]) -> Result;
257
258	/// Computes the keccak_256 32-bit hash on the given input buffer.
259	///
260	/// - The `input` and `output` buffer may overlap.
261	/// - The output buffer is expected to hold at least 32 bits.
262	/// - It is the callers responsibility to provide an output buffer that is large enough to hold
263	///   the expected amount of bytes returned by the hash function.
264	///
265	/// # Parameters
266	///
267	/// - `input`: The input data buffer.
268	/// - `output`: The output buffer to write the hash result to.
269	fn hash_keccak_256(input: &[u8], output: &mut [u8; 32]);
270
271	/// Stores the input data passed by the caller into the supplied `output` buffer,
272	/// starting from the given input data `offset`.
273	///
274	/// The `output` buffer is guaranteed to always be fully populated:
275	/// - If the call data (starting from the given `offset`) is larger than the `output` buffer,
276	///   only what fits into the `output` buffer is written.
277	/// - If the `output` buffer size exceeds the call data size (starting from `offset`), remaining
278	///   bytes in the `output` buffer are zeroed out.
279	/// - If the provided call data `offset` is out-of-bounds, the whole `output` buffer is zeroed
280	///   out.
281	///
282	/// # Note
283	///
284	/// This function traps if:
285	/// - the input was previously forwarded by a [`call()`][`Self::call()`].
286	/// - the `output` buffer is located in an PolkaVM invalid memory range.
287	///
288	/// # Parameters
289	///
290	/// - `output`: A reference to the output data buffer to write the call data.
291	/// - `offset`: The offset index into the call data from where to start copying.
292	fn call_data_copy(output: &mut [u8], offset: u32);
293
294	/// Stores the U256 value at given `offset` from the input passed by the caller
295	/// into the supplied buffer.
296	///
297	/// # Note
298	/// - If `offset` is out of bounds, a value of zero will be returned.
299	/// - If `offset` is in bounds but there is not enough call data, the available data
300	/// is right-padded in order to fill a whole U256 value.
301	/// - The data written to `output` is a little endian U256 integer value.
302	///
303	/// # Parameters
304	///
305	/// - `output`: A reference to the fixed output data buffer to write the value.
306	/// - `offset`: The offset (index) into the call data.
307	fn call_data_load(output: &mut [u8; 32], offset: u32);
308
309	/// Instantiate a contract with the specified code hash.
310	///
311	/// This function creates an account and executes the constructor defined in the code specified
312	/// by the code hash.
313	///
314	/// # Parameters
315	///
316	/// - `ref_time_limit`: how much *ref_time* Weight to devote to the execution.
317	/// - `proof_size_limit`: how much *proof_size* Weight to devote to the execution.
318	/// - `deposit`: The storage deposit limit for instantiation. Passing `None` means setting no
319	///   specific limit for the call, which implies storage usage up to the limit of the parent
320	///   call.
321	/// - `value`: The value to transfer into the contract.
322	/// - `input`: The code hash and constructor input data buffer. The first 32 bytes are the code
323	///   hash of the code to be instantiated. The remaining bytes are the constructor call data.
324	/// - `address`: A reference to the address buffer to write the address of the contract. If
325	///   `None` is provided then the output buffer is not copied.
326	/// - `output`: A reference to the return value buffer to write the constructor output buffer.
327	///   If `None` is provided then the output buffer is not copied.
328	/// - `salt`: The salt bytes to use for this instantiation.
329	///
330	/// # Errors
331	///
332	/// Please consult the [ReturnErrorCode][`crate::ReturnErrorCode`] enum declaration for more
333	/// information on those errors. Here we only note things specific to this function.
334	///
335	/// An error means that the account wasn't created and no address or output buffer
336	/// is returned unless stated otherwise.
337	///
338	/// - [CalleeReverted][`crate::ReturnErrorCode::CalleeReverted]: Output buffer is returned.
339	/// - [CalleeTrapped][`crate::ReturnErrorCode::CalleeTrapped]
340	/// - [TransferFailed][`crate::ReturnErrorCode::TransferFailed]
341	/// - [OutOfResources][`crate::ReturnErrorCode::OutOfResources]
342	fn instantiate(
343		ref_time_limit: u64,
344		proof_size_limit: u64,
345		deposit: &[u8; 32],
346		value: &[u8; 32],
347		input: &[u8],
348		address: Option<&mut [u8; 20]>,
349		output: Option<&mut &mut [u8]>,
350		salt: Option<&[u8; 32]>,
351	) -> Result;
352
353	/// Load the latest block timestamp in seconds into the supplied buffer
354	///
355	/// # Parameters
356	///
357	/// - `output`: A reference to the output data buffer to write the timestamp.
358	fn now(output: &mut [u8; 32]);
359
360	/// Returns the block ref_time limit.
361	fn gas_limit() -> u64;
362
363	/// Cease contract execution and save a data buffer as a result of the execution.
364	///
365	/// This function never returns as it stops execution of the caller.
366	/// This is the only way to return a data buffer to the caller. Returning from
367	/// execution without calling this function is equivalent to calling:
368	/// ```nocompile
369	/// return_value(ReturnFlags::empty(), &[])
370	/// ```
371	///
372	/// Using an unnamed non empty `ReturnFlags` triggers a trap.
373	///
374	/// # Parameters
375	///
376	/// - `flags`: Flag used to signal special return conditions to the supervisor. See
377	///   [`ReturnFlags`] for a documentation of the supported flags.
378	/// - `return_value`: The return value buffer.
379	fn return_value(flags: ReturnFlags, return_value: &[u8]) -> !;
380
381	/// Set the value at the given key in the contract storage.
382	///
383	/// The key and value lengths must not exceed the maximums defined by the `pallet-revive`
384	/// parameters.
385	///
386	/// # Parameters
387	///
388	/// - `key`: The storage key.
389	/// - `encoded_value`: The storage value.
390	///
391	/// # Return
392	///
393	/// Returns the size of the pre-existing value at the specified key if any.
394	fn set_storage(flags: StorageFlags, key: &[u8], value: &[u8]) -> Option<u32>;
395
396	/// Sets the storage entry for a fixed 256‑bit key with a fixed 256‑bit value.
397	///
398	/// If the provided 32‑byte value is all zeros then the key is cleared (i.e. deleted),
399	/// mimicking Ethereum’s SSTORE behavior.
400	///
401	/// # Parameters
402	/// - `key`: The fixed 256‑bit storage key (32 bytes).
403	/// - `value`: The fixed 256‑bit storage value (32 bytes).
404	///
405	/// # Return
406	/// Returns the size (in bytes) of the pre‑existing value at the specified key, if any.
407	fn set_storage_or_clear(flags: StorageFlags, key: &[u8; 32], value: &[u8; 32]) -> Option<u32>;
408
409	/// Retrieves the storage entry for a fixed 256‑bit key.
410	///
411	/// If the key does not exist, the output buffer is filled with 32 zero bytes.
412	///
413	/// # Parameters
414	/// - `key`: The fixed 256‑bit storage key (32 bytes).
415	/// - `output`: A mutable output buffer (32 bytes) where the storage entry is written.
416	fn get_storage_or_zero(flags: StorageFlags, key: &[u8; 32], output: &mut [u8; 32]);
417
418	/// Stores the value transferred along with this call/instantiate into the supplied buffer.
419	///
420	/// # Parameters
421	///
422	/// - `output`: A reference to the output data buffer to write the transferred value.
423	fn value_transferred(output: &mut [u8; 32]);
424
425	/// Returns the size of the returned data of the last contract call or instantiation.
426	fn return_data_size() -> u64;
427
428	/// Stores the returned data of the last contract call or contract instantiation.
429	///
430	/// # Parameters
431	/// - `output`: A reference to the output buffer to write the data.
432	/// - `offset`: Byte offset into the returned data
433	fn return_data_copy(output: &mut &mut [u8], offset: u32);
434
435	/// Returns the amount of ethereum gas left.
436	fn gas_left() -> u64;
437
438	/// Stores the current block author of into the supplied buffer.
439	///
440	/// # Parameters
441	///
442	/// - `output`: A reference to the output data buffer to write the block author.
443	fn block_author(output: &mut [u8; 20]);
444
445	/// Stores the current block number of the current contract into the supplied buffer.
446	///
447	/// # Parameters
448	///
449	/// - `output`: A reference to the output data buffer to write the block number.
450	fn block_number(output: &mut [u8; 32]);
451
452	/// Stores the block hash of the given block number into the supplied buffer.
453	///
454	/// # Parameters
455	///
456	/// - `block_number`: A reference to the block number buffer.
457	/// - `output`: A reference to the output data buffer to write the block number.
458	fn block_hash(block_number: &[u8; 32], output: &mut [u8; 32]);
459
460	/// Reverts the execution and cedes all supplied gas,
461	/// akin to the `INVALID` EVM opcode.
462	fn consume_all_gas() -> !;
463
464	/// Remove the calling account and transfer remaining **free** balance.
465	///
466	/// This function never returns. Either the termination was successful and the
467	/// execution of the destroyed contract is halted. Or it failed during the termination
468	/// which is considered fatal and results in a trap + rollback.
469	///
470	/// # Parameters
471	///
472	/// - `beneficiary`: The address of the beneficiary account
473	///
474	/// # Traps
475	///
476	/// - The contract is live i.e is already on the call stack.
477	/// - Failed to send the balance to the beneficiary.
478	/// - The deletion queue is full.
479	fn terminate(beneficiary: &[u8; 20]) -> !;
480
481	/// Calculates Ethereum address from the ECDSA compressed public key and stores
482	/// it into the supplied buffer.
483	///
484	/// # Parameters
485	///
486	/// - `pubkey`: The public key bytes.
487	/// - `output`: A reference to the output data buffer to write the address.
488	///
489	/// # Errors
490	///
491	/// - [EcdsaRecoveryFailed][`crate::ReturnErrorCode::EcdsaRecoveryFailed]
492	#[unstable_hostfn]
493	fn ecdsa_to_eth_address(pubkey: &[u8; 33], output: &mut [u8; 20]) -> Result;
494
495	/// Verify a sr25519 signature
496	///
497	/// # Parameters
498	///
499	/// - `signature`: The signature bytes.
500	/// - `message`: The message bytes.
501	///
502	/// # Errors
503	///
504	/// - [Sr25519VerifyFailed][`crate::ReturnErrorCode::Sr25519VerifyFailed]
505	#[unstable_hostfn]
506	fn sr25519_verify(signature: &[u8; 64], message: &[u8], pub_key: &[u8; 32]) -> Result;
507}
508
509mod private {
510	pub trait Sealed {}
511	impl Sealed for super::HostFnImpl {}
512}