From 7c5d229a20d773b68ca2e8d37c48f67928b5bce8 Mon Sep 17 00:00:00 2001 From: Michael Mueller Date: Wed, 5 Mar 2025 19:54:50 +0100 Subject: [PATCH] Implement new address derivation --- Cargo.lock | 18 ++++++------ build-image/Dockerfile | 5 ++-- crates/extrinsics/src/instantiate.rs | 5 ++-- crates/extrinsics/src/integration_tests.rs | 2 +- crates/extrinsics/src/lib.rs | 34 ++++++++++++++++++++++ crates/extrinsics/src/map_account.rs | 8 ++--- 6 files changed, 53 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b202e8b81..3a9d5d7e5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12039,7 +12039,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.10.0" -source = "git+https://github.com/paritytech/polkadot-sdk#9a8061e6efc6607383160249319573696270d672" +source = "git+https://github.com/paritytech/polkadot-sdk#1dbaeba9044ef491847a8204da98cd9e74534cdb" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -12182,7 +12182,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#9a8061e6efc6607383160249319573696270d672" +source = "git+https://github.com/paritytech/polkadot-sdk#1dbaeba9044ef491847a8204da98cd9e74534cdb" dependencies = [ "proc-macro2", "quote", @@ -12212,7 +12212,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.25.0" -source = "git+https://github.com/paritytech/polkadot-sdk#9a8061e6efc6607383160249319573696270d672" +source = "git+https://github.com/paritytech/polkadot-sdk#1dbaeba9044ef491847a8204da98cd9e74534cdb" dependencies = [ "environmental", "parity-scale-codec", @@ -12691,7 +12691,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "24.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#9a8061e6efc6607383160249319573696270d672" +source = "git+https://github.com/paritytech/polkadot-sdk#1dbaeba9044ef491847a8204da98cd9e74534cdb" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -12756,7 +12756,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#9a8061e6efc6607383160249319573696270d672" +source = "git+https://github.com/paritytech/polkadot-sdk#1dbaeba9044ef491847a8204da98cd9e74534cdb" dependencies = [ "Inflector", "expander", @@ -12954,7 +12954,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?rev=9adb8d28ab1f6744f1f [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#9a8061e6efc6607383160249319573696270d672" +source = "git+https://github.com/paritytech/polkadot-sdk#1dbaeba9044ef491847a8204da98cd9e74534cdb" [[package]] name = "sp-storage" @@ -12983,7 +12983,7 @@ dependencies = [ [[package]] name = "sp-storage" version = "19.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#9a8061e6efc6607383160249319573696270d672" +source = "git+https://github.com/paritytech/polkadot-sdk#1dbaeba9044ef491847a8204da98cd9e74534cdb" dependencies = [ "impl-serde 0.5.0", "parity-scale-codec", @@ -13055,7 +13055,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#9a8061e6efc6607383160249319573696270d672" +source = "git+https://github.com/paritytech/polkadot-sdk#1dbaeba9044ef491847a8204da98cd9e74534cdb" dependencies = [ "parity-scale-codec", "tracing", @@ -13281,7 +13281,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "20.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#9a8061e6efc6607383160249319573696270d672" +source = "git+https://github.com/paritytech/polkadot-sdk#1dbaeba9044ef491847a8204da98cd9e74534cdb" dependencies = [ "anyhow", "impl-trait-for-tuples", diff --git a/build-image/Dockerfile b/build-image/Dockerfile index 5c096b5fd..0b7f15274 100644 --- a/build-image/Dockerfile +++ b/build-image/Dockerfile @@ -19,10 +19,11 @@ ARG WGET_VERSION=1.21-1+deb11u1 # g++ package version ARG G_VERSION=4:10.2.1-1 ARG MUSL_V=1.2.2-1 -# The rust version used by `ink_linting` +# The Rust version used by `ink_linting`. +# See https://github.com/use-ink/ink/blob/master/linting/rust-toolchain.toml. ARG RUST_LINTER_VERSION=nightly-2025-02-20 -# metadata +# Metadata LABEL ink.use.image.vendor="Use Ink" \ ink.use.image.title="useink/contracts-verifiable" \ ink.use.image.description="Inherits from docker.io/bitnami/minideb:bullseye. \ diff --git a/crates/extrinsics/src/instantiate.rs b/crates/extrinsics/src/instantiate.rs index 5504b743c..e75e01fd0 100644 --- a/crates/extrinsics/src/instantiate.rs +++ b/crates/extrinsics/src/instantiate.rs @@ -23,6 +23,7 @@ use super::{ }, state_call, submit_extrinsic, + AccountIdMapper, ContractMessageTranscoder, ErrorVariant, }; @@ -634,14 +635,14 @@ async fn contract_address + Clone>( data: &[u8], ) -> Result { let account_id = Signer::account_id(signer); - let deployer = H160::from_slice(&account_id.encode()[..20]); - let account_nonce = get_account_nonce(client, rpc, &account_id).await?; + let deployer = AccountIdMapper::to_address(&account_id.encode()[..]); // copied from `pallet-revive` let origin_is_caller = false; let addr = if let Some(salt) = salt { pallet_revive::create2(&deployer, code, data, salt) } else { + let account_nonce = get_account_nonce(client, rpc, &account_id).await?; pallet_revive::create1( &deployer, // the Nonce from the origin has been incremented pre-dispatch, so we diff --git a/crates/extrinsics/src/integration_tests.rs b/crates/extrinsics/src/integration_tests.rs index fff8ab944..3c0db33ec 100644 --- a/crates/extrinsics/src/integration_tests.rs +++ b/crates/extrinsics/src/integration_tests.rs @@ -930,7 +930,7 @@ async fn adhere_to_limits_during_build_upload_instantiate_call() { assert!(output.status.success(), "instantiate failed: {stderr}"); let contract_account = extract_contract_address(stdout); - cargo_contract(project_path) + let output = cargo_contract(project_path) .arg("call") .args(["--message", "push"]) .args(["--contract", contract_account]) diff --git a/crates/extrinsics/src/lib.rs b/crates/extrinsics/src/lib.rs index e3b437a06..cb75c6236 100644 --- a/crates/extrinsics/src/lib.rs +++ b/crates/extrinsics/src/lib.rs @@ -102,6 +102,10 @@ use scale::{ Decode, Encode, }; +use sp_core::{ + keccak_256, + H160, +}; use subxt::{ backend::legacy::{ rpc_methods::DryRunResult, @@ -325,6 +329,36 @@ pub fn url_to_string(url: &url::Url) -> String { } } +pub struct AccountIdMapper {} +impl AccountIdMapper { + //pub fn to_address(account_id: &E::AccountId) -> H160 { + pub fn to_address(account_id: &[u8]) -> H160 { + let mut account_bytes: [u8; 32] = [0u8; 32]; + account_bytes.copy_from_slice(&account_id[..32]); + if Self::is_eth_derived(account_id) { + // this was originally an eth address + // we just strip the 0xEE suffix to get the original address + H160::from_slice(&account_bytes[..20]) + } else { + // this is an (ed|sr)25510 derived address + // avoid truncating the public key by hashing it first + let account_hash = keccak_256(account_bytes.as_ref()); + H160::from_slice(&account_hash[12..]) + } + } + + /// Returns true if the passed account id is controlled by an Ethereum key. + /// + /// This is a stateless check that just compares the last 12 bytes. Please note that + /// it is theoretically possible to create an ed25519 keypair that passed this + /// filter. However, this can't be used for an attack. It also won't happen by + /// accident since everbody is using sr25519 where this is not a valid public key. + //fn is_eth_derived(account_id: &[u8]) -> bool { + fn is_eth_derived(account_bytes: &[u8]) -> bool { + account_bytes[20..] == [0xEE; 12] + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/extrinsics/src/map_account.rs b/crates/extrinsics/src/map_account.rs index b2942e64c..1358f1f08 100644 --- a/crates/extrinsics/src/map_account.rs +++ b/crates/extrinsics/src/map_account.rs @@ -18,6 +18,7 @@ use super::{ dry_run_extrinsic, pallet_revive_primitives::StorageDeposit, submit_extrinsic, + AccountIdMapper, ContractMessageTranscoder, ErrorVariant, }; @@ -172,13 +173,10 @@ where let call = MapAccount::new().build(); let events = submit_extrinsic(&self.client, &self.rpc, &call, self.opts.signer()).await?; - - let addr = self.opts.signer().account_id(); - let addr = &addr.encode()[..20]; - + let account_id = self.opts.signer().account_id(); Ok(MapAccountExecResult { events, - address: H160::from_slice(addr), + address: AccountIdMapper::to_address(&account_id.encode()[..]), }) }