0

i am using GETH for the architecture and deployment of my contract on a private chain and it works pretty fine, but unfortunately i want to return data from a transaction function and this makes me crazy. I know that to read returned value of transactions is necessary to involves solidity's events and then, trough WEB3 we can read them. I'll show my detailed steps to read events but nothing works at all. Any kind of help would be really appreciated. This is the code that i need to gather:

This is the event declaration right above the contract constructor

event Accessed(string _msg,address _add, uint _time);


function transfer(bytes32 _ID) public returns (address)
{
    // Only the current owner can transfer the token.
    if (ID == _ID)
        {    
                owner = msg.sender;
                taddr.push(msg.sender); //taddr is an array used for storing address of whoever call the
                                        //transfer function
                ttime.push(now);        //same but it stores the timestamp
                Accessed("someone executed the transfer function",owner,now);
                return(owner); 
        } 
}
 function getOwners() view public returns (address[],uint[]) //this should print the two above arrays and return them
{

     return (taddr,ttime);

}

So what i want is mainly get the 2 arrays as return or at least read every call of the transaction() function.

After the deployment i use

var myContract = web3.eth.contract([ABI]);
var meta = myContract.at("address");
var Transfer = meta.Accessed({}, {fromBlock: 0, toBlock: 'latest'});
Transfer.watch(function(err, e) {
   if (err) {
      console.log(err);
} else {
      console.log("new Transfer executed from", e);
}
});

With this snippet on any node console i'm listening for any call of the Transfer() function but nothing happens. This is what i get in response of the event watch

 {
 callbacks: [],
 filterId: "0x1b2e43d107ba5d1426df7243a74e6c04",
 getLogsCallbacks: [],
 implementation: {
 getLogs: function(),
 newFilter: function(),
 poll: function(),
 uninstallFilter: function()
 },
 options: {
 address: "0x18776b68d09660c4ddbfda8e71f67906c7147edf",
 from: undefined,
 fromBlock: "0x0",
 to: undefined,
 toBlock: "latest",
 topics:["0xa938469e072f18fc99f2e[...]", 
 null, null, null]
 },
 pollFilters: [],
 requestManager: {
 polls: {
 0x3ef60ce0d464242fac329bd3e1720427: {
    data: {...},
    id: "0x3ef60ce0d464242fac329bd3e1720427",
    callback: function(error, messages),
    uninstall: function()
  },
  0x80efdb3c4df0b69c53f1f9ce47d527bb: {
    data: {...},
    id: "0x80efdb3c4df0b69c53f1f9ce47d527bb",
    callback: function(error, messages),
    uninstall: function()
  },
  0xb62a9e7d2148f67acf56a96aca3046f2: {
    data: {...},
    id: "0xb62a9e7d2148f67acf56a96aca3046f2",
    callback: function(error, messages),
    uninstall: function()
  },
  0xe63a8aea7e45a2576b0852dd129c37d7: {
    data: {...},
    id: "0xe63a8aea7e45a2576b0852dd129c37d7",
    callback: function(error, messages),
    uninstall: function()
  }
},
provider: {
  newAccount: function(),
  openWallet: function(),
  send: function github.com/ethereum/go-ethereum/console.(*bridge).Send-fm(),
  sendAsync: function github.com/ethereum/go-ethereum/console.(*bridge).Send-fm(),
  sign: function(),
  unlockAccount: function()
},
timeout: {},
poll: function(),
reset: function(keepIsSyncing),
send: function(data),
sendAsync: function(data, callback),
sendBatch: function(data, callback),
setProvider: function(p),
startPolling: function(data, pollId, callback, uninstall),
stopPolling: function(pollId)
},
formatter: function(),
get: function(callback),
stopWatching: function(callback),
watch: function(callback)
}

Same happens with event.get()

SO in your opinion what is the problem? Am i missing something?

Many thanks

2 Answers 2

1
contract ExampleContract {
  event ReturnValue(address indexed _from, int256 _value);

function foo(int256 _value) returns (int256) {
    ReturnValue(msg.sender, _value);
    return _value;
  }
}

A frontend can then obtain the return value:

var exampleEvent = exampleContract.ReturnValue({_from: web3.eth.coinbase});
exampleEvent.watch(function(err, result) {
  if (err) {
    console.log(err)
    return;
  }
  console.log(result.args._value)
  // check that result.args._from is web3.eth.coinbase then
  // display result.args._value in the UI and call    
  // exampleEvent.stopWatching()
})


exampleContract.foo.sendTransaction(2, {from: web3.eth.coinbase})

When the transaction invoking foo is mined, the callback inside the watch will be triggered. This effectively allows the frontend to obtain return values from foo.

In your case you are directly printing result e in console. I recommend you to use e.args._add to print intended value in console.

Refer this article for more details

1
  • Thanks sir for clarifying and example. I tried out your example and it worked, the same approach applied to mine, does not. This lead me in adjust a bit the code, may something is wrong. By the way, your problem is a bit different because your transaction is not a proper transaction but is something more a call. You do not alterate the state of the EVM so the return value is fully available to be returned. On the opposite, my event is build inside a SET so the return cant be executed. Do you have any suggestions that i may try on my code to see if it works? May 21, 2018 at 9:00
0

You're missing the keyword emit in front of your event. Like so:

function transfer(bytes32 _ID) public returns (address) {
    // Only the current owner can transfer the token.
    if (ID == _ID) {    
      owner = msg.sender;
      taddr.push(msg.sender);
      ttime.push(now);        //same but it stores the timestamp
      emit Accessed("someone executed the transfer function",owner,now);
      
      return(owner); 
    } 
}

Also, block.timestamp should generally be used instead of now. now is officially deprecated in version 0.7.0, but even if using an earlier version, using block.timestamp will help with reusability for other contracts in the future.

1
  • The most used solidity version in 2018 was 0.4 where using emit wasn't required. If there was an error it was something else.
    – Ismael
    Oct 22, 2021 at 6:04

Your Answer

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

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