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 /// Stores the address of the caller into the supplied buffer.
123 ///
124 /// If this is a top-level call (i.e. initiated by an extrinsic) the origin address of the
125 /// extrinsic will be returned. Otherwise, if this call is initiated by another contract then
126 /// the address of the contract will be returned.
127 ///
128 /// If there is no address associated with the caller (e.g. because the caller is root) then
129 /// it traps with `BadOrigin`.
130 ///
131 /// # Parameters
132 ///
133 /// - `output`: A reference to the output data buffer to write the caller address.
134 fn caller(output: &mut [u8; 20]);
135
136 /// Stores the origin address (initator of the call stack) into the supplied buffer.
137 ///
138 /// If there is no address associated with the origin (e.g. because the origin is root) then
139 /// it traps with `BadOrigin`. This can only happen through on-chain governance actions or
140 /// customized runtimes.
141 ///
142 /// # Parameters
143 ///
144 /// - `output`: A reference to the output data buffer to write the origin's address.
145 fn origin(output: &mut [u8; 20]);
146
147 /// Retrieve the code hash for a specified contract address.
148 ///
149 /// # Parameters
150 ///
151 /// - `addr`: The address of the contract.
152 /// - `output`: A reference to the output data buffer to write the code hash.
153 ///
154 /// # Note
155 ///
156 /// If `addr` is not a contract but the account exists then the hash of empty data
157 /// `0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470` is written,
158 /// otherwise `zero`.
159 fn code_hash(addr: &[u8; 20], output: &mut [u8; 32]);
160
161 /// Returns the code size for a specified contract address.
162 ///
163 /// # Parameters
164 ///
165 /// - `addr`: The address of the contract.
166 ///
167 /// # Note
168 ///
169 /// If `addr` is not a contract the `output` will be zero.
170 fn code_size(addr: &[u8; 20]) -> u64;
171
172 /// Execute code in the context (storage, caller, value) of the current contract.
173 ///
174 /// Reentrancy protection is always disabled since the callee is allowed
175 /// to modify the callers storage. This makes going through a reentrancy attack
176 /// unnecessary for the callee when it wants to exploit the caller.
177 ///
178 /// # Parameters
179 ///
180 /// - `flags`: See [`CallFlags`] for a documentation of the supported flags.
181 /// - `address`: The address of the code to be executed. Should be decodable as an
182 /// `T::AccountId`. Traps otherwise.
183 /// - `ref_time_limit`: how much *ref_time* Weight to devote to the execution.
184 /// - `proof_size_limit`: how much *proof_size* Weight to devote to the execution.
185 /// - `deposit_limit`: The storage deposit limit for delegate call. Passing `None` means setting
186 /// no specific limit for the call, which implies storage usage up to the limit of the parent
187 /// call.
188 /// - `input`: The input data buffer used to call the contract.
189 /// - `output`: A reference to the output data buffer to write the call output buffer. If `None`
190 /// is provided then the output buffer is not copied.
191 ///
192 /// # Errors
193 ///
194 /// An error means that the call wasn't successful and no output buffer is returned unless
195 /// stated otherwise.
196 ///
197 /// - [CalleeReverted][`crate::ReturnErrorCode::CalleeReverted]: Output buffer is returned.
198 /// - [CalleeTrapped][`crate::ReturnErrorCode::CalleeTrapped]
199 /// - [OutOfResources][`crate::ReturnErrorCode::OutOfResources]
200 fn delegate_call(
201 flags: CallFlags,
202 address: &[u8; 20],
203 ref_time_limit: u64,
204 proof_size_limit: u64,
205 deposit_limit: &[u8; 32],
206 input_data: &[u8],
207 output: Option<&mut &mut [u8]>,
208 ) -> Result;
209
210 /// Deposit a contract event with the data buffer and optional list of topics. There is a limit
211 /// on the maximum number of topics specified by `event_topics`.
212 ///
213 /// There should not be any duplicates in `topics`.
214 ///
215 /// # Parameters
216 ///
217 /// - `topics`: The topics list. It can't contain duplicates.
218 fn deposit_event(topics: &[[u8; 32]], data: &[u8]);
219
220 /// Retrieve the value under the given key from storage.
221 ///
222 /// The key length must not exceed the maximum defined by the contracts module parameter.
223 ///
224 /// # Parameters
225 /// - `key`: The storage key.
226 /// - `output`: A reference to the output data buffer to write the storage entry.
227 ///
228 /// # Errors
229 ///
230 /// [KeyNotFound][`crate::ReturnErrorCode::KeyNotFound]
231 fn get_storage(flags: StorageFlags, key: &[u8], output: &mut &mut [u8]) -> Result;
232
233 /// Computes the keccak_256 32-bit hash on the given input buffer.
234 ///
235 /// - The `input` and `output` buffer may overlap.
236 /// - The output buffer is expected to hold at least 32 bits.
237 /// - It is the callers responsibility to provide an output buffer that is large enough to hold
238 /// the expected amount of bytes returned by the hash function.
239 ///
240 /// # Parameters
241 ///
242 /// - `input`: The input data buffer.
243 /// - `output`: The output buffer to write the hash result to.
244 fn hash_keccak_256(input: &[u8], output: &mut [u8; 32]);
245
246 /// Stores the input data passed by the caller into the supplied `output` buffer,
247 /// starting from the given input data `offset`.
248 ///
249 /// The `output` buffer is guaranteed to always be fully populated:
250 /// - If the call data (starting from the given `offset`) is larger than the `output` buffer,
251 /// only what fits into the `output` buffer is written.
252 /// - If the `output` buffer size exceeds the call data size (starting from `offset`), remaining
253 /// bytes in the `output` buffer are zeroed out.
254 /// - If the provided call data `offset` is out-of-bounds, the whole `output` buffer is zeroed
255 /// out.
256 ///
257 /// # Note
258 ///
259 /// This function traps if:
260 /// - the input was previously forwarded by a [`call()`][`Self::call()`].
261 /// - the `output` buffer is located in an PolkaVM invalid memory range.
262 ///
263 /// # Parameters
264 ///
265 /// - `output`: A reference to the output data buffer to write the call data.
266 /// - `offset`: The offset index into the call data from where to start copying.
267 fn call_data_copy(output: &mut [u8], offset: u32);
268
269 /// Stores the U256 value at given `offset` from the input passed by the caller
270 /// into the supplied buffer.
271 ///
272 /// # Note
273 /// - If `offset` is out of bounds, a value of zero will be returned.
274 /// - If `offset` is in bounds but there is not enough call data, the available data
275 /// is right-padded in order to fill a whole U256 value.
276 /// - The data written to `output` is a little endian U256 integer value.
277 ///
278 /// # Parameters
279 ///
280 /// - `output`: A reference to the fixed output data buffer to write the value.
281 /// - `offset`: The offset (index) into the call data.
282 fn call_data_load(output: &mut [u8; 32], offset: u32);
283
284 /// Instantiate a contract with the specified code hash.
285 ///
286 /// This function creates an account and executes the constructor defined in the code specified
287 /// by the code hash.
288 ///
289 /// # Parameters
290 ///
291 /// - `ref_time_limit`: how much *ref_time* Weight to devote to the execution.
292 /// - `proof_size_limit`: how much *proof_size* Weight to devote to the execution.
293 /// - `deposit`: The storage deposit limit for instantiation. Passing `None` means setting no
294 /// specific limit for the call, which implies storage usage up to the limit of the parent
295 /// call.
296 /// - `value`: The value to transfer into the contract.
297 /// - `input`: The code hash and constructor input data buffer. The first 32 bytes are the code
298 /// hash of the code to be instantiated. The remaining bytes are the constructor call data.
299 /// - `address`: A reference to the address buffer to write the address of the contract. If
300 /// `None` is provided then the output buffer is not copied.
301 /// - `output`: A reference to the return value buffer to write the constructor output buffer.
302 /// If `None` is provided then the output buffer is not copied.
303 /// - `salt`: The salt bytes to use for this instantiation.
304 ///
305 /// # Errors
306 ///
307 /// Please consult the [ReturnErrorCode][`crate::ReturnErrorCode`] enum declaration for more
308 /// information on those errors. Here we only note things specific to this function.
309 ///
310 /// An error means that the account wasn't created and no address or output buffer
311 /// is returned unless stated otherwise.
312 ///
313 /// - [CalleeReverted][`crate::ReturnErrorCode::CalleeReverted]: Output buffer is returned.
314 /// - [CalleeTrapped][`crate::ReturnErrorCode::CalleeTrapped]
315 /// - [TransferFailed][`crate::ReturnErrorCode::TransferFailed]
316 /// - [OutOfResources][`crate::ReturnErrorCode::OutOfResources]
317 fn instantiate(
318 ref_time_limit: u64,
319 proof_size_limit: u64,
320 deposit: &[u8; 32],
321 value: &[u8; 32],
322 input: &[u8],
323 address: Option<&mut [u8; 20]>,
324 output: Option<&mut &mut [u8]>,
325 salt: Option<&[u8; 32]>,
326 ) -> Result;
327
328 /// Load the latest block timestamp in seconds into the supplied buffer
329 ///
330 /// # Parameters
331 ///
332 /// - `output`: A reference to the output data buffer to write the timestamp.
333 fn now(output: &mut [u8; 32]);
334
335 /// Returns the block ref_time limit.
336 fn gas_limit() -> u64;
337
338 /// Cease contract execution and save a data buffer as a result of the execution.
339 ///
340 /// This function never returns as it stops execution of the caller.
341 /// This is the only way to return a data buffer to the caller. Returning from
342 /// execution without calling this function is equivalent to calling:
343 /// ```nocompile
344 /// return_value(ReturnFlags::empty(), &[])
345 /// ```
346 ///
347 /// Using an unnamed non empty `ReturnFlags` triggers a trap.
348 ///
349 /// # Parameters
350 ///
351 /// - `flags`: Flag used to signal special return conditions to the supervisor. See
352 /// [`ReturnFlags`] for a documentation of the supported flags.
353 /// - `return_value`: The return value buffer.
354 fn return_value(flags: ReturnFlags, return_value: &[u8]) -> !;
355
356 /// Set the value at the given key in the contract storage.
357 ///
358 /// The key and value lengths must not exceed the maximums defined by the contracts module
359 /// parameters.
360 ///
361 /// # Parameters
362 ///
363 /// - `key`: The storage key.
364 /// - `encoded_value`: The storage value.
365 ///
366 /// # Return
367 ///
368 /// Returns the size of the pre-existing value at the specified key if any.
369 fn set_storage(flags: StorageFlags, key: &[u8], value: &[u8]) -> Option<u32>;
370
371 /// Stores the value transferred along with this call/instantiate into the supplied buffer.
372 ///
373 /// # Parameters
374 ///
375 /// - `output`: A reference to the output data buffer to write the transferred value.
376 fn value_transferred(output: &mut [u8; 32]);
377
378 /// Stores the price for the specified amount of gas into the supplied buffer.
379 ///
380 /// # Parameters
381 ///
382 /// - `ref_time_limit`: The *ref_time* Weight limit to query the price for.
383 /// - `proof_size_limit`: The *proof_size* Weight limit to query the price for.
384 /// - `output`: A reference to the output data buffer to write the price.
385 fn weight_to_fee(ref_time_limit: u64, proof_size_limit: u64, output: &mut [u8; 32]);
386
387 /// Returns the size of the returned data of the last contract call or instantiation.
388 fn return_data_size() -> u64;
389
390 /// Stores the returned data of the last contract call or contract instantiation.
391 ///
392 /// # Parameters
393 /// - `output`: A reference to the output buffer to write the data.
394 /// - `offset`: Byte offset into the returned data
395 fn return_data_copy(output: &mut &mut [u8], offset: u32);
396
397 /// Returns the amount of ref_time left.
398 fn ref_time_left() -> u64;
399
400 /// Stores the current block author of into the supplied buffer.
401 ///
402 /// # Parameters
403 ///
404 /// - `output`: A reference to the output data buffer to write the block author.
405 fn block_author(output: &mut [u8; 20]);
406
407 /// Stores the current block number of the current contract into the supplied buffer.
408 ///
409 /// # Parameters
410 ///
411 /// - `output`: A reference to the output data buffer to write the block number.
412 fn block_number(output: &mut [u8; 32]);
413
414 /// Retrieve the account id for a specified address.
415 ///
416 /// # Parameters
417 ///
418 /// - `addr`: A `H160` address.
419 /// - `output`: A reference to the output data buffer to write the account id.
420 ///
421 /// # Note
422 ///
423 /// If no mapping exists for `addr`, the fallback account id will be returned.
424 #[unstable_hostfn]
425 fn to_account_id(addr: &[u8; 20], output: &mut [u8]);
426
427 /// Stores the block hash of the given block number into the supplied buffer.
428 ///
429 /// # Parameters
430 ///
431 /// - `block_number`: A reference to the block number buffer.
432 /// - `output`: A reference to the output data buffer to write the block number.
433 #[unstable_hostfn]
434 fn block_hash(block_number: &[u8; 32], output: &mut [u8; 32]);
435
436 /// Call into the chain extension provided by the chain if any.
437 ///
438 /// Handling of the input values is up to the specific chain extension and so is the
439 /// return value. The extension can decide to use the inputs as primitive inputs or as
440 /// in/out arguments by interpreting them as pointers. Any caller of this function
441 /// must therefore coordinate with the chain that it targets.
442 ///
443 /// # Note
444 ///
445 /// If no chain extension exists the contract will trap with the `NoChainExtension`
446 /// module error.
447 ///
448 /// # Parameters
449 ///
450 /// - `func_id`: The function id of the chain extension.
451 /// - `input`: The input data buffer.
452 /// - `output`: A reference to the output data buffer to write the call output buffer. If `None`
453 /// is provided then the output buffer is not copied.
454 ///
455 /// # Return
456 ///
457 /// The chain extension returned value, if executed successfully.
458 #[unstable_hostfn]
459 fn call_chain_extension(func_id: u32, input: &[u8], output: Option<&mut &mut [u8]>) -> u32;
460
461 /// Call some dispatchable of the runtime.
462 ///
463 /// # Parameters
464 ///
465 /// - `call`: The call data.
466 ///
467 /// # Return
468 ///
469 /// Returns `Error::Success` when the dispatchable was successfully executed and
470 /// returned `Ok`. When the dispatchable was executed but returned an error
471 /// `Error::CallRuntimeFailed` is returned. The full error is not
472 /// provided because it is not guaranteed to be stable.
473 ///
474 /// # Comparison with `ChainExtension`
475 ///
476 /// Just as a chain extension this API allows the runtime to extend the functionality
477 /// of contracts. While making use of this function is generally easier it cannot be
478 /// used in all cases. Consider writing a chain extension if you need to do perform
479 /// one of the following tasks:
480 ///
481 /// - Return data.
482 /// - Provide functionality **exclusively** to contracts.
483 /// - Provide custom weights.
484 /// - Avoid the need to keep the `Call` data structure stable.
485 #[unstable_hostfn]
486 fn call_runtime(call: &[u8]) -> Result;
487
488 /// Checks whether the caller of the current contract is the origin of the whole call stack.
489 ///
490 /// Prefer this over [`is_contract()`][`Self::is_contract`] when checking whether your contract
491 /// is being called by a contract or a plain account. The reason is that it performs better
492 /// since it does not need to do any storage lookups.
493 ///
494 /// # Return
495 ///
496 /// A return value of `true` indicates that this contract is being called by a plain account
497 /// and `false` indicates that the caller is another contract.
498 #[unstable_hostfn]
499 fn caller_is_origin() -> bool;
500
501 /// Checks whether the caller of the current contract is root.
502 ///
503 /// Note that only the origin of the call stack can be root. Hence this function returning
504 /// `true` implies that the contract is being called by the origin.
505 ///
506 /// A return value of `true` indicates that this contract is being called by a root origin,
507 /// and `false` indicates that the caller is a signed origin.
508 #[unstable_hostfn]
509 fn caller_is_root() -> bool;
510
511 /// Clear the value at the given key in the contract storage.
512 ///
513 /// # Parameters
514 ///
515 /// - `key`: The storage key.
516 ///
517 /// # Return
518 ///
519 /// Returns the size of the pre-existing value at the specified key if any.
520 #[unstable_hostfn]
521 fn clear_storage(flags: StorageFlags, key: &[u8]) -> Option<u32>;
522
523 /// Checks whether there is a value stored under the given key.
524 ///
525 /// The key length must not exceed the maximum defined by the contracts module parameter.
526 ///
527 /// # Parameters
528 /// - `key`: The storage key.
529 ///
530 /// # Return
531 ///
532 /// Returns the size of the pre-existing value at the specified key if any.
533 #[unstable_hostfn]
534 fn contains_storage(flags: StorageFlags, key: &[u8]) -> Option<u32>;
535
536 /// Calculates Ethereum address from the ECDSA compressed public key and stores
537 /// it into the supplied buffer.
538 ///
539 /// # Parameters
540 ///
541 /// - `pubkey`: The public key bytes.
542 /// - `output`: A reference to the output data buffer to write the address.
543 ///
544 /// # Errors
545 ///
546 /// - [EcdsaRecoveryFailed][`crate::ReturnErrorCode::EcdsaRecoveryFailed]
547 #[unstable_hostfn]
548 fn ecdsa_to_eth_address(pubkey: &[u8; 33], output: &mut [u8; 20]) -> Result;
549
550 /// Computes the blake2_256 32-bit hash on the given input buffer.
551 ///
552 /// - The `input` and `output` buffer may overlap.
553 /// - The output buffer is expected to hold at least 32 bits.
554 /// - It is the callers responsibility to provide an output buffer that is large enough to hold
555 /// the expected amount of bytes returned by the hash function.
556 ///
557 /// # Parameters
558 /// */
559 /// - `input`: The input data buffer.
560 /// - `output`: The output buffer to write the hash result to.
561 #[unstable_hostfn]
562 fn hash_blake2_256(input: &[u8], output: &mut [u8; 32]);
563
564 /// Computes the blake2_128 16-bit hash on the given input buffer.
565 ///
566 /// - The `input` and `output` buffer may overlap.
567 /// - The output buffer is expected to hold at least 16 bits.
568 /// - It is the callers responsibility to provide an output buffer that is large enough to hold
569 /// the expected amount of bytes returned by the hash function.
570 /// # Parameters
571 ///
572 /// - `input`: The input data buffer.
573 /// - `output`: The output buffer to write the hash result to.
574 #[unstable_hostfn]
575 fn hash_blake2_128(input: &[u8], output: &mut [u8; 16]);
576
577 /// Checks whether a specified address belongs to a contract.
578 ///
579 /// # Parameters
580 ///
581 /// - `address`: The address to check
582 ///
583 /// # Return
584 ///
585 /// Returns `true` if the address belongs to a contract.
586 #[unstable_hostfn]
587 fn is_contract(address: &[u8; 20]) -> bool;
588
589 /// Stores the minimum balance (a.k.a. existential deposit) into the supplied buffer.
590 ///
591 /// # Parameters
592 ///
593 /// - `output`: A reference to the output data buffer to write the minimum balance.
594 #[unstable_hostfn]
595 fn minimum_balance(output: &mut [u8; 32]);
596
597 /// Retrieve the code hash of the currently executing contract.
598 ///
599 /// # Parameters
600 ///
601 /// - `output`: A reference to the output data buffer to write the code hash.
602 #[unstable_hostfn]
603 fn own_code_hash(output: &mut [u8; 32]);
604
605 /// Replace the contract code at the specified address with new code.
606 ///
607 /// # Note
608 ///
609 /// There are a couple of important considerations which must be taken into account when
610 /// using this API:
611 ///
612 /// 1. The storage at the code address will remain untouched. This means that contract
613 /// developers must ensure that the storage layout of the new code is compatible with that of
614 /// the old code.
615 ///
616 /// 2. Contracts using this API can't be assumed as having deterministic addresses. Said another
617 /// way, when using this API you lose the guarantee that an address always identifies a specific
618 /// code hash.
619 ///
620 /// 3. If a contract calls into itself after changing its code the new call would use
621 /// the new code. However, if the original caller panics after returning from the sub call it
622 /// would revert the changes made by [`set_code_hash()`][`Self::set_code_hash`] and the next
623 /// caller would use the old code.
624 ///
625 /// # Parameters
626 ///
627 /// - `code_hash`: The hash of the new code. Should be decodable as an `T::Hash`. Traps
628 /// otherwise.
629 ///
630 /// # Panics
631 ///
632 /// Panics if there is no code on-chain with the specified hash.
633 #[unstable_hostfn]
634 fn set_code_hash(code_hash: &[u8; 32]);
635
636 /// Verify a sr25519 signature
637 ///
638 /// # Parameters
639 ///
640 /// - `signature`: The signature bytes.
641 /// - `message`: The message bytes.
642 ///
643 /// # Errors
644 ///
645 /// - [Sr25519VerifyFailed][`crate::ReturnErrorCode::Sr25519VerifyFailed]
646 #[unstable_hostfn]
647 fn sr25519_verify(signature: &[u8; 64], message: &[u8], pub_key: &[u8; 32]) -> Result;
648
649 /// Retrieve and remove the value under the given key from storage.
650 ///
651 /// # Parameters
652 /// - `key`: The storage key.
653 /// - `output`: A reference to the output data buffer to write the storage entry.
654 ///
655 /// # Errors
656 ///
657 /// [KeyNotFound][`crate::ReturnErrorCode::KeyNotFound]
658 #[unstable_hostfn]
659 fn take_storage(flags: StorageFlags, key: &[u8], output: &mut &mut [u8]) -> Result;
660
661 /// Remove the calling account and transfer remaining **free** balance.
662 ///
663 /// This function never returns. Either the termination was successful and the
664 /// execution of the destroyed contract is halted. Or it failed during the termination
665 /// which is considered fatal and results in a trap + rollback.
666 ///
667 /// # Parameters
668 ///
669 /// - `beneficiary`: The address of the beneficiary account
670 ///
671 /// # Traps
672 ///
673 /// - The contract is live i.e is already on the call stack.
674 /// - Failed to send the balance to the beneficiary.
675 /// - The deletion queue is full.
676 #[unstable_hostfn]
677 fn terminate(beneficiary: &[u8; 20]) -> !;
678
679 /// Stores the amount of weight left into the supplied buffer.
680 /// The data is encoded as Weight.
681 ///
682 /// If the available space in `output` is less than the size of the value a trap is triggered.
683 ///
684 /// # Parameters
685 ///
686 /// - `output`: A reference to the output data buffer to write the weight left.
687 #[unstable_hostfn]
688 fn weight_left(output: &mut &mut [u8]);
689
690 /// Execute an XCM program locally, using the contract's address as the origin.
691 /// This is equivalent to dispatching `pallet_xcm::execute` through call_runtime, except that
692 /// the function is called directly instead of being dispatched.
693 ///
694 /// # Parameters
695 ///
696 /// - `msg`: The message, should be decodable as a [VersionedXcm](https://paritytech.github.io/polkadot-sdk/master/staging_xcm/enum.VersionedXcm.html),
697 /// traps otherwise.
698 /// - `output`: A reference to the output data buffer to write the [Outcome](https://paritytech.github.io/polkadot-sdk/master/staging_xcm/v3/enum.Outcome.html)
699 ///
700 /// # Return
701 ///
702 /// Returns `Error::Success` when the XCM execution attempt is successful. When the XCM
703 /// execution fails, `ReturnCode::XcmExecutionFailed` is returned
704 #[unstable_hostfn]
705 fn xcm_execute(msg: &[u8]) -> Result;
706
707 /// Send an XCM program from the contract to the specified destination.
708 /// This is equivalent to dispatching `pallet_xcm::send` through `call_runtime`, except that
709 /// the function is called directly instead of being dispatched.
710 ///
711 /// # Parameters
712 ///
713 /// - `dest`: The XCM destination, should be decodable as [VersionedLocation](https://paritytech.github.io/polkadot-sdk/master/staging_xcm/enum.VersionedLocation.html),
714 /// traps otherwise.
715 /// - `msg`: The message, should be decodable as a [VersionedXcm](https://paritytech.github.io/polkadot-sdk/master/staging_xcm/enum.VersionedXcm.html),
716 /// traps otherwise.
717 ///
718 /// # Return
719 ///
720 /// Returns `ReturnCode::Success` when the message was successfully sent. When the XCM
721 /// execution fails, `ReturnErrorCode::XcmSendFailed` is returned.
722 #[unstable_hostfn]
723 fn xcm_send(dest: &[u8], msg: &[u8], output: &mut [u8; 32]) -> Result;
724}
725
726mod private {
727 pub trait Sealed {}
728 impl Sealed for super::HostFnImpl {}
729}