Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Events emitted from external functions log different data than public functions #3493

Closed
carver opened this issue Feb 13, 2018 · 10 comments
Closed
Assignees
Labels

Comments

@carver
Copy link

carver commented Feb 13, 2018

I posted full reproduction details on StackExchange

The short version is that calling these two functions produces different log output:

pragma solidity 0.4.19;

contract EmitStringPublicAndExternal {
    event EmitString(string logme);

    function logPublic(string logme) public {
        EmitString(logme);
    }

    function logExternal(string logme) external {
        EmitString(logme);
    }
}

When I call both functions with "glitch" (in geth --dev), I get logs with two different data:

  • public: 0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006676c697463680000000000000000000000000000000000000000000000000000
  • external: 0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006676c69746368

Note: "glitch" encoded with UTF-8, and then hex-encoded, is: 0x676c69746368

@axic
Copy link
Member

axic commented Feb 13, 2018

Good catch. public should be the correct one :)

0000000000000000000000000000000000000000000000000000000000000020
0000000000000000000000000000000000000000000000000000000000000006
676c697463680000000000000000000000000000000000000000000000000000

@chriseth
Copy link
Contributor

Does this also happen with the new encoder?

@jitenhub
Copy link

jitenhub commented Feb 14, 2018

Nice catch. But its not bug its depends on memory allocation, In solidity all public functions immediately copies arguments to memory. In this process of copying values in to memory EVM will pad with 32 bytes.

EmitString(logme)

0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006676c69746368

As per EVM documentation EmitString(logme) logme is string type saving or representation would be 1st 32 bytes(32*2=64 chars) will represents location of string

0x0000000000000000000000000000000000000000000000000000000000000020 = 32

Now pointer will move to 33bytes to next 32 bytes is length so length is

0000000000000000000000000000000000000000000000000000000000000006 = 6, i.e next 6 bytes are data.

676c69746368 hex representation of string.

Memory representation of any bytes is padded with multiples of 32 bytes. Thats a reason you are getting 676c697463680000000000000000000000000000000000000000000000000000

Where is case of external functions can read directly from calldata. What is values your passing it will send same thing to the network. So thats reason you able to see only 676c69746368

Memory allocation is expensive, whereas reading from calldata is cheap.

That means its not a bug.

@chriseth
Copy link
Contributor

@jitenhub all you say is correct, but what is your point?

@jitenhub
Copy link

@chriseth Its not bug

@axic axic added the bug 🐛 label Apr 17, 2018
@chriseth chriseth changed the title Events omitted from external functions log different data than public functions Events emitted from external functions log different data than public functions May 4, 2018
@chriseth
Copy link
Contributor

chriseth commented May 4, 2018

@jitenhub I would still say we should properly ABI-encode calldata arrays with padding.

@chriseth
Copy link
Contributor

chriseth commented May 4, 2018

The padding should be added at ArrayUtils.cpp:309.

@chriseth chriseth self-assigned this May 7, 2018
@chriseth
Copy link
Contributor

chriseth commented May 7, 2018

Finished work on this, but cannot push to github from this network. Hope I can push later today.

@chriseth
Copy link
Contributor

chriseth commented May 7, 2018

Note that as soon as this is merged, it is not possible to forward bytes data anymore via call. We need #3955 for this, but that is a breaking change.

@chriseth
Copy link
Contributor

Result of discussion: Add a warning for hash functions, and do the rest (including call*) with 0.5.0 proper.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants