转载请注明。
talk is cheap show you the code
import (
"math/big"
"testing"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/core/types"
"io/ioutil"
"github.com/ethereum/go-ethereum/accounts/keystore"
"github.com/stretchr/testify/require"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"context"
"fmt"
"github.com/ethereum/go-ethereum/common"
)
// 交易发起方keystore文件地址
var fromKeyStoreFile = "";
// keystore文件对应的密码
var password = "";
// 交易接收方地址
var toAddress = ""
// http服务地址, 例:http://localhost:8545
var httpUrl = "http://ip:port"
/*
以太坊交易发送
*/
func TestSendTx(t *testing.T){
// 交易发送方
// 获取私钥方式一,通过keystore文件
fromKeystore,err := ioutil.ReadFile(fromKeyStoreFile)
require.NoError(t,err)
fromKey,err := keystore.DecryptKey(fromKeystore,password)
fromPrivkey := fromKey.PrivateKey
fromPubkey := fromPrivkey.PublicKey
fromAddr := crypto.PubkeyToAddress(fromPubkey)
// 获取私钥方式二,通过私钥字符串
//privateKey, err := crypto.HexToECDSA("私钥字符串")
// 交易接收方
toAddr := common.StringToAddress(toAddress)
// 数量
amount := big.NewInt(14)
// gasLimit
var gasLimit uint64 = 300000
// gasPrice
var gasPrice *big.Int = big.NewInt(200)
// 创建客户端
client, err:= ethclient.Dial(httpUrl)
require.NoError(t, err)
// nonce获取
nonce, err := client.PendingNonceAt(context.Background(), fromAddr)
// 认证信息组装
auth := bind.NewKeyedTransactor(fromPrivkey)
//auth,err := bind.NewTransactor(strings.NewReader(mykey),"111")
auth.Nonce = big.NewInt(int64(nonce))
auth.Value = amount // in wei
//auth.Value = big.NewInt(100000) // in wei
auth.GasLimit = gasLimit // in units
//auth.GasLimit = uint64(0) // in units
auth.GasPrice = gasPrice
auth.From = fromAddr
// 交易创建
tx := types.NewTransaction(nonce,toAddr,amount,gasLimit,gasPrice,[]byte{})
// 交易签名
signedTx ,err:= auth.Signer(types.HomesteadSigner{}, auth.From, tx)
//signedTx ,err := types.SignTx(tx,types.HomesteadSigner{},fromPrivkey)
require.NoError(t, err)
// 交易发送
serr := client.SendTransaction(context.Background(),signedTx)
if serr != nil {
fmt.Println(serr)
}
// 等待挖矿完成
bind.WaitMined(context.Background(),client,signedTx)
}
代码运行前需做如下准备工作:
本地启动一个以太坊节点,该节点连接到哪个网络,之后的交易就相应发送到该网络中。
通过geth启动本地私网例子,供参考:
geth --networkid 11 --dev --datadir data1 --rpcapi personal,db,eth,net,web3 --rpc --ws
上述go代码简单说明,知道原理的看代码注释就一清二楚了。
明确:
1.通过什么发送交易
交易发送通过的是client,该client可以支持连接http或者websocket端口
2.发送交易需要提供哪些信息
这些信息就是client.SendTransaction的参数
nonce,toAddr,amount,gasLimit,gasPrice,payload[]
3.挖矿在交易发送后进行
如果不等待挖矿执行完成,程序就会直接退出,交易将不会成功