Cómo enviar una transacción firmada a Ropsten a través de INFURA en Golang

Quiero enviar y transmitir una transacción firmada por el remitente a la red Ropsten a través de INFURA en Golang.

Pude enviar una transacción firmada y recibí una respuesta de INFURA como se indica a continuación, sin embargo, este hash de transacción parece no estar en la red de Ropsten porque no se puede encontrar en https://ropsten.etherscan.io/ .

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

Agradezco mucho si alguien me da un consejo sobre cómo se puede enviar la transacción firmada a Ropsten a través de INFURA.

Consulte a continuación mi código de muestra.


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
}

Respuestas (1)

Aquí hay un ejemplo práctico de cómo enviar una transacción sin procesar usando el paquete go-ethereum a la puerta de enlace ropsten infura:

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())
}

Puede ver la transacción aquí https://ropsten.etherscan.io/tx/0xdf72fd028cc0d49a2acd854d922422cb629492a2db2248150cb44e0f228cccfb

Agradezco tu respuesta. Puedo enviar mi propia transacción sin procesar a Ropsten ahora. Método SendTransaction entendido que usa eth_sendRawTransaction en el método CallContext. Muchas gracias.