From 67e41edc1bcc025e3b257c0e202482662681b6ba Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Fri, 1 Aug 2025 18:26:47 +0200 Subject: [PATCH 1/9] Mark `account_id` stable --- crates/env/src/api.rs | 1 - crates/env/src/engine/off_chain/impls.rs | 1 - crates/env/src/engine/on_chain/pallet_revive.rs | 1 - crates/ink/src/env_access.rs | 1 - 4 files changed, 4 deletions(-) diff --git a/crates/env/src/api.rs b/crates/env/src/api.rs index ed1ada1ac6..75ad1e2975 100644 --- a/crates/env/src/api.rs +++ b/crates/env/src/api.rs @@ -117,7 +117,6 @@ where /// # Errors /// /// If the returned value cannot be properly decoded. -#[cfg(feature = "unstable-hostfn")] pub fn account_id() -> E::AccountId where E: Environment, diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs index a4b49d5c19..db9cd8194b 100644 --- a/crates/env/src/engine/off_chain/impls.rs +++ b/crates/env/src/engine/off_chain/impls.rs @@ -537,7 +537,6 @@ impl TypedEnvBackend for EnvInstance { }) } - #[cfg(feature = "unstable-hostfn")] fn account_id(&mut self) -> E::AccountId { // todo should not use `Engine::account_id` self.get_property::(Engine::address) diff --git a/crates/env/src/engine/on_chain/pallet_revive.rs b/crates/env/src/engine/on_chain/pallet_revive.rs index 12fc77bc0b..8b37aaa6a1 100644 --- a/crates/env/src/engine/on_chain/pallet_revive.rs +++ b/crates/env/src/engine/on_chain/pallet_revive.rs @@ -443,7 +443,6 @@ impl TypedEnvBackend for EnvInstance { self.get_property_little_endian::(ext::now) } - #[cfg(feature = "unstable-hostfn")] fn account_id(&mut self) -> E::AccountId { let mut scope = self.scoped_buffer(); diff --git a/crates/ink/src/env_access.rs b/crates/ink/src/env_access.rs index 850d2a3575..96da970118 100644 --- a/crates/ink/src/env_access.rs +++ b/crates/ink/src/env_access.rs @@ -279,7 +279,6 @@ where /// # Note /// /// For more details visit: [`ink_env::account_id`] - #[cfg(feature = "unstable-hostfn")] pub fn account_id(self) -> E::AccountId { ink_env::account_id::() } From c504bef3a2e4f5aa91775b7770849929846cc598 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Sun, 3 Aug 2025 12:16:38 +0200 Subject: [PATCH 2/9] Implement `to_account_id` host function --- crates/engine/src/database.rs | 23 ++++++- crates/engine/src/ext.rs | 18 ++++++ crates/env/src/api.rs | 14 ++++ crates/env/src/backend.rs | 8 ++- crates/env/src/engine/off_chain/impls.rs | 10 ++- .../env/src/engine/on_chain/pallet_revive.rs | 8 +++ crates/ink/src/env_access.rs | 42 ++++++++++++ crates/primitives/src/types.rs | 1 - .../lang-err/constructors-return-value/lib.rs | 3 +- .../internal/misc-hostfns/Cargo.toml | 27 ++++++++ .../internal/misc-hostfns/lib.rs | 64 +++++++++++++++++++ 11 files changed, 211 insertions(+), 7 deletions(-) create mode 100755 integration-tests/internal/misc-hostfns/Cargo.toml create mode 100755 integration-tests/internal/misc-hostfns/lib.rs diff --git a/crates/engine/src/database.rs b/crates/engine/src/database.rs index 39c23c1a07..22c86b9273 100644 --- a/crates/engine/src/database.rs +++ b/crates/engine/src/database.rs @@ -27,6 +27,7 @@ const STORAGE_OF: &[u8] = b"contract-storage:"; const CONTRACT_PREFIX: &[u8] = b"contract:"; const MSG_HANDLER_OF: &[u8] = b"message-handler:"; const CODE_HASH_OF: &[u8] = b"code-hash:"; +const ACCOUNT_ID_OF: &[u8] = b"account-id:"; /// Returns the database key under which to find the balance for contract `who`. pub fn balance_of_key(who: &Address) -> [u8; 32] { @@ -36,6 +37,14 @@ pub fn balance_of_key(who: &Address) -> [u8; 32] { hashed_key } +/// Returns the database key under which to find the account id for the address `who`. +pub fn account_id_of_key(who: &Address) -> [u8; 32] { + let keyed = who.0.to_vec().to_keyed_vec(ACCOUNT_ID_OF); + let mut hashed_key: [u8; 32] = [0; 32]; + super::hashing::blake2b_256(&keyed[..], &mut hashed_key); + hashed_key +} + /// Returns the database key under which to find the storage for contract `who`. pub fn storage_of_contract_key(who: &Address, key: &[u8]) -> [u8; 32] { let keyed = who @@ -152,15 +161,25 @@ impl Database { } /// Returns the balance of the contract at `addr`, if available. - pub fn get_acc_balance(&self, _addr: &AccountId) -> Option { + pub fn get_acc_balance(&self, _account_id: &AccountId) -> Option { todo!() } /// Sets the balance of `addr` to `new_balance`. - pub fn set_acc_balance(&mut self, _addr: &AccountId, _new_balance: Balance) { + pub fn set_acc_balance(&mut self, _account_id: &AccountId, _new_balance: Balance) { todo!() } + /// Retrieves the account id for a specified contract address. + pub fn to_account_id(&self, addr: &Address) -> Vec { + let hashed_key = account_id_of_key(addr); + self.get(&hashed_key).cloned().unwrap_or_else(|| { + let mut bytes = [0xEE; 32]; + bytes[..20].copy_from_slice(&addr.as_bytes()[..20]); + Vec::from(bytes) + }) + } + pub fn get_balance(&self, addr: &Address) -> Option { let hashed_key = balance_of_key(addr); self.get(&hashed_key).map(|encoded_balance| { diff --git a/crates/engine/src/ext.rs b/crates/engine/src/ext.rs index a3d8504eaf..066467a8ae 100644 --- a/crates/engine/src/ext.rs +++ b/crates/engine/src/ext.rs @@ -274,6 +274,24 @@ impl Engine { set_output(output, callee) } + pub fn account_id(&self, output: &mut &mut [u8]) { + let callee = self + .exec_context + .callee + .as_ref() + .expect("no callee has been set"); + let account_id = self.database.to_account_id(callee); + set_output(output, account_id.as_slice()) + } + + /// Retrieves the account id for a specified contract address. + pub fn to_account_id(&self, input: &[u8], output: &mut &mut [u8]) { + let addr = + scale::Decode::decode(&mut &input[..]).expect("unable to decode Address"); + let account_id = self.database.to_account_id(&addr); + set_output(output, account_id.as_slice()) + } + /// Conduct the BLAKE-2 256-bit hash and place the result into `output`. pub fn hash_blake2_256(input: &[u8], output: &mut [u8; 32]) { super::hashing::blake2b_256(input, output); diff --git a/crates/env/src/api.rs b/crates/env/src/api.rs index 75ad1e2975..b2fd620a9d 100644 --- a/crates/env/src/api.rs +++ b/crates/env/src/api.rs @@ -108,6 +108,20 @@ where }) } +/// Retrieves the account id for a specified contract address. +/// +/// # Errors +/// +/// If the returned value cannot be properly decoded. +pub fn to_account_id(addr: Address) -> E::AccountId +where + E: Environment, +{ + ::on_instance(|instance| { + TypedEnvBackend::to_account_id::(instance, addr) + }) +} + /// Returns the account ID of the executed contract. /// /// # Note diff --git a/crates/env/src/backend.rs b/crates/env/src/backend.rs index 86c06d70e0..4e3f3d6528 100644 --- a/crates/env/src/backend.rs +++ b/crates/env/src/backend.rs @@ -276,12 +276,18 @@ pub trait TypedEnvBackend: EnvBackend { /// For more details visit: [`block_timestamp`][`crate::block_timestamp`] fn block_timestamp(&mut self) -> E::Timestamp; + /// Retrieves the account id for a specified contract address. + /// + /// # Note + /// + /// For more details visit: [`to_account_id`][`crate::to_account_id`] + fn to_account_id(&mut self, addr: Address) -> E::AccountId; + /// Returns the address of the executed contract. /// /// # Note /// /// For more details visit: [`account_id`][`crate::account_id`] - #[cfg(feature = "unstable-hostfn")] fn account_id(&mut self) -> E::AccountId; /// Returns the address of the executed contract. diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs index db9cd8194b..627240e713 100644 --- a/crates/env/src/engine/off_chain/impls.rs +++ b/crates/env/src/engine/off_chain/impls.rs @@ -537,9 +537,15 @@ impl TypedEnvBackend for EnvInstance { }) } + fn to_account_id(&mut self, addr: Address) -> E::AccountId { + let mut full_scope: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE]; + let full_scope = &mut &mut full_scope[..]; + Engine::to_account_id(&self.engine, addr.as_bytes(), full_scope); + scale::Decode::decode(&mut &full_scope[..]).unwrap() + } + fn account_id(&mut self) -> E::AccountId { - // todo should not use `Engine::account_id` - self.get_property::(Engine::address) + self.get_property::(Engine::account_id) .unwrap_or_else(|error| { panic!("could not read `account_id` property: {error:?}") }) diff --git a/crates/env/src/engine/on_chain/pallet_revive.rs b/crates/env/src/engine/on_chain/pallet_revive.rs index 8b37aaa6a1..4a22e00e84 100644 --- a/crates/env/src/engine/on_chain/pallet_revive.rs +++ b/crates/env/src/engine/on_chain/pallet_revive.rs @@ -455,6 +455,14 @@ impl TypedEnvBackend for EnvInstance { .expect("A contract being executed must have a valid account id.") } + fn to_account_id(&mut self, addr: Address) -> E::AccountId { + let mut scope = self.scoped_buffer(); + let account_id: &mut [u8; 32] = scope.take(32).try_into().unwrap(); + ext::to_account_id(addr.as_fixed_bytes(), account_id); + scale::Decode::decode(&mut &account_id[..]) + .expect("A contract being executed must have a valid account id.") + } + fn address(&mut self) -> Address { let mut scope = self.scoped_buffer(); diff --git a/crates/ink/src/env_access.rs b/crates/ink/src/env_access.rs index 96da970118..fa26d91a27 100644 --- a/crates/ink/src/env_access.rs +++ b/crates/ink/src/env_access.rs @@ -238,6 +238,48 @@ where ink_env::block_timestamp::() } + /// Retrieves the account id for a specified contract address. + /// + /// # Example + /// + /// ``` + /// #[ink::contract] + /// pub mod only_owner { + /// #[ink(storage)] + /// pub struct OnlyOwner { + /// owner: AccountId, + /// value: u32, + /// } + /// + /// impl OnlyOwner { + /// #[ink(constructor)] + /// pub fn new(owner: AccountId) -> Self { + /// Self { owner, value: 0 } + /// } + /// + /// /// Allows incrementing the contract's `value` only + /// /// for the owner (i.e. the account which instantiated + /// /// this contract. + /// /// + /// /// The contract panics if the caller is not the owner. + /// #[ink(message)] + /// pub fn increment(&mut self) { + /// let caller = self.env().address(); + /// let caller_acc = self.env().to_account_id(&caller); + /// assert!(self.owner == caller_acc); + /// self.value = self.value + 1; + /// } + /// } + /// } + /// ``` + /// + /// # Note + /// + /// For more details visit: [`ink_env::account_id`] + pub fn to_account_id(self, addr: Address) -> E::AccountId { + ink_env::to_account_id::(addr) + } + /// Returns the account ID of the executed contract. /// /// # Example diff --git a/crates/primitives/src/types.rs b/crates/primitives/src/types.rs index 2ff8ba048b..b9bea12006 100644 --- a/crates/primitives/src/types.rs +++ b/crates/primitives/src/types.rs @@ -469,7 +469,6 @@ pub enum Origin { pub struct AccountIdMapper {} impl AccountIdMapper { - //pub fn to_address(account_id: &E::AccountId) -> Address { pub fn to_address(account_id: &[u8]) -> Address { let mut account_bytes: [u8; 32] = [0u8; 32]; account_bytes.copy_from_slice(&account_id[..32]); diff --git a/integration-tests/internal/lang-err/constructors-return-value/lib.rs b/integration-tests/internal/lang-err/constructors-return-value/lib.rs index 8874447bef..0fc0ba77b3 100644 --- a/integration-tests/internal/lang-err/constructors-return-value/lib.rs +++ b/integration-tests/internal/lang-err/constructors-return-value/lib.rs @@ -134,7 +134,8 @@ pub mod constructors_return_value { .await?; // Infallible constructors return `Result<(), ()>`. - let decoded_result = infallible_constructor_result.constructor_result::>(); + let decoded_result = + infallible_constructor_result.constructor_result::>(); assert!( decoded_result.is_ok(), "Constructor dispatch should have succeeded" diff --git a/integration-tests/internal/misc-hostfns/Cargo.toml b/integration-tests/internal/misc-hostfns/Cargo.toml new file mode 100755 index 0000000000..76e4a325aa --- /dev/null +++ b/integration-tests/internal/misc-hostfns/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "misc_hostfns" +description = "E2E tests for various host functions" +version = "6.0.0-alpha.1" +authors = ["Use Ink "] +edition = "2021" +publish = false + +[dependencies] +ink = { path = "../../../crates/ink", default-features = false, features = ["unstable-hostfn"] } + +[dev-dependencies] +ink_e2e = { path = "../../../crates/e2e" } + +[lib] +path = "lib.rs" + +[features] +default = ["std"] +std = [ + "ink/std", +] +ink-as-dependency = [] +e2e-tests = [] + +[package.metadata.ink-lang] +abi = "ink" diff --git a/integration-tests/internal/misc-hostfns/lib.rs b/integration-tests/internal/misc-hostfns/lib.rs new file mode 100755 index 0000000000..c5c6e18cd7 --- /dev/null +++ b/integration-tests/internal/misc-hostfns/lib.rs @@ -0,0 +1,64 @@ +#![cfg_attr(not(feature = "std"), no_std, no_main)] + +#[ink::contract] +mod misc_hostfns { + #[ink(storage)] + pub struct MiscHostfns {} + + impl MiscHostfns { + #[ink(constructor)] + pub fn new() -> Self { + Self {} + } + + /// Takes an auction data struct as input and returns it back. + #[ink(message)] + pub fn addr_account_id(&self) { + let addr = self.env().address(); + let to_account_id = self.env().to_account_id(addr); + let account_id = self.env().account_id(); + assert_eq!(to_account_id, account_id); + } + } + + #[cfg(test)] + mod tests { + use super::*; + + #[ink::test] + fn works() { + let contract = MiscHostfns::new(); + contract.addr_account_id(); + } + } + + #[cfg(all(test, feature = "e2e-tests"))] + mod e2e_tests { + use super::*; + use ink_e2e::ContractsBackend; + + type E2EResult = std::result::Result>; + + #[ink_e2e::test] + async fn e2e_works(mut client: Client) -> E2EResult<()> { + // given + let mut constructor = MiscHostfnsRef::new(); + let contract = client + .instantiate("misc_hostfns", &ink_e2e::alice(), &mut constructor) + .submit() + .await + .expect("instantiate failed"); + let call_builder = contract.call_builder::(); + + // then + let acc = call_builder.addr_account_id(); + let _call_res = client + .call(&ink_e2e::alice(), &acc) + .submit() + .await + .expect("call failed"); + + Ok(()) + } + } +} From ab54452abb2b06453418e3d83ffe2d98966acc28 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 5 Aug 2025 21:08:23 +0200 Subject: [PATCH 3/9] Misc cleanups --- .../sandbox-runtime/pallet-revive-caller/src/executor.rs | 4 ---- .../public/upgradeable-contracts/delegator/lib.rs | 3 +++ 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/integration-tests/public/runtime-call-contract/sandbox-runtime/pallet-revive-caller/src/executor.rs b/integration-tests/public/runtime-call-contract/sandbox-runtime/pallet-revive-caller/src/executor.rs index 32b699a93a..7aa9439b66 100644 --- a/integration-tests/public/runtime-call-contract/sandbox-runtime/pallet-revive-caller/src/executor.rs +++ b/integration-tests/public/runtime-call-contract/sandbox-runtime/pallet-revive-caller/src/executor.rs @@ -25,8 +25,6 @@ use pallet_revive::{ use sp_runtime::traits::Bounded; pub struct PalletReviveExecutor { - // todo - //pub origin: AccountIdOf, pub origin: OriginFor, pub contract: Address, pub value: BalanceOf, @@ -59,8 +57,6 @@ where let data = input.encode(); let result = pallet_revive::Pallet::::bare_call( self.origin.clone(), - // ::AddressMapper::to_account_id(&self. - // contract), self.contract, self.value, self.gas_limit, diff --git a/integration-tests/public/upgradeable-contracts/delegator/lib.rs b/integration-tests/public/upgradeable-contracts/delegator/lib.rs index d957e1221b..0859de96e8 100644 --- a/integration-tests/public/upgradeable-contracts/delegator/lib.rs +++ b/integration-tests/public/upgradeable-contracts/delegator/lib.rs @@ -141,6 +141,7 @@ pub mod delegator { .await; /* + // todo let code_hash = client .upload("delegatee", &origin) .submit() @@ -284,6 +285,7 @@ pub mod delegator { .await; /* + // todo let code_hash = client .upload("delegatee", &origin) .submit() @@ -308,6 +310,7 @@ pub mod delegator { let delegatee_addr = contract.addr; /* + // todo let code_hash2 = client .upload("delegatee2", &origin) .submit() From e0343a93ce57bb2d736f2d9f92fa79e86e68038c Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 5 Aug 2025 21:25:59 +0200 Subject: [PATCH 4/9] Make `clippy` happy --- integration-tests/internal/misc-hostfns/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/integration-tests/internal/misc-hostfns/lib.rs b/integration-tests/internal/misc-hostfns/lib.rs index c5c6e18cd7..5cec7434e5 100755 --- a/integration-tests/internal/misc-hostfns/lib.rs +++ b/integration-tests/internal/misc-hostfns/lib.rs @@ -1,4 +1,5 @@ #![cfg_attr(not(feature = "std"), no_std, no_main)] +#![allow(clippy::new_without_default)] #[ink::contract] mod misc_hostfns { From 5fae734481d99718b82918fb68ce8b344112d9a9 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 5 Aug 2025 21:33:59 +0200 Subject: [PATCH 5/9] Fix error message --- integration-tests/internal/lang-err/call-builder/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration-tests/internal/lang-err/call-builder/lib.rs b/integration-tests/internal/lang-err/call-builder/lib.rs index 55ee2d7005..86e16e50ae 100755 --- a/integration-tests/internal/lang-err/call-builder/lib.rs +++ b/integration-tests/internal/lang-err/call-builder/lib.rs @@ -115,7 +115,7 @@ mod call_builder { let result = params .try_instantiate() - .expect("Error from the Contracts pallet."); + .expect("Error from the `pallet-revive`."); match result { Ok(_) => None, From 432ca09759c5a17bedeab5ac3191044674358218 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 5 Aug 2025 21:35:09 +0200 Subject: [PATCH 6/9] Fix comments and example --- crates/ink/src/env_access.rs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/crates/ink/src/env_access.rs b/crates/ink/src/env_access.rs index fa26d91a27..011d8c2877 100644 --- a/crates/ink/src/env_access.rs +++ b/crates/ink/src/env_access.rs @@ -258,8 +258,7 @@ where /// } /// /// /// Allows incrementing the contract's `value` only - /// /// for the owner (i.e. the account which instantiated - /// /// this contract. + /// /// for the owner. /// /// /// /// The contract panics if the caller is not the owner. /// #[ink(message)] @@ -284,13 +283,12 @@ where /// /// # Example /// - /// todo this code example doesn't use `account_id()`. /// ``` /// #[ink::contract] /// pub mod only_owner { /// #[ink(storage)] /// pub struct OnlyOwner { - /// owner: ink::Address, + /// owner: AccountId, /// value: u32, /// } /// @@ -298,19 +296,18 @@ where /// #[ink(constructor)] /// pub fn new() -> Self { /// Self { - /// owner: Self::env().caller(), + /// owner: Self::env().account_id(), /// value: 0, /// } /// } /// /// /// Allows incrementing the contract's `value` only - /// /// for the owner (i.e. the account which instantiated - /// /// this contract. + /// /// for the owner. /// /// /// /// The contract panics if the caller is not the owner. /// #[ink(message)] /// pub fn increment(&mut self) { - /// let caller = self.env().caller(); + /// let caller = self.env().account_id(); /// assert!(self.owner == caller); /// self.value = self.value + 1; /// } From 5047e1427fed0f188e3ba004ddb24796e05d4c90 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 5 Aug 2025 21:39:32 +0200 Subject: [PATCH 7/9] Mark `to_account_id` unstable --- crates/engine/src/database.rs | 2 +- crates/engine/src/ext.rs | 2 +- crates/env/src/api.rs | 3 ++- crates/env/src/backend.rs | 3 ++- crates/env/src/engine/off_chain/impls.rs | 1 + crates/env/src/engine/on_chain/pallet_revive.rs | 1 + crates/ink/src/env_access.rs | 6 ++++-- 7 files changed, 12 insertions(+), 6 deletions(-) diff --git a/crates/engine/src/database.rs b/crates/engine/src/database.rs index 22c86b9273..349bfa752e 100644 --- a/crates/engine/src/database.rs +++ b/crates/engine/src/database.rs @@ -170,7 +170,7 @@ impl Database { todo!() } - /// Retrieves the account id for a specified contract address. + /// Retrieves the account id for a specified address. pub fn to_account_id(&self, addr: &Address) -> Vec { let hashed_key = account_id_of_key(addr); self.get(&hashed_key).cloned().unwrap_or_else(|| { diff --git a/crates/engine/src/ext.rs b/crates/engine/src/ext.rs index 066467a8ae..b626bc6d1e 100644 --- a/crates/engine/src/ext.rs +++ b/crates/engine/src/ext.rs @@ -284,7 +284,7 @@ impl Engine { set_output(output, account_id.as_slice()) } - /// Retrieves the account id for a specified contract address. + /// Retrieves the account id for a specified address. pub fn to_account_id(&self, input: &[u8], output: &mut &mut [u8]) { let addr = scale::Decode::decode(&mut &input[..]).expect("unable to decode Address"); diff --git a/crates/env/src/api.rs b/crates/env/src/api.rs index b2fd620a9d..32b396435d 100644 --- a/crates/env/src/api.rs +++ b/crates/env/src/api.rs @@ -108,11 +108,12 @@ where }) } -/// Retrieves the account id for a specified contract address. +/// Retrieves the account id for a specified address. /// /// # Errors /// /// If the returned value cannot be properly decoded. +#[cfg(feature = "unstable-hostfn")] pub fn to_account_id(addr: Address) -> E::AccountId where E: Environment, diff --git a/crates/env/src/backend.rs b/crates/env/src/backend.rs index 4e3f3d6528..7e816e3052 100644 --- a/crates/env/src/backend.rs +++ b/crates/env/src/backend.rs @@ -276,11 +276,12 @@ pub trait TypedEnvBackend: EnvBackend { /// For more details visit: [`block_timestamp`][`crate::block_timestamp`] fn block_timestamp(&mut self) -> E::Timestamp; - /// Retrieves the account id for a specified contract address. + /// Retrieves the account id for a specified address. /// /// # Note /// /// For more details visit: [`to_account_id`][`crate::to_account_id`] + #[cfg(feature = "unstable-hostfn")] fn to_account_id(&mut self, addr: Address) -> E::AccountId; /// Returns the address of the executed contract. diff --git a/crates/env/src/engine/off_chain/impls.rs b/crates/env/src/engine/off_chain/impls.rs index 627240e713..ac62624f8f 100644 --- a/crates/env/src/engine/off_chain/impls.rs +++ b/crates/env/src/engine/off_chain/impls.rs @@ -537,6 +537,7 @@ impl TypedEnvBackend for EnvInstance { }) } + #[cfg(feature = "unstable-hostfn")] fn to_account_id(&mut self, addr: Address) -> E::AccountId { let mut full_scope: [u8; BUFFER_SIZE] = [0; BUFFER_SIZE]; let full_scope = &mut &mut full_scope[..]; diff --git a/crates/env/src/engine/on_chain/pallet_revive.rs b/crates/env/src/engine/on_chain/pallet_revive.rs index 4a22e00e84..79703afe6a 100644 --- a/crates/env/src/engine/on_chain/pallet_revive.rs +++ b/crates/env/src/engine/on_chain/pallet_revive.rs @@ -455,6 +455,7 @@ impl TypedEnvBackend for EnvInstance { .expect("A contract being executed must have a valid account id.") } + #[cfg(feature = "unstable-hostfn")] fn to_account_id(&mut self, addr: Address) -> E::AccountId { let mut scope = self.scoped_buffer(); let account_id: &mut [u8; 32] = scope.take(32).try_into().unwrap(); diff --git a/crates/ink/src/env_access.rs b/crates/ink/src/env_access.rs index 011d8c2877..5ae91639e2 100644 --- a/crates/ink/src/env_access.rs +++ b/crates/ink/src/env_access.rs @@ -172,6 +172,7 @@ where /// #[ink(message)] /// pub fn foo(&self) {} /// + /// // todo /// // /// Returns a tuple of /// // /// - the result of adding the `rhs` to the `lhs` /// // /// - the gas costs of this addition operation @@ -238,7 +239,7 @@ where ink_env::block_timestamp::() } - /// Retrieves the account id for a specified contract address. + /// Retrieves the account id for a specified address. /// /// # Example /// @@ -274,7 +275,8 @@ where /// /// # Note /// - /// For more details visit: [`ink_env::account_id`] + /// For more details visit: [`ink_env::to_account_id`] + #[cfg(feature = "unstable-hostfn")] pub fn to_account_id(self, addr: Address) -> E::AccountId { ink_env::to_account_id::(addr) } From 355fe7a7201be5d8978f6ab00a3d6644648799d0 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Tue, 5 Aug 2025 22:23:39 +0200 Subject: [PATCH 8/9] Fix doc test --- crates/ink/src/env_access.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/ink/src/env_access.rs b/crates/ink/src/env_access.rs index 5ae91639e2..ad76d3024b 100644 --- a/crates/ink/src/env_access.rs +++ b/crates/ink/src/env_access.rs @@ -265,7 +265,7 @@ where /// #[ink(message)] /// pub fn increment(&mut self) { /// let caller = self.env().address(); - /// let caller_acc = self.env().to_account_id(&caller); + /// let caller_acc = self.env().to_account_id(caller); /// assert!(self.owner == caller_acc); /// self.value = self.value + 1; /// } From 938a4f47731420b5083b9dfc2415f44679f2d7ac Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Wed, 6 Aug 2025 10:07:39 +0200 Subject: [PATCH 9/9] Update changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ac785780a..51f375c145 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,12 +18,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Improve handling of Solidity constructor return and revert data - [#2552](https://github.com/use-ink/ink/pull/2552) - Implement `SolEncode` and `SolDecode` for `Option` - [#2545](https://github.com/use-ink/ink/pull/2545) - Allow writing E2E fuzz tests for contracts - [#2570](https://github.com/use-ink/ink/pull/2570) +- Implements the API for the `pallet-revive` host function `to_account_id` - [#2578](https://github.com/use-ink/ink/pull/2578) ### Changed - Use marker trait for finding ink! storage `struct` during code analysis - [2499](https://github.com/use-ink/ink/pull/2499) - Solidity ABI compatibility metadata improvements - [#2511](https://github.com/use-ink/ink/pull/2511) - Share intermediate build artifacts across all contract builds in e2e tests - [#2531](https://github.com/use-ink/ink/pull/2531) - Refactor Solidity bytes wrapper(s) - [#2569](https://github.com/use-ink/ink/pull/2569) +- Marks the `pallet-revive` host function `account_id` stable - [#2578](https://github.com/use-ink/ink/pull/2578) ### Fixed - Update metadata version to version 6 ‒ [#2507](https://github.com/use-ink/ink/pull/2507)