Was ist msg.data?

Ist msg.datagleich {from: addr1, data:something}?

Wie geht man mit den Daten „etwas“ um?

bei Ausführung dieses Codes:

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

Wie liest man die "Daten: etwas"? Zum Beispiel:data: web3.toHex('something')

Danke!

Aktualisierung 4, 7 2017

Demo: Ich habe eine Ereignisfunktion in die sendCoin-Funktion eingefügt.

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

die LogMsgData drucken dies:

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

und wo ist {from: account,data:web3.toHex('test'),gas:500000}?

Herzlich willkommen. Fühlen Sie sich frei, Details über das, was Sie erreichen möchten, und den Kontext anzugeben. Es könnte den Leuten helfen, zu erkennen, was Sie wissen möchten. Schauen Sie hier nach Informationen, die hilfreich sein könnten: ethereum.stackexchange.com/questions/8076/…
Danke, auf alle Parameter kann von msg.data aus zugegriffen werden (EVM-Begriff ist calldata) . ethereum.stackexchange.com/questions/5684/…

Antworten (2)

Für diese Funktion musste ich etwas tiefer in den Inhalt von msg.data eintauchen .

Ich dachte, es wäre erwähnenswert, dass Parameter mit variabler Länge wie Arrays, Bytes und Strings eine komplexere strukturierte msg.data erzeugen.

Bei folgender Methode:

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

Wenn wir diese Methode aufrufen, haben die folgenden Parameter:

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

Die Antwort würde wie folgt aufgeteilt werden:

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

Sie können sehen, dass Strings, Bytes und Arrays alle ihre Datengröße und Daten an das Ende von msg.data angehängt haben. Anstelle der Stelle, an der normalerweise die Parameterdaten erscheinen würden, haben Sie eine 32-Byte-Ganzzahl, die den Speicherort der Parameterdaten beschreibt.

Guter erster Beitrag!
Haha danke! Ich werde die 10-Jahres-Schulden der Auslaugung von Antworten auf den Stapelüberlauf als zurückgezahlt betrachten.
  1. Ja, in web3.eth.sendTransaction({from: ..., to: addressOfE, data: something});, dann in Vertrag E, msg.datawird das etwas sein.

  2. Meistens wird ein Vertrag jedoch msg.dataindirekt und einfach abgewickelt.

Wenn Sie beispielsweise eine Vertragsinstanz in web3.js haben

// 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){ ... });

dann in Solidity, der Vertrag bei 0x78e9 ... hätte so etwas wie

function myStateChangingMethod(string someStr, uint someNumber)und der Vertrag muss nicht analysiert werden msg.data- weil someStrer den Wert haben wird someParam1und someNumberden Wert haben wird 23.

Hinweis: Verwechseln Sie #1 und #2 nicht. Zum Beispiel gibt es databeim Aufrufen in #2 kein Objekt myStateChangingMethod: Verwenden Sie stattdessen einen dritten Parameter.


  1. Ein weiteres Beispiel ist die Verwendung von Soliditycall . Zum Beispiel sendet ein Vertrag C eine Nachricht an D mit D.call(something), dann msg.datawird das etwas sein.

Hier ist ein "Beweis", den Sie in Remix ausprobieren können:

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);
    }
}

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

danke für deine Antwort, aber bei der Ausführung web3.eth.sendTransaction({from: ..., to: addressOfE, data: something}); Wie liest man die "Daten: etwas"? Beispiel. Daten: web3.toHex('etwas')
Holen Sie sich die Transaktion und schauen Sie sich die inputImmobilie an? Oder meinst du getData?
Ja, ich möchte auf die Daten zugreifen: web3.toHex ('etwas') im Vertragsinternen, kann das sein?
Bitten Sie um Klarheit zu Punkt 1 der obigen Antwort? Wenn ja, haben Sie in der Fallback-Funktion Ihres Vertrags versucht, sich msg.datawie in Punkt 3 zu protokollieren? (Ich kann den Punkt 1 der Antwort bearbeiten, um die Fallback-Funktion zu erwähnen.)
Ja, die LogMsgData-Funktion druckt nur den Parameter "bb", sie hat den Parameter nicht in {} gedruckt, z. siehe oben Demo, danke
Sie müssen tun, myContractInstance.myStateChangingMethod('someParam1', 23, web3.toHex('test'), {value: 200, gas: 2000}, function(err, result){ ... });anstatt myContractInstance.myStateChangingMethod('someParam1', 23, {value: 200, gas: 2000, data:web3.toHex('test') }, function(err, result){ ... });ich werde der Antwort eine Notiz hinzufügen, und diese Kommentare sollten wahrscheinlich bereinigt werden, und bei Bedarf sollte eine weitere Frage gestellt werden.
Hallo, @eth, nachdem ich den C- und D-Code des Vertrags geschrieben habe, erhalte ich in Remix einen Fehler, der besagt, dass der Arrayify-Wert ungültig ist. Wie kann ich dein Beispiel zum Laufen bringen? transact to C.test errored: Error encoding arguments: Error: invalid arrayify value (argument="value" value=["0x00""0xaa""0xff"] code=INVALID_ARGUMENT version=bytes/5.5.0)
@IlanAizelmanWS Remix hat sich stark verändert. Ich denke, eine Frage wie diese zu posten, aber 2022 im Titel zu verwenden, wird Ihnen helfen? ethereum.stackexchange.com/questions/13483/…