1. 程式人生 > >Go語言實現以太坊交易傳送程式碼

Go語言實現以太坊交易傳送程式碼

轉載請註明。

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.挖礦在交易傳送後進行

如果不等待挖礦執行完成,程式就會直接退出,交易將不會成功