EVM Object Format (EOF)

But in the case of an EOA recipient it should not!

The extcodesize check is not redundant, it’s necessary to implement the semantics.

2 Likes

Ah, you’re totally right. I misread the purpose of the check in these EIPs. It’s there to skip the onReceived() calls without reverting. Without it the EIPs will still work for contracts but not for EOAs.

So yeah, this does seem like a new use case for the check. I still think it does not make the EIPs unimplementable though, it just neuters some of their safeguards, which previously wasn’t considered a strong enough reason for an additional call return code.

The way you’d implement it without the check would be for ‘safe transfer’ to always issue a call and check whether it’s an EOA based on the status and return data. If the call is successful and the return data is empty, it’s probably an EOA. Of course this will have some false positives, e.g. if it just happens to be a contract has an onERC1155Received() function that returns nothing. Or if the contract intercepts the call in its fallback function.

I don’t think this is qualitatively different from the case of the extcodesize check on high-level calls in Solidity that we brought up earlier. Still, if this additional case is enough to sway the decision towards making this case properly distinguishable, I’m all for it.

EOF Call 52 notes

  • Clients
    • Besu and EVMONE are adapting to recent spec changes
    • Nethermind and Geth are progressing with their implementations, currently working on state test issues
    • EELS has started an implementation
    • No updates from Reth or EthJS
  • Compilers
    • No updates from Solidity or Vyper
  • Spec Updates
    • Discussed the need to differentiate EOAs from contract accounts, for ERC-721’s safe transafer from method
      • Two major options: return codes (as outlined above) and reworking EXTCODESIZE
        • Return codes could be tweaked to set high bits for flags. bit 7 - failure, bit 6 - was an EOA bits 0-3 status.
          However, this could impose overhead for contracts that don’t care about EOA status
          Ipsilon will ping @rodiazet to see if we can quantify the overhead we would see out of solidity
        • EXTCODESIZE could be recast like DIFFICULTY/RANDOAO was recast.
          A new IS_CONTRACT opcode would overlay it, returns 0 if it has no code and 1 if it does, regardless of size. Compiler logic that only tests codesize > 0 would still work.
          The downside is this is an infringement of banning code introspection. While not a bad one as it is a simple question of “do you execute code”
    • Discussed changing max_stack_height in the types section in light of the requirements for input_size already existing, so that a double counting can be removed from CALLF checks.
      There were concerns about a non-essential change going in this late, however @chfast was not on the call it was decided to push it out two weeks when he can be present to advocate for his change
    • Banning EOFCREATE and RETURNCONTRACT referencing the same container was finalized
  • Testing updates
    • We discussed the issues around system contract actions such as beacon block, block hash, and withdrawals/deposits/consolidations.
      A new field will be added to the “env” section of t8n requests indicating if those block level action should or should not be performed. This will allow state tests to evaluate just the TX and not the whole block.
    • We also discussed differentiating initcode and runtime code in EOF container validation tests. a new field will be added allowing test consumers to differentiate. PRs will be forthcoming.
  • Devnet
    • Because we do not have multiple clients ready we will not be launching a devnet in June. Target is now July.
    • Kurtosis is ready to support EOF networks. Assertor tests need to be written to deomnstrate basic readiness for EOF create transactions.

Next call is in 2 weeks, on 10 July. Danno and Piotr will be absent.

2 Likes

The max_stack_height change is rather cleanup but it also leads to bigger change removing the need for runtime access to the type section (please discuss the details there). In my opinion this is worth the effort especially for the code chunking.

This is late, but I’d like to answer the VLQ question in the context of instructions. For EOF header this is probably fine, but I’m not sure how much it matters there.

For instructions VLQ doesn’t look good. EOF makes bytecode translation much easier (JIT/AOT compilers) but also improves situation for interpreters by a lot by removing jumpdest analysis. I.e. interpreters can start executing just after reading the EOF header.

Using VLQ to encode instruction immediates makes the interpretation more complex because for some instruction VLQ decoding is involved and it is rather impractical to cache the results or preprocess the code. For some instructions like RJUMPV VLQ cannot be used normally because random access to the table is needed so we need a workaround in this case.

sorry, missed the last meeting as I was taking a vacation!

I think this is the same as IS_CONTRACT opcode, since you can always (static)call an address and check the status code to deteremine if it is an EOA. But I guess you can always bust out and call a specially designed legacy contract to query the code of a given address right?

I think this should be run by the AA folks tbh and see what they think, as I have seen a lot of calls for “shouldn’t be able to tell difference between EOA and contract”, not sure if the ERC721 safeTransfer case has been considered.

Hmm I think for almost all instructions with immediates there is an improvement, since there is no limit on the addressability size. For example, with VLQ we could add fewer stack instructions; a single opcode with variable length could be used for SWAPN/EXCHANGE. And from a performance point of view VLQ is an improvement since in common code patterns it improves codesize.

RJUMPV is indeed a special case which would need its own encoding to preserve the property of random-access to the table. (But I don’t think it’s a particularly hard problem to solve, it just needs a bit of spec work).

By the way, these are already all discussion points that were addressed in the VLQ proposed addition to EOF update EOF container specs with variable-length encodings by charles-cooper · Pull Request #37 · ipsilon/eof · GitHub.

I’m extremely late to the party, but am I reading EIP-3540 correctly? It seems that both the entire EOF blob and one of the section kinds are called “containers”. That seems like confusing terminology.

hey, so i implemented an onchain interpreter

i wanted to confirm that

https://github.com/rainlanguage/rain.interpreter/blob/main/src/lib/eval/LibEvalNP.sol#L146

would be implementable with RJUMPV and retain constant time function calls here

it looks like RJUMPV might be able to replace my hand rolled assembly, which would be nice, but i also might be missing something here and if i can’t do what i need in EOF that would be a problem for me

You would need to change your function encoding to an int enum from 0 to 255. And you would be limited to 256 functions. Or you would need to stack dispatchers, one for the first byte, jumping to one for the second, etc.

EIP 3540 does not have rationale for removing EXTCODE access. It should be mentioned and alternatives should be discussed.

1 Like

Agreed on the missing rationale, will track this. The currently proposed substitute is EIP-7761 HASCODE instruction, alternatives to it are also discussed there.

How will eth_getCode behave for EOF? Will it return EF00 like EXTCODECOPY, the full object, or the code segment?

By the name you are referring to the JSON-RPC API eth_getCode, correct?

The EIPs only handle in EVM execution, so the JSON-RPC specs are out of scope and no change in the APIs is proposed.

That being said, I expect it should return the entire EOF code object as it exists in the account trie. The concerns about code introspection are only for introspection within the EVM, not from the outside. For cross-layer concerns like the JSON-RPC, I don’t see how we could possibly enforce non-introspection, as you could just re-play all the transactions (which executing contracts don’t have access to).

1 Like

Please, include Solidity ABI to EOF. Currently we need to download ABI from Etherscan if we need it, i. e. we have to use centralized service. This is suboptimal. And not all contracts have ABI available at Etherscan. Also, there are a lot of automatically generated contracts.

So, please include ABI to EOF. This will enhance transparency and debuggability.

You may say that I should not mix EVM and Solidity. Yes, I agree. So, let’s do this: EOF includes additional section for “language-specific type info” (which is agnostic to language) and Solidity compiler always generates its ABI and it puts to this section.

Also: EOF is great moment for implementing native tokens (EIP-7809). See my arguments why native tokens are cool: https://ethereum-magicians.org/t/eip-7809-native-tokens/21615/9

I do not realistically see an explicit ABI section being adopted on mainnet. Possibly on some rollups on an optional basis, but I expect there would be other devs who would want the code representations as lean as possible.

You can ask the solidity devs to put their ABI in the data section but their 4byte ABI is non-standard and neither can nor should be mandatory. Opting into this pattern can make your own code more accessible but there will always be non-compliance.

I recommend you take this suggestion to the solidity team. I’m sure they will be happy to make this the default.

This is already solved in Solidity by contract metadata. Metadata contains ABI definitions among other things. It can’t realistically be embedded directly in the contract due to how bulky the uncompressed JSON data is (too easy to hit the EIP-170 code size limit), but the hash is there and the full metadata is meant to be made widely available via distributed filesystems like IPFS or Swarm.

You also don’t need to use centralized services like Etherscan. You can use Sourcify, which makes all of its data publicly available, also on IPFS.

2 Likes

Adding to @cameel’s comments, you can visualize the metadata encoding and the contents at playground.sourcify.dev

1 Like