Increasing address size from 20 to 32 bytes

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.

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.

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.

1 Like

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

Is there still an intention to continue with this proposal?

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.

1 Like

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)

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) {

Is this discussion still ongoing?

How should contracts which have functions with address arguments handle this compression/decompression?

Presumably the ERC-20 interface is incompatible with 32 byte addresses as it expects a 20 byte address as calldata. If a new-style contract calls the transfer function of an ERC-20 contract with a 32 byte address should it be compressed by the calling contract or by the EVM (though I’m not sure how the EVM would know to compress it).

If the responsibility of compressing addresses is left to the caller (that is, a 32 byte address-aware caller):

  • We introduce a COMPRESSADDRESS opcode that allows new-style contracts to interact with legacy contracts by compressing an arbitrary address to 20 bytes.

  • And DECOMPRESSADDRESS opcode allowing new-style contracts to implement an ERC-20 interface allowing for transfers to 20 byte addresses.

The compiler would use these opcodes to cast between 20 byte and 32 byte address types.

Limitations
The opcodes are only available to contracts. EOAs interacting with legacy contracts will need to compress the address before sending the transaction.
For example:

  • An EOA transfers ERC-20 tokens to a 32 byte address by calling the transfer function. They first compress the address before inserting it into the transaction calldata.
  • This compressed address won’t be present in the translation table.
  • Later, ETH is distributed to all token holders. Each address is decompressed by the CALL opcode when distributing ETH.
  • The address cannot be decompressed, so ETH will be sent to the non-existent 20 byte address.

The initial proposal also has this limitation in some cases. Consider a legacy contract with some withdrawal mechanism with a 20 byte address which can be configured by an EOA. A client compresses a 32 byte withdrawal address and sends a transaction to set the contract. When the withdrawal is activated the ETH will be sent to the 20 byte address.

We can work around this by adding an compressible_addresses field to the transaction when calling legacy contracts. Any 32 byte addresses in the field are added to the translation table.

Regarding the limitation under the scheme proposed above we can allow 32 byte address EOAs to sign transactions using its compressed 20 byte address. This back compatibility allows EOAs to recover funds sent to compressed addresses.