11

Is msg.data equal to {from: addr1, data:something}?

How to handle the data 'something'?

when execution this code:

web3.eth.sendTransaction({from: ..., to: addressOfE, data: something}); 

how to read the "data: something " ? For example: data: web3.toHex('something')

thank you!

update 4, 7 2017

demo: I put a event function in sendCoin function.

"event LogMsgData(bytes calldata);" 
when i call this, 
meta.sendCoin(receiver, amount, {from: account, data:web3.toHex('test'), gas:500000});

the LogMsgData print this:

//"0x90b98a11     -> MethodID
//000000000000000000000000f178589cf1ef5af554863d8cef601c9fc02ca2ed   -> receiver address 
//0000000000000000000000000000000000000000000000000000000000000002"  -> the amount

and where is {from: account,data:web3.toHex('test'),gas:500000} ?

12

I had to dig a little deeper into the contents of msg.data for this feature.

I thought it would be worth noting that variable length parameters like arrays, bytes and strings produce a more complex structured msg.data.

Given the following method:

function getMsgData(
  address _address,
  bytes _bytes,
  uint _int,
  uint[] _array,
  string _string
 )
  external
  returns (bytes)
 {
   return msg.data;
 }

If we call this method the following params:

contract.getMsgData(
 someAddress,
 web3.toHex('my bytes'),
 12,
 [1, 4, 412],
 'thisislargerthanthirtytwobytesstring'
);

The response would be broken down like this:

0x
d1621754 // (1) methodId
000000000000000000000000c6e012db5298275a4c11b3e07d2caba88473fce1 // (2) "_address"
00000000000000000000000000000000000000000000000000000000000000a0 // (3) location of start of "_bytes" data (item 7) = 160 bytes
000000000000000000000000000000000000000000000000000000000000000c // (4) "_val" = 12
00000000000000000000000000000000000000000000000000000000000000e0 // (5) location of start of "_array" data (item 9) = 224 bytes
0000000000000000000000000000000000000000000000000000000000000160 // (6) location of start of "_string" data (item 13) = 352 bytes
0000000000000000000000000000000000000000000000000000000000000008 // (7) size of "_bytes" data in bytes (32 bytes)
6d79206279746573000000000000000000000000000000000000000000000000 // (8) "_bytes" data padded to 32 bytes
0000000000000000000000000000000000000000000000000000000000000003 // (9) length of "_array" data = 3
0000000000000000000000000000000000000000000000000000000000000001 // (10) _array[0] value = 1
0000000000000000000000000000000000000000000000000000000000000004 // (11) _array[2] value = 4
000000000000000000000000000000000000000000000000000000000000019c // (12) _array[3] value = 412
0000000000000000000000000000000000000000000000000000000000000024 // (13) size of "_string" data in bytes (64 bytes)
7468697369736c61726765727468616e74686972747974776f6279746573737472696e670..0 // (14) "_string" data padded to 64 bytes

You can see that strings, bytes and arrays all have their data size and data appended to the end of msg.data. In place of where the parameters data would normally appear you have a 32 byte interger which describes the location of the params data.

  • 2
    Good first post! – Meshugah - Bank Of Hodlers Jun 6 '18 at 20:34
  • 5
    Haha, thanks! I'll consider 10-year debt of leaching answers of stack overflow repaid. – aflesher Jun 6 '18 at 23:43
4
  1. Yes, in web3.eth.sendTransaction({from: ..., to: addressOfE, data: something});, then in contract E, msg.data will be the something.

  2. However, most of the time a contract handles msg.data indirectly and easily.

For example, if you have a contract instance in web3.js

// creation of contract object
var MyContract = web3.eth.contract(abi);

// initiate contract for an address
var myContractInstance = MyContract.at('0x78e97bcc5b5dd9ed228fed7a4887c0d7287344a9');

myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000}, function(err, result){ ... });

then in Solidity, the contract at 0x78e9... would have something like

function myStateChangingMethod(string someStr, uint someNumber) and the contract doesn't have to parse msg.data -- because someStr will have the value someParam1 and someNumber will have the value 23.

Note: Do not mix up #1 and #2. For example, there is no data object when invoking myStateChangingMethod in #2: use a third parameter instead.


  1. Another example is using Solidity's call. For example, a contract C sends a message to D using D.call(something), then msg.data will be the something.

Here is a "proof" to try in Remix:

contract C {
    // in Remix, pass bytes as an array like: // ["0x00","0xaa", "0xff"]
    function test(address addressOfD, bytes bb) {
        addressOfD.call(bb);
    }
}

contract D {
    event LogMsgData(bytes calldata);

    function() {
        LogMsgData(msg.data);
    }
}

enter image description here

enter image description here

  • thanks for your answer, but when execution web3.eth.sendTransaction({from: ..., to: addressOfE, data: something}); how to read the "data: something " ? example. data: web3.toHex('something') – wakerch Apr 9 '17 at 9:35
  • Get the transaction and look at the input property? Or do you mean getData? – eth Apr 9 '17 at 10:15
  • yeah , i want to access the data:web3.toHex('something') in contract internal , can it be ? – wakerch Apr 9 '17 at 11:53
  • Are you asking for clarity about point1 of answer above? If so, in your contract's fallback function have you tried logging msg.data like it's done in point3? (I can edit the answer's point1 to mention the fallback function.) – eth Apr 10 '17 at 4:57
  • Yes, the LogMsgData function only print the parameter "bb", it didn't print the parameter in {} , ex. look upside demo, thank you – wakerch Apr 11 '17 at 4:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.