I know that there is a method called getDecodedLogs to get the event log data corresponding to the transaction. The first parameter is TransactionResultReceipt, and the second parameter is contractABI. However, no matter how I fill in the TransactionResultReceipt, I get an error: receipts.reduce is not a function. Should I fill in all the data returned by this transaction, or only the event data obtained? But I have tried everything, but it still doesn’t work. Is there any simple case that I can refer to?
Hey @william I’m sorry that we don’t have a documented use case for this. But generally you would pass in the receipts of the invocation call result
Could you share a code snippet of how you are populating the TransactionResultReceipt
Array to be passed to getDecodedLogs
?
It may also be helpful for us if you explained what you are trying to accomplish at high level so that we can understand why you are trying to get the event log data.
Thanks for reply @maschad
my tx info blow:
{
type: 0,
scriptGasLimit: <BN: 0x23348>,
scriptLength: <BN: 0x18>,
scriptDataLength: <BN: 0x7e>,
policyTypes: 8,
inputsCount: 2,
outputsCount: 2,
witnessesCount: 1,
receiptsRoot: '0x00f032b95ee79a616acd92392e342a2bd26fc88377f837b946aa870fee511a1e',
script: '0x724028c0724428985d451000724828a02d41148a24040000',
scriptData: '0x00000000000003e8f8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad078f57764df7c07f6fe33ff3189f9369bf0ed2b5d1c4d24269567609186dedf63f00000000000028f000000000000029000000000000000008726567697374657200000000000000066d796e616d650000000000000001',
policies: [ { type: 8, data: <BN: 0x4ae3> } ],
inputs: [
{
type: 1,
txID: '0xc5b36f02e140f51618eecc4742c149832de1062482f7257ff7b402511b3c3271',
outputIndex: 0,
balanceRoot: '0x0000000000000000000000000000000000000000000000000000000000000000',
stateRoot: '0x8702e549de831ac9dd7317e26729c18dc05f54f5510d84bf4d28ae828f1c6863',
txPointer: [Object],
contractID: '0x8f57764df7c07f6fe33ff3189f9369bf0ed2b5d1c4d24269567609186dedf63f'
},
{
type: 0,
txID: '0xc5b36f02e140f51618eecc4742c149832de1062482f7257ff7b402511b3c3271',
outputIndex: 1,
owner: '0x3e15247411a05edc60391d7410eabc3d0ee2eb5f8b2bd8102b41e7e94b22fbf2',
amount: <BN: 0x1f192c>,
assetId: '0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07',
txPointer: [Object],
witnessIndex: 0,
predicateGasUsed: <BN: 0x0>,
predicateLength: <BN: 0x0>,
predicateDataLength: <BN: 0x0>,
predicate: '0x',
predicateData: '0x'
}
],
outputs: [
{
type: 1,
inputIndex: 0,
balanceRoot: '0xc329289089acc5d1db406cfecbaf64a596a7ac89fab3a70b111d7edb8bca0168',
stateRoot: '0xf94a394ee2af558bd0d7585415ad7ac88f69844c0c0c19762ace6f5a1b8ed4d0'
},
{
type: 2,
to: '0x3e15247411a05edc60391d7410eabc3d0ee2eb5f8b2bd8102b41e7e94b22fbf2',
amount: <BN: 0x1eca61>,
assetId: '0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07'
}
],
witnesses: [
{
dataLength: 64,
data: '0x9a5062d0a94216c852d46004972b51e68fdd2a24a299a1ed6052e3ee10a7851a97be672fcc03e168dbccc94b0f6df4a8b598f51a2dfc3cd1bd8e7f30da06a6c0'
}
]
}
my event data below:
{
archiveHeight: 3290425,
nextBlock: 3198752,
totalExecutionTime: 13,
data: [
{
blockHeight: 3198751,
txId: '0xe639c7a0feb8a79e5a44fc9bdaa61b297ec750e19684f0911a29bc68d45cb4e7',
receiptIndex: 38,
receiptType: 6,
rootContractId: '0x8f57764df7c07f6fe33ff3189f9369bf0ed2b5d1c4d24269567609186dedf63f',
ra: 0,
rb: 5566286078492628000,
pc: 28964,
is: 11688,
ptr: 67106273,
len: 75,
digest: '0xa7e7d0e66fbec45f1432ca25770c1b7824454673c088316974e6d88292aec33d',
data: '0x40000000667753a24000000068588722000000000000000b6d796e616d652e7377617900000000000000003e15247411a05edc60391d7410eabc3d0ee2eb5f8b2bd8102b41e7e94b22fbf2'
}
]
}
I using hyperfuel get the event log data.
I want use getDecodedLogs() to parse the event log data.
How should I do?
The reason why event log data needs to be obtained is because the dapp has a market function. People can place orders, cancel orders, and purchase orders. Therefore, event log data needs to be scanned and processed for these behaviors and put into a centralized database. , and then the front-client reads these data processed interfaces to display the market order list and implement corresponding market buying and selling display and execution functions.
Hey @william thanks for sharing this information.
It seems like what you shared is the TransactionScript
which is used to create the transaction request. As I had mentioned before the getDecodedLogs
function expects an Array of TransactionResultReceipt
.
I’ve found your transaction on the explorer here.
If you scroll down on the json
output you should see an array of receipts
, if you pass that array of receipts
to getDecodedLogs
along with the other parameters required and it should successfully decode the logs.
I’ve shared it here so you can copy/paste.
receipts:[
{
__typename:"Receipt",
id:null,
to:"0x8f57764df7c07f6fe33ff3189f9369bf0ed2b5d1c4d24269567609186dedf63f",
pc:"11688",
is:"11688",
toAddress:null,
amount:"1000",
assetId:"0xf8f8b6283d7fa5b672b530cbb84fcccb4ff8dc40f8176ef4544ddb1f1952ad07",
gas:"113150",
param1:"10480",
param2:"10496",
val:null,
ptr:null,
digest:null,
reason:null,
ra:null,
rb:null,
rc:null,
rd:null,
len:null,
receiptType:"CALL",
result:null,
gasUsed:null,
data:null,
sender:null,
recipient:null,
nonce:null,
contractId:null,
subId:null
},
{
__typename:"Receipt",
id:"0x8f57764df7c07f6fe33ff3189f9369bf0ed2b5d1c4d24269567609186dedf63f",
to:null,
pc:"28964",
is:"11688",
toAddress:null,
amount:null,
assetId:null,
gas:null,
param1:null,
param2:null,
val:null,
ptr:"67106273",
digest:"0xa7e7d0e66fbec45f1432ca25770c1b7824454673c088316974e6d88292aec33d",
reason:null,
ra:"0",
rb:"5566286078492628248",
rc:null,
rd:null,
len:"75",
receiptType:"LOG_DATA",
result:null,
gasUsed:null,
data:"0x40000000667753a24000000068588722000000000000000b6d796e616d652e7377617900000000000000003e15247411a05edc60391d7410eabc3d0ee2eb5f8b2bd8102b41e7e94b22fbf2",
sender:null,
recipient:null,
nonce:null,
contractId:null,
subId:null
},
{
__typename:"Receipt",
id:"0x8f57764df7c07f6fe33ff3189f9369bf0ed2b5d1c4d24269567609186dedf63f",
to:null,
pc:"29320",
is:"11688",
toAddress:null,
amount:null,
assetId:null,
gas:null,
param1:null,
param2:null,
val:null,
ptr:"67105249",
digest:"0x6aac4c241ff23f5acc8ccd969908a220cb3303818383f7a6a414688dd87fdb3e",
reason:null,
ra:null,
rb:null,
rc:null,
rd:null,
len:"19",
receiptType:"RETURN_DATA",
result:null,
gasUsed:null,
data:"0x000000000000000b6d796e616d652e73776179",
sender:null,
recipient:null,
nonce:null,
contractId:null,
subId:null
},
{
__typename:"Receipt",
id:null,
to:null,
pc:"10388",
is:"10368",
toAddress:null,
amount:null,
assetId:null,
gas:null,
param1:null,
param2:null,
val:"1",
ptr:null,
digest:null,
reason:null,
ra:null,
rb:null,
rc:null,
rd:null,
len:null,
receiptType:"RETURN",
result:null,
gasUsed:null,
data:null,
sender:null,
recipient:null,
nonce:null,
contractId:null,
subId:null
},
{
__typename:"Receipt",
id:null,
to:null,
pc:null,
is:null,
toAddress:null,
amount:null,
assetId:null,
gas:null,
param1:null,
param2:null,
val:null,
ptr:null,
digest:null,
reason:null,
ra:null,
rb:null,
rc:null,
rd:null,
len:null,
receiptType:"SCRIPT_RESULT",
result:"0",
gasUsed:"144200",
data:null,
sender:null,
recipient:null,
nonce:null,
contractId:null,
subId:null
}
],
Please let me know if this resolves your issue.
Thanks for your reply @maschad
I pasted the receipts in, but it still cannot be parsed. What I get is empty array.
At the same time, I still have a question, how do I get this receipts through code, even if it still cannot be parsed now.
At the same time, I have another question. I can easily obtain the log data corresponding to the contract through hyperfuel, but this data needs to be parsed. Is there a better way to parse this log data?
my event data below:
{
archiveHeight: 3290425,
nextBlock: 3198752,
totalExecutionTime: 13,
data: [
{
blockHeight: 3198751,
txId: '0xe639c7a0feb8a79e5a44fc9bdaa61b297ec750e19684f0911a29bc68d45cb4e7',
receiptIndex: 38,
receiptType: 6,
rootContractId: '0x8f57764df7c07f6fe33ff3189f9369bf0ed2b5d1c4d24269567609186dedf63f',
ra: 0,
rb: 5566286078492628000,
pc: 28964,
is: 11688,
ptr: 67106273,
len: 75,
digest: '0xa7e7d0e66fbec45f1432ca25770c1b7824454673c088316974e6d88292aec33d',
data: '0x40000000667753a24000000068588722000000000000000b6d796e616d652e7377617900000000000000003e15247411a05edc60391d7410eabc3d0ee2eb5f8b2bd8102b41e7e94b22fbf2'
}
]
}
The event data structure in my contract is like this:
......
struct BuyEvent {
time: u64,
price: u64,
strings: String,
buyer: Identity,
seller: Identity,
}
......
log(BuyEvent {
time: timestamp(),
price: market.unwrap().price,
strings: String::from_ascii_str(_str),
seller: market.unwrap().owner,
buyer: msg_sender().unwrap(),
});
Hi @william thanks for the clarification, I suspect there may be a problem with how you are passing the ABI.
The proposed method of passing those receipts and the corresponding ABI / ABIs to getDecodedLogs
should work, please note that if there are multiple contract calls, you will have to pass the externalAbis
as well. Please verify the ABIs are correct.
To answer your second question, how you would retrieve the logs from submitting a transaction
await wallet.fund(request, txCost);
const tx = await wallet.sendTransaction(request);
// These are the logs
const { logs } = await tx.waitForResult();
and here’s how you would do a contract call.
const { logs } = await callTest
.multiCall([
advancedLogContract.functions
.test_log_from_other_contract(10, otherLogId)
.addContracts([otherAdvancedLogContract]),
callTest.functions.boo(testStruct),
configurable.functions.echo_struct(),
coverage.functions.echo_str_8('fuelfuel'),
])
.call();
If you are still having a problems, please open a bug report on the repository with clear instructions for reproduction of the error.
Unfortunately, I was not able to solve this problem. What I want is to scan the log data corresponding to my contract on the chain and parse it, not to obtain the data when calling. I plan to use hyperindex. It is said that it can scan the log data on the chain and parse it normally, but I still hope that the official can improve this function.
Hi @william I’m sorry that hasn’t resolved it. Could you share the Contract ABI and I can take a look?
I’m interested to hear the results of the hyperindex query, please share if that resolves the issue.
Thank you, using hyperindex I have been able to set the log data to the database.
As you’ve got the event data (data
property on the receipt), and you know the shape of the log, you could instantiate the StructCoder
directly. But as @maschad states, the easiest way to do this is via the ABI, then you can just call the ABICoder
directly rather than having to manage coders yourself, as documented here.
But heres how I’d expect it to work based off your description:
const data = arrayify(
'0x40000000667753a24000000068588722000000000000000b6d796e616d652e7377617900000000000000003e15247411a05edc60391d7410eabc3d0ee2eb5f8b2bd8102b41e7e94b22fbf2'
);
const identityCoder = new EnumCoder('Identity', {
Address: new StructCoder('Address', {
bits: new B256Coder(),
}),
ContractId: new StructCoder('ContractId', {
bits: new B256Coder(),
}),
});
const buyEventCoder = new StructCoder('BuyEvent', {
time: new BigNumberCoder('u64'),
price: new BigNumberCoder('u64'),
strings: new StdStringCoder(),
buyer: identityCoder,
seller: identityCoder,
});
const [decoded] = buyEventCoder.decode(data, 0);
However I’m getting some decoding errors so I expect the shape isn’t as we expect. So if you share the ABI, we can can match it to a logId
, which will equate to a type which we can then pass to the ABICoder
. All the coders and their expected bytes can be found here.
Thank you @danielbate , I redeployed the contract, re-obtained the log data. After using your method, I can successfully decode the data. Thank you very much. There are two methods we can use now. One is to obtain the log data and then decode the data. The other is to use hyperindex.
This topic was automatically closed 20 days after the last reply. New replies are no longer allowed.