Skip to content
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

Ethereum address implicit accounts #9969

Closed
wants to merge 4 commits into from

Conversation

staffik
Copy link
Contributor

@staffik staffik commented Oct 19, 2023

Part of near/NEPs#498

Approach:

  • Add AccountType enum: NamedAccount, NearImplicitAccount, or EthImplicitAccount.
  • Parse 40 characters long hexadecimal addresses prefixed with '0x' as EthImplicitAccount.
  • Add derive_account_id_from_public_key function that returns '0x' + keccak256(public_key)[12:32].hex() if the public key type is SECP256K1.
  • action_implicit_account_creation_transfer: in case of EthImplicitAccount creates an account without an access key. Fees are the same as for NearImplicitAccount minus ActionCosts::add_full_access_key.
  • verify_and_charge_transaction: if access key not found for transaction.public_key, and signer_id is EthImplicitAccount, and derive_account_id_from_public_key(transaction.public_key) == *signer_id, then add full access key to that account, with nonce equal to the transaction's nonce.
  • tools/mirror: EthImplicitAccount account has to be mapped to a new address, for which we know the secret key. Because the new address has to be derived from the secret key, we need to map the existing ETH address to a new secret key first. Because the ETH address length is 20 bytes, and secret key length is 32 bytes, the mapped secret key is less secure.

To do:

  • Make test_transaction_hash_collision_for_eth_implicit_account_fail passes.
  • Make meta_tx_create_eth_implicit_account test passes.
  • Verify why test_trying_to_create_eth_implicit_account_runtime passes, because it probably shouldn’t.
  • Discuss what nonce should be used for a transaction from EthImplicitAccountwhen there is no access key added to that account.
  • Test ETH-implicit addresses in Python tests (Nayduck).
  • Verify if the fuzzing testing util works correctly (runtime-tester).
  • Verify if the fork-network tool works correctly.
  • Verify if the mirror tool works correctly. First discuss the way ETH addresses (and keys) are mapped and whether it is secure enough.
  • Change protocol version, update documentation.

@staffik staffik force-pushed the eth-wallet-n-transaction-support branch 2 times, most recently from 3981e27 to 3e47bf0 Compare October 19, 2023 15:03
core/account-id/src/lib.rs Outdated Show resolved Hide resolved
core/account-id/src/lib.rs Outdated Show resolved Hide resolved
@staffik staffik force-pushed the eth-wallet-n-transaction-support branch from dd17891 to 36a58be Compare October 23, 2023 14:00
@staffik staffik force-pushed the eth-wallet-n-transaction-support branch 3 times, most recently from bea1220 to 3b6c95e Compare October 26, 2023 14:46
Copy link
Contributor Author

@staffik staffik left a comment

Choose a reason for hiding this comment

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

Questions and things left to be done.
@birchmd can you look at some of the questions?

@@ -502,6 +502,7 @@ async fn construction_derive(
let public_key: near_crypto::PublicKey = (&public_key)
.try_into()
.map_err(|_| errors::ErrorKind::InvalidInput("Invalid PublicKey".to_string()))?;
// TODO Rosetta-RPC: should we handle ETH-implicit accounts here?
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should we handle ETH-implicit accounts here?

@@ -127,11 +143,35 @@ impl AccountId {
/// assert!(!alice_app.is_sub_account_of(&near_tla));
/// ```
pub fn is_sub_account_of(&self, parent: &AccountId) -> bool {
// TODO Is it ok that an account could be a sub account of an EthImplicitAccount ?
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is it ok that an account could be a sub account of an ETH-implicit account?

);
}

// TODO, does not pass, see `verify_and_charge_transaction(...)`
Copy link
Contributor Author

@staffik staffik Oct 26, 2023

Choose a reason for hiding this comment

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

TODO: does not pass because a transaction is replayed.

ProcessTxResponse::InvalidTx(InvalidTxError::InvalidNonce { .. })
);
}

/// Test that duplicate transactions from implicit accounts are not rejected until protocol upgrade.
// TODO Since we set access key nonce differently when creating ETH-implicit accounts, we cannot repeat the below test for ETH-implicit account ?
Copy link
Contributor Author

@staffik staffik Oct 26, 2023

Choose a reason for hiding this comment

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

TODO Verify after we decide on what nonce should be used by user.

meta_tx_create_implicit_account(near_implicit_test_account());
}

// TODO make the test passes
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO

@@ -517,6 +518,7 @@ impl Scope {
Ok(self.accounts[self.accounts.len() - 1].clone())
}

// Test-utils/fuzzing: used for runtime tests, make sure everything is ok.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO

AccountType::NearImplicitAccount => {
match key {
PublicKey::ED25519(k) => SecretKey::ED25519(map_ed25519(k, secret)),
// TODO Is it true?
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does NEAR-implicit account can only have ED25519 access key added?

AccountType::EthImplicitAccount => {
match key {
PublicKey::SECP256K1(_) => map_secp256k1_from_eth_address(account_id, secret),
// TODO Is it true?
Copy link
Contributor Author

@staffik staffik Oct 26, 2023

Choose a reason for hiding this comment

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

Does ETH-implicit account can only have SECP256K1 access key added?

Comment on lines +120 to +121
// TODO Deriving secret keys from ETH addresses reduces potential entropy.
// However, it is only for the Mirror tool. Are we ok with that?
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ETH address is 20 bytes length, shorter than public key (32 bytes) from which it is derived.
It reduces potential entropy so it has security impact.
But mirror needs to map ETH address to a new one, and we first need to map the address to a new public key, from which we then derive a new ETH address.
Are we ok with the security impact for the mirror tool?

let public_key = PublicKey::from_implicit_account(&target_account)
.expect("must be implicit");
nonce_updates.insert((target_account, public_key));
// TODO Tools/Mirror: For ETH-implicit account we do not add access key on creation, but make sure it is ok for Mirror.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

TODO

@staffik staffik force-pushed the eth-wallet-n-transaction-support branch from 3b6c95e to f7b9af7 Compare October 27, 2023 09:01
@staffik
Copy link
Contributor Author

staffik commented Oct 27, 2023

Moving to #10018, in order to split this PR into several smaller PRs.

@staffik staffik closed this Oct 27, 2023
staffik added a commit to near/near-account-id-rs that referenced this pull request Nov 3, 2023
Part of near/nearcore#10018.

This PR introduces some changes from
near/nearcore#9969 laying groundwork for real
protocol changes to be done in a separate PR.

Summary:
- Add `AccountType` enum: `NamedAccount`, `NearImplicitAccount`, or
`EthImplicitAccount`.
- Parse 40 characters long hexadecimal addresses prefixed with `'0x'` as
`EthImplicitAccount`.
github-merge-queue bot pushed a commit that referenced this pull request Nov 6, 2023
Part of #10018.

This PR introduces some changes from
#9969 laying groundwork for real
protocol changes to be done in a separate PR.
Some changes might look redundant (especially `match
receiver_id.get_account_type() { ...`) but they will make it easier to
read changes done in the next PR.

Changes done in [near-account-id
1.0.0-alpha.2](near/near-account-id-rs#14):
- Add `AccountType` enum: `NamedAccount`, `NearImplicitAccount`, or
`EthImplicitAccount`.
- Parse 40 characters long hexadecimal addresses prefixed with `'0x'` as
`EthImplicitAccount`.
- `AccountType::is_implicit()` returns true for both
`NearImplicitAccount` and `EthImplicitAccount`.

Summary of this PR:
- Bump version of `near-account-id` to `1.0.0-alpha.2`.
- Do not use `is_implicit()` for now, as we do not want to treat
`EthImplicitAccount` as implicit as for now.
- Add `derive_account_id_from_public_key` function that currently only
supports `ED25519` key type and returns hex-encoded copy of the key.
- Refactor/rename tests a bit.
@Ekleog-NEAR Ekleog-NEAR deleted the eth-wallet-n-transaction-support branch March 29, 2024 14:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants