Producing the logs
When the same event is logged with the same string argument, the data
in the transaction receipt is different, depending on whether the function was external
or public
.
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
Why is this happening?
Full public
transaction & result
> web3.eth.getTransaction('0xfd726f1a6f94f4050aff1baee4aa50c56d127a633bfc01ebe3b023ea926aad0f')
{
blockHash: "0xf0e7c13f811d06874a0191da3b135649cac4c9cd42a331c611734593d441a4f3",
blockNumber: 21,
from: "0x39708c52aea50be256bccd350d043ff36ffbb0e6",
gas: 124415,
gasPrice: 1,
hash: "0xfd726f1a6f94f4050aff1baee4aa50c56d127a633bfc01ebe3b023ea926aad0f",
input: "0x6a85450600000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006676c697463680000000000000000000000000000000000000000000000000000",
nonce: 20,
r: "0xb13ed94a954ce5e9b0c7823f4da21561f1d2d1b1a04b44cfd1f8b65acee8e1b9",
s: "0x1bb866cde428d538ba7920e58d64a6acb14d918a39dd8e7fb39b019dc9424261",
to: "0x2e64f811ab15803d34e2e6c503263f1393677aa9",
transactionIndex: 0,
v: "0xa96",
value: 0
}
> web3.eth.getTransactionReceipt('0xfd726f1a6f94f4050aff1baee4aa50c56d127a633bfc01ebe3b023ea926aad0f')
{
blockHash: "0xf0e7c13f811d06874a0191da3b135649cac4c9cd42a331c611734593d441a4f3",
blockNumber: 21,
contractAddress: null,
cumulativeGasUsed: 24415,
from: "0x39708c52aea50be256bccd350d043ff36ffbb0e6",
gasUsed: 24415,
logs: [{
address: "0x2e64f811ab15803d34e2e6c503263f1393677aa9",
blockHash: "0xf0e7c13f811d06874a0191da3b135649cac4c9cd42a331c611734593d441a4f3",
blockNumber: 21,
data: "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006676c697463680000000000000000000000000000000000000000000000000000",
logIndex: 0,
removed: false,
topics: ["0xd98695e9e68b6580b8d80f03676b8575f4cc4225687169877f72d5c2b39ff61c"],
transactionHash: "0xfd726f1a6f94f4050aff1baee4aa50c56d127a633bfc01ebe3b023ea926aad0f",
transactionIndex: 0
}],
logsBloom: "0x00000000000000000000000000000002000000000000000000000000400000000000000000000001000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000040000000",
status: "0x1",
to: "0x2e64f811ab15803d34e2e6c503263f1393677aa9",
transactionHash: "0xfd726f1a6f94f4050aff1baee4aa50c56d127a633bfc01ebe3b023ea926aad0f",
transactionIndex: 0
}
Full external
transaction & result
> web3.eth.getTransaction('0x09677264874077078d4b271f85ec7a940cf69f9b751b9a94e1cbf0f40dff1e86')
{
blockHash: "0xe2e6036b11aa7abe948c5008e72758186a83d679c7a3d03f55a9ad959ce12680",
blockNumber: 22,
from: "0x39708c52aea50be256bccd350d043ff36ffbb0e6",
gas: 123833,
gasPrice: 1,
hash: "0x09677264874077078d4b271f85ec7a940cf69f9b751b9a94e1cbf0f40dff1e86",
input: "0xd486916900000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006676c697463680000000000000000000000000000000000000000000000000000",
nonce: 21,
r: "0xe06e321ae4e3031ba30a32585050d5ed10388bba591e33d5e3d17077e2dd7323",
s: "0x7b2d1a18453ef5bd66d8065fbf1f159d029b3a64b52488382cfb8bafc6b00f09",
to: "0x2e64f811ab15803d34e2e6c503263f1393677aa9",
transactionIndex: 0,
v: "0xa96",
value: 0
}
> web3.eth.getTransactionReceipt('0x09677264874077078d4b271f85ec7a940cf69f9b751b9a94e1cbf0f40dff1e86')
{
blockHash: "0xe2e6036b11aa7abe948c5008e72758186a83d679c7a3d03f55a9ad959ce12680",
blockNumber: 22,
contractAddress: null,
cumulativeGasUsed: 23833,
from: "0x39708c52aea50be256bccd350d043ff36ffbb0e6",
gasUsed: 23833,
logs: [{
address: "0x2e64f811ab15803d34e2e6c503263f1393677aa9",
blockHash: "0xe2e6036b11aa7abe948c5008e72758186a83d679c7a3d03f55a9ad959ce12680",
blockNumber: 22,
data: "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006676c69746368",
logIndex: 0,
removed: false,
topics: ["0xd98695e9e68b6580b8d80f03676b8575f4cc4225687169877f72d5c2b39ff61c"],
transactionHash: "0x09677264874077078d4b271f85ec7a940cf69f9b751b9a94e1cbf0f40dff1e86",
transactionIndex: 0
}],
logsBloom: "0x00000000000000000000000000000002000000000000000000000000400000000000000000000001000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000040000000",
status: "0x1",
to: "0x2e64f811ab15803d34e2e6c503263f1393677aa9",
transactionHash: "0x09677264874077078d4b271f85ec7a940cf69f9b751b9a94e1cbf0f40dff1e86",
transactionIndex: 0
}
web3.js
parses both formats
> espe.allEvents({'fromBlock': 0, toBlock: 'latest'}).get()
[{
address: "0x2e64f811ab15803d34e2e6c503263f1393677aa9",
args: {
logme: "glitch"
},
blockHash: "0xf0e7c13f811d06874a0191da3b135649cac4c9cd42a331c611734593d441a4f3",
blockNumber: 21,
event: "EmitString",
logIndex: 0,
removed: false,
transactionHash: "0xfd726f1a6f94f4050aff1baee4aa50c56d127a633bfc01ebe3b023ea926aad0f",
transactionIndex: 0
}, {
address: "0x2e64f811ab15803d34e2e6c503263f1393677aa9",
args: {
logme: "glitch"
},
blockHash: "0xe2e6036b11aa7abe948c5008e72758186a83d679c7a3d03f55a9ad959ce12680",
blockNumber: 22,
event: "EmitString",
logIndex: 0,
removed: false,
transactionHash: "0x09677264874077078d4b271f85ec7a940cf69f9b751b9a94e1cbf0f40dff1e86",
transactionIndex: 0
}]
The external
version appears to produce an invalid ABI encoding
As I read this section of the ABI doc (emphasis mine), the version of the event without the trailing 0s seems broken:
bytes
, of length k (which is assumed to be of typeuint256
):enc(X) = enc(k) pad_right(X), i.e. the number of bytes is encoded as a uint256 followed by the actual value of X as a byte sequence, followed by the minimum number of zero-bytes such that
len(enc(X))
is a multiple of 32.
Why am I asking?
I don't think this affects the question, but just in case...
The eth-abi
python utility rejects the external
version of the event log as invalid. I'm trying to make sure I understand if the ABI spec and eth-abi
need to be updated, or ... is this a Solidity bug?