Skip to content

Commit

Permalink
Implement new address derivation
Browse files Browse the repository at this point in the history
  • Loading branch information
cmichi committed Mar 5, 2025
1 parent 01323d1 commit 7c5d229
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 19 deletions.
18 changes: 9 additions & 9 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions build-image/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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. \
Expand Down
5 changes: 3 additions & 2 deletions crates/extrinsics/src/instantiate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use super::{
},
state_call,
submit_extrinsic,
AccountIdMapper,
ContractMessageTranscoder,
ErrorVariant,
};
Expand Down Expand Up @@ -634,14 +635,14 @@ async fn contract_address<C: Config, Signer: tx::Signer<C> + Clone>(
data: &[u8],
) -> Result<H160, subxt::Error> {
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
Expand Down
2 changes: 1 addition & 1 deletion crates/extrinsics/src/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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])
Expand Down
34 changes: 34 additions & 0 deletions crates/extrinsics/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ use scale::{
Decode,
Encode,
};
use sp_core::{
keccak_256,
H160,
};
use subxt::{
backend::legacy::{
rpc_methods::DryRunResult,
Expand Down Expand Up @@ -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::*;
Expand Down
8 changes: 3 additions & 5 deletions crates/extrinsics/src/map_account.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use super::{
dry_run_extrinsic,
pallet_revive_primitives::StorageDeposit,
submit_extrinsic,
AccountIdMapper,
ContractMessageTranscoder,
ErrorVariant,
};
Expand Down Expand Up @@ -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()[..]),
})
}

Expand Down

0 comments on commit 7c5d229

Please sign in to comment.