Giter Site home page Giter Site logo

Comments (9)

Pai-Sho avatar Pai-Sho commented on August 16, 2024 1

I see the problem is on my side. I should not be treating the values as a tuple in encode. v4.0.0 yields the correct result

from eth-abi.

fselmo avatar fselmo commented on August 16, 2024

@Uxio0 what version of eth-abi are you using? There was an encoding bug that was also fixed for dynamic encoding. The most recent version of eth-abi lines up with Solidity encoding of empty bytes. Neither of what you posted is what Solidity returns. My suggestion is to try to update your library to use the latest eth-abi. If you need some time to transition to the latest version then, yeah, we need to figure out how / why encode is differing from encode_single within the same version.

I'm also assuming that you used the different methods since both of your code snippets are using encode and neither use encode_single (though the second imports it). I assumed that was just a typo. (I already confirmed this discrepancy in version 3.0.1 below)

Solidity encoding used for reference:

contract Contract {
    function encodeEmptyBytes() public pure returns (bytes memory) {
        bytes memory _b;
        return abi.encode(_b);
    }
}

which returns (consistent with the latest version of eth-abi):

b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

from eth-abi.

fselmo avatar fselmo commented on August 16, 2024

Hmm I do see the discrepancy in 3.0.1 which is definitely a bug as they should yield the same results. I think this is a result of the bug that was in the encoding. We can and should definitely put up a patch version for 3.0.1 with this bugfix but, again, neither of these are correct compared to what Solidity returns. I suggest upgrading to the latest version of eth-abi as soon as you can.

Thanks for submitting this.

from eth-abi.

fselmo avatar fselmo commented on August 16, 2024

On second thought, and looking at this again, I don't see any easy way to fix this since

  1. The way encode (previously encode_abi) was written, it is inherently doing something different than encode_single and results in a different result.

  2. Modifying encode() in this version to return encode_single() if the length is 1 breaks encode()'s behavior (breaking change). This is because if you used encode_abi() in the past, with a single item, it would produce a different result. This is the most unfortunate part of this change.

  3. They are really both wrong and this bug is fixed in the latest eth-abi version.

The only answer I see here really is unfortunately just skipping this version altogether and updating the docs to reflect this and encourage users to only use the latest version. Thankfully we've moved away from decoupling encoding a single item from many. This just leads to more surface + room for errors like these.

Is there any other option I missed that would be better for you as you are transitioning to the new eth-abi version? @Uxio0

from eth-abi.

Uxio0 avatar Uxio0 commented on August 16, 2024

Hi @fselmo and thanks for the detailed answer:

I was using v2.2.0 and v3.0.1. Indeed:

len(eth_abi.encode(['bytes'], [b'']))
96
len(eth_abi.encode_single('bytes', b''))
64

but with 4.0.0

len(eth_abi.encode(['bytes'], [b'']))
64

You are right, I wanted to make sure everything was working before migrating to v4.0.0 and indeed it was fixed in the last version. I will update to v4.0.0 and then do the refactor in the same step.

Thank you very much

from eth-abi.

Pai-Sho avatar Pai-Sho commented on August 16, 2024

@fselmo I am still observing this behavior with v4.0.0, and it's causing problems upgrading

Example:

with v2.2.0

encode_single(
    '(address,uint256,uint256,uint256,bytes)',
    ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", 1000, 1, 0, b'']
)

with v4.0.0

encode(
    ['(address,uint256,uint256,uint256,bytes)'],
    [("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", 1000, 1, 0, b'')]
)

These should return the same result, but they do not.

from eth-abi.

fselmo avatar fselmo commented on August 16, 2024

@fselmo I am still observing this behavior with v4.0.0, and it's causing problems upgrading

Example:

with v2.2.0

encode_single(
    '(address,uint256,uint256,uint256,bytes)',
    ["0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", 1000, 1, 0, b'']
)

with v4.0.0

encode(
    ['(address,uint256,uint256,uint256,bytes)'],
    [("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", 1000, 1, 0, b'')]
)

These should return the same result, but they do not.

2.2.0 had a bug. Do not compare anything to those results. Instead compare the latest encode to Solidity.

from eth-abi.

Pai-Sho avatar Pai-Sho commented on August 16, 2024

@fselmo Hmm, using v2.2.0, v4.0.0 and solidity I'm getting 3 different answers

Using the above examples, I get

0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000
for v4.0.0

0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
for v2.2.0

and
0x000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc200000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000
with solidity abi.encode(address(0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2), uint256(1000), uint256(1), uint256(0), bytes(""));

from eth-abi.

fselmo avatar fselmo commented on August 16, 2024

closing as resolved / completed / stale

from eth-abi.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.