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
Sie können web3.toAscii(transactionID.input)
die Daten in einem lesbaren Format zurückgeben.
Lesen Sie web3.toAscii
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.
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])
});
})();
Beachten Sie, dass Sie hierfür die ABI des Vertrages benötigen.
Verwenden @ethersproject/abi
Sie , 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.
Diese JavaScript/Node.js-Bibliothek kann Smart-Contract-Eingabedaten und Eingabedaten zur Vertragserstellung dekodieren, wenn der JSON-Abi gegeben ist:
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.
In Python erfolgt dies mit der Methode decode_function_input Contract:
contract.decode_function_input(transaction.input)
sehen:
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.
SwapnilKumbhar
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ückNiksmac
achso
hexToAscii()
, versuchen Sie es mitweb3.hexToString()
! Hat für mich funktioniert, als sich wedertoAscii
nochtoUtf8
richtig verhalten haben.Adamc
web3.toAscii is not a function
. Um dieses Problem zu beheben, verwenden Sieweb3.utils.toAscii()
stattdessen