Skip to content

Commit

Permalink
allow multi account conversion (polkadot-evm#1295)
Browse files Browse the repository at this point in the history
  • Loading branch information
siyukok authored May 23, 2024
1 parent 2499d18 commit 638a858
Showing 1 changed file with 73 additions and 6 deletions.
79 changes: 73 additions & 6 deletions primitives/account/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
use scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
// Substrate
use sp_core::{ecdsa, RuntimeDebug, H160, H256};
use sp_core::{crypto::AccountId32, ecdsa, RuntimeDebug, H160, H256};
use sp_io::hashing::keccak_256;
use sp_runtime::MultiSignature;
use sp_runtime_interface::pass_by::PassByInner;

/// A fully Ethereum-compatible `AccountId`.
Expand All @@ -31,7 +32,7 @@ use sp_runtime_interface::pass_by::PassByInner;
#[derive(Encode, Decode, MaxEncodedLen, TypeInfo)]
pub struct AccountId20(pub [u8; 20]);

#[cfg(feature = "std")]
#[cfg(feature = "serde")]
impl_serde::impl_fixed_hash_serde!(AccountId20, 20);

#[cfg(feature = "std")]
Expand Down Expand Up @@ -84,6 +85,19 @@ impl From<[u8; 20]> for AccountId20 {
}
}

impl<'a> TryFrom<&'a [u8]> for AccountId20 {
type Error = ();
fn try_from(x: &'a [u8]) -> Result<AccountId20, ()> {
if x.len() == 20 {
let mut data = [0; 20];
data.copy_from_slice(x);
Ok(AccountId20(data))
} else {
Err(())
}
}
}

impl From<AccountId20> for [u8; 20] {
fn from(val: AccountId20) -> Self {
val.0
Expand All @@ -102,6 +116,30 @@ impl From<AccountId20> for H160 {
}
}

impl AsRef<[u8]> for AccountId20 {
fn as_ref(&self) -> &[u8] {
&self.0[..]
}
}

impl AsMut<[u8]> for AccountId20 {
fn as_mut(&mut self) -> &mut [u8] {
&mut self.0[..]
}
}

impl AsRef<[u8; 20]> for AccountId20 {
fn as_ref(&self) -> &[u8; 20] {
&self.0
}
}

impl AsMut<[u8; 20]> for AccountId20 {
fn as_mut(&mut self) -> &mut [u8; 20] {
&mut self.0
}
}

impl From<ecdsa::Public> for AccountId20 {
fn from(pk: ecdsa::Public) -> Self {
let decompressed = libsecp256k1::PublicKey::parse_compressed(&pk.0)
Expand All @@ -114,8 +152,23 @@ impl From<ecdsa::Public> for AccountId20 {
}
}

#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))]
#[derive(Eq, PartialEq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)]
impl From<[u8; 32]> for AccountId20 {
fn from(bytes: [u8; 32]) -> Self {
let mut buffer = [0u8; 20];
buffer.copy_from_slice(&bytes[..20]);
Self(buffer)
}
}

impl From<AccountId32> for AccountId20 {
fn from(account: AccountId32) -> Self {
let bytes: &[u8; 32] = account.as_ref();
Self::from(*bytes)
}
}

#[derive(Eq, PartialEq, Clone, RuntimeDebug, Encode, Decode, TypeInfo)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct EthereumSignature(ecdsa::Signature);

impl sp_runtime::traits::Verify for EthereumSignature {
Expand All @@ -140,9 +193,23 @@ impl sp_runtime::traits::Verify for EthereumSignature {
}
}

impl From<MultiSignature> for EthereumSignature {
fn from(signature: MultiSignature) -> Self {
match signature {
MultiSignature::Ed25519(_) => {
panic!("Ed25519 not supported for EthereumSignature")
}
MultiSignature::Sr25519(_) => {
panic!("Sr25519 not supported for EthereumSignature")
}
MultiSignature::Ecdsa(sig) => Self(sig),
}
}
}

impl EthereumSignature {
pub fn new(s: ecdsa::Signature) -> Self {
EthereumSignature(s)
Self(s)
}
}

Expand Down Expand Up @@ -223,4 +290,4 @@ mod tests {
let account_fmt = format!("{}", account);
assert_eq!(account_fmt, "0xE04CC55ebEE1cBCE552f250e85c57B70B2E2625b");
}
}
}

0 comments on commit 638a858

Please sign in to comment.