Gas and Size savings: Offer a OpenZeppelin Lite distro SDK to the mainline SDK offering
I was looking at including OZ ECDSA contracts for a project, and comparing the releases saw a sizable difference in compiled output.
I am not asserting that the changes are superfluous, what I am asserting is that potentially it be made easier to inport only the dependencies that are needed. solidity import mechanics being what they are, maybe offering a stripped down version of the main branch for contracts that do not see much changes release to release, or maybe an opinionated categorial release flavour (eg “cryptography sdk, token sdk, etc). I understand that this introduces additional maintenance requirements, which is why I would think contracts not seeing much changes (such as signature related ones) would be more palatable for maintaining on a LTS basis.
I would think making the contracts better partially importable would be the easiest way to achieve the performance KPIs over releases.
Below is a totally not scientific nor statistically significant benchmark of what was casually observed. Repeated and reproducible testings should be made before any action be taken ofc. I post this only to start a conversation to see if such changes would be considered/better testing implemented for the project maintainers to use for consideration etc.
Thanks for yalls awesome work, I always learn something from the people that work at OZ!
Repository, note this includes non OZ contracts as well
Motivation
Reduce gas and size for ECDSA Signature Methods, reduce imported bloat, etc.
Benchmarks
Openzeppelin
Contract | Size (kB) | Margin (kB) |
---|---|---|
ECDSA | 0.086 | 24.49 |
Math | 0.086 | 24.49 |
Strings | 0.086 | 24.49 |
Disco
Contract | Size (kB) | Margin (kB) |
---|---|---|
ECDSA | 0.045 | 24.531 |
Strings | 0.045 | 24.531 |
Changes
Following changes have been made and tested
Strings
Strings.sol
includes the needed SafeMath
logic that was removed in 4.8.0 of OpenZeppelin/Contracts
. This reduces the size of the compiled contract by 50%.
ECDSA
Assembly changes
/**
* @dev Returns an Ethereum Signed Message, created from `s`. This
* produces hash corresponding to the one signed with the
* https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
* JSON-RPC method as part of EIP-191.
*
* See {recover}.
*/
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
}
/**
* @dev Returns an Ethereum Signed Typed Data, created from a
* `domainSeparator` and a `structHash`. This produces hash corresponding
* to the one signed with the
* https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
* JSON-RPC method as part of EIP-712.
*
* See {recover}.
*/
function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(ptr, "\x19\x01")
mstore(add(ptr, 0x02), domainSeparator)
mstore(add(ptr, 0x22), structHash)
data := keccak256(ptr, 66)
}
}