Golang Binding – Calling Contract Methods and Retrieving Return Values

go-ethereumgolangtestnetstransactions

Suppose i have contract like:

pragma solidity ^0.4.11;

contract MyToken {
  uint256 a;

  function SimpleGetter() returns(string) {
    return "something";
  }

  function DoTheGreat(address _to) returns(uint256) payable {
       /// ...
       return /* <...> */;
  }
}

I've followed article a bit outdated, but still very useful and have generated Go binding for my contract, then just end up with something like:

// Generate "CEO" keypair(wallet)
key, _ := crypto.GenerateKey()
CEOAuth := bind.NewKeyedTransactor(key)

// Create genesis
alloc := make(core.GenesisAlloc)
alloc[CEOAuth.From] = core.GenesisAccount{Balance: big.NewInt(20000000000000)}

sim := backends.NewSimulatedBackend(core.GenesisAccount{Address: auth.From, Balance: big.NewInt(10000000000)})

// Deploy a token contract on the simulated blockchain
_, _, token, err := DeployMyToken(CEOAuth, sim, ..)
if err != nil {
    log.Fatalf("Failed to deploy new token contract: %v", err)
}

sim.Commit()

val, _ := token.SimpleGetter(nil)
fmt.Println("Something from contrract:", val)

I actually using MyTokenSession:

 the Token contract instance into a session
session := &MyTokenSession{
    Contract: token,
    CallOpts: bind.CallOpts{
        Pending: true,
    },
    TransactOpts: bind.TransactOpts{
        From:     CEOAuth.From,
        Signer:   CEOAuth.Signer,
        GasLimit: big.NewInt(3141592),
    },
}

The problem is that we take a look at Go bidining from abigen for our function DoTheGreat(), it looks like:

func (_MyToken *MyTokenSession) DoTheGreat(_to common.Address) (*types.Transaction, error) {
    // ....
}

As you can see, it returns *types.Transaction and i don't see a way to understand do i have to sign it, send it, and how to get the return values from my contract function.

The value for tx.Value() is *big.Int, but it is not related to data returned by contract, it is always zero. Could someone throw in some code for my case?

Best Answer

type.Transaction is a transaction type. When you call a contract using the code generated via abigen, signing and broadcasting is handled for you, using the key details specified in your session. The transaction returned will contain the information of the transaction that was broadcasted.

Before you can observe any effects of the transaction, you need to wait for it to be mined, and the check the tx receipt. As far as I'm aware, return values are currently not returned in the tx receipt, and EIPs to allow that are still under consideration. If you wish to extract data from a write-transaction, use events. If your function does not alter the state of the contract, mark it as a view or pure function. abigen will produce read only methods for view and pure functions that return the appropriate data instead of types.Transaction.

The value field you see is the value transferred from the From account in that transaction, which is 0 for most contract calls.