-
Notifications
You must be signed in to change notification settings - Fork 146
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
Allow Setting of EVM Address by EOA #1082
base: main
Are you sure you want to change the base?
Changes from all commits
226d5b1
fe1a3c1
ef50d53
6ab73e0
8f3f51b
b1648e1
32b20dc
0074a38
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,248 @@ | ||
--- | ||
hip: 1082 | ||
title: Allow Setting of EVM Address by EOA | ||
author: Nana Essilfie-Conduah <@Nana-EC> | ||
working-group: Richard Bair <@rbair>, Atul Mahamuni <@atul-hedera>, Ty Smith <ty-swirldslabs>, Serg Metelin <@sergmetelin>, Ali Nikan <@alinik4n>, Greg Scullard <@gregscullard> | ||
requested-by: Hedera community | ||
type: Standards Track | ||
category: Service | ||
needs-council-approval: Yes | ||
status: Draft | ||
created: 11-18-24 | ||
discussions-to: https://github.com/hashgraph/hedera-improvement-proposal/discussions/1070 | ||
updated: 01-21-25 | ||
replaces: 631 | ||
requires: 583 | ||
--- | ||
|
||
## Abstract | ||
|
||
Permits accounts without an alias to set one. | ||
|
||
[HIP 583](https://hips.hedera.com/hip/hip-583) opened the doors for greater account compatibility with EVM flows by | ||
utilizing the account alias to encompass the EVM address. However, given the static nature of the alias and concerns of | ||
complexity, existing accounts with a missing alias value were not permitted to set their alias. | ||
This HIP aims to rectify this by allowing EOAs who have no alias set to set it to an ECDSA key derived evm address | ||
value they can prove ownership of. | ||
|
||
This HIP also replaces the need for [HIP 631: Account Virtual Addresses](https://hips.hedera.com/hip/hip-631) as it | ||
aimed to resolve this issue as well as provide even greater functionality. A form of HIP 631 could be revisited in the | ||
future but not with the goal of providing address equivalence with the EVM. | ||
|
||
## Motivation | ||
|
||
On Ethereum, every account is addressed by an address which is derived from an ECDSA public key. The | ||
EVM also has a specific precompile function, `ecrecover`, that given an ECDSA signature can extract the public key | ||
and convert that public key into an address. This allows an EVM program to figure out the address of | ||
transaction signers. | ||
Hiero accounts are not limited to ECDSA keys, and Hiero accounts can rotate their keys. Both of these | ||
features are not found in Ethereum Externally Owned Accounts (EOA), and present some conflict with the | ||
`ecrecover` precompile. The EVM address alias introduced in [HIP-583](https://hips.hedera.com/hip/hip-583) | ||
was added so that accounts could be created that augmented their account administration key (typically | ||
referred to simply as the "account key" or "key"), with an EVM compatible "alias". This alias could match | ||
exactly what an address would be on Ethereum. The user could call a smart contract, signed with the | ||
private key associated with their alias, and the smart contract could use `ecrecover` to recover the public | ||
key, derive the alias, and lookup the account. | ||
However, not all accounts on Hedera use ECDSA keys or were created after HIP-583 was defined. This HIP adds support for | ||
specifying an alias on an account, so long as that account does not already have a valid alias and the alias to be set | ||
is not already in use on the network. [HIP-631](https://hips.hedera.com/hip/hip-631) defines a more complex set of | ||
rules that would allow multiple aliases to be defined for any given account. This HIP differs from HIP-631 in | ||
that it supports only a single alias. HIP-631 could be implemented compatibly at a later date if desired. | ||
|
||
> Note 1: An ECDSA derived address alias is unique across the network. Only 1 account may utilize a given alias as a | ||
time. Attempts to create an account or update an account to use an already in use alias will be rejected by the network. | ||
|
||
> Note 2: Key rotation and aliases are separate concepts. A valid alias when set is immutable and remains for the | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the alias is immutable once set and the user loses their ECDSA private key, not only are the EVM assets associated with that key lost, but that Hedera account loses its ability to be associated with a different EVM address. The user would have to create a new Hedera account, associate it with a new EVM address, and transfer all Hedera assets from the old account to the new account. Additionally, the immutable binding prevents the use case where an individual or organization has multiple Hedera accounts and wants to transfer the EVM association from one Hedera account to another. I think these limitations need to be documented as a potentially undesirable side effect of an immutable association and a disadvantage of not implementing the full 631. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @edward-swirldslabs you're correct. Do you still suggest calling this out explicitly here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Additionally, this wouldn't change in an implementation of HIP 631, as the alias is still immutable and the new virtual addresses would again be tied up to a single account at a time. If they wanted to move the address though it would be a CryptoUpdate vs a CryptoDelta + CryptoCreate as is the case of the existing network pre and post this HIP. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am fine with this HIP going through as is, but think there should be a new HIP to extend capability to allow for alias rotation:
This way there are no inaccessible assets caused by permanent alias associations. UX problems should be solved at the level of UX, not here. Tracking possible keys whose alias can be activated and tracking asset associations to ECDSA keys so the user doesn't throw away a key with active assets associated is a UX responsibility. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This conversation is resolvable from my perspective. |
||
lifetime of an account. An accounts key however, is mutable and rotatable. Rotating a key has no effect on a users alias. | ||
|
||
## Rationale | ||
|
||
[HIP-631: Account Virtual Addresses](https://hips.hedera.com/hip/hip-631) lays out the challenges faced by | ||
accounts without an ECDSA derived EVM address that want to interact with the EVM in a compatible way while still | ||
supporting key rotation and complex keys. While HIP-631 may be a comprehensive solution to the problem, it | ||
requires complex user flows in wallets that may cause more pain than it resolves. | ||
Instead, an intermediate approach i.e. a HIP 631 Lite (this HIP) could help users without an EVM address. It would | ||
enable accounts to interact with the EVM, even contracts using `ecrecover`, regardless of the public key on its account. | ||
In a sense, the current network already supports the ability to set the EVM address, it just only works during account | ||
creation. Thus, this HIP allows those previously created accounts to be updated and interact with the | ||
EVM as one would expect. | ||
|
||
### Foundational Concepts | ||
|
||
Every account in Hiero has a 20-byte EVM alias by default. It is created **not** by using the key on the account, | ||
which may change, but by computing a "long-zero" alias by taking the account ID (such as 0.0.1234) and | ||
converting it into a 20-byte representation. | ||
Given any account, you can send HBAR, or Tokens, to any other account by using either its Account ID, or by using | ||
its built-in long-zero alias. | ||
A user may specify an alias **in addition to** the long-zero alias. This additional alias is typically based on an | ||
ECDSA key, exactly the same way as it is done in Ethereum. This key may, or may not, be the admin key on the | ||
account. But to use this alias, the user must assert they own the key by signing the transaction that sets the alias | ||
with the corresponding private key of that alias, to prevent "alias squatting" by malicious actors. | ||
When a user interacts with a smart contract, if a user-defined alias based on ECDSA is present, it will be used as | ||
the address by which the smart contract interacts with the account. The smart contract will not be able to use | ||
the long-zero address. If the account does not have a user-defined alias based on ECDSA, then the long-zero | ||
alias will be used to represent the account in the smart contract system. | ||
Accounts with user-defined aliases based on ECDSA work with smart contracts that make use of `ecrecover`. | ||
Accounts that work with smart contracts using their long-zero address will not work with smart contracts that | ||
use `ecrecover`. | ||
Smart contracts can, and frequently do, store in state the EVM address of accounts that use the smart contract. | ||
For this reason, smart contracts **will not work** with accounts whose EVM address changes. This is why | ||
the user-defined alias cannot be changed after it has been set, since this has become the address by which | ||
contracts will refer to the account. | ||
Due to this fact, the user must always sign contract calls with the key associated with the user-defined ECDSA | ||
alias, and must never lose that key. If for any reason the key must be rotated, all value in the account must be | ||
transferred to a new account, possibly incurring custom fees for HTS tokens. This is the same as how it works | ||
on Ethereum. | ||
|
||
<aside> | ||
🚨 **Open Task:** : Add account, address key relationship diagram for clarity | ||
</aside> | ||
|
||
## User stories | ||
|
||
1. As an existing account with an ED key but no EVM address alias, I would like to set an ECDSA derived EVM address | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this user story, wouldn't the user have to update the ED key to the new ECDSA key that corresponds with the EVM address for 'ecrecover' to function? Maybe I'm misunderstanding the phrase 'correct ecrecover functionality', or is the implication that the key is being updated as well There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, the user would just use their ECDSA key in a wallet to sign. So far as the EVM address can be extracted from the signature the ecercover flow would work |
||
alias on my account that will identify my account on the EVM. | ||
2. As an existing account with an EC key but no EVM address alias, I would like to set an ECDSA derived EVM address | ||
alias on my account that will identify my account on the EVM. | ||
3. As an existing account with a complex key but no EVM address alias, I would like to set an ECDSA derived EVM address | ||
alias on my account that will identify my account on the EVM. | ||
4. As an account with an EVM address alias set after creation, I would like to set an evm address override to my | ||
previous long zero address for a `ContractCreate` transaction. | ||
5. As an account with an EVM address alias set after creation, I have already made some smart contract calls using my | ||
long-zero EVM address, and I would like to continue using the long-zero address for specific | ||
`ContractCall` transactions. | ||
6. As a wallet provider, I want to create accounts ahead of time with no alias, and then when the user takes | ||
possession of the account, they can set the key and alias to an ECDSA key for full EVM compatibility | ||
7. As a wallet provider, I want to track which alias an account has used with which smart contract, so that | ||
accounts that had previously used a smart contract with a long-zero address will continue to use the long-zero | ||
address, even if they have a new EVM friendly alias that they use with other accounts. | ||
8. As an existing account with a non-ECDSA key and no EVM address alias, I would like to update my key to an ECDSA key | ||
and set an ECDSA derived EVM address alias on my account that will identify my account on the EVM. | ||
|
||
## Specification | ||
|
||
This HIP requires two changes to consensus nodes: | ||
|
||
1. Modify `CryptoUpdate` transactions so allow the alias to be set to an ECDSA derived address if the alias | ||
has never been set. | ||
2. Modify `ContractCall` to support an "EVM address override", so the long-zero or ECDSA derive alias may | ||
be explicitly used. | ||
|
||
|
||
### Protobuf | ||
```protobuf | ||
message CryptoUpdateTransactionBody { | ||
... | ||
|
||
/** | ||
* An EVM-compatible 20-byte address derived the keccak-256 hash of a ECDSA_SECP256K1 primitive key. | ||
* The transaction MUST be signed by the corresponding private key, and the `alias` on the account MUST | ||
* be unset prior to this call. Once set, this value cannot be changed. | ||
*/ | ||
bytes alias = 19; | ||
} | ||
``` | ||
|
||
The `ContractCall` transaction will allow the user to specify an `evm_address_override` to explicitly specify | ||
the use of the long-zero EVM address to represent the account in the transaction. | ||
|
||
```protobuf | ||
message ContractCallTransactionBody { | ||
... | ||
/** | ||
* The 20-byte EVM address to use for the given transaction. This address must be the Hedera num alias of the account. | ||
*/ | ||
bytes evm_address_override = 5; | ||
} | ||
``` | ||
|
||
No change is needed to expose the evm address as it is covered by the `evm_address` property on `TransactionRecord` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have both
I'm not exactly sure what that means. We should double check on whether we write the evm_address, alias, or both in the transaction record after an update. And we should move this comment into the previous section for |
||
|
||
### HSCS System Contract API | ||
The Hedera Account Service (HAS) system contract will need to be updated to add support for a `setEvmAddressAlias()` | ||
function to expose the `CryptoUpdate` HAPI functionality and allow EOAs to call this logic directly from dApps. | ||
|
||
### SDK | ||
|
||
SDKs will need to update the `AccountUpdateTransaction` to support the `setAlias()` function as it does on | ||
`AccountCreateTransaction`. This will populate the `evm_address` in the `CryptoUpdateTransactionBody`to be submitted. | ||
`ContractExecuteTransaction` will need to support a new `setEVmAddressOverride()` | ||
function to set the `evm_address_override` property on the `ContractCall` transaction. | ||
In addition to updated `AccountUpdateTransaction` functionality the SDK will want to add new methods to | ||
streamline account key specifications by developers with considerations for alias: | ||
- `setKeyWithAlias(ECDSAKey)` - Explicitly calls out the alias will be set and converts the public key to an | ||
address in the background | ||
- `setKeyWithAlias(Key, ECDSAKey)` - Allows for setting the account key and a separate key that the evmAddress | ||
should be derived from. A user must sign the transaction with both keys for this flow to be successful. | ||
- `setKeyWithoutAlias(Key)` - Explicitly calls out that the alias is not set. This is useful for wallets that create | ||
accounts with default keys and rotate keys later. | ||
|
||
### Mirror Node | ||
|
||
Mirror Nodes should be sure to support the setting of the evm address / alias value on an account when processing | ||
a `CryptoUpdate` transaction. As in the case of a `CryptoCreate` the new value can be retrieved from the `evm_address` | ||
property on `TransactionRecord`. | ||
If no custom logic already exists to ignore this Mirror Nodes will be unimpaired by the change | ||
|
||
The Mirror Node API should see no schema changes. `alias` and `evm_address` fields under | ||
`/api/v1/accounts/{idOrAliasOrEvmAddress}` would return the updated alias value. | ||
`/api/v1/contracts/{contractIdOrAddress}/results` and `/api/v1/contracts/results` endpoints would display the updated | ||
`evm_address` field for the account in accordance with record stream entries. | ||
|
||
Note: Historical values of accounts `evm_address` field under the `/api/v1/accounts` and `/api/v1/contracts` should | ||
remain unchanged to ensure correctness based on the block time. | ||
|
||
### Wallets | ||
|
||
The HIP provides opportunities for increased user functionality. | ||
- Wallets are encouraged to create accounts with an ECDSA derived address alias | ||
- Wallets are encouraged to support the ability for users to set an ECDSA derived alias in the future. This may require | ||
wallets to support multiple keys for users that may decide to interchange between addresses. | ||
|
||
## Backwards Compatibility | ||
|
||
Any account interacting with a smart contract using its long-zero address, that subsequently sets an ECDSA derived | ||
alias, MAY need to use the `evm_address_override` when working with that smart contract, if the smart contract | ||
maintained a reference to the account. Alternatively, the user may call the smart contract using the | ||
`evm_address_override` to move assets or data contained within the smart contract from the long-zero address to their | ||
new ECDSA-derived address. | ||
|
||
## Security Implications | ||
|
||
None. | ||
|
||
## How to Teach This | ||
|
||
SDK examples, blogs and tutorials on docs.hedera.com. We recommend updating all samples and tutorials to use | ||
ECDSA derived aliases in all cases with the matching ECDSA key being used as the account admin key, as this is | ||
the expected normal flow. We strongly recommend only **advanced** users set the alias on existing accounts, | ||
and only once their wallets support it. Otherwise, we recommend setting an alias on an existing account only be | ||
undertaken by wallets or dapps that pre-create accounts but never use them, until given to a user where the alias | ||
and key are then set. | ||
|
||
## Reference Implementation | ||
|
||
|
||
## Rejected Ideas | ||
|
||
### Implement HIP 631 | ||
[HIP 631: Account Virtual Addresses](https://hips.hedera.com/hip/hip-631) would have added the ability to add multiple | ||
evm address and specify any one of them as the desired address for use. However, this didn't unblock existing accounts | ||
as the alias remained unset as it was immutable. Additionally the solution offered a complex UX that would | ||
overcomplicated the issue. Focusing on setting aliases that were already `null` and supporting evm address overrides | ||
for accounts that are migrating themselves provides a solution that is focused and less complex. | ||
|
||
## Open Issues | ||
|
||
None | ||
|
||
## References | ||
|
||
- [HIP-583](https://hips.hedera.com/hip/hip-583) | ||
- [HIP-631](https://hips.hedera.com/hip/hip-631) | ||
- [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf) - See Appendix E for `ecrecover` definition | ||
|
||
## Copyright/license | ||
|
||
This document is licensed under the Apache License, Version 2.0 -- see [LICENSE](../LICENSE) or | ||
(https://www.apache.org/licenses/LICENSE-2.0) |
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.
This section and the following two need some additional blank lines to introduce paragraphing in the rendered version.