Dekodieren von Transaktionseingabedaten mit web3j (Java)

Mein Anwendungsfall ist folgender: Ich möchte, dass ein Daemon überwacht, wie Benutzer mit meinem Smart Contract interagieren. Ich sehe es so, dass ich eingehende Blöcke anschaue und versuche, Eingabedaten mit einer zu meinem Vertrag korrespondierenden Adresse zu dekodieren. Ich konnte in web3J keine Möglichkeit finden, Daten zu dekodieren.

1- Gibt es mit web3J eine Möglichkeit, die Daten zu entschlüsseln?

2- Habe ich eine andere Möglichkeit, mein Ziel zu erreichen, als die Eingabedaten zu entschlüsseln? Ereignisse scheinen mir eine schwierige Wahl zu sein, da ich nicht in der Lage sein werde, alle Dinge einfach zu überwachen. Und diese Methoden können nicht auf Smart Contracts angewendet werden, die ich nicht besitze.

Danke für die Hilfe.

Ein Vorschlag für JS existiert bereits abi-decoder answer . Ein Crawler in JS, der regelmäßig Daten pusht, ist eine Option.
Auch für web3j wurde hier schon ein Vorschlag gemacht . Es hilft jedoch nicht bei der Kompatibilität mit der Bibliothek.

Antworten (4)

Ich schätze, irgendwie für die erste Frage. Wenn Sie sich ansehen, was eine Transaktion ist, ist es für einen Knoten nur eine große lange Bytefolge. Wenn die Bytes in ASCII konvertierbar sind, können Sie verwenden

web3.toAscii()

Das kann dir etwas bringen oder auch nicht. Hier ist zum Beispiel ein TX, den ich auf Ropsten gemacht habe, wo Sie einige lesbare Eingabedaten und einige nicht lesbare Daten zurückerhalten: https://ropsten.etherscan.io/tx/0xe4058b8f612f20600d8aae1230d93b7b5c63398ddde0a3a6aed236659f425c0e (klicken Sie einfach unten auf die Eingabe In ASCII konvertieren )

Der beste (einfachste) Weg, dies zu tun, besteht jedoch darin, den Dapp zu besitzen. Wenn sie also ein Formular ausfüllen, speichern Sie einfach die Eingabedaten. Das Nächstbeste, wie Sie sagten, ist die Verwendung von Ereignissen. Sie sind ärgerlich, aber Sie könnten zu Beginn Ihrer Verträge nur ein langes Ereignis haben:

    contract Test {
       event Input(string desc, address _party, uint _input1, string _input2);  

     function somefunc(uint _input1, string _input2) returns(bool success){
        Input("Input",msg.sender,_input1,_input2);
      return true;
   }
}

Aber für die Verträge anderer Leute haben Sie Pech, da Sie dieses Ereignis nicht haben.

Vielen Dank für die Antwort. Ich habe gerade ein neues Problem auf web3j github hinzugefügt, um eine solche Möglichkeit zu implementieren. Wenn man sich den Code ansieht, sieht es nicht allzu schwer aus, einige Funktionen zurückzuentwickeln und die Zeichenfolge zu dekodieren. Was codiert wird, ist die Funktion <name> , Parameterwert.
Super, tolle Sachen zu wissen. Es scheint, als wäre es in Ordnung, wenn Sie versuchen, es zu decodieren, solange der Vertrag nicht absichtlich versucht, die Eingaben zu verbergen
Auch in diesem Fall stört es mich nicht allzu sehr. Ich werde die Eingabe extrahieren und den Benutzern die Eingabe anbieten, da sie möglicherweise eine Zugriffsberechtigung haben, die meine Server-App nicht hat.
    ERC20 javaToken = ERC20.load(contractAddress, web3, creds, new DefaultGasProvider());
    System.out.println("ALL HISTORY OF TT");
    javaToken.transferEventFlowable(DefaultBlockParameterName.EARLIEST, DefaultBlockParameterName.LATEST)
     .subscribe(event
     -> System.out.println("from: " + event._from + ", to: " + event._to + ", value: " + event._value));    

Ich denke, das wird dir helfen

Die Logik, die ich verwendet habe, ist wie folgt:

web3j.transactionflowable.subscribe(tx -> {

checkIfMyTransaction(tx.getTo, tx.getHash);

});

public void checkIfMyTransaction(String toAddress, String txHash){

// check data base if the address belong to my application and then following logic. This can be contract address or wallet address. 

// if contract address:

EthTransaction ethTransaction=web3j.getTransactionByHash(txHash).send;
Transaction transaction=ethTransaction.getTransaction.get();
transaction.getFrom;
transaction.getBlockNumer;

// Take all info like blocknumber, blockhash etc from above call. For input data, we create new method. 

decodeInput(transaction.getInput);
}

public void decodeInput(String data) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    String inputData = data;
    String method = inputData.substring(0,10);
    log.info("Method >>>>>> " +method);
    String to = inputData.substring(10,74);
    String value = inputData.substring(74);
    Method refMethod = TypeDecoder.class.getDeclaredMethod("decode",String.class,int.class,Class.class);
    refMethod.setAccessible(true);
    Address address = (Address)refMethod.invoke(null,to,0,Address.class);
    log.info("Address>>>>>> " +address.toString());
    Uint256 amount = (Uint256) refMethod.invoke(null,value,0,Uint256.class);
    log.info("amount >>>>>> " +amount);
}

Ich hatte die gleiche Anforderung und fing an, dies in den Web3j-Vertrags-Wrapper-Generator zu hacken. Aufgrund des (IMHO) zu komplizierten Ansatzes habe ich dies aufgegeben und stattdessen meine eigene, eigenständige Java-Bibliothek dafür geschrieben. Sie brauchen web3j überhaupt nicht, Sie müssen nur die ABI von Contract im JSON-Format.

https://github.com/rvüllriede/evm-abi-decoder

Anwendungsbeispiel:

// Abi can be found here: https://etherscan.io/address/0x7a250d5630b4cf539739df2c5dacb4c659f2488d#code
AbiDecoder uniswapv2Abi=new AbiDecoder(pathToAbiJsonFile).getFile());

// tx: https://etherscan.io/tx/0xde2b61c91842494ac208e25a2a64d99997c382f6aaf0719d6a719b5cff1f8a07
String inputData="0x18cbafe5000000000000000000000000000000000000000000000000000000000098968000000000000000000000000000000000000000000000000000165284993ac4ac00000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000d4cf8e47beac55b42ae58991785fa326d9384bd10000000000000000000000000000000000000000000000000000000062e8d8510000000000000000000000000000000000000000000000000000000000000002000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2";

/**
 * #  Name          Type       Data
 * ----------------------------------------------------------------------
 * 0  amountIn      uint256    10000000
 * 1  amountOutMin  uint256    6283178947560620
 * 2  path          address[]  0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
 *                             0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
 * 3  to            address    0xD4CF8e47BeAC55b42Ae58991785Fa326d9384Bd1
 * 4  deadline      uint256    1659426897
 */

DecodedFunctionCall decodedFunctionCall=uniswapv2Abi.decodeFunctionCall(inputData);

System.out.println(decodedFunctionCall.getName()); // prints swapExactTokensForETH

Es ist noch ein junges Projekt, wenn Sie auf Probleme stoßen (z. B. mit bestimmten Verträgen), lassen Sie es mich bitte über den github project issue tracker wissen.

Ich hoffe, das hilft!

Kopieren und fügen Sie dieselbe Antwort nicht mehrmals ein. Sie werden als Spam markiert.
Thx für den Hinweis! Ich habe nur versucht, auch bei der anderen Frage zu helfen. Ich werde stattdessen auf diesen Thread verlinken.