¿Qué es msg.data?

es msg.dataigual a {from: addr1, data:something}?

¿Cómo manejar los datos 'algo'?

al ejecutar este código:

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

¿Cómo leer los "datos: algo"? Por ejemplo:data: web3.toHex('something')

¡gracias!

actualización 4, 7 2017

demostración: puse una función de evento en la función sendCoin.

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

LogMsgData imprime esto:

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

y donde esta {from: account,data:web3.toHex('test'),gas:500000}?

Bienvenidos. Siéntase libre de incluir detalles sobre lo que está tratando de lograr y el contexto. Podría ayudar a las personas a reconocer lo que quieres saber. Eche un vistazo aquí a la información que podría ayudar: ethereum.stackexchange.com/questions/8076/…
Gracias, se puede acceder a todos los parámetros desde msg.data (el término EVM es calldata). ethereum.stackexchange.com/questions/5684/…

Respuestas (2)

Tuve que profundizar un poco más en el contenido de msg.data para esta característica .

Pensé que valdría la pena señalar que los parámetros de longitud variable, como matrices, bytes y cadenas, producen un msg.data estructurado más complejo.

Dado el siguiente método:

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

Si llamamos a este método los siguientes parámetros:

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

La respuesta se dividiría así:

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

Puede ver que las cadenas, los bytes y las matrices tienen su tamaño de datos y datos adjuntos al final de msg.data. En lugar de donde normalmente aparecerían los datos de parámetros, tiene un entero de 32 bytes que describe la ubicación de los datos de parámetros.

¡Buena primera publicación!
¡Jaja gracias! Consideraré la deuda de 10 años de las respuestas de lixiviación del desbordamiento de la pila pagada.
  1. Sí, en web3.eth.sendTransaction({from: ..., to: addressOfE, data: something});, luego en el contrato E, msg.dataserá el algo.

  2. Sin embargo, la mayoría de las veces un contrato se maneja msg.dataindirecta y fácilmente.

Por ejemplo, si tiene una instancia de contrato en 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){ ... });

luego en Solidity, el contrato en 0x78e9... tendría algo como

function myStateChangingMethod(string someStr, uint someNumber)y el contrato no tiene que analizarse msg.data, porque someStrtendrá el valor someParam1y someNumbertendrá el valor 23.

Nota: No mezcle #1 y #2. Por ejemplo, no hay ningún dataobjeto cuando se invoca myStateChangingMethoden el n.° 2: use un tercer parámetro en su lugar.


  1. Otro ejemplo es el uso de Soliditycall . Por ejemplo, un contrato C envía un mensaje a D usando D.call(something), entonces msg.dataserá el algo.

Aquí hay una "prueba" para probar en 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);
    }
}

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

gracias por su respuesta, pero cuando se ejecuta web3.eth.sendTransaction({from: ..., to: addressOfE, data: something}); ¿Cómo leer los "datos: algo"? ejemplo. datos: web3.toHex('algo')
Obtener la transacción y mirar la inputpropiedad? ¿O quieres decir getData?
sí, quiero acceder a los datos: web3.toHex('algo') en el contrato interno, ¿puede ser?
¿Está pidiendo claridad sobre el punto 1 de la respuesta anterior? Si es así, en la función de respaldo de su contrato, ¿ha intentado iniciar sesión msg.datacomo se hace en el punto 3? (Puedo editar el punto 1 de la respuesta para mencionar la función de respaldo).
Sí, la función LogMsgData solo imprime el parámetro "bb", no imprime el parámetro en {} , ej. mirar al revés demostración, gracias
Debe hacer myContractInstance.myStateChangingMethod('someParam1', 23, web3.toHex('test'), {value: 200, gas: 2000}, function(err, result){ ... });en lugar de myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000, data:web3.toHex('test') }, function(err, result){ ... });agregar una nota a la respuesta, y estos comentarios probablemente deberían limpiarse y se debe hacer otra pregunta si es necesario.
Hola, @eth, después de escribir el código C y D del contrato, recibo un error en Remix que dice valor de matriz no válido. ¿Cómo puedo hacer que tu ejemplo funcione? Transact to C.test con error: Error al codificar argumentos: Error: valor de arrayify no válido (argument="value" value=["0x00""0xaa""0xff"] code=INVALID_ARGUMENT version=bytes/5.5.0)
@IlanAizelmanWS Remix ha cambiado mucho. Creo que publicar una pregunta como esta pero usando 2022 en el título, ¿te ayudará? ethereum.stackexchange.com/questions/13483/…