`ECDSA.recover()` accepting signature from `calldata`?
🧐 Motivation
Current ECDSA.recover is accepting a signature typed bytes memory but since signatures are often passed as calldata, adding a method that reads the signature directly from calldata instead of copying to memory could be more gas efficient.
📝 Details
Alternative assembly code reading from calldata without copy:
bytes calldata signature
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := calldataload(signature.offset)
s := calldataload(add(signature.offset, 0x20))
v := byte(0, calldataload(add(signature.offset, 0x40)))
}
Current code:
bytes memory signature
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
I'm personally not excited about this. We keep adding variants and having a lot of duplicate code. I'd like to see Solidity allow us to write these functions in a generic way. See https://github.com/ethereum/solidity/issues/13207.
If someone is looking for a gas-efficient way to accept signatures they should not use this function (even with calldata array), instead they should use recover(bytes32 hash, bytes32 r, bytes32 vs).