2

Assuming I have control of the contract (meaning I haven't yet deployed it so I can still edit it), is there some way for me to make it so I can read state inside it without transacting? For example, I know I could create something like a getter function which returns the value I'm looking for, but this incurs transaction fees.

What other options do I have? I feel like emitting events inside the contract might be what I'm looking for, but I don't fully understand whether it's free to read those events vs. having to create a transaction for that too. It also seems like there might be some way I can create the transaction but just execute it locally so that I don't have to pay anything.

Any insights? Thank you!

2

I'm not the best expert here, but I would like to point out two things:

  • if you have to debug the behavior of your contract, you should really get into Events.

  • when you want to read the state of something inside the contract, you do not need to create a transaction and pay a fee, but you can simply call the function. When you have to change the state, you must send a transaction and pay for the execution, while a read through a call is free from the point of view of the transaction fee.

I hope this can be helpful :)

  • What @gatb27 said. I would just add that contract-to-contract "messages" are distinct from "transactions" and play by different rules. If you think of messages as additional transactions you'll bring misleading assumptions into the picture. Possibly overthink it. – Rob Hitchens - B9lab Apr 14 '17 at 16:08
1

It is very simple to simulate the result of any transaction without actually sending it or paying a fee, using the eth_call RPC command, which in web3 is equivalent to eth.call({txObj}) or myContract.myFunction.call(args). This will return the return value of a function without actually changing any state on the blockchain, for free.

0

Made a little example to show different elementary modes.

There is a caller contract, a "constant" contract and a "writer" contract. You can invoke the caller contract from externally owned account with either sendTransaction() or .call() and this will change things (create a transaction or just interrogate results).

There's a callConstant() function that talks to a contract function is marked constant and can't alter the chain, but it does return a result.

There's also a callWriter() function that calls a function that can update the chain, and also returns a value. This inter-contract communication is a "message". It doesn't create a new transaction and it's resolved more or less immediately.

I say can update the chain because the client has the option of "calling" either function with the passive call() option which does not send a state-changing transaction to the chain. Therefore, the "dry-run" mode can have no lasting impact.

pragma solidity ^0.4.6;

contract Caller {

  Constant public c;
  Writer public w;

  event LogReturnedValue(uint valueReceived);

  function Caller() {
    c = new Constant();
    w = new Writer();
  }

  // can send transactions to these two functions to call function in another contract with read-only/read-write 

  function callConstant() 
    public
    returns(uint x)
  {
    uint gotVal = c.returnValue();
    LogReturnedValue(gotVal);
    return gotVal;
  }

  function callWriter() 
    public
    returns(uint y)
  {
    uint gotVal = w.returnValue();
    LogReturnedValue(gotVal);
    return gotVal;        
  }
}

contract Constant {

  function returnValue() 
    public
    constant // <-- indicates read-only function cannot change the chain
    returns(uint X)
  {
    return 1;
  }


  uint public counter;

  function returnValue()
    public
    returns(uint Y)
  {
    counter++;
    return 2;
  }

}

Main take-away: There is a matrix of function design and invocation methods that takes some getting used to.

Hope it helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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