Wie entschlüsselt man Eingabedaten aus einer Transaktion?

Ich sende mit dem folgenden Befehl eine Transaktion an ein Konto mit einigen Daten:

eth.sendTransaction({from:eth.accounts[0],to:eth.accounts[1],value:web3.toWei(1,"ether"),data:web3.toHex("http://localhost:8545")})

Ich erhalte dieses Ergebnis, indem ich das Protokoll der Transaktion extrahiere (mit testRPC ausgeführt):

   tx hash         : 0xf654aee5ed23f9aeebd2d73c69c7b9c21a4862787966d09bcb09ed44efc1f252
   nonce           : 0
   blockHash       : 0x6ff8a0e3ac606abd2ede4331b82af52a0daa98448025051fb3b3d50f749aa49f
   blockNumber     : 1
   transactionIndex: 0
   from            : 0xf64918835bc21dff9e8210a807b3964d1be35dd0
   to              : 0x08f986b7535c2b72687d3cb193135f1c6e27c336
   value           : 1000000000000000000
   time            : 1483614904 Thu, 05 Jan 2017 11:15:04 GMT
   gasPrice        : 1
   gas             : 90000
   input           : 0x687474703a2f2f6c6f63616c686f73743a38353435

Ich möchte die letzte Zeile "input" entschlüsseln und versuchen, " http://localhost:8545 " zu erhalten. Ich habe hier und hier einige Arbeiten gesehen, die meiner Frage ähneln , aber das funktioniert in meinem Fall nicht. Außerdem habe ich es versucht .toString('hex')), aber es bleibt als Hex.

Wie kann ich das erreichen?

Danke im Voraus

Antworten (11)

Sie können web3.toAscii(transactionID.input)die Daten in einem lesbaren Format zurückgeben.

Lesen Sie web3.toAscii

Dies funktioniert mit einer Transaktion, die über die Befehlszeile gesendet wird, aber wenn ich Transaktionen mit web3 an meinen Vertrag sende, contract.addBalance.sendTransaction(contractAddress, {from: senderAddress, to: contractAddress, gas:1000000, value: web3.toWei(7, "ether"),data:web3.toHex("http://localhost:8545")})wenn ich versuche, web3.toAscii (transaction.input) abzurufen, gibt es einige zufällige symbolische Werte zurück
@SwapnilKumbhar überprüfen Sie Ihre Datenparameter.
Wenn Sie bei der Verwendung von Codierungsproblemen auftreten hexToAscii(), versuchen Sie es mit web3.hexToString()! Hat für mich funktioniert, als sich weder toAsciinoch toUtf8richtig verhalten haben.
Abhängig von der Version von web3, die Sie verwenden, kann der Fehler auftreten web3.toAscii is not a function. Um dieses Problem zu beheben, verwenden Sie web3.utils.toAscii()stattdessen

Um Daten zu decodieren, können Sie eine Bibliothek namens abi-decoder verwenden

Sie müssen eine ABI für den Smart Contract bereitstellen, den Sie decodieren möchten, und dann einfach die Eingabedaten einfügen. Sehr einfach.

Der einzige Nachteil würde passieren, wenn Ihre Eingabedaten Smart Contract Creation „Constructor“ sind, dann müssen Sie in diesem Fall die Bibliothek ändern, um dies zu berücksichtigen.

Was ist der beste Weg, um die Smart Contract-Erstellungsdaten zu entschlüsseln?
In diesem Fall ist es am besten, meine Version der oben genannten Bibliothek zu verwenden. Sie finden sie hier. Importieren Sie sie einfach und verwenden Sie sie in Ihrem Projekt. Es wird funktionieren. github.com/Neufund/smart-contract-watch/blob/master /src/…
leider hat die von Ihnen vorgestellte Lösung nicht funktioniert github.com/Neufund/smart-contract-watch/issues/70

Wenn Sie von der Ethers js- Bibliothek gehört haben, bietet sie eine fantastische Funktion namens parseTransaction . Ich habe sie nach sehr langer Suche gefunden, da sie in keinem Online-Forum erwähnt wurde, und ich lerne immer noch viel über dieses Zeug.

Aber ich fand es am besten zum Decodieren von Verträgen und zugehörigen Funktionsaufrufen.

    const ethers = require('ethers');
    const ABI = require('./abi.json'); // Contract ABI
    const provider = ethers.getDefaultProvider();

    const inter = new ethers.utils.Interface(ABI);

    (async() => {
      const tx = await provider.getTransaction('0xa30e9e19967bd3307feeddcf99b26be0d804cdc0ade6929f3b9328a95e388b4c');
        const decodedInput = inter.parseTransaction({ data: tx.data, value: tx.value});
    
        // Decoded Transaction
        console.log({
            function_name: decodedInput.name,
            from: tx.from,
            to: decodedInput.args[0],
            erc20Value: Number(decodedInput.args[1])
          });        
    })();

UI-Tools

Beachten Sie, dass Sie hierfür die ABI des Vertrages benötigen.

Knotenpakete

Empfehlung

Verwenden @ethersproject/abiSie , das ist der sicherste Ansatz von allen. Ethers ist in Tausenden von Ethereum-Projekten kampferprobt und es gibt wahrscheinlich keinen Fehler in der Implementierung der ABI-Codierung/Decodierung.

Wir haben ein nettes Werkzeug zum Dekodieren gemacht. Fügen Sie einfach den Transaktions-Hash in die Eingabe ein und erhalten Sie das Ergebnis. Überprüfen Sie es Es funktioniert mit Mainnet, Kovan, Ropsten und Rinkeby, aber der Vertragscode muss in Etherscan überprüft werden. Wir verwenden die Etherscan-API, um Transaktions- und Vertragsdaten abzurufen, und web3 zum Entschlüsseln.

Es wird nicht empfohlen, nur Link-Antworten zu schreiben. Es sollte gut sein, wenn Sie eine kleine Erklärung über die Seite hinzufügen, z. B. welche Tools / Bibliotheken Sie für den Decoder verwenden.
@WTD Es wäre schön, wenn es auch eine Rohtransaktion (signiert und unsigniert) als Eingabe akzeptieren würde, nicht nur einen TX-Hash.
Wir haben gerade unser Tool aktualisiert. Jetzt ist es einfach, die Daten (Eingabe und Ausgabe) aller Aufrufe zu überprüfen, die während der Transaktion ausgeführt werden.
Es scheint, dass dieses Tool nicht mehr funktioniert – das Einfügen einer txid und das Klicken auf „Decode“ bewirkt nichts.

Diese JavaScript/Node.js-Bibliothek kann Smart-Contract-Eingabedaten und Eingabedaten zur Vertragserstellung dekodieren, wenn der JSON-Abi gegeben ist:

https://github.com/miguelmota/ethereum-input-data-decoder

Eine vollständige Definition dessen, was Sie zu decodieren versuchen (das Eingabedatenfeld), finden Sie hier: https://github.com/ethereum/wiki/wiki/Ethereum-Contract-ABI . Es ist schwierig, aber ich konnte C++ schreiben, das die in den Transaktionen aufgezeichneten Funktionsargumente vollständig analysiert. Für Ihre spezielle Frage ist die Dekodierung des Hex richtig, aber für den allgemeineren Fall der Eingabedaten, die den Funktionsaufruf und seine Parameter darstellen, müssen Sie die in diesem Dokument beschriebene Schnittstelle dekodieren.

Ihr C++ ist nicht zufällig Open Source, oder?
Wow. Ich brauchte ein Jahr, um zu antworten, aber "ja", es ist Open Source (es war nicht im Januar). Weitere Informationen finden Sie hier: quickblocks.io .

In Python erfolgt dies mit der Methode decode_function_input Contract:

contract.decode_function_input(transaction.input)

sehen:

Ich sehe in der ursprünglichen Frage keinen Vertrag, nur eine Transaktion. Sind das nicht zwei verschiedene Dinge?

Erwägen Sie die Verwendung von truffle und abi-decoder :

# compile contracts to generate ABIs
truffle compile

# let's do it from truffle console
truffle console

const abiDecoder = require('abi-decoder');

# take ABIs of required contracts
const { abi: abi1 } = require('./build/contracts/sc1.json');
const { abi: abi2 } = require('./build/contracts/sc2.json');
..

# register ABIs
abiDecoder.addABI(abi1);
abiDecoder.addABI(abi2);
..

# take 'TX data' of transaction & decode it (take for example the first transaction in  100th block)

let input = (await web3.eth.getTransactionFromBlock(100, 0)).input

abiDecoder.decodeMethod(input);

/* result
{
  name: 'request',
  params: [
    { name: '_control', value: 'control', type: 'string' },
    { name: '_tId', value: 'tid', type: 'string' },
    { name: '_number', value: 'inumber', type: 'string' }
  ]
}
*/

ich benutze"web3": "^1.6.1",

const data = await web3.eth.getTransaction(txHash);
return web3.eth.abi.decodeParameters(
      // ERC20 transfer method args
      [
        { internalType: 'address', name: 'recipient', type: 'address' },
        { internalType: 'uint256', name: 'amount', type: 'uint256' },
      ],
      `0x${txData.input.substring(10)}`
    );

Die ersten 4 Bytes der Eingabe sind die Signatur der Methode

Ausgang:

 {
    "0": "0x45d8253c7980d5718C5Fa3626d446886Fd857CfE",
    "1": "160750000000000000000",
    "__length__": 2,
    "recipient": "0x45d8253c7980d5718C5Fa3626d446886Fd857CfE",
    "amount": "160750000000000000000"
  }

Dokumente: https://web3js.readthedocs.io/en/v1.2.11/web3-eth-abi.html#decodeparameters

Zärtlich zu verwenden ist eine gute Option. Wenn Sie einen verifizierten Vertrag hinzufügen (oder die abi/sources haben, die Sie direkt ausschreiben können), können Sie rohe Transaktionsdaten liefern und eine Simulation damit ausführen, und es wird Ihnen angezeigt, wie die Eingabe dekodiert wird.