I wanted to gather feedback around proposing a new EXTSLOAD
opcode, which would allow a contract to read a storage position from another account.
While I understand that this could be regarded as a Bad Idea ™ since it promotes breaking encapsulation, I think it naturally follows EXTCODEHASH
. Once you have validated that an account holds a particular kind of contract using EXTCODEHASH
, you can safely use EXTSLOAD
to check a storage position from that account, knowing that it will have the semantics you expect.
The gas cost for this operation could be much cheaper than actually performing a call to execute a getter from a contract, since it does not require executing (nor loading!) any code on the queried contract, but just retrieving a single storage location.
As for high-level usage of this opcode, this means that getters for a contract (assuming it will rely on a single implementation) could be implemented as methods from Solidity libraries that use this opcode behind the scenes to check the code hash and subsequently retrieve the value from storage.
contract Box {
uint256 value;
constructor (uint256 _value) public { value = _value; }
}
library BoxReader {
function getValue(Box target) internal {
// optionally use extcodehash on Box to validate it matches the code
// use extsload on Box to retrieve the value
}
}
contract Reader {
using BoxReader for Box;
Box box;
constructor() { box = new Box(); }
function readBox() public {
uint256 value = box.getValue();
// ...
}
}
Besides gas cost savings, the actual use case that drove me to this opcode was using EXTCODEHASH
for validating implementation contracts behind DELEGATECALL
proxy contracts. On a system that relies on this pattern for upgradeability, using EXTCODEHASH
for checking that a contract has the expected code does not cut it, since it may be a proxy sitting in front of the actual implementation contract. This means that the validation would actually be a 3-step process:
- EXTCODEHASH the target account to check it is indeed a proxy,
- EXTSLOAD to retrieve the implementation contract’s address,
- and then EXTCODEHASH the retrieved implementation address and compare it against the desired one
Given I’m not that familiar with the internals of EVM implementations, I wanted to gather some feedback around this before formally proposing it as an EIP. Thanks in advance for any comments!