最近,想用golang做个以太坊的交易发送(不使用合约生成的代理类)。首先,在本机找了一圈发现之前的代码没了(换电脑了。。。想吐);接着,在自己简书上翻了一圈发现只记录了js版本的;然后,打算去网上摘一下 哈哈,找了几分钟,没找到自己想要的那种。可气的是,发现国内的某网站的文章竟然要钱才能看???are you kidding me?既然这样,那咱就手撸一下,顺便,给新手学习或者省事想摘一下的朋友做点贡献,开源!!!
安装一下类库: github.com/ethereum/go-ethereum v1.14.7,完成后开撸,,,
先做一个交易发送的方法封装,暴露出常用的参数,另外,支持gasprice和gaslimit的参数外部自定义赋值,以及内部动态获取。代码如下:
// 仅实现发送DynamicFeeTx类型的交易
func sendTransaction(ec *ethclient.Client, prvHex string, to *common.Address, value *big.Int, input []byte, gasPrice *big.Int, gasLimit uint64) (common.Hash, error) {
chainID, err := ec.ChainID(context.Background())
if err != nil {
return common.Hash{}, err
}
prvBytes, err := hexutil.Decode(prvHex)
if err != nil {
return common.Hash{}, err
}
prv, err := crypto.ToECDSA(prvBytes)
if err != nil {
return common.Hash{}, err
}
from := crypto.PubkeyToAddress(prv.PublicKey)
if gasPrice == nil || gasPrice.Uint64() == 0 {
gasPrice, err = ec.SuggestGasTipCap(context.Background())
if err != nil {
return common.Hash{}, err
}
}
if gasLimit == 0 {
gasLimit, err = ec.EstimateGas(context.Background(), ethereum.CallMsg{
From: from,
To: to,
Value: value,
Data: input,
})
if err != nil {
return common.Hash{}, err
}
}
nonce, err := ec.PendingNonceAt(context.Background(), from)
if err != nil {
return common.Hash{}, err
}
signer := types.LatestSignerForChainID(chainID)
// signer := types.NewLondonSigner(chainID) // 本地私有网络使用旧版本时,需要自定义。
tx, err := types.SignNewTx(prv, signer, &types.DynamicFeeTx{
Nonce: nonce,
GasTipCap: gasPrice,
GasFeeCap: gasPrice,
Gas: gasLimit,
To: to,
Value: value,
Data: input,
AccessList: nil,
})
if err != nil {
return common.Hash{}, err
}
return tx.Hash(), ec.SendTransaction(context.Background(), tx)
}
下面做一个转账1 ether的测试,代码如下:
func main() {
transferTest()
//txUrl: https://holesky.etherscan.io/tx/0x4b0bdf38b91d225cf78c2034b90a05eec2f82b3df79286638fc505ffcf7a8b00
}
func transferTest() {
url := "https://holesky.infura.io/v3/d9044f2a78842d6b3e39aed7cxxx"
client, err := ethclient.Dial(url)
if err != nil {
fmt.Printf(" ethclient.Dial error:%s", err.Error())
return
}
privateKey := "0x" //addr: 0xAa1a88aa89F50ee9B7e3F6124f18a31d5E6dB1F9
transferTo := common.HexToAddress("0xBC1F42383f9567B43C219200D83C71CF144C1146")
tx, err := sendTransaction(client, privateKey, &transferTo, big.NewInt(1000000000000000000), nil, big.NewInt(0), 0)
if err != nil {
fmt.Printf(" sendTransaction error:%s", err.Error())
return
}
fmt.Printf("txHash: %s \n", tx.Hex())
}
ide执行结果如下:
txHash: 0x4b0bdf38b91d225cf78c2034b90a05eec2f82b3df79286638fc505ffcf7a8b00
Process finished with the exit code 0
结束!