Skip to content

feat: custom runtime functions to generate deterministic Eth address from an MSA ID #2358

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 33 commits into from
May 7, 2025

Conversation

JoeCap08055
Copy link
Collaborator

@JoeCap08055 JoeCap08055 commented Apr 24, 2025

Goal

This PR adds some internal pallet functions and custom runtime to deterministically generate an Ethereum address from an MSA ID, and vice versa.

The general approach is:

  • Use a domain separator prefix to eliminate any possible conflict with addresses generated by CREATE2
  • Use a salt that is the hash of the string "MSA Generated"
  • Take the last 20 bytes of the hash of (prefix + MSA ID + salt)
  • If returning a string for the runtime query, pass through an ERC-55 checksum algorithm to alter the returned hex string

Note, although addresses generated in this manner cannot be reversed to recover the related MSA ID, they can be verified (ie, given an address and an MSA ID, we can determine whether or not the address is the result of applying the above algorithm to the MSA ID). It is not envisioned that there would ever be an on-chain requirement to recover the MSA ID from the address; if such a use case was desired for off-chain purposes, it would be relatively trivial to populate a static lookup table mapping all known or possible MSAs to their corresponding address, or vice-versa.

Closes #2353
Closes #2352

Discussion

  • Q0: Currently returning ASCII bytes; or do we want to return the binary address bytes?
    • A: Now returning a struct containing both the binary address & checksummed string

Checklist

  • Updated Pallet Readme?
  • Updated js/api-augment for Custom RPC APIs?
  • Design doc(s) updated?
  • Unit Tests added?
  • e2e Tests added?
  • Benchmarks added?
  • Spec version incremented?

Copy link

codecov bot commented Apr 24, 2025

Codecov Report

Attention: Patch coverage is 96.96970% with 1 line in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
common/primitives/src/msa.rs 0.00% 1 Missing ⚠️
Files with missing lines Coverage Δ
pallets/msa/src/lib.rs 92.25% <100.00%> (+0.32%) ⬆️
common/primitives/src/msa.rs 87.95% <0.00%> (-1.08%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release metadata-version-not-incremented Metadata has changed since the latest full release, but the version has not been incremented labels Apr 24, 2025
@enddynayn
Copy link
Collaborator

Would you mind adding a brief explanation to the PR description about why this feature is being introduced?

Copy link
Collaborator

@aramikm aramikm left a comment

Choose a reason for hiding this comment

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

There are a number of questions around this approach:

  1. What is the scope and goal of these ETH addresses? Are we expecting to use these in the bridges to send money to and from Ethereum?
  2. Ideas about generation
    1. I don't like any addresses prefixed or postfixed with zeros since those are likely the precompiles in some chain or another
    2. Another alternative might be to have the first or last 8 bytes for MsaID and either use it with some kind of tag to hash or use as a seed to generate the remaining 12 bytes.
    3. Another alternatives would be that If they behave like a smart contract then maybe it should get generated like a smart contract or at least in a similar way.
    4. In general, l think there might be better ways to generate these addresses that are more natural with more entropy. I think it would worth doing some research since we are going to be stuck with them for a long time.
  3. We should probably use something similar trait AccountAddressMapper

@JoeCap08055
Copy link
Collaborator Author

There are a number of questions around this approach:

  1. What is the scope and goal of these ETH addresses? Are we expecting to use these in the bridges to send money to and from Ethereum?
  • In order to be able to have MSAs receive tokens at a known address, that can be deterministically generated and operate with the balances pallet normall
  • Since there will be no private key associated with this address, it will be impossible to transfer tokens away from the MSA address except by such methods as we specifically provide
  1. Ideas about generation

    1. I don't like any addresses prefixed or postfixed with zeros since those are likely the precompiles in some chain or another
  • We can prefix/postfix with whatever value we want
  1. Another alternative might be to have the first or last 8 bytes for MsaID and either use it with some kind of tag to hash or use as a seed to generate the remaining 12 bytes.
  • Using a hash instead of a known pre/post-fix makes it difficult to determine that the key was generated with this algorithm & therefore reverse the process. However, if we determine reversal (ie, get MSA ID from address) is not important, or if we want to simply maintain a mapping (perhaps off-chain), then we could fill with a hash.
  1. Another alternatives would be that If they behave like a smart contract then maybe it should get generated like a smart contract or at least in a similar way.
  2. In general, l think there might be better ways to generate these addresses that are more natural with more entropy. I think it would worth doing some research since we are going to be stuck with them for a long time.
  • Is entropy important just for an address, as long as it's not possible to have a conflict in the address space? Remember, it's not an actual public key, just an address to send tokens to.
  1. We should probably use something similar trait AccountAddressMapper

@github-actions github-actions bot removed metadata-changed Metadata has changed since the latest full release metadata-version-not-incremented Metadata has changed since the latest full release, but the version has not been incremented labels Apr 24, 2025
@JoeCap08055
Copy link
Collaborator Author

Would you mind adding a brief explanation to the PR description about why this feature is being introduced?

It's in the linked issue #2353 and its parent #2351

@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release metadata-version-not-incremented Metadata has changed since the latest full release, but the version has not been incremented labels Apr 24, 2025
@github-actions github-actions bot removed metadata-changed Metadata has changed since the latest full release metadata-version-not-incremented Metadata has changed since the latest full release, but the version has not been incremented labels Apr 24, 2025
@wesbiggs
Copy link
Contributor

Can any user can send tokens to these addresses at any time (as long as they know the MSA and the algorithm to determine the account)? Or will the accounts be marked in some way that prevents this from happening other than via chain code?

If not, two cases to consider, neither of which may prevent a threat, but just thinking it through...

  1. Send tokens to a known MSA (prior to that MSA receiving a reward)
  2. Send tokens to a not-yet-allocated MSA which is later allocated

@wilwade
Copy link
Collaborator

wilwade commented Apr 25, 2025

@wesbiggs

Can any user can send tokens to these addresses at any time (as long as they know the MSA and the algorithm to determine the account)?

This would be the idea. So yes, it is possible for anyone to send tokens to any MSA, even future MSAs, (although there is no way to specifically select an MSA Id or batch transactions in such a way that ensures a specific MSA Id at this time)

@aramikm aramikm self-requested a review April 25, 2025 21:42
@harry-evans
Copy link
Collaborator

Most of this sounds fine to me. I don’t love the idea of being able to send tokens to a non existent MSA, given that they are assigned vs claimed (token accounts are “claimed” by proving you have the private key, while MSAs are assigned based on the next available number/id).

I don’t think that really matters, but in ideal world that would be an obvious error that we would just reject when the txn was submitted. Not sure it is worth the work to implement or the runtime efficiency overhead, but that is the only thing that I would really change.

@JoeCap08055
Copy link
Collaborator Author

OK, rethinking the implementation of this based on some conversation.

We could use MultiAddress<AccountId, Address>::Address20, which is a tuple wrapper for [u8; 20].

However, what might be even better is:
H160 from pallet_revive, which is just an alias for struct (pub [u8; 20]), and as a bonus is the exact type returned from pallet_revive::create2, which we could leverage to generate addresses from MSA IDs.

Downside of using create2: it's not reversible (but it is verifiable). Since I don't really see any on-chain use cases for reversing the transformation to recover the original MSA ID, I think this is fine.

So, if we use create2, it takes the following inputs, for which we presumably will need to create some values:

  • deployer address (should we create a dummy address for this, as a constant?)
  • code (OK to be zero bytes? It's just going to get hashed.)
  • input_data (MSA ID goes here to be hashed?)
  • salt (perhaps 'MSA Generated Address'?)

@github-actions github-actions bot added the metadata-changed Metadata has changed since the latest full release label Apr 29, 2025
@github-actions github-actions bot added the metadata-changed Metadata has changed since the latest full release label May 6, 2025
@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release and removed metadata-changed Metadata has changed since the latest full release labels May 6, 2025
Copy link
Collaborator

@enddynayn enddynayn left a comment

Choose a reason for hiding this comment

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

👍 great!

Copy link
Collaborator

@aramikm aramikm 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, added some nits

@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release and removed metadata-changed Metadata has changed since the latest full release labels May 6, 2025
@github-actions github-actions bot added metadata-changed Metadata has changed since the latest full release and removed metadata-changed Metadata has changed since the latest full release labels May 6, 2025
@github-actions github-actions bot removed the metadata-changed Metadata has changed since the latest full release label May 6, 2025
@JoeCap08055 JoeCap08055 enabled auto-merge (squash) May 6, 2025 20:22
@JoeCap08055 JoeCap08055 disabled auto-merge May 6, 2025 20:41
@github-actions github-actions bot added the metadata-changed Metadata has changed since the latest full release label May 6, 2025
@github-actions github-actions bot removed the metadata-changed Metadata has changed since the latest full release label May 6, 2025
Copy link
Collaborator

@shannonwells shannonwells left a comment

Choose a reason for hiding this comment

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

Nothing blocking, leave it up to you to incorporate any suggestions, otherwise GTG!

@github-actions github-actions bot added the metadata-changed Metadata has changed since the latest full release label May 6, 2025
@github-actions github-actions bot removed the metadata-changed Metadata has changed since the latest full release label May 7, 2025
@JoeCap08055 JoeCap08055 enabled auto-merge (squash) May 7, 2025 13:55
@github-actions github-actions bot added the metadata-changed Metadata has changed since the latest full release label May 7, 2025
@JoeCap08055 JoeCap08055 merged commit f1e6b7e into main May 7, 2025
31 checks passed
@JoeCap08055 JoeCap08055 deleted the feat/derive-eth-address-from-msa branch May 7, 2025 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
metadata-changed Metadata has changed since the latest full release
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Derive an Ethereum address for an MSA Given that I know an MSA Id, I can send that MSA tokens
8 participants