Der Ereignis-Parser in web3 bietet eine nette Parsing-Funktion für Ereignisse, und ich verwende ihn zum Protokollieren aller Ereignisse in einer Datei, aber es ist sehr schwierig, einzelne Ereignisse für eine bestimmte Transaktion für automatisierte Tests zu betrachten, da dies unnötig und schwierig ist zur Verwaltung des Nebenläufigkeitsaspekts, wenn keiner vorhanden sein muss.
Wenn ich mit web3 ein Transaktionsergebnis erhalte, habe ich den Transaktionsbeleg in der Hand und das ist der perfekte Zeitpunkt, um das Ergebnis synchron zu prüfen und Pass/Fail-Testkriterien anzuwenden.
Ich möchte den Protokollabschnitt der Quittung analysieren, kann aber in web3 keine Funktion dafür finden. Existiert es?
Tun Sie dies: Sie müssen Code aus web3 ziehen, und es funktioniert am besten, wenn Ihr Frontend mit etwas wie webpack oder browserify gebündelt ist:
var SolidityCoder = require("web3/lib/solidity/coder.js");
var log = receipt.logs[0];
var data = SolidityCoder.decodeParams(["string", "uint"], log.data.replace("0x", ""));
In diesem Fall dekodieren wir Protokolldaten, die zwei Variablen enthalten, eine vom Typ String und eine vom Typ uint.
BEARBEITEN:
Wenn Sie die ABI zur Verfügung haben, können Sie erkennen, welches Ereignis sich auf diese ABI bezieht:
var SolidityCoder = require("web3/lib/solidity/coder.js");
// You might want to put the following in a loop to handle all logs in this receipt.
var log = receipt.logs[0];
var event = null;
for (var i = 0; i < abi.length; i++) {
var item = abi[i];
if (item.type != "event") continue;
var signature = item.name + "(" + item.inputs.map(function(input) {return input.type;}).join(",") + ")";
var hash = web3.sha3(signature);
if (hash == log.topics[0]) {
event = item;
break;
}
}
if (event != null) {
var inputs = event.inputs.map(function(input) {return input.type;});
var data = SolidityCoder.decodeParams(inputs, log.data.replace("0x", ""));
// Do something with the data. Depends on the log and what you're using the data for.
}
SolidityCoder.decodeParams(["string", "uint"], log.data.replace("0x", ""));
Parameter geändert werden, wenn unser Funktionseingabetyp ein Array wie dieses ist: function newObject(bytes32 _id, uint256 number_of_sub_states, bytes32[10] sub_states_types, bytes32[10] sub_states_values, address _owner)
? Vielen Dank.var SolidityCoder = require("web3/lib/solidity/coder.js");
, erhalte ich diese Fehlermeldung: Error: Cannot find module 'web3/lib/solidity/coder.js'
Weißt du, was der Grund ist?, Danke.Sie können die web3.eth.abi.decodeLog
Funktion jetzt verwenden (web3 1.0).
Beispiel aus der Dokumentation:
web3.eth.abi.decodeLog([{
type: 'string',
name: 'myString'
},{
type: 'uint256',
name: 'myNumber',
indexed: true
},{
type: 'uint8',
name: 'mySmallNumber',
indexed: true
}],
'0x0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000748656c6c6f252100000000000000000000000000000000000000000000000000',
['0x000000000000000000000000000000000000000000000000000000000000f310', '0x0000000000000000000000000000000000000000000000000000000000000010']);
> Result {
'0': 'Hello%!',
'1': '62224',
'2': '16',
myString: 'Hello%!',
myNumber: '62224',
mySmallNumber: '16'
}
Timo:
Vielen Dank für den Hinweis. Sie haben mich gezwungen, endlich einige der Interna von web3.js zu verstehen.
Ich habe einen saubereren Weg gefunden, dies zu tun, der alle Eckfälle des eigentlich ziemlich komplizierten Protokollnachrichtenformats abdeckt (z. B. Indizierung). Ich habe gerade SolidityEvent von web3 verwendet, um die bereits getestete Arbeit für mich zu erledigen.
Unten ist der Code. Ich habe diesen Code auf GitHub , einschließlich Testcode .
// XXX move this to a hook function
var SolidityEvent = require("web3/lib/web3/event.js");
Pudding.logParser = function (logs, abi) {
// pattern similar to lib/web3/contract.js: addEventsToContract()
var decoders = abi.filter(function (json) {
return json.type === 'event';
}).map(function(json) {
// note first and third params required only by enocde and execute;
// so don't call those!
return new SolidityEvent(null, json, null);
});
return logs.map(function (log) {
return decoders.find(function(decoder) {
return (decoder.signature() == log.topics[0].replace("0x",""));
}).decode(log);
})
}
Verwenden Sie für web3.js 1.0 Folgendes:
contractInstance.inputs = [{"indexed": false, "name": "_id", "type": "uint256"}]; //event abi
contractInstance._decodeEventABI({data: '0x0'}); //event raw data
Ausgang
{
returnValues:
Result {
'0': '1',
_id: '1',
},
raw: {
data: '0x0'
}
}
Sobald Sie den Transaktionsbeleg ( tr
) haben, kennen Sie die Blocknummer der Transaktion ( tr.blockNumber
). Sie können also Folgendes tun:
myContract.MyEvent (
{},
{fromBlock: tr.blockNumber, toBlock: tr.blockNumber}).
get ().
filter (function (e) {
return e.transactionHash == tr.transactionHash
});
Dadurch wird ein Array aller Ereignisse des Typs zurückgegeben MyEvent
, die durch den Vertrag myContract
in der Transaktion generiert wurden, auf die durch die Transaktionsquittung verwiesen wird tr
.
Mit web3.js 0.20.6.
$ node
> var AllEvents = require('web3/lib/web3/allevents')
undefined
> var decodeEventsForContract = (C, tr) => {
const ae = new AllEvents(C._web3, C.abi, C.address);
// ae.decode mutates the args, so we deep copy
return JSON.parse(JSON.stringify(tr))
.logs
.filter(l => l.address === C.address)
.map(l => ae.decode(l));
}
undefined
> decodeEventsForContract(MyTokenContract, txreceipt);
[ { logIndex: 0,
transactionIndex: 0,
transactionHash: '0xbc68d5ddc391fab84cd633a77dbc815cbc42546a13de9d123f7a5b820faa3cb4',
blockHash: '0xb604998aa0b6bece492530c9cbab494349a31b18a34067f225e1b59613952051',
blockNumber: 21,
address: '0x345ca3e014aaf5dca488057592ee47305d9b3e10',
type: 'mined',
event: 'Transfer',
args:
{ from: '0x0000000000000000000000000000000000000000',
to: '0x627306090abab3a6e1400e9345bc60c78a8bef57',
value: [BigNumber] } },
{ logIndex: 1,
transactionIndex: 0,
transactionHash: '0xbc68d5ddc391fab84cd633a77dbc815cbc42546a13de9d123f7a5b820faa3cb4',
blockHash: '0xb604998aa0b6bece492530c9cbab494349a31b18a34067f225e1b59613952051',
blockNumber: 21,
address: '0x345ca3e014aaf5dca488057592ee47305d9b3e10',
type: 'mined',
event: 'Mint',
args:
{ to: '0x627306090abab3a6e1400e9345bc60c78a8bef57',
value: [BigNumber],
minter: '0x627306090abab3a6e1400e9345bc60c78a8bef57' } } ]
Paul S