本系列课程:
第一节:
第二节:
第三节:
首先我们要安装 ,本篇文章是在windows系统下操作,其他系统操作步骤基本类似,可自行参考安装
然后我们打开 命令行终端,快捷键:windows+R,输入cmd,然后回车
能正确输出安装版本号证明我们环境变量已经配置成功
(本文以标准ERC20合约作为示例,不知道怎么生成的可关注公众号私信我)
[
{
"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"
},
……
]
abigen --abi abi.json --pkg main --type Token --out Token.go
--abi abi.json 为我们要通过abigen生成go文件的 源文件路径
--pkg main 为我们要生成go文件里面的包名(生成的go文件第一行代码 如:package main)
--type Token 为我们生成go文件里可操作对象/方法/变量的组成部分,比如我这里写的是Token,那么生成的go文件里面的代码格式大概如下:
可以看到,里面无论是结构体、方法、变量,均会以该名字进行命名
--out Token.go 为生成go文件的名称 (ps:如果省略此命令,生成的go文件内容会打印在命令行终端上)
// Code generated - DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.
package main
import (
"errors"
"math/big"
"strings"
ethereum "github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
)
// Reference imports to suppress errors if they are not otherwise used.
var (
_ = errors.New
_ = big.NewInt
_ = strings.NewReader
_ = ethereum.NotFound
_ = bind.Bind
_ = common.Big1
_ = types.BloomLookup
_ = event.NewSubscription
_ = abi.ConvertType
)
// TokenMetaData contains all meta data concerning the Token contract.
var TokenMetaData = &bind.MetaData{
ABI: "……"
}
var TokenABI = TokenMetaData.ABI
// Token is an auto generated Go binding around an Ethereum contract.
type Token struct {
TokenCaller // Read-only binding to the contract
TokenTransactor // Write-only binding to the contract
TokenFilterer // Log filterer for contract events
}
func (_Token *TokenSession) BalanceOf(account common.Address) (*big.Int, error) {
return _Token.Contract.BalanceOf(&_Token.CallOpts, account)
}
func (_Token *TokenTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) {
return _Token.Contract.contract.Transfer(opts)
}
…………
可以看到,里面定义了很多结构体以及我们在合约里定义的方法在go文件里都有具体的实现,其实就是abigen帮我们把我们合约里定义的方法转成了go可以直接调用的方法,从而简化了我们的操作
go get -u github.com/ethereum/go-ethereum
"context"
"fmt"
"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/ethclient"
"math/big"
"os"
const (
privateKey = "你的钱包私钥"
contractAddress = "调用合约地址"
toAddress = "接收转账地址" //这里我使用transfer方法作为案例,所以需要一个接收转账地址
)
func main() {}
client, err := ethclient.Dial("https://goerli.infura.io/v3/3214cac49d3e48ad196cdfcefae1f8")
if err != nil {
fmt.Println("ethclient.Dial error : ", err)
os.Exit(0)
}
token, err := NewToken(common.HexToAddress(contractAddress), client)
if err != nil {
fmt.Println("NewToken error : ", err)
}
call方法主要用来调用智能合约的查询方法(即不修改链上数据,不花费gas)
这里,我们调用的是智能合约的TotalSupply方法,它会返回该智能合约的总供应量
totalSupply, err := token.TotalSupply(nil)
if err != nil {
fmt.Println("token.TotalSupply error : ", err)
}
fmt.Println("totalSupply is : ", totalSupply)
可以看到,控制台成功打印出返回信息
send方法,主要用来调用智能合约里会修改链上数据的方法(花费gas)
我们以Transfer方法为例,进行一笔账号之间的转账操作:
// 获取当前区块链的ChainID
chainID, err := client.ChainID(context.Background())
if err != nil {
fmt.Println("获取ChainID失败:", err)
return
}
privateKeyECDSA, err := crypto.HexToECDSA(privateKey)
if err != nil {
fmt.Println("crypto.HexToECDSA error ,", err)
return
}
gasTipCap, _ := client.SuggestGasTipCap(context.Background())
//构建参数对象
opts, err := bind.NewKeyedTransactorWithChainID(privateKeyECDSA, chainID)
if err != nil {
fmt.Println("bind.NewKeyedTransactorWithChainID error ,", err)
return
}
//设置参数
opts.GasFeeCap = big.NewInt(108694000460)
opts.GasLimit = uint(100000)
opts.GasTipCap = gasTipCap
amount, _ := new(big.Int).SetString("100000000000000000000", 10)
//调用合约transfer方法
tx, err := token.Transfer(opts, common.HexToAddress(toAddress), amount)
if err != nil {
fmt.Println("token.Transfer error ,", err)
return
}
fmt.Println("使用go调用智能合约第三讲:transfer tx : ", tx.Hash().Hex())
成功返回哈希值,让我们去区块链浏览器里看一下
可以看到链上交易已经完成
到此,使用go与智能合约的教程全部完成,你学会了吗?没有学会不要紧,多做两遍,熟能生巧,你一定也可以的!如果在学习过程中有任何问题,欢迎给我留言,另外公众号也会不定期分享关于区块链、web3的前沿信息,感兴趣的朋友可以保持关注
请关注公众号:外柏叁布道者(web3_preacher),回复 “go合约调用” 领取完整代码
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- ryyc.cn 版权所有 湘ICP备2023022495号-3
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务