本文已参与「新人创作礼」活动,一起开启掘金创作之路
1、编写智能合约
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;
contract Faucet {
//每天转账次数
uint transferNum=0;
//每次转账金额
uint eachAmount =1 ether;
function withdraw(address addr) payable public {
require(transferNum < 10,"hightest transfer num");
payable(addr).transfer(eachAmount);
transferNum++;
}
// function pay() public payable {}
fallback() payable external {}
receive() payable external {}
}
2、与go交互,生成go文件
1、使用remix复制abi 2、控制台输入命令
//facuet为文件名称,Agreement为文件夹名称
geth abigen --abi faucet.abi --pkg Agreement --type faucet --out faucet.go
3、之后在Agreement文件夹下生成了go文件
3、调用go文件中的方法
1、初始化
//定义常量,方便迭代、更改
const (
chainID = 8565 //8888 //链id
//账户文件
fileKeystore = "UTC--2021-12-28T17-30-07.282049100Z--982ca83b2221f620b7c43303cc66a34b6c1c70ad"
privateKey = "111" //账户文件密码
faucetAddress = "0x4215fd451f6219DA9eb9216Bcc5E74F96B55C884" //合约地址
gasLimit = 3000000
)
// HaveClient 获取 ethclient.Client 对象
func HaveClient() (*ethclient.Client, error) {
client, err := ethclient.Dial("http://localhost:9696") //区块链节点的url
if err != nil {
log.Fatal(err)
}
defer client.Close()
//Background()返回一个非空的Context。 通常由主函数使用
chainID, err := client.NetworkID(context.Background())
if err != nil {
log.Fatal(err)
}
fmt.Println(chainID)
return client, err
}
// HaveFacet 获取 NewFaucet
func HaveFacet(client *ethclient.Client) (*Faucet, error) {
//通过合约地址返回各种方法
ins, err := NewFaucet(common.HexToAddress(faucetAddress), client)
if err != nil {
log.Fatal(err)
}
return ins, err
}
//获取账户文件和密码 opts
func HaveGetOpts() *bind.TransactOpts {
//账户文件
b, err := ioutil.ReadFile(fileKeystore)
if err != nil {
log.Fatal(err)
}
//账户密码
key, err := keystore.DecryptKey(b, privateKey)
if err != nil {
log.Fatal(err)
}
fmt.Println("key:", key)
reader, _ := os.Open(fileKeystore)
//这个方法即将被弃用,所以我把它注释了,使用下面这种方法
//opts, err := bind.NewTransactor(reader, "111")
opts, err := bind.NewTransactorWithChainID(reader,"111",big.NewInt(chainID))
if err != nil {
log.Fatal("NewTransactor ", err)
}
return opts
}
//获取gasPrice
func getGasPrice(client *ethclient.Client) (*big.Int, error) {
gasPrice, err := client.SuggestGasPrice(context.Background())
if err != nil {
log.Fatal(err)
}
return gasPrice, err
}
2、调用方法
//水龙头,合约给账户发送以太币
func SendFaucetETH(client *ethclient.Client, contract *FaucetTransactor, Address common.Address) (*types.Transaction, error) {
//实例化,使用账户密码文件
opts := HaveGetOpts()
//通过调用faucet方法,进行转账操作
res, err := contract.Faucet(opts, Address)
//gasPrice, err := client.SuggestGasPrice(context.Background())
if err != nil {
log.Fatal(err)
}
opts.GasLimit = gasLimit
opts.GasPrice, err = getGasPrice(client)
return res, err
}