But in the case of an EOA recipient it should not!
The extcodesize check is not redundant, it’s necessary to implement the semantics.
But in the case of an EOA recipient it should not!
The extcodesize check is not redundant, it’s necessary to implement the semantics.
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
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.Next call is in 2 weeks, on 10 July. Danno and Piotr will be absent.
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.
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).
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.
Adding to @cameel’s comments, you can visualize the metadata encoding and the contents at playground.sourcify.dev