0

I have a simple sol file message.sol

pragma solidity >=0.5.10;

contract Message {
   
    string public message;

    constructor(string memory initMessage) public {
        message = initMessage;
    }

    function update(string memory newMessage) public {
        message = newMessage;
    }
}

I'm autogenerating a go file using abigen with the following command (I have both ABI and bin files at this point):

abigen --bin=message.bin --abi=message.abi --pkg=message --out=message.go

message.go

// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.

package message

import (
    "math/big"
    "strings"

    ethereum "github.com/ethereum/go-ethereum"
    "github.com/ethereum/go-ethereum/accounts/abi"
    "github.com/ethereum/go-ethereum/accounts/abi/bind"
    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/event"
)

// Reference imports to suppress errors if they are not otherwise used.
var (
    _ = big.NewInt
    _ = strings.NewReader
    _ = ethereum.NotFound
    _ = bind.Bind
    _ = common.Big1
    _ = types.BloomLookup
    _ = event.NewSubscription
)

// MessageABI is the input ABI used to generate the binding from.
const MessageABI = "[{\"inputs\":[{\"internalType\":\"string\",\"name\":\"initMessage\",\"type\":\"string\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"message\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"newMessage\",\"type\":\"string\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"

// MessageBin is the compiled bytecode used for deploying new contracts.
var MessageBin = "0x608060405234801561001057600080fd5b5060405161046d38038061046d8339818101604052602081101561003357600080fd5b810190808051604051939291908464010000000082111561005357600080fd5b90830190602082018581111561006857600080fd5b825164010000000081118282018810171561008257600080fd5b82525081516020918201929091019080838360005b838110156100af578181015183820152602001610097565b50505050905090810190601f1680156100dc5780820380516001836020036101000a031916815260200191505b50604052505081516100f6915060009060208401906100fd565b5050610190565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061013e57805160ff191683800117855561016b565b8280016001018555821561016b579182015b8281111561016b578251825591602001919060010190610150565b5061017792915061017b565b5090565b5b80821115610177576000815560010161017c565b6102ce8061019f6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c80633d7403a31461003b578063e21f37ce146100e3575b600080fd5b6100e16004803603602081101561005157600080fd5b81019060208101813564010000000081111561006c57600080fd5b82018360208201111561007e57600080fd5b803590602001918460018302840111640100000000831117156100a057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610160945050505050565b005b6100eb610177565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561012557818101518382015260200161010d565b50505050905090810190601f1680156101525780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b8051610173906000906020840190610205565b5050565b6000805460408051602060026001851615610100026000190190941693909304601f810184900484028201840190925281815292918301828280156101fd5780601f106101d2576101008083540402835291602001916101fd565b820191906000526020600020905b8154815290600101906020018083116101e057829003601f168201915b505050505081565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061024657805160ff1916838001178555610273565b82800160010185558215610273579182015b82811115610273578251825591602001919060010190610258565b5061027f929150610283565b5090565b5b8082111561027f576000815560010161028456fea264697066735822122049781e300a3c8dcc2a492edee37b89eea410fe8dcba8a89d6e1c72061023d40e64736f6c63430007000033"

// DeployMessage deploys a new Ethereum contract, binding an instance of Message to it.
func DeployMessage(auth *bind.TransactOpts, backend bind.ContractBackend, initMessage string) (common.Address, *types.Transaction, *Message, error) {
    parsed, err := abi.JSON(strings.NewReader(MessageABI))
    if err != nil {
        return common.Address{}, nil, nil, err
    }

    address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(MessageBin), backend, initMessage)
    if err != nil {
        return common.Address{}, nil, nil, err
    }
    return address, tx, &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil
}

// Message is an auto generated Go binding around an Ethereum contract.
type Message struct {
    MessageCaller     // Read-only binding to the contract
    MessageTransactor // Write-only binding to the contract
    MessageFilterer   // Log filterer for contract events
}

// MessageCaller is an auto generated read-only Go binding around an Ethereum contract.
type MessageCaller struct {
    contract *bind.BoundContract // Generic contract wrapper for the low level calls
}

// MessageTransactor is an auto generated write-only Go binding around an Ethereum contract.
type MessageTransactor struct {
    contract *bind.BoundContract // Generic contract wrapper for the low level calls
}

// MessageFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
type MessageFilterer struct {
    contract *bind.BoundContract // Generic contract wrapper for the low level calls
}

// MessageSession is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type MessageSession struct {
    Contract     *Message          // Generic contract binding to set the session for
    CallOpts     bind.CallOpts     // Call options to use throughout this session
    TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session
}

// MessageCallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type MessageCallerSession struct {
    Contract *MessageCaller // Generic contract caller binding to set the session for
    CallOpts bind.CallOpts  // Call options to use throughout this session
}

// MessageTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type MessageTransactorSession struct {
    Contract     *MessageTransactor // Generic contract transactor binding to set the session for
    TransactOpts bind.TransactOpts  // Transaction auth options to use throughout this session
}

// MessageRaw is an auto generated low-level Go binding around an Ethereum contract.
type MessageRaw struct {
    Contract *Message // Generic contract binding to access the raw methods on
}

// MessageCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type MessageCallerRaw struct {
    Contract *MessageCaller // Generic read-only contract binding to access the raw methods on
}

// MessageTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type MessageTransactorRaw struct {
    Contract *MessageTransactor // Generic write-only contract binding to access the raw methods on
}

// NewMessage creates a new instance of Message, bound to a specific deployed contract.
func NewMessage(address common.Address, backend bind.ContractBackend) (*Message, error) {
    contract, err := bindMessage(address, backend, backend, backend)
    if err != nil {
        return nil, err
    }
    return &Message{MessageCaller: MessageCaller{contract: contract}, MessageTransactor: MessageTransactor{contract: contract}, MessageFilterer: MessageFilterer{contract: contract}}, nil
}

// NewMessageCaller creates a new read-only instance of Message, bound to a specific deployed contract.
func NewMessageCaller(address common.Address, caller bind.ContractCaller) (*MessageCaller, error) {
    contract, err := bindMessage(address, caller, nil, nil)
    if err != nil {
        return nil, err
    }
    return &MessageCaller{contract: contract}, nil
}

// NewMessageTransactor creates a new write-only instance of Message, bound to a specific deployed contract.
func NewMessageTransactor(address common.Address, transactor bind.ContractTransactor) (*MessageTransactor, error) {
    contract, err := bindMessage(address, nil, transactor, nil)
    if err != nil {
        return nil, err
    }
    return &MessageTransactor{contract: contract}, nil
}

// NewMessageFilterer creates a new log filterer instance of Message, bound to a specific deployed contract.
func NewMessageFilterer(address common.Address, filterer bind.ContractFilterer) (*MessageFilterer, error) {
    contract, err := bindMessage(address, nil, nil, filterer)
    if err != nil {
        return nil, err
    }
    return &MessageFilterer{contract: contract}, nil
}

// bindMessage binds a generic wrapper to an already deployed contract.
func bindMessage(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
    parsed, err := abi.JSON(strings.NewReader(MessageABI))
    if err != nil {
        return nil, err
    }
    return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
}

// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_Message *MessageRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
    return _Message.Contract.MessageCaller.contract.Call(opts, result, method, params...)
}

// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_Message *MessageRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
    return _Message.Contract.MessageTransactor.contract.Transfer(opts)
}

// Transact invokes the (paid) contract method with params as input values.
func (_Message *MessageRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
    return _Message.Contract.MessageTransactor.contract.Transact(opts, method, params...)
}

// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_Message *MessageCallerRaw) Call(opts *bind.CallOpts, result interface{}, method string, params ...interface{}) error {
    return _Message.Contract.contract.Call(opts, result, method, params...)
}

// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_Message *MessageTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
    return _Message.Contract.contract.Transfer(opts)
}

// Transact invokes the (paid) contract method with params as input values.
func (_Message *MessageTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) {
    return _Message.Contract.contract.Transact(opts, method, params...)
}

// Message is a free data retrieval call binding the contract method 0xe21f37ce.
//
// Solidity: function message() view returns(string)
func (_Message *MessageCaller) Message(opts *bind.CallOpts) (string, error) {
    var (
        ret0 = new(string)
    )
    out := ret0
    err := _Message.contract.Call(opts, out, "message")
    return *ret0, err
}

// Message is a free data retrieval call binding the contract method 0xe21f37ce.
//
// Solidity: function message() view returns(string)
func (_Message *MessageSession) Message() (string, error) {
    return _Message.Contract.Message(&_Message.CallOpts)
}

// Message is a free data retrieval call binding the contract method 0xe21f37ce.
//
// Solidity: function message() view returns(string)
func (_Message *MessageCallerSession) Message() (string, error) {
    return _Message.Contract.Message(&_Message.CallOpts)
}

// Update is a paid mutator transaction binding the contract method 0x3d7403a3.
//
// Solidity: function update(string newMessage) returns()
func (_Message *MessageTransactor) Update(opts *bind.TransactOpts, newMessage string) (*types.Transaction, error) {
    return _Message.contract.Transact(opts, "update", newMessage)
}

// Update is a paid mutator transaction binding the contract method 0x3d7403a3.
//
// Solidity: function update(string newMessage) returns()
func (_Message *MessageSession) Update(newMessage string) (*types.Transaction, error) {
    return _Message.Contract.Update(&_Message.TransactOpts, newMessage)
}

// Update is a paid mutator transaction binding the contract method 0x3d7403a3.
//
// Solidity: function update(string newMessage) returns()
func (_Message *MessageTransactorSession) Update(newMessage string) (*types.Transaction, error) {
    return _Message.Contract.Update(&_Message.TransactOpts, newMessage)
}

After my go file is generated I'm trying to deploy my contract as following:

main.go

import (
    "context"
    "crypto/ecdsa"
    "fmt"
    "log"
    "math/big"

    "github.com/ethereum/go-ethereum/accounts/abi/bind"
    "github.com/ethereum/go-ethereum/crypto"
    "github.com/ethereum/go-ethereum/ethclient"

    messsage "GOPATH/projectpath/bin/contracts"
)

func main() {
    client, err := ethclient.Dial("https://rinkeby.infura.io/v3/projectid")
    if err != nil {
       log.Fatal(err)
    }

    privateKey, err := crypto.HexToECDSA("XXXXXXXXXXXXXXXXXXXXXXXXXXXX")
    if err != nil {
       log.Fatal(err)
    }
    
    publicKey := privateKey.Public()
    publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
    if !ok {
        log.Fatal("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
    }
    fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)

    nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
    if err != nil {
        log.Fatal(err)
    }
    
    gasLimit := uint64(21000)
    gasPrice, err := client.SuggestGasPrice(context.Background())
    if err != nil {
        log.Fatal(err)
    }

    auth := bind.NewKeyedTransactor(privateKey)
    auth.Nonce = big.NewInt(int64(nonce))
    auth.Value = big.NewInt(0) // in wei
    auth.GasLimit = gasLimit   // in units
    auth.GasPrice = gasPrice

    input := "1.0"
    address, tx, instance, err := message.DeployMessage(auth, client, input)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(address.Hex())
    fmt.Println(tx.Hash().Hex())
    _ = instance
}

But while running main.go I get the following error displayed in console, which refers to the autogenerated go file.

/bin/contracts
bin\contracts\Message.go:158:54: cannot use result (type interface {}) as type *[]interface {} in argument to _Message.Contract.MessageCaller.contract.Call: need type assertion
bin\contracts\Message.go:177:40: cannot use result (type interface {}) as type *[]interface {} in argument to _Message.Contract.contract.Call: need type assertion
bin\contracts\Message.go:199:31: cannot use out (type *string) as type *[]interface {} in argument to _Message.contract.Call

I'm not sure why this is happening because the file was autogenerated and this is my first time working with smart contracts with go so any help would be much appreciated.

0

One problem I find with abigen these days is that when you build a new project you will download the latest geth imports into that project.

Your ABIGEN on the other hand tends comes from your installed GETH codebase which may be out of sync.

Try downloading new GETH and make a new ABIGEN

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.