6

Geth's code can be used as a library. Are there any code examples that use Geth to sign a transaction locally? I then want to POST the resulting string using eth_sendRawTransaction.

7

Richard's answer pointed me in the right direction, but I had to remove some cruft to get it to do what I wanted. Here's some code that works (just replace the hardcoded values):

package main

import (
    "bytes"
    "fmt"
    "math/big"

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

func main() {

    chainId := big.NewInt(3) // ropsten

    senderPrivKey, _ := crypto.HexToECDSA("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
    recipientAddr := common.HexToAddress("0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")

    nonce := uint64(7)
    amount := big.NewInt(1000000000000000000) // 1 ether
    gasLimit := big.NewInt(100000)
    gasPrice := big.NewInt(20000000000) // 20 gwei

    tx := types.NewTransaction(nonce, recipientAddr, amount, gasLimit, gasPrice, nil)

    signer := types.NewEIP155Signer(chainId)
    signedTx, _ := types.SignTx(tx, signer, senderPrivKey)
    fmt.Println(signedTx)

    var buff bytes.Buffer
    signedTx.EncodeRLP(&buff)
    fmt.Printf("0x%x\n", buff.Bytes())
}
2

I've played around with this in the past, admittedly by borrowing code from elsewhere.

Here's some code to get you started. The crux is below, though you'll need to check the linked file for the imports, etc.:

func SendEthereum(sender *ethKeys.AccountKey, 
                  recipient common.Address, 
                  amountToSend int64) (interface{}, error) {

    var zero interface{}

    myEipc, err := ethIpc.NewEthIpc()
    if err != nil {
        return zero, err
    }
    defer myEipc.Close()

    ec, _ := myEipc.EthClient()

    nonce, err := ec.PendingNonceAt(context.TODO(), sender.PublicKey())
    gasPrice, err := ec.SuggestGasPrice(context.TODO())
    if err != nil {
        return zero, err
    }

    fmt.Println("Nonce : ", nonce)
    fmt.Println("GasPrice : ", gasPrice)
    s := types.NewEIP155Signer(params.TestnetChainConfig.ChainId)

    var amount big.Int
    amount.SetInt64(amountToSend)

    var gasLimit big.Int
    gasLimit.SetInt64(121000) // because it is a send - quite standard

    data := common.FromHex("0x")
    t := types.NewTransaction(nonce, 
                              recipient, 
                              &amount, 
                              &gasLimit, 
                              gasPrice, 
                              data)

    nt, err := types.SignTx(t, s, sender.GetKey())
    if err != nil {
        return zero, err
    }

    err = ec.SendTransaction(context.TODO(), nt)

    return nt.Hash(), err
}

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.