1

I would like to get the result of a function by listening its emitted event. These are two pieces of code of my contrats

CONTRACT 1:

function createTradeableContract() public stopInEmergency returns(address subcontractAddr) {
        TradeableContract tc = new TradeableContract(msg.sender); 
        contracts.push(tc);
        return tc;      
    }

CONTRACT 2:

function TradeableContract (address ownerAddr) public {
        owner = ownerAddr;
        NewOwnerEvent(0x0,owner);
}

I am using web3.0 1.0 beta. I wrote this code. I cannot understand why I cannot see the event in the logs.

self.contractCreator.methods.createTradeableContract().send({from: selectedAccount})
        .once('receipt', function(receipt){ 
            console.log("receipt");
            console.log(receipt);                                
            console.log("eventos...");
            console.log(receipt.logs); //it is undefined

         })
        .on('error', function(error){ 
            console.log("erro");
            console.log(error);
         })
        .then( receipt => 
        {
            console.log(receipt);
            console.log("events...");
            console.log(receipt.logs); //it is undefined

        })
        .catch (error => console.warn(error));

If I use Remix, I can see the event in the console (below).

[
    {
        "from": "0x8722aff990eda4d2d11915705076af5823f5f14c",
        "topic": "0x09f86d61eb5d6904c1fa8e5f071f171ec90eccc6e0a7b61d563a7d693db815f6",
        "event": "NewOwnerEvent",
        "args": {
            "0": "0x0000000000000000000000000000000000000000",
            "1": "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c",
            "old": "0x0000000000000000000000000000000000000000",
            "current": "0xCA35b7d915458EF540aDe6068dFe2F44E8fa733c",
            "length": 2
        }
    }
]

Since I cannot get the returned value of a function that change state, I am using events. But... What is the best way to get the emmited event after invoking the function?

5
  • What is the output when you run the web3 code? Commented Aug 21, 2018 at 0:32
  • receipt.logs is undefined Commented Aug 21, 2018 at 0:43
  • I'm not the strongest player with the 1.0 beta changes, but I suspect the conceptual oversight is that there two async processes, not one. The first async request returns a receipt. You need to wait for the transaction to mine, and then get the transaction (also, async), and then you will see your logs. Remix makes this very convenient, to the point of hiding it, so it's easy to overlook. That would be the necessary process in the old web3 and probably still is unless they've wrapped it up two steps into one. Commented Aug 21, 2018 at 0:57
  • As far as I understood, there are many callbacks. web3js.readthedocs.io/en/1.0/callbacks-promises-events.html. According with this link, the "then" is called when the transaction is mined. So, I think that the event should be available. Commented Aug 21, 2018 at 1:01
  • For the watching event when calling smart contract; I'm using this code and it working fine ``` event.watch(function (err, response) { if(response.event == 'NewOwnerEvent') { self.setState({ tx_success: true, isLoading: false }); } }); ```
    – Tony Dang
    Commented Aug 21, 2018 at 3:29

3 Answers 3

1

When you send a transaction, you get a transaction receipt.

The next step is to wait for the transaction to be mined, then inspect the transaction, and there you will see the logs.

Higher levels in the stack confuse this issue, but it is always there.

  1. Remix does it for you. It also uses replay so you can see returned values. Logs and returned values are just given - two things you don't find when making your own code with Web3.
  2. Truffle test does it for you. When you return myContract.someFunction(), it returns the promise of the mined transaction. Then, you can carry on with then... Again, this tends to fog up the windshield a little bit because these convenience features are doing things we have to do for ourselves in other circumstances.

Have a look at this library that returns the promise of the mined transaction. This, so one can create concise code that 1) sends the transaction and waits for a receipt, then 2) waits for the transaction to be mined and returns the transaction. https://gist.github.com/xavierlepretre/88682e871f4ad07be4534ae560692ee6

Your log will be there.

That library predates Web3 Beta 1.0. Perhaps a kind soul will chime in and describe how to refactor. The takeaway is you should not expect transaction logs in receipts. It's not inconsistent, but Remix and truffle test can make it seem so.

Hope it helps.

0

You can refer to this document to know how to watch smart contract event

https://github.com/ethereum/wiki/wiki/JavaScript-API#contract-events

1
  • Thank you for your answer. I am trying to get the specific event that was emmited during the function execution. Also, I am using web3 1.0. Commented Aug 21, 2018 at 12:32
0

I changed the contract 1 to emit a event there.

function createTradeableContract() public stopInEmergency returns(address subcontractAddr) { TradeableContract tc = new TradeableContract(msg.sender); contracts.push(tc); NewTradeableWallet(address(tc)); return tc;
}

Now I can see the event in the receipt.

{transactionHash: "0xcc1976e7e355f7a51ed20f0dd34e05e026dd7d165aa4a3ade457bb6a1c3ac94a", transactionIndex: 0, blockHash: "0x51a2fc3486ac8a5f8f48cb901d51048ba6d742b355e16f8ea2a385f02e8852b7", blockNumber: 21, gasUsed: 731488, …}
blockHash:     "0x51a2fc3486ac8a5f8f48cb901d51048ba6d742b355e16f8ea2a385f02e8852b7"
blockNumber: 21
contractAddress: null
cumulativeGasUsed: 731488
events: 
  0:
{logIndex: 0, transactionIndex: 0, transactionHash: "0xcc1976e7e355f7a51ed20f0dd34e05e026dd7d165aa4a3ade457bb6a1c3ac94a", blockHash: "0x51a2fc3486ac8a5f8f48cb901d51048ba6d742b355e16f8ea2a385f02e8852b7", blockNumber: 21, …}
NewTradeableWallet:
address: "0x4E72770760c011647D4873f60A3CF6cDeA896CD8"
blockHash:    "0x51a2fc3486ac8a5f8f48cb901d51048ba6d742b355e16f8ea2a385f02e8852b7"
blockNumber:21
event: "NewTradeableWallet"
id: "log_6608b960"
logIndex: 1

................

Note that the event did not came on receipt.logs. Anyway, I can now take the returned vaue, that was my initial problem.

But I still do not understand why sometimes events came inside logs and sometimes not. In my unit test, I successfully check events inside logs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.