[Ethereum] How to bind Go auto-generated code to a smart contract over IPC

abigo-ethereumprivate-blockchain

I wish to create a go-binding to my smart contract which was mined on a private blockchain.

I've looked at the Native Dapps : Go binding to Ethereum contracts tutorial (located here : https://github.com/ethereum/go-ethereum/wiki/Native-DApps:-Go-bindings-to-Ethereum-contracts), which is a tutorial for auto-generating go functions which will call/interact on/with the smart contract.

From what I understand, this allows you to call any function of the smart contract for which you generate code, on your blockchain, without having to encode your method signature and parameters, all this over an IPC connection.

I guess the other solution would be to encode your method signature and parameters and send transactions manually?

  • What I want

I want my private blockchain to be the backend of the binding, so that calling an auto-generated method will act on my actual blockchain.

  • What I first did

According to the tutorial written by the official go-ethereum project (link above) this is done by creating an IPC client, and then using that IPC Client to generate the backend of the binding.

  • The problem

This method involved two functions of two packages from the go-ethereum project, which are NewIPCClient() from the rpc package and NewRPCBackend() from the backends package. The first was changed to DialIPC(), and was the subject of an issue here about 4 months ago.

I'm successfully using rpc.DialIPC() but the backends.NewRPCBackend()
method was suppressed and I can't seem to work around it.

My code looks like that :

import (
"log"
"strings"

"golang.org/x/net/context"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/accounts/abi/bind/backends"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/rpc"

"github.com/gorilla/mux"
)

ctx := context.TODO();

//Create an IPC based RPC connection
conn, errConn := rpc.DialIPC(ctx, "/home/geth/datadir/geth.ipc")
if errConn != nil {
    log.Fatalf("Failed to connect to the node : %v", errConn)
}

//Creates the transactor : account that will be used to send transaction on the blockchain. Specific of the node the binary will be generated on.
auth, errAuth := bind.NewTransactor(strings.NewReader(key), "test")
if errAuth != nil {
    log.Fatalf("Failed to create new transactor : %v", errAuth)
}

//Establish the binding. Takes the adress of the contract and the blockchain in parameter
service, errServ := NewDataPublishingService(common.HexToAddress("0x5217502dac0c987d65a3325a4ea95bedc3c2a6aa"), backends.NewRPCBackend())
if errServ != nil {
    log.Fatalf("Failed to instantiate a Token contract : %v", errServ)
}

//Open a session in the binding. This session will be used to send transactions on the blockchain or launch calls.
session := &DataPublishingServiceSession{
    Contract : service,
    CallOpts : bind.CallOpts{},
    TransactOpts : bind.TransactOpts{
        From : auth.From,
        Signer : auth.Signer,
    },
}

The error I'm getting

./server.go:91: undefined: backends.NewRPCBackend

This is, as I said, because the function was suppressed


To sum up, I checked the contents of the backends package as it is today.
All it contains is a NewSimulatedBackend() method which creates a blockchain from scratch. I was thinking of a solution which consisted of recoding the type SimulatedBackend to create a link to my own blockchain, but I gave it up because this will instead recreate another instance of my blockchain (at least from what I understand).

I didn't find documentation on this issue (not on github nor here), so I would love and look forward to any kind of input so how this would be done.

Best Answer

You need to use ethClient now

I am binding an object called NewMaths...

import "github.com/ethereum/go-ethereum/ethclient"
...

func getClient() (client *ethclient.Client, err error) {
    endPoint := "/Users/daveappleton/Library/Ethereum/geth.ipc"
    client, err = ethclient.Dial(endPoint)
    return
}
...
client, err := getClient()
if err != nil {
    fmt.Println(err)
    return
}
nnm, err = NewNewMaths(common.HexToAddress(address), client) 
if err != nil {
    log.Fatalf("Failed to instantiate the NewMaths contract: %v", err)
}

ownerTx, err = bind.NewTransactor(strings.NewReader(mon_key), ",password")
if err != nil {
    log.Fatalf("Failed to create authorized transactor: %v", err)
}

Keeping it brief as you look as if you have most of it. Will answer more if you need it.