Skip to content

Conversation

@partylikeits1983
Copy link
Contributor

@partylikeits1983 partylikeits1983 commented Jan 7, 2026

This PR implements conversion functions for Solidity address type (bytes20) to Miden AccountId & Address.

Concretely what functionality does this PR add?

This PR adds Rust conversion functions to convert AccountId into solidity address type and back. Additionally there is a masm procedure to convert the address type represented as [5; Felt] (part of CLAIM note inputs) into AccountId. TLDR; part of bridging EVM<>Miden

NOTE:
This PR does not assume it possible to represent any arbitrary Ethereum address as an AccountId.

This PR adds functions to be able to represent an AccountId as an Ethereum address (20 byte hex string) and adds conversion functions which can take this very specific ethereum address which represents an AccountId and convert it back to AccountId.

Why?

Because to bridge from EVM to Miden, a user will call the bridgeAsset() function on an EVM chain. The destination address on Miden will be this ethereum address which represents an AccountId on Miden.


Builds on top of #2188

Added Rust helper functions:

  • account_id_to_ethereum_address_hex: AccountId -> Solidity address type
  • ethereum_address_hex_to_account_id: Solidity address type to AccountId
  • ethereum_address_to_felts: Solidity address type to address[5] (part of CLAIM note inputs)

MASM helper procedures:

  • hashing a address[5] type with keccak256 (might not be necessary, but this was a first test before implementing Implement getLeafValue() in MASM #2220)

  • converting address[5] type into an AccountId type

Resolves: #2229

@partylikeits1983 partylikeits1983 changed the title Ajl solidity type conversions Solidity address <> Miden AccountId helper functions Jan 7, 2026
@partylikeits1983 partylikeits1983 self-assigned this Jan 7, 2026
@partylikeits1983 partylikeits1983 added agglayer no changelog This PR does not require an entry in the `CHANGELOG.md` file labels Jan 7, 2026
@partylikeits1983 partylikeits1983 changed the base branch from agglayer to ajl-claim-bridge-in January 8, 2026 22:16
Base automatically changed from ajl-claim-bridge-in to agglayer January 8, 2026 22:55
@partylikeits1983 partylikeits1983 force-pushed the ajl-solidity-type-conversions branch 2 times, most recently from fe30e67 to cf2dd5e Compare January 9, 2026 00:12
@partylikeits1983 partylikeits1983 force-pushed the ajl-solidity-type-conversions branch from cf2dd5e to 46143c8 Compare January 9, 2026 00:15
@partylikeits1983 partylikeits1983 marked this pull request as ready for review January 9, 2026 00:18
Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thank you. I left some more comments inline.

Copy link
Contributor

@mmagician mmagician left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a discrepancy between u32 and u64 usage.
IIUC, the changes in this PR propose a representation of the address such that the first element is zero, and the rest are u64s (w/o overflowing the max field size).

However, for hashing the elements with keccak, which is needed as part of #2220, we need all elements to fit inside u32s. And then we necessarily need all 5 u32s to be non-zeros to represent 160 bytes of the Ethereum address.

Let me know if this makes sense or whether I'm missing some context.

Copy link
Collaborator

@igamigo igamigo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still getting familiar with some of this code but leaving a couple of comments

@partylikeits1983
Copy link
Contributor Author

partylikeits1983 commented Jan 9, 2026

@mmagician @igamigo

I clarified the byte/u32-limb/64-bit word representations in doc comments (and aligned Rust limb ordering with MASM), added explicit “no mod-reduction” checks when constructing felts from 64-bit words, and switched the AccountId -> EthAddress conversion to From<AccountId> since it’s infallible.

I also simplified the ethereum_address_to_account_id procedure

Copy link
Contributor

@mmagician mmagician left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unless I'm missing something, I have the same comment as before: this needs a rather fundamental rework still, because it is not possible to represent 20 non-zero bytes corresponding to an Ethereum address with 4 u32s (i.e. 128 bits), so the PR is conceptually incorrect.

Copy link
Contributor

@mmagician mmagician left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, with some small outstanding comments re: naming, efficiency and function structuring.
It would be good to still align on the naming & structure before merging, but otherwise ✅

Copy link
Contributor

@bobbinth bobbinth left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Thank you! I left some more comments inline. Once these are addresses, we should be good to go (but also would be good to get @mmagician's sign-off).

Comment on lines +54 to +59
#! The Ethereum address format is represented as 5 u32 limbs (20 bytes total) in *little-endian limb order*:
#! addr0 = bytes[16..19] (least-significant 4 bytes)
#! addr1 = bytes[12..15]
#! addr2 = bytes[ 8..11]
#! addr3 = bytes[ 4.. 7]
#! addr4 = bytes[ 0.. 3] (most-significant 4 bytes)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason, I had previously thought that Ethereum addresses are natively in little-endian order - but it seems like they are in big-endian order. So, does this mean that to get the address in this form we need to reverse the bytes?

If so, it may be worth going back to the "native" order of Ethereum addresses - i.e., addr0 = bytes[0..3].

@mmagician mmagician merged commit 2cbfeb1 into agglayer Jan 16, 2026
15 checks passed
@mmagician mmagician deleted the ajl-solidity-type-conversions branch January 16, 2026 08:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agglayer no changelog This PR does not require an entry in the `CHANGELOG.md` file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants