Skip to content

Commit

Permalink
add checksum implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
ryanleecode committed Apr 1, 2024
1 parent 1852a5b commit 386c4dc
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 10 deletions.
7 changes: 0 additions & 7 deletions Cargo.lock

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

3 changes: 1 addition & 2 deletions signer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ std = ["regex/std", "sp-crypto-hashing/std", "pbkdf2/std", "sha2/std", "hmac/std
# https://github.com/rust-bitcoin/rust-bitcoin/issues/930#issuecomment-1215538699
sr25519 = ["schnorrkel"]
ecdsa = ["secp256k1"]
eth = ["keccak-hash", "secp256k1", "bip32", "ethaddr"]
eth = ["keccak-hash", "secp256k1", "bip32"]

# Make the keypair algorithms here compatible with Subxt's Signer trait,
# so that they can be used to sign transactions for compatible chains.
Expand Down Expand Up @@ -52,7 +52,6 @@ bip32 = { workspace = true, features = ["alloc", "secp256k1"], optional = true }
schnorrkel = { workspace = true, optional = true }
secp256k1 = { workspace = true, optional = true, features = ["alloc", "recovery"] }
keccak-hash = { workspace = true, optional = true }
ethaddr = { workspace = true, optional = true }

# We only pull this in to enable the JS flag for schnorrkel to use.
getrandom = { workspace = true, optional = true }
Expand Down
26 changes: 25 additions & 1 deletion signer/src/eth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,29 @@ impl AsRef<[u8; 65]> for Signature {
#[derive(Debug, Copy, Clone, PartialEq, Eq, codec::Encode)]
pub struct AccountId20(pub [u8; 20]);

impl AccountId20 {
fn checksum(&self) -> String {
let hex_address = hex::encode(self.0);
let hash = keccak(hex_address.as_bytes());

let mut checksum_address = String::with_capacity(42);
checksum_address.push_str("0x");

for (i, ch) in hex_address.chars().enumerate() {
// Get the corresponding nibble from the hash
let nibble = hash[i / 2] >> (if i % 2 == 0 { 4 } else { 0 }) & 0xf;

if nibble >= 8 {
checksum_address.push(ch.to_ascii_uppercase());
} else {
checksum_address.push(ch);
}
}

checksum_address
}
}

impl AsRef<[u8]> for AccountId20 {
fn as_ref(&self) -> &[u8] {
&self.0
Expand All @@ -132,7 +155,7 @@ impl AsRef<[u8]> for AccountId20 {

impl Display for AccountId20 {
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
write!(f, "{}", ethaddr::Address::from_slice(&self.0))
write!(f, "{}", self.checksum())
}
}

Expand Down Expand Up @@ -386,6 +409,7 @@ mod test {
hex!("0f02ba4d7f83e59eaa32eae9c3c4d99b68ce76decade21cdab7ecce8f4aef81a");
const KEY_3: [u8; 32] =
hex!("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");

#[test]
fn test_account_derivation_1() {
let kp = Keypair::from_seed(KEY_1).expect("valid keypair");
Expand Down

0 comments on commit 386c4dc

Please sign in to comment.