-
Notifications
You must be signed in to change notification settings - Fork 650
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
ETH-implicit account support (old design) #10056
Conversation
a96103c
to
d0a8e78
Compare
8e150b8
to
6e1c7b1
Compare
f7ba202
to
861bdca
Compare
0713461
to
48102ce
Compare
6c79934
to
da30e31
Compare
More questions:
@birchmd wdyt? |
2c3f3a3
to
d10bfc5
Compare
7cb592f
to
1206d09
Compare
18de969
to
ca32c1a
Compare
Sorry accidentally closed PR and reopened :( @staffik , please re-request review when ready so it can get attention from reviewers |
ca32c1a
to
2e74bc6
Compare
// TODO(eth-implicit) This functionality will be managed by `Wallet Contract` | ||
// and no access key will be added. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this code should be removed from this PR instead of being added now only to be removed later when we push the Wallet Contract. Adding and removing code creates unnecessary churn in my opinion. For example, not having this check_access_key
function means we don't need the InvalidPublicKeyForEthAddress
variant of InvalidAccessKeyError
, and we don't need the big new integration tests around handling nonces at the access key level. I didn't look into it too deeply, but maybe we will also be able to remove some of the places in the runtime where the protocol version is being newly passed in as an argument.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Without the Wallet Contract
placeholder I would have to remove perhaps the entire code from this PR to keep CI happy. I think there are 2 options:
- We merge this PR as a basis for the next PR.
- I close this PR and work on a new one with
Wallet Contract
in mind from the beginning.
I have no strong opinion which approach is better.
The first option requires more reviewers time but it can spot some issues earlier (by reviewers or nightly testing).
The second option looks clearer, as it be better visible within one PR what changes, and save reviewers time now.
Feel free to just leave some comments, that would help in both options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the second approach better. Not just to save review time, but to save you time as well. I think starting fresh from the master branch should be easier for the new PR than trying to remove code you just added.
The overall structure of this PR looks good to me. I don't have any comments about this PR which might inform you for the new PR.
Closed, will reintroduce some changes in a new PR following the new design, for ease of development and reviewing. |
## Context Tracking issue: #10018. Design: near/NEPs#518 (comment). ### Goal We want the NEAR Protocol's ecosystem to be closer with Ethereum by integrating Web3 wallet support. To accomplish that, some changes on the protocol level are needed with an emphasis on user experience continuity. Following the design, the main change on the protocol level would be to have ETH-style addresses managed by a new `Wallet Contract` integrated into the protocol. For seamless onboarding of EVM users, the contract will be free of charge. ### Previous work This PR is built on top of a [preparatory PR](#10020). It reintroduces some changes from a [closed PR](#10056) that follows an old design. ## Summary On a transfer to an ETH-implicit address: 1. An account is created at this address. 2. The account does not have any access key added. Thus, it is not possible to make a transaction from this account directly. 3. The Wallet Contract (as a part of the protocol) is deployed to the account. For this PR, an empty smart contract is used as a placeholder. ### Changes - On a transfer to an ETH-implicit address, if an account does not exist yet at this address: - Create account at this address. - Deploy a `Wallet Contract` placeholder (empty contract now) to this account. - Update fee for a transfer to an ETH-implicit address to include account creation cost. `Wallet Contract` deployment is free of charge (user only pays for an increased storage). - Tests: - Test whether it is possible to create an ETH-implicit account by making a transfer to that address, and whether further funds can be sent to this account. - Test that no access key is added to an ETH-implicit account (the account is locked) and in consequence no transactions are possible from this account. - Guard the changes with `EthImplicitAccounts` protocol feature and `eth_implicit_accounts` runtime config flag. ## Next work - Discuss how the `Wallet Contract` should be integrated into the protocol for efficiency. - Use the `Wallet Contract` placeholder implementation that allows to transfer funds only.
Part of #10018.
(Note 2023-11-17) This PR follows the old design. The next PR will incorporate changes required by the new design.
Regarding changes on the protocol level, the new design is different from the old one by:
Wallet Contract
(see the new design NEP) should be added.Wallet Contract
that manages the account.This PR introduces real protocol changes for supporting ETH-implicit addresses, following the preparatory PR.
On transfer to a ETH-implicit address, an account is added (if does not exist yet) on chain, without access key yet.
On a transaction from that address, if there is no access key yet, and the address is
'0x' + keccak(pub_key)[12:32]
derived from the public key, a full access key is added to that account with nonce set to the transaction nonce.Summary:
InvalidPublicKeyForEthAddress
error, that means that an ETH-implicit address was not derived from the provided public key.derive_account_id_from_public_key
function that returns'0x' + keccak256(public_key)[12:32].hex()
if the public key type isSECP256K1
.action_implicit_account_creation_transfer
: in case ofEthImplicitAccount
creates an account without an access key.NearImplicitAccount
minusActionCosts::add_full_access_key
.verify_and_charge_transaction
,validate_delegate_action_key
: if access key not found fortransaction.public_key
, andsigner_id
isEthImplicitAccount
that was derived fromtransaction.public_key
then add full access key to that account. Newly created access key will have nonce set to transaction nonce.account_id.get_account_type().is_implicit()
now. See Setup for ETH-implicit accounts #10020 (comment).checked_feature!("stable", EthImplicit, protocol_version)
and/orprotocol_feature_eth_implicit
(if necessary).