赞
踩
上一篇文章,我们讲解了go如何使用函数选择器的方式进行智能合约的调用,接下来让我们一起学习一下如何使用abi的方式进行智能合约的调用
本系列课程:
go get -u github.com/ethereum/go-ethereum
- import (
- "context"
- "crypto/ecdsa"
- "fmt"
- "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"
- "math/big"
- "os"
- )
- const (
- privateKey = "你的钱包私钥"
- contractAddress = "调用合约地址"
- toAddress = "接收转账地址" //这里我使用transfer方法作为案例,所以需要一个接收转账地址
- )
func transfer(client *ethclient.Client, privateKey, toAddress, contract string) (string, error) {}
- //从私钥推导出 公钥
- privateKeyECDSA, err := crypto.HexToECDSA(privateKey)
- if err != nil {
- fmt.Println("crypto.HexToECDSA error ,", err)
- return "", err
- }
- publicKey := privateKeyECDSA.Public()
- publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
- if !ok {
- fmt.Println("publicKeyECDSA error ,", err)
- return "", err
- }
- //从公钥推导出钱包地址
- fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
- fmt.Println("钱包地址:", fromAddress.Hex())
这里就跟使用函数选择器的方式不一样了,也是本篇文章的重点介绍内容
(不会获取合约abi文件 可以关注公众号:外柏叁布道者(web3_preacher)给我留言)
- [
- {
- "inputs": [],
- "stateMutability": "nonpayable",
- "type": "constructor"
- },
- {
- "anonymous": false,
- "inputs": [
- {
- "indexed": true,
- "internalType": "address",
- "name": "owner",
- "type": "address"
- },
- {
- "indexed": true,
- "internalType": "address",
- "name": "spender",
- "type": "address"
- },
- {
- "indexed": false,
- "internalType": "uint256",
- "name": "value",
- "type": "uint256"
- }
- ],
- "name": "Approval",
- "type": "event"
- },
- .....
- ]
- //读取abi文件
- abiData, err := os.ReadFile("./part2/abi.json")
- if err != nil {
- fmt.Println("os.ReadFile error ,", err)
- return "", err
- }
- contractAbi, err := abi.JSON(bytes.NewReader(abiData))
- if err != nil {
- fmt.Println("abi.JSON error ,", err)
- return "", err
- }
- amount, _ := new(big.Int).SetString("100000000000000000000", 10)
- data, err := contractAbi.Pack("transfer", common.HexToAddress(toAddress), amount)
- if err != nil {
- fmt.Println("contractAbi.Pack error ,", err)
- return "", err
- }
实际上这步操作跟我们第一章里讲到的代码(见下面)的作用是一样的,有兴趣的朋友,可以自行阅读一下contractAbi.Pack这个方法的源码
- var data []byte
- methodName := crypto.Keccak256([]byte("transfer(address,uint256)"))[:4]
- paddedToAddress := common.LeftPadBytes(common.HexToAddress(toAddress).Bytes(), 32)
- amount, _ := new(big.Int).SetString("100000000000000000000", 10)
- paddedAmount := common.LeftPadBytes(amount.Bytes(), 32)
- data = append(data, methodName...)
- data = append(data, paddedToAddress...)
- data = append(data, paddedAmount...)
- //获取nonce
- nonce, err := client.NonceAt(context.Background(), fromAddress, nil)
- if err != nil {
- return "", err
- }
- //获取小费
- gasTipCap, _ := client.SuggestGasTipCap(context.Background())
- //transfer 默认是 使用 21000 gas
- gas := uint64(100000)
- //最大gas fee
- gasFeeCap := big.NewInt(38694000460)
-
- contractAddress := common.HexToAddress(contract)
- //创建交易
- tx := types.NewTx(&types.DynamicFeeTx{
- Nonce: nonce,
- GasTipCap: gasTipCap,
- GasFeeCap: gasFeeCap,
- Gas: gas,
- To: &contractAddress,
- Value: big.NewInt(0),
- Data: data,
- })
- // 获取当前区块链的ChainID
- chainID, err := client.ChainID(context.Background())
- if err != nil {
- fmt.Println("获取ChainID失败:", err)
- return "", err
- }
-
- fmt.Println("当前区块链的ChainID:", chainID)
- //创建签名者
- signer := types.NewLondonSigner(chainID)
- //对交易进行签名
- signTx, err := types.SignTx(tx, signer, privateKeyECDSA)
- if err != nil {
- return "", err
- }
- //发送交易
- err = client.SendTransaction(context.Background(), signTx)
- if err != nil {
- return "", err
- }
- func main() {
- client, err := ethclient.Dial("https://goerli.infura.io/v3/3214cac49d354e48ad196cdfcefae1f8")
- if err != nil {
- fmt.Println("ethclient.Dial error : ", err)
- os.Exit(0)
- }
- tx, err := transfer(client, privateKey, toAddress, contractAddress)
- if err != nil {
- fmt.Println("transfer error : ", err)
- os.Exit(0)
- }
-
- fmt.Println("使用go调用智能合约第二讲:transfer tx : ", tx)
-
- }
我们的代码已经成功执行了,让我们去区块链浏览器了看一下
可以看到区块链已经确认了我们的本次交易
本次教程,我们学会了如何使用go调用合约abi的方式与智能合约进行交互,如果在学习的过程中有任何问题可以在公众号给我留言,看到我会第一时间回复你的,另外公众号也会不定期分享关于区块链、web3的前沿信息,感兴趣的朋友可以保持关注
请关注公众号:外柏叁布道者(web3_preacher),回复 “go合约调用” 领取完整代码
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。