2

I want to send and broadcast a signed transaction by sender to the Ropsten network through INFURA in Golang.

I was able to send a signed transaction and recieved a response from INFURA as per below, however, this transaction hash seems not to be in Ropsten network because this cannot be found in https://ropsten.etherscan.io/.

{"jsonrpc":"2.0","id":69,"result":"0x44814c40f6193cb73d6f7aa2d0109c57e4586730564e1b08c3477f1b4e33d45c"}

Much appreciate if someone give me advice how signed transaction can be sent to Ropsten through INFURA.

Please refer to below my sample code.


package main

import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "io/ioutil"
    "math/big"
    "net/http"
    "strings"
    "unsafe"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/crypto"
)

func SendRawTransaction(amount int64) (address string) {
    url := "https://api.infura.io/v1/jsonrpc/ropsten" //According to  https://infura.io/docs/api/post/network

    from := "0x98263A537a237364E9e835Af210acDF90efC2223"
    to := "0xab60821b9894fF2787077E6d9ef6ee997b60e350"

    //Preparing sign method
    chainID := big.NewInt(3) //ropsten
    prvKey := "7a01f6905db8252701220775de0190636b8956672417776e66c04670388df799" //PrivateKey of "from"
    senderPrivKey, _ := crypto.HexToECDSA(prvKey)
    recipientAddr := common.HexToAddress(to)
    nonce := uint64(20)
    amount := big.NewInt(100000000000000000) //ETH0.1
    gasLimit := uint64(100000)
    gasPrice := big.NewInt(20000000000)

    /***** Preparing Data struct of request body for send_RawTransaction *****/

    type Data struct {
        Jsonrpc string   `json:"jsonrpc"`
        Method  string   `json:"method"`
        Params  []string `json:"params"`
        ID      int      `json:"id"`
    }

    data := Data{}
    data.Jsonrpc = "2.0"
    data.Method = "eth_sendRawTransaction"
    data.ID = 69

    /***** Preparing params struct for Data.Params *****/
    params := Params{}
    params.From = from
    params.To = to

    /***** Preparing signed transaction *****/
    tx := types.NewTransaction(nonce, recipientAddr, amount, gasLimit, gasPrice, nil)
    signer := types.NewEIP155Signer(chainID)
    signedTx, _ := types.SignTx(tx, signer, senderPrivKey)

    /***** Encoding signed transaction by RLP *****/
    var buff bytes.Buffer
    signedTx.EncodeRLP(&buff)
    tmp := fmt.Sprintf("0x%x", buff.Bytes())

    /***** Adding Params to data *****/
    data.Params = append(data.Params, tmp)

    /***** *****/
    jsonStrByte, err := json.Marshal(data)
    if err != nil {
        fmt.Println(err)
    }

    req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonStrByte))
    req.Header.Set("Content-Type", "application/json")
    client := &http.Client{}
    res, err := client.Do(req)
    defer func() {
        io.Copy(ioutil.Discard, res.Body)
        res.Body.Close()
    }()
    if err != nil {
        fmt.Println("err: ", err)
    }


    type Response struct {
        Jsonrpc string `json:"jsonrpc"`
        ID      int    `json:"id"`
        Result  string `json:"result"`
    }

    var response Response

    temp := json.NewDecoder(res.Body)
    err = temp.Decode(&response)
    if err != nil {
        fmt.Println("err: ", err)
        panic(err.Error)
    }

    defer res.Body.Close()
    fmt.Println(response)

    return response.Result
}

1 Answer 1

2

Here's a working example of sending a raw transaction using the go-ethereum package to the ropsten infura gateway:

package main

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

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/crypto"
    "github.com/ethereum/go-ethereum/ethclient"
)

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

    privateKey, err := crypto.HexToECDSA("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
    if err != nil {
        log.Fatal(err)
    }

    publicKey := privateKey.Public()
    publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
    if !ok {
        log.Fatal("error casting public key to ECDSA")
    }

    fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
    nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
    if err != nil {
        log.Fatal(err)
    }

    value := new(big.Int)
    value.SetString("100000000000000000", 10) // in wei (0.1 eth)
    gasLimit := uint64(21000)                 // in units
    gasPrice, err := client.SuggestGasPrice(context.Background())
    if err != nil {
        log.Fatal(err)
    }

    toAddress := common.HexToAddress("0x4592d8f8d7b001e72cb26a73e4fa1806a51ac79d")
    var data []byte
    tx := types.NewTransaction(nonce, toAddress, value, gasLimit, gasPrice, data)
    signedTx, err := types.SignTx(tx, types.HomesteadSigner{}, privateKey)
    if err != nil {
        log.Fatal(err)
    }

    err = client.SendTransaction(context.Background(), signedTx)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("tx sent: %s", signedTx.Hash().Hex())
}

You can see the transaction here https://ropsten.etherscan.io/tx/0xdf72fd028cc0d49a2acd854d922422cb629492a2db2248150cb44e0f228cccfb

1
  • Appreciate your answer. I can send own raw transaction to Ropsten now. Understood SendTransaction method which uses eth_sendRawTransaction in CallContext method. Thank you so much.
    – A. Take
    Commented Jun 12, 2018 at 3:59

Your Answer

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

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