Skip to content
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

Post-constantinople, we should use extcodehash instead of extcodesize #4834

Closed
chriseth opened this issue Aug 16, 2018 · 13 comments
Closed

Post-constantinople, we should use extcodehash instead of extcodesize #4834

chriseth opened this issue Aug 16, 2018 · 13 comments
Projects

Comments

@chriseth
Copy link
Contributor

Once constantinople is finalized, we should use extcodehash instead of extcodesize to check if the called account exists, because it is cheaper.

@chriseth chriseth added this to Inbox in Backlog (breaking) via automation Aug 16, 2018
@anurag-git
Copy link
Contributor

@chriseth , is it as simple as replacing extcodesize with extcodehash. Please help to produce some details so that I can work on it

@chriseth
Copy link
Contributor Author

chriseth commented Sep 4, 2018

Yes, it is very simple, but I think we should wait until constantinople is finalized.

@axic
Copy link
Member

axic commented Sep 4, 2018

In theory it can be implemented under the constantinople switch, but I'd feel safer committing to this around early October because then the EIPs included in constantinople should be final.

@Agusx1211
Copy link

Bump!

This may reduce all calls to external contracts by ~300 GAS, because currently after each call the address is checked using extcodesize, which uses 700 GAS, and extcodehash uses only 400 GAS.

@chriseth , is it as simple as replacing extcodesize with extcodehash. Please help to produce some details so that I can work on it

It should also be checked that the result of extcodehash is not c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 (account with no code).

@chriseth
Copy link
Contributor Author

@Agusx1211 thanks for bringing this up again! Note that the constant c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 has a deploy-time cost of more than 8576 gas, so this only amortizes after 20 calls. This should be checked against the runs optimizer parameter.

@chriseth chriseth added this to To do in 0.5.12 via automation Jul 11, 2019
@chriseth chriseth removed this from Inbox in Backlog (breaking) Jul 11, 2019
@chriseth chriseth removed this from To do in 0.5.12 Oct 2, 2019
@chriseth chriseth added this to To do in 0.5.13 via automation Oct 2, 2019
@leonardoalt leonardoalt added this to To do in 0.5.14 via automation Nov 14, 2019
@leonardoalt leonardoalt removed this from To do in 0.5.13 Nov 14, 2019
@chriseth
Copy link
Contributor Author

If we want to avoid providing the constant literally, we could use keccak256(0, 0), which is an extra 39 gas and 4-5 bytes of code (which costs 1000 gas to deploy).

@axic
Copy link
Member

axic commented Nov 18, 2019

This may reduce all calls to external contracts by ~300 GAS, because currently after each call the address is checked using extcodesize, which uses 700 GAS, and extcodehash uses only 400 GAS.

This was an obvious pricing mistake and it is rectified by EIP-1884 in the upcoming Istanbul update.

@chriseth
Copy link
Contributor Author

Oh wow, I thought extcodehash is cheaper because the size is not directly stored in the trie. So in the end, both opcodes have the same cost?

@axic
Copy link
Member

axic commented Nov 18, 2019

Good point though that size is not stored, size should cost more :)

But the issue was balance and codehash should cost equal because both are stored in the account.

@chriseth
Copy link
Contributor Author

So does that mean we can now close this?

@axic
Copy link
Member

axic commented Nov 19, 2019

Unless extcodesize is repriced, it seems that added cost of checking for empty hash makes this change not very useful. I'd opt for closing now.

0.5.14 automation moved this from To do to Done Nov 19, 2019
@thegostep
Copy link

thegostep commented Nov 27, 2019

Does solidity provide a global for determining if a contract exists or is this assembly technique still best approach?

uint256 codeSize;
assembly { codeSize := extcodesize(0x123...) }
bool exists = codeSize > 0;

@chriseth
Copy link
Contributor Author

It is the best approach.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
0.5.14
  
Done
Development

No branches or pull requests

5 participants