Open UsmannK opened 2 years ago
I had the same problem and found this info: Don't add an empty data slot to ABI-encoded empty strings from storage
And I re-registered the bytes type encoder:
import eth_abi
from eth_abi.encoding import encode_uint_256
from eth_abi.registry import BaseEquals, encoding
from eth_abi.utils.padding import zpad_right
class NewByteStringEncoder(encoding.ByteStringEncoder):
is_dynamic = True
@classmethod
def encode(cls, value):
cls.validate_value(value)
value_length = len(value)
encoded_size = encode_uint_256(value_length)
if value_length == 0:
return encoded_size
ceil32 = value_length if value_length % 32 == 0 else value_length + 32 - (value_length % 32)
padded_value = zpad_right(value, ceil32)
return encoded_size + padded_value
eth_abi.abi.registry.unregister_encoder(
BaseEquals("bytes", with_sub=False),
)
eth_abi.abi.registry.register_encoder(
BaseEquals("bytes", with_sub=False),
NewByteStringEncoder
)
In solidity calldata has special conventions for encoding. See: https://docs.soliditylang.org/en/v0.8.14/types.html#arrays
This results in a scheme where some things are packed tightly and others aren't.
Is there a way to use this library to easily match the semantics of
abi.encodeWithSignature
?Specifically I am looking for a way to do the following:
Here the empty bytes are getting encoded as
0x000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
but I'd like it to be
0x0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000
essentially, there should be 32 fewer bytes