Title: Increasing_address_size_from_20_to_32_bytes
Category: Working_Groups

Author: vbuterin
Date: 2021-03-06T16:06:13.290Z

Why increase the address size?
At some point, perhaps soon, we are going to have to increase the address size from 20 bytes to 32 bytes. Some reasons for this include:

Adding an address space ID if we use a state expiry scheme that requires it

Adding a shard ID if we have multiple EVM-capable execution shards
Security: 20 bytes is not secure enough

To elaborate on (3), current 20 byte (160 bit) addresses only provide 80 bits of collision resistance, meaning that someone can spend 2**80 computing work to generate two pieces of contract init code (or (sender, ID) pairs, or one piece of contract code and one EOA private key) that have the same address. 2**80 will soon be within reach of sophisticated attackers; the bitcoin blockchain has already made more than 2**90 hashes.
This possibility of attack means that if someone gives you an address that is not yet on-chain, and claims that the address has some property, they cannot prove that the address actually has that property, because they could have some second way of accessing that account. The properties of addresses become more complicated: you can trust an address if either (i) it is on chain, or (ii) you personally created it; for example, an organization cannot safely receive funds at a multisig unless that multisig has already been published on-chain, because whoever was the last to provide their public key could have chosen their private key in such a way as to make the address also a valid EOA controlled by themselves.
These problems can be eliminated if we go up to 32 byte addresses, increasing the hash length and simultaneously adding shard and epoch data and a version number to add forward compatibility for the future. The challenge, however, is that existing contracts are designed to accept 20 byte addresses. Solidity type-checks addresses to verify that they are in range, and byte-packs addresses to save storage space. This document attempts to give some proposals for how this can be done reasonably backwards-compatibly.

Proposal
We make a new address schema as follows:
Byte 0    : Version byte (must be 1 for now)
Byte 1-2  : Must be zero (could be shard number in the future)
Byte 3-5  : Epoch number (0 <= e <= 16777215)
Byte 6-31 : 26 byte hash

For example, the private key 0x0000...01 should correspond to the new-style address:
0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF
Note that given a 32-byte value, it’s always possible to tell if it’s new-style or old-style: new-style addresses have the version byte set to 1 or higher, so they are >= 2**160, whereas old-style addresses are < 2**160.
We add:

A new opcode, CREATE3, that is capable of generating 32 byte addresses. If we add address space separation, it would take the desired epoch number as an input, allowing contracts to create new contracts in their preferred address space
A new transaction type that makes the msg.sender a new-style address, and if it’s a contract creation, creates the contract at a new-style address
A new opcode, BIGCALLER, that returns the address of the caller regardless of whether it’s new-style or old-style (Solidity and other langs would be expected to treat the output as a BigAddress type which would be an alias for bytes32 instead of bytes20)

The CALLER opcode, if the caller is new-style, instead converts the address into a “compressed address”:
DOMAIN_SEPARATION_KEY = b'\xfeBLAHBLAHBLAH'

def get_compressed_address(address: 'bytes32'):
    if address[:12] == bytes([0] * 12):
        return address[12:]
    return sha3(DOMAIN_SEPARATION_KEY + address)[12:]

It also immediately saves the mapping from the compressed address to the original address in a translation table. That is, it sets storage slot compressed_address of contract TRANSLATION_TABLE_ADDR to address.
The *CALL and *EXT opcodes, if they encounter an old-style destination address, attempt to decompress it:
DOMAIN_SEPARATION_KEY = b'\xfeBLAHBLAHBLAH'
TRANSLATION_TABLE_ADDR = bytes([1] + [0, 0, 0, 0, 0] + [0] * 25 + [255])
ZERO_CHUNK = bytes32([0] * 32)

def get_decompressed_address(state: 'EthereumState', address: 'bytes32'):
    # If the address is already new-style, just call that address directly
    if address[:12] != bytes([0] * 12):
        return address
    elif state[TRANSLATION_TABLE_ADDR][address] != ZERO_CHUNK:
        return state[TRANSLATION_TABLE_ADDR][address]
    else:
        return address

This ensures that new-style addresses would be able to interact with pre-existing contracts, maintain persistent identities, hold tokens, etc.

Example
Suppose that Alice has a new-style address ALICE_LONG and the compressed form is ALICE_SHORT. Alice tries to interact with a simple auction contract, AUCTIONEER (which is pre-existing, so it uses the CALLER opcode).

Alice calls AUCTIONEER from ALICE_LONG to make a bid, passing along 5 ETH. AUCTIONEER uses the CALLER opcode to get the caller, and the opcode returns ALICE_SHORT (and simultaneously adds ALICE_SHORT -> ALICE_LONG to the translation table). AUCTIONEER confirms that Alice’s bid is higher than any existing one, and saves Alice’s bid, using ALICE_SHORT as her identity.
Bob calls AUCTIONEER with a 6 ETH bid. AUCTIONEER confirms that Bob’s bid is higher, and needs to refund Alice her bid as her bid is now losing. AUCTIONEER uses CALL passing along ALICE_SHORT as an argument. The CALL opcode looks up ALICE_SHORT in the translation table, gets ALICE_LONG as a result, and so correctly sends Alice’s 5 ETH back to ALICE_LONG.


Alternatives
It’s worth noting that we don’t have to do this if we are okay with unpublished addresses requiring the creator to be trusted. If we are okay with this weaker security property, then we could instead just move to a scheme where the hash decreases to 15 bytes (still 120 bits of preimage security) and the remaining 5 bytes get used for version/shard/epoch, though this would instead require somehow invalidating existing addresses that collide with the new schema.

Author: esaulpaugh
Date: 2021-03-06T18:09:33.440Z

vbuterin:

Solidity and other langs would be expected to treat the output as a BigAddress type which would be an alias for bytes32 instead of bytes20


The current ABI spec treats address as uint160, not bytes20 though
https://docs.soliditylang.org/en/latest/abi-spec.html

Author: anono1618
Date: 2021-03-06T19:40:38.844Z

Can we reserve a nibble for a checksum, even if it is optional and only used by front ends?
Perhaps have addresses start with checksum c and an “E” to mean Ethereum, so addresses would look like
cE01000001060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F
c being a checksum
“E” denoting ethereum
01 Version Number
000001 Epoch
060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F being the hash (but counting byte number).

Author: greg7mdp
Date: 2021-03-06T22:58:15.586Z

vbuterin on reddit> The amount of computing power needed to break a key or hash goes up exponentially with the length, so we really can be sure that 32 bytes is sufficient for the foreseeable future.
Isn’t the hash length really 26 bytes not 32 in the proposal? Shouldn’t we increase the hash part to 32 bytes in case of quantum surprises? Maybe we could go to 40 byte addresses, and in the spirit of anono1618’s suggestion starting with oxE (for Ethereum) followed by a 12 bit checksum to catch typos.

Author: vbuterin
Date: 2021-03-06T23:38:11.816Z

26 bytes is enough in a post-quantum context too. If we really want, we could later on switch around the addressing scheme again to increase the hash portion to 28 bytes.

Can we reserve a nibble for a checksum, even if it is optional and only used by front ends?

What properties are you trying to get that Ethereum’s existing mixed-case checksum scheme doesn’t already provide?

Author: greg7mdp
Date: 2021-03-07T00:06:00.351Z

I didn’t know about Ethereum’s existing mixed-case checksum scheme . So now the addresses will be case-sensitive?

26 bytes is enough in a post-quantum context too

Do we know that for a fact? Unless this is proven somehow, I think going a bit longer on the addresses may make people feel better and alleviate (possibly irrational) fears. Considering what is at stake, it is better to err on the side of too much rather than not enough when it comes to wallet security.

Author: greg7mdp
Date: 2021-03-07T00:49:06.212Z

Also a byte seems wasteful for a version number. A nibble would be plenty, and if we ever reach version 15 we can increase the version size to one byte in that version.
And why start at version 1? 0 is just as good, isn’t it?

Author: greg7mdp
Date: 2021-03-07T00:57:28.024Z

It is not very clear to me why 3 bytes are reserved for the epoch (what will this epoch embedded within addresses be used for?).

Author: vbuterin
Date: 2021-03-07T01:12:52.337Z

We could do 2 bytes for the epoch as well; I suppose having 108 bits of collision resistance instead of 104 (from adding an extra byte to the hash, making it 27) is more urgent for future-proofness than having epoch space to last 16777216 years instead of a mere 65536.

Also a byte seems wasteful for a version number

Partial bytes just make code ugly imo

Author: vbuterin
Date: 2021-03-07T01:14:20.032Z

So now the addresses will be case-sensitive?

Theoretically, we could make addresses case-sensitive today. There just hasn’t been enough of a community effort to force adoption of the checksum scheme. But we could actually try putting our minds to making it mandatory! (even before any address size change)

Author: greg7mdp
Date: 2021-03-07T01:58:29.527Z

If changing the address size, it seems much cleaner to set aside a byte for the checksum, rather than encode it using a upper/lowercase scheme. It seems to me that the checksum is really needed when entering addresses by hand, so making such entry more difficult and error prone to enter by making the addresses cases sensitive is a step backward imo.
I still don’t understand the planned use of the epoch. I naively thought it was in eth2 epoch units of ~6.4 minutes. If it is a number of years then yes three bytes is wildly excessive. IMO 1 byte allowing for 256 years would be plenty.
It might well be that there is some benefit of have “must be zero” bytes reserved for future uses, in the hope that the address length will not have to change again, so maybe that could be an argument for longer addresses (40 bytes?) with a longer ultra secure (even to wildly paranoid types)  hash (32 bytes?) and mbz fields.

Partial bytes just make code ugly imo 

Then at least make the first version be 224 instead of one, so that all ethereum addresses will start with 0xE.
Actually, on second thought, maybe it would be nice to start at version 226, so that eth addresses would start with 0xE2 which could be read as Ethereum 2.0.

Author: greg7mdp
Date: 2021-03-07T02:10:30.596Z

Also, the Mixed-case checksum scheme is useful only to catch input errors. Is it possible that an address could get corrupted while sending a transaction or executing contract code? If that is the case, having a checksum allowing to validate that a 32 or 40 byte string is indeed a valid address might be good to have.

Author: vbuterin
Date: 2021-03-07T02:18:13.306Z

greg7mdp:

it seems much cleaner to set aside a byte for the checksum, rather than encode it using a upper/lowercase scheme.


How so? Remember that there’s no need for a checksum within the EVM; the checksum is a user-interface-level convenience. So it should be part of the representation format (as the mixed-case-hex thing is), and not part of the raw address format.

making such entry more difficult and error prone to enter by making the addresses cases sensitive

The mixed-case checksums don’t have this risk. If you get the uppercase/lowercase wrong, that can ONLY lead to a “bad checksum” error, NEVER to you accidentally typing in a different but valid address.

Is it possible that an address could get corrupted while sending a transaction or executing contract code?

I can’t possibly imagine what could cause such a thing to happen.

so maybe that could be an argument for longer addresses (40 bytes?)

Addresses longer than 32 bytes are extra-problematic because there are 32 byte limits everywhere in ethereum: storage slot keys, storage slot values, ABI bytes32 values, SSZ chunk sizes… so IMO better to just stick to 32.

Actually, on second thought, maybe it would be nice to start at version 226, so that eth addresses would start with 0xE2 which could be read as Ethereum 2.0.

I’m ok with this if people want it!

Author: greg7mdp
Date: 2021-03-07T02:36:53.114Z

If you get the uppercase/lowercase wrong, that can ONLY lead to a “bad checksum” error, NEVER to you accidentally typing in a different but valid address

I get that, but it may still get frustrating and not user friendly. Suppose someone trying to send a large amount to a paper wallet. He enters the address, but we just made this entry more difficult because the letters are now case-sensitive. He clicks “send” and gets an error that the address is incorrect. He now totally freaks out.
I think most users would rather type case-insensitive addresses with an additional checksum byte, than having to worry about upper and lower case letters in addresses.
I would describe your argument as saying: “It is OK if I make your task more difficult, because I can guarantee that I will let you know if you fail it, and therefore it won’t have terrible consequences”.
There could also be a benefit to be able to check whether addresses are valid in program databases (beacon nodes, etc.). Maybe?

Author: zamicol
Date: 2021-03-07T05:27:22.088Z

Yes please!  At least a nibble, if not four bytes like Bitcoin.  Two bytes would allow 1/65536 mistakes to get through.  A nibble 1/16 mistakes would get through.
Another point: It’s not just users that bit flip.  It’s not just for user interfaces.  This is a real issue, for computers as well.
See my post on Reddit.

Author: zamicol
Date: 2021-03-07T09:07:33.140Z

EIP-55 addresses are just regular addresses on chain.  There’s no checksum on chain.
EIP-55 addresses are also optional.  What I’m asking for is mandatory checksums.
Thank goodness applications like Metamask use checksums by default.  But then again, it’s only ~15 bits on average.
But that’s another problem in of itself.  The checksum strength is not guaranteed, it’s only “an average” value.  It could be very few bits actually in the checksum.  It totally depends on how many alpha characters the original address has.
Ethereum addresses are 42 characters long with (when checksummed) a base 22 character set.
If they were efficient (which they are not) they could hold 179 bits of data.
For a 42 string length in “base 66”, you can store 242 bits.  Which is enough room to do everything Vitalik is suggesting to do and have enough bits left over to add checksums.
If using Bitcoin’s base 58, you’d need 44 characters.

Author: vbuterin
Date: 2021-03-07T13:27:11.776Z

zamicol:

Another point: It’s not just users that bit flip . It’s not just for user interfaces. This is a real issue, for computers as well.


It’s worth noting that in bitcoin, the checksum is also purely a user convenience, not an in-protocol thing; the bitcoin protocol treats addresses purely as a 20-byte hash with no redundancy or error detection of any kind. So as far as I can tell, that is the industry standard way of doing it. And if there are bit flips, they’re far more likely to happen in the much larger parts of the protocol that are not addresses.

Author: greg7mdp
Date: 2021-03-07T15:16:21.328Z

Even if it had no technical value (a fact that I am not quite convinced is true), having a checksum is a very potent bragging claim (even better if bitcoin doesn’t have it).
It allows us to say:

Ethereum has an built in way to validate that addresses are indeed valid addresses, and not just any random string of bits. Before any token transfer, addresses are validated against the embedded checksum and any inconsistency will cause the transaction to be aborted.

Sadly, marketing is important, even for things which make little technical sense.

Author: John-Status
Date: 2021-03-07T16:00:29.558Z

Proposal: any new address schema should support encoding multiple shard and L2 rollup chain IDs in a single address
The shard and L2 rollup chain IDs that are encoded in the address would represent the destination chains into which the address owner is happy to receive tokens e.g. If an address includes the IDs for say the Ethereum L1, Optimism L2 and ZKSync L2 chains, this would signal that the owner of the address is happy for tokens sent to this address to be sent on the Ethereum L1, Optimism L2 and ZKSync L2 chains.
In a world with multiple rollups, encoding multiple chain IDs in the address would enable wallets to automatically know which L2 rollup chains are valid destinations (for that address) without requiring any additional user input.
Without this change, when (in a world with multiple rollups) a user wishes to make a token transfer, the user would need to know the name of the destination chain in addition to the destination address.  This is much worse than the token transfer user experience on Ethereum today!
Requiring users to enter a destination chain name (in addition to a destination address) introduces the following UX regressions:


significantly increases scope for user error (e.g. user sends tokens to the correct address but on the wrong chain)


Adds another concept (the fact there are multiple chains with different names) for users to learn, hindering adoption.  For mainstream adoption we need to make Ethereum easier to use, not harder.


Because in reality most users would only enter/select a single destination chain, in many cases the routing of these cross chain transactions would be suboptimal, increasing the transaction cost the user has to pay, decreasing the transaction speed, and increasing the number of transactions that need to be performed which needlessly places additional load on the network. Many to many chain routing is better than many to one chain routing.


If multiple chain IDs are encoded in Ethereum addresses, all these problems go away and the token transfer user experience in a world with multiple rollups is just as good as the token transfer user experience today.
How it would work:
Let’s say Alice has funds associated with her address on rollups A, B and C.  She wants to send funds to Bob who uses his address on rollups B, C and D.  Bob sends his address to Alice, and in the address it is encoded that Bob is happy to receive funds to that address on rollups B, C and D.
Alice has 30 ETH associated with her address in total, and this is split equally across rollups A, B and C (10 ETH on each).  Alice wants to send Bob 20 ETH.  Because Bob’s address has told Alice’s wallet that he is happy to accept funds to rollups B, C and D, Allice’s wallet automatically works out that the quickest and cheapest way to send 20 ETH to Bob is to send 10 ETH from her address to his address on rollup B and another 10 ETH from her address to his address on rollup C.  This means that this transfer doesn’t have to cross any rollup boundaries therefore avoiding the latency and cost of moving funds between rollups.
In terms of the routing of payments, the above is one of the simplest possible examples.  In reality different L2s will have different bridge costs and delays, and the sender’s funds will frequently be spread across multiple rollups in a way that won’t match up so neatly with the rollups on which a recipient is happy to receive funds.  And when L2 to L2 transfers become feasible there will also be different costs when moving funds between different L2’s adding another layer of routing complexity.  It’s unreasonable to expect users to understand and manually work out the best answer to these complex routing problems each time they want to make a token transfer.
Encoding multiple chain IDs in ethereum addresses provides wallets with the information they require to compute the quickest and cheapest way of transferring funds (that are assigned to the same address across multiple rollups) to a recipient whose address is also used across multiple rollups.
Assumptions around token UX in a in a world with multiple rollups


In the future, wallets will include simultaneous support for multiple rollup chains (in addition to Ethereum L1)


When this happens, wallets will display the token balance for a given address across both Ethereum L1 and all the rollup chains that the wallet supports.


Token bridges will be built into wallets, so when a user wishes to transfer tokens across chains, they will be able to do this directly in their wallet without needing to navigate to a token bridge DApp.


See this rough visual mockup which illustrates these UX assumptions and shows how a token transfer flow could work in a world of multiple rollups if multiple chain IDs can be encoded in an address.
Mockup_of_sending_tokens_to_multiple_L2s_with_destination_chain_IDs_encoded_in_address33193×2061 552 KB
Benefits of being able to encode multiple chain IDs in an address in a world with multiple rollups:


The user sending tokens only needs to know the destination address (just like when using Ethereum today).  Without this change, in a world with multiple rollups, a simple user to user token transfer requires the user to know both the destination address and the destination chain name.


Less scope for user error e.g. the user doesn’t have the opportunity to mistakenly enter the name of the wrong destination chain.  Follows the UX principle that “when possible, the best way of handling errors is to remove the possibility of the user making the error in the first place!”


Lower transaction fees, faster transactions and reduced number of transactions… Wallets would be able to automatically calculate the most efficient routing to transfer X tokens from account A to account B when (for example) account A holds X tokens across rollup A, rollup B and rollup C, and where account B is happy to receive tokens on rollup B, rollup C and rollup D.


Requiring the user to manually enter the destination chain for a transaction makes the UX of transferring tokens more complex.  By having the ability to encode multiple chain IDs in an address, Ethereum doesn’t get harder to use than it is today in a multi-rollup world.


Open questions:


What is the max number of chain IDs we would allow to be encoded in a single address?  The cost of allowing a greater number of chain IDs to be encoded in a single address is increased address length.  Could allowing a max of say 8 or 16 chain IDs to be encoded in a single address be a sensible number?


What is the global max number of chain IDs that would be available for use in the future?  The cost of having a greater global max number of chain IDs is increased address length.  On the flip side, the greater the number of chain IDs supported the more future proof this format would be.  Perhaps aim to support a total of 32k or 64k chain IDs in total??


A table of which chain IDs map to which chains would have to live somewhere


Other thoughts


Encoding Chain IDs in addresses should be optional e.g. an address should be valid even if no Chain IDs are encoded in it.


I’m +1 on adding native support for checksums to any future address format.


We’ve been looking into how we can encode multiple chain IDs into Ethereum’s current address format using mixed case encoding (EIP-55’s checksum encoding mechanism), but it’s not possible to use mixed case encoding for both multiple chain IDs and a checksum at the same time.  Natively supporting multiple chain IDs in a new address format would resolve this issue.


IMHO the ability to encode multiple chain IDs in ethereum addresses is highly desirable from a user experience perspective!

Author: zamicol
Date: 2021-03-07T16:09:11.663Z

That sounds like a fair compromise.  I would ask to enforce checksums for user interfaces.

Author: greg7mdp
Date: 2021-03-07T17:20:35.446Z

I’m wondering if, instead of deciding on one address format which has hardcoded support for shards/L2 chains addressing, it might not be getter to have optional address extensions.
So in the base 32 byte address, there could be a byte stating whether the address is followed by a second 32 byte extended address. If the byte is 0, there is no extended address information. If the byte is not 0, its value would specify the type of the address extension that follows in the next 32 bytes. Any address extension would be optional, but as you described providing it might be a way to optimize transfers.

Author: John-Status
Date: 2021-03-07T17:51:14.397Z

Great idea!  Doesn’t increase the base address size, and provides 32 bytes in which to encode multiple chain IDs when this functionality is needed 
IMHO this extension (that enables multiple chain IDs to be encoded) will be needed in most cases when an address that tokens might be sent to is shared/published.  E.g. when users share addresses with one another, most of the time they should be using this address extension.

Author: anono1618
Date: 2021-03-07T18:46:08.262Z

Just enforcement, and obviousness that the checksum exists.

Author: zamicol
Date: 2021-03-07T19:05:41.584Z

Why not allow for the full 256 bit keccak256 checksum?  GUIs can include however many bytes they want at the end of the address when copying and pasting.   Ethereum can specify that anything under 4 bytes is invalid for GUIs.

Author: fare
Date: 2021-03-07T19:24:57.599Z

I’m all for longer addresses… but if you’re going to make big incompatible changes, why not bundle that with switching from EVM to EWASM or RISCV or something, instead of making an ugly and futile attempt at backwards compatibility?

Author: rubi
Date: 2021-03-08T07:22:46.005Z

vbuterin:

To elaborate on (3), current 20 byte (160 bit) addresses only provide 80 bits of collision resistance, meaning that someone can spend 2**80 computing work to generate two pieces of contract init code (or (sender, ID) pairs, or one piece of contract code and one EOA private key) that have the same address. 2**80 will soon be within reach of sophisticated attackers; the bitcoin blockchain has already made more than 2**90 hashes.


This may be misleading. It also requires 2**80 bytes (around 1 bn petabytes) of (fast) memory. You can trade off to something like 1,000 petabytes memory and 2**100 hashes, but it’s still hard.
I’m not saying this is not a problem, just making current situation somewhat clearer.

Author: vbuterin
Date: 2021-03-08T15:20:26.483Z

This may be misleading. It also requires 2**80 bytes (around 1 bn petabytes) of (fast) memory.

I’m pretty sure you can use cycle finding algos to find a collision in sqrt time and O(1) memory.
Eg. https://diglib.tugraz.at/download.php?id=576a7826f0534&location=browse around page 55 talks about some approaches to do this.

Author: jochem-brouwer
Date: 2021-03-08T15:57:01.667Z

What was the motivation to use 20 byte addresses instead of the 32-byte addresses which are generated by default?

Author: vbuterin
Date: 2021-03-08T17:13:20.939Z

It was a holdover from bitcoin (much like the v value in signatures being increased by 27).

Author: poemm
Date: 2021-03-08T19:06:14.255Z

This is a brief survey of all (?) EVM opcodes which interact with addresses.

ADDRESS, ORIGIN, CALLER, COINBASE

Input: nothing.
Output: stack item with an address from the execution environment. Currently 160 bits.

BALANCE, EXTCODESIZE, EXTCODECOPY, EXTCODEHASH

Input: an address from stack, which we currently truncate to 160 bits.
Output: info about that address is possibly pushed to stack.

CALL, CALLCODE, DELEGATECALL, STATICCALL

Input: an address from stack, which we currently truncate to 160 bits.
Output: error code from the message call.

CREATE, CREATE2

Input: The init code, endowment, and possibly a salt.
Output: new account’s address (currently 160 bits) to stack, where the new address is roughly: Hash(creating contract's address, creating contract's nonce or a salt, init code)[12:32]. This interacts with addresses in two ways: as the input and output of a hash.
SELFDESTRUCT
Input: an address from stack, which we currently truncate to 160 bits.
Output: send the remaining balance to that address.

SLOAD, SSTORE

These only implicitly touch the current contract’s address to read/write its storage.

Author: UliGall
Date: 2021-03-08T21:29:45.123Z

Did someone consider the effects of this change to vanity addresses? It seems to me that 0x01000000000157aE408398dF7E5f4552091A69125d5dFcb7B8C2659029395bdF might be considered as a vanity adress and that it will be harder in the future to differentiate between “high-effort” and “low-effort” ones. Might not be the most important detail, but as users often check some parts of the address to verify the correctness, we should keep this in mind.

Author: cdili
Date: 2021-03-09T03:07:08.839Z

Is it worth considering some of the following?

use SHA3 instead of KECCAK?
address extension, post 21 Increasing address size from 20 to 32 bytes


(extensions may want to consider multihash “support” https://w3c-ccg.github.io/multihash/index.xml)

Author: rubi
Date: 2021-03-09T11:42:28.796Z

vbuterin:

I’m pretty sure you can use cycle finding algos to find a collision in sqrt time and O(1) memory.
Eg. https://diglib.tugraz.at/download.php?id=576a7826f0534&location=browse  around page 55 talks about some approaches to do this.


A random collision indeed. But here you need chosen prefixs - two different ones. Notice the fact that the prefixes are different is meaningful since the iterators travel different paths in the space.

Author: vbuterin
Date: 2021-03-10T17:13:06.770Z

Notice the fact that the prefixes are different is meaningful since the iterators travel different paths in the space.

At worst, you can just have an iterator that randomly hops between both parts of the space (EOA pubkeys and contract codes fitting a template), and if you find a collision there’s a 50% chance that one preimage is a pubkey and the other preimage is a contract code. So I don’t think this is a barrier.

Author: rubi
Date: 2021-03-10T23:06:54.535Z

vbuterin:

an iterator that randomly hops between both parts of the space


Err… You need everything to be deterministic so you keep cycling.
Edit: Ah of course if you use (state % 2) as your random number then everything works out deterministically and perfectly. True.

Author: Arachnid
Date: 2021-03-11T01:18:08.785Z

If we’re defining a new address format, can we please define a canonical text representation that is not just the hexadecimal encoding of the address? Ethereum’s lack of a checksum in its text representation is one of its greatest weaknesses, and if everyone has to support a new address format anyway, that’s an excellent time to fix it. This should be a core part of any new address proposal, and not an afterthought - if 32 byte hexadecimal addresses get a foothold, it will be impossible to fix this (again).

Author: qizhou
Date: 2021-03-12T10:37:00.805Z

Why not still keep 20 bytes in EVM, while adding extra fields in tx/msg to including chain_id/epoch_id?  From a normal user perspective, the address is 32 bytes instead of 20 bytes, but wallets will automatically translate 32 bytes to 20 bytes byte hash + chain_id + others and put them in proper data fields.
For example, a tx sending to a 32-byte address will put “to” field as 20 bytes, and “to_chain_id” field from a 32-byte address.
And EVM can stay as it is except adding a few OPCODE to read like “to_chain_id” of current tx context.

Author: vbuterin
Date: 2021-03-13T20:48:37.501Z

qizhou:

Why not still keep 20 bytes in EVM, while adding extra fields in tx/msg to including chain_id/epoch_id? From a normal user perspective, the address is 32 bytes instead of 20 bytes, but wallets will automatically translate 32 bytes to 20 bytes byte hash + chain_id + others and put them in proper data fields.


I don’t think that would actually solve either the address space expansion problem or the security problem… the issues all happen in the EVM, not in clients.

Author: MicahZoltu
Date: 2021-03-17T08:06:11.315Z

vbuterin:

What properties are you trying to get that Ethereum’s existing mixed-case checksum scheme  doesn’t already provide?


Contract level checksum validation or (maybe in the future) EVM level checksum validation.

Author: greg7mdp
Date: 2021-05-13T20:28:44.343Z

Is there a benefit to having the shard id in the address, instead of adding it in the transaction along with the chain id?

Author: dankrad
Date: 2021-06-04T16:08:31.955Z

vbuterin:

It’s worth noting that we don’t have to do this if we are okay with unpublished addresses requiring the creator to be trusted. If we are okay with this weaker security property, then we could instead just move to a scheme where the hash decreases to 15 bytes (still 120 bits of preimage security) and the remaining 5 bytes get used for version/shard/epoch, though this would instead require somehow invalidating existing addresses that collide with the new schema.


The situation is actually much worse than this: You can write a harmless looking contract – let’s say a token wrapper or a uniswap clone – and use a collision to deploy it to an address that’s also an EOA. You deploy the contract, and after user funds have poured in (trusting the functionality according to the immutable contract code) you can steal everything using the EOA key.

Author: axic
Date: 2021-06-16T17:23:13.624Z

We (me, @chfast, @gumb0, @hugo-dc) have been working on the address space extension topic the past two weeks. It seems to open up a lot of questions. First we have created a hopefully more comprehensive specification based on this forum and explored questions (they are listed in the latter part of the document): ASE (Address Space Extension) with Translation Map - HackMD
Posting it now in case someone else is working on this too – it would be nice to collaborate to find answers more quickly. We expect to update this document as we go next week. Any feedback is welcome, but be prepared the content is in flux.
There are some differences to the description in this forum, which are listed as bullet points. One difference is we removed references to epochs in the document, and just state bytes 1-5 are reserved and must be zero (i.e it would be epoch 0). This is meant to help decoupling this proposal from state expiry in the sense it could be introduced earlier and independently.
We are now working on some new ideas and analysis of some concerns we have identified.

Author: axic
Date: 2021-06-25T12:16:48.008Z

axic:

We are now working on some new ideas and analysis of some concerns we have identified.


We have published this collection of concerns here: Issues with ASE (with a translation map) - HackMD
It is a very long list and some points are more developed than others.

Author: shugangyao1
Date: 2022-09-03T04:46:57.657Z

32 bytes new addr:
0-11 Byte :  EVM/contract internal ID
12-31 Byte :  old 20 Byte Addr

Author: YamenMerhi
Date: 2023-01-12T14:56:37.487Z

Is there still an intention to continue with this proposal?

Author: MicahZoltu
Date: 2023-01-13T06:04:30.606Z

I still think it is necessary for some improvements that many would like to see on Ethereum.  However, we were never able to come to agreement on the least worst way to do the migration.  All options come with consequences/costs.

Author: dogeprotocol
Date: 2023-11-17T18:16:36.162Z

We were evaluating something on these lines; there is a type named FunctionType that consists of 4 bytes function hash plus 20 bytes address (4 + 20). This means that maximum an address can be (within the current 32 byte limitation) is 28 bytes.
Above proposal needs to account for this FunctionType as well.
(See lines 124 o 126)

github.com


ethereum/go-ethereum/blob/master/accounts/abi/unpack.go
// Copyright 2017 The go-ethereum Authors
// This file is part of the go-ethereum library.
//
// The go-ethereum library is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// The go-ethereum library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.

package abi

import (
	"encoding/binary"




  This file has been truncated. show original






Blockquote
// A function type is simply the address with the function selection signature at the end.
//
// readFunctionType enforces that standard by always presenting it as a 24-array (address + sig = 24 bytes)
func readFunctionType(t Type, word byte) (funcTy [24]byte, err error) {

Author: Madjarx
Date: 2025-05-06T09:19:34.161Z

Is this discussion still ongoing?