在本地以太坊私链上,使用go调用智能合约,获取事件日志

这篇具有很好参考价值的文章主要介绍了在本地以太坊私链上,使用go调用智能合约,获取事件日志。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、关于开发环境搭建配置等可参考之前的文章 2、部署合约代码erc20.js

const hre = require("hardhat");
async function main() {
  const CONTRACT = await hre.ethers.getContractFactory("ERC20");

  const contract = await CONTRACT.deploy();
  await contract.init("ERC20Name","ERC20Symbol");
  console.log("name:",contract.name(),"symbol:",contract.symbol());
  await contract.deployed();

  console.log(`contract deployed to ${contract.address}`);
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

3、启动并上链

#切换到智能合约项目位置
npx hardhat node
#新开一个窗口,确保localhost已经在hardhat.config.js中配置了,可查看第一步链接对照
npx hardhat run scripts/erc.js --network localhost

4、新建一个文件夹,存放go项目,完成mod初始化等

完整go项目文件目录

5、拷贝智能合约compile产生的ABI,在新文件夹中新建一个erc20.json文件

 文章来源地址https://www.toymoban.com/news/detail-503299.html

在本地以太坊私链上,使用go调用智能合约,获取事件日志

 

6、安装abigen

go get github.com/ethereum/go-ethereum

#切换路径 cd $GOPATH/pkg/mod/github.com/ethereum/go-ethereum@v1.10.25
sudo make && make devtools

#测试安装
abigen --help

7、将ABI生成GO文件

abigen --abi erc20.json -pkg json -type erc20 --out erc20.go

8、编写调用文件 main.go

package main

import (
	"context"
	"crypto/ecdsa"
	"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"
	"mysolidity/json"
)

func main() {
	//合约地址
	contractAddress := "0x5FbDB2315678afecb367f032d93F642f64180aa3"
	//连接本地的以太坊私链(一定要保证本地以太坊私链已经启动)
	conn, err := ethclient.Dial("http://127.0.0.1:8545")
	fmt.Println("connect to local node...", conn)
	if err != nil {
		fmt.Errorf("could not connect to local node: %v", err)
		return
	}
	//创建合约
	erc20, err := json.NewErc20(common.HexToAddress(contractAddress), conn)
	if err != nil {
		fmt.Errorf("failed to instantiate a Token contract: %v", err)
		return
	}
	fmt.Println("contract token:", erc20)
	//调用合约查询方法
	name, err := erc20.Name(&bind.CallOpts{
		Pending:     false,
		From:        common.Address{},
		BlockNumber: nil,
		Context:     nil,
	})
	if err != nil {
		fmt.Errorf("name:%v", err)
		return
	}
	symbol, err := erc20.Symbol(&bind.CallOpts{
		Pending:     false,
		From:        common.Address{},
		BlockNumber: nil,
		Context:     nil,
	})
	if err != nil {
		fmt.Errorf("name:%v", err)
		return
	}
	fmt.Println("name:", name, "symbol:", symbol)
	//查询第一个账户余额
	b, err := erc20.BalanceOf(&bind.CallOpts{
		Pending:     false,
		From:        common.Address{},
		BlockNumber: nil,
		Context:     nil,
	}, common.HexToAddress("0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266"))//启动node默认生成的第1个账户地址
	if err != nil {
		fmt.Errorf("BalanceOf:%v", err)
		return
	}
	fmt.Println("first balance:", b)
	第一个账户给第二个账户转账
	//私钥,需要生成签名
	privateKey, err := crypto.HexToECDSA("ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")//私钥注意去掉ox,这是启动node默认生成的第1个账户的私钥
	if err != nil {
		fmt.Errorf("err:%v\n", err)
		return
	}
	publicKey := privateKey.Public()
	publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
	if !ok {
		fmt.Errorf("cannot assert type: publicKey is not of type *ecdsa.PublicKey")
		return
	}
	fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
	nonce, err := conn.PendingNonceAt(context.Background(), fromAddress)
	if err != nil {
		fmt.Errorf("%v", err)
		return
	}
	gasPrice, err := conn.SuggestGasPrice(context.Background())
	if err != nil {
		fmt.Errorf("%v", err)
		return
	}
	//chainID
	id, err := conn.ChainID(context.Background())
	if err != nil {
		return
	}
	fmt.Println("chainID:", id)
	auth, _ := bind.NewKeyedTransactorWithChainID(privateKey, id)
	auth.Nonce = big.NewInt(int64(nonce))
	auth.Value = big.NewInt(10)    
	auth.GasLimit = uint64(300000) 
	auth.GasPrice = gasPrice
	tx, err := erc20.Transfer(&bind.TransactOpts{
		Signer:   auth.Signer,
		From:     fromAddress,
		GasLimit: auth.GasLimit,
		GasPrice: auth.GasPrice,
		Context:  nil,
	}, common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"), big.NewInt(8))
	if err != nil {
		fmt.Errorf("transfer:%v", err)
		return
	}
	fmt.Println("tx.GasPrice():", tx.GasPrice())
	//查询两个账户余额
	b, err = erc20.BalanceOf(&bind.CallOpts{From: fromAddress}, common.HexToAddress("0x70997970C51812dc3A010C7d01b50e0d17dc79C8"))//启动node默认生成的第2个账户地址
	if err != nil {
		fmt.Errorf("BalanceOf:%v", err)
		return
	}
	fmt.Println("second balance:", b)
	b, err = erc20.BalanceOf(&bind.CallOpts{From: fromAddress}, fromAddress)
	if err != nil {
		fmt.Errorf("BalanceOf:%v", err)
		return
	}
	fmt.Println("first balance:", b)
}

9、查询事件日志(完整开发的一般流程,在链端开发智能合约后,由前端使用web3.js等进行交互,后端通过查询事件日志修改数据库信息展示)

package main

import (
	"context"
	"fmt"
	"github.com/ethereum/go-ethereum"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethclient"
	"math/big"
	"mysolidity/json"
)

func main() {
	//合约地址
	contractAddress := common.HexToAddress("0x5FbDB2315678afecb367f032d93F642f64180aa3")
	//websocket监听
	client, err := ethclient.Dial("ws://127.0.0.1:8545/ws")
	if err != nil {
		fmt.Errorf("could not connect to local node: %v", err)
		return
	}
	query := ethereum.FilterQuery{
		FromBlock: big.NewInt(1), //生产环境中,从0开始,查询后修改区块记录,下一次就从后一个有记录的区块数开始
		ToBlock:   big.NewInt(100),
		Addresses: []common.Address{
			contractAddress,
		},
	}
	erc20, _ := json.NewErc20(contractAddress, client)
	logs, err := client.FilterLogs(context.Background(), query)
	if err != nil {
		fmt.Errorf("err:%v\n", err)
		return
	}
	for _, vLog := range logs {
		if len(vLog.Topics) == 0 {
			continue
		}
		event := vLog.Topics[0].Hex()
		if event == TransferEvent() { //对对应的事件进行对应的处理
			fmt.Println(vLog.Data)
			data, err := erc20.ParseTransfer(vLog)
			if err != nil {
				fmt.Errorf("err:%v\n", err)
				continue
			}
			fmt.Println(data.From.Hex(), data.To.Hex(), data.Value.Int64(), data.Raw.Data)
		}
	}
}
func TransferEvent() string {
	event := crypto.Keccak256Hash([]byte("Transfer(address,address,uint256)")).Hex()
	return event
}

10、测试结果(main.go为最后一次运行结果)

在本地以太坊私链上,使用go调用智能合约,获取事件日志

在本地以太坊私链上,使用go调用智能合约,获取事件日志

 

到了这里,关于在本地以太坊私链上,使用go调用智能合约,获取事件日志的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 《如何搭建一条私有多Geth节点的链》最新版以太坊私链搭建官方文档要点翻译

    Last edited on January 31, 2023 This guide explains how to set up a private network of multiple Geth nodes. An Ethereum network is private if the nodes are not connected to the main network. In this context private only means reserved or isolated, rather than protected or secure. A fully controlled, private Ethereum network is useful as a backend for core de

    2024年02月08日
    浏览(55)
  • java使用web3j,部署智能合约在测试链上,并调用(万字详细教程)

    最近在学区块链相关,想做点自己感兴趣的。网上关于这块部分的坑也比较多,最近也是问了很多行业从事者才慢慢填坑,因此记录下来分享一下。 钱包 :metemask、 solidity编译器 :remix 、 java ide :idea。 智能合约编写的我选择在remix上方便,而且部署的时候不需要自定义gasP

    2024年01月16日
    浏览(58)
  • 玩以太坊链上项目的必备技能(初识智能合约语言-Solidity之旅一)

    前面一篇关于 智能合约 翻译文讲到了,是一种计算机程序,既然是程序,那就可以使用 程序语言 去编写 智能合约 了。 而若想玩区块链上的项目,大部分区块链项目都是开源的,能看得懂 智能合约 代码,或找出其中的漏洞,那么,学习 Solidity 这门高级的智能合约语言是有

    2023年04月16日
    浏览(96)
  • ganache私链部署智能合约+本地网络Dapp

    参考自(3条消息) 区块链投票应用:使用solidity+truffle+metamsk开发Dapp应用_一袋芋头的博客-CSDN博客下载了项目示例webpack之后   我们需要将里面的其他合约都删除,也可以直接删除这两个文件夹里的内容  然后就可以开始正片了(当然,你得先前就安装好环境) 开启ganache私链,

    2024年02月08日
    浏览(43)
  • 以太坊私钥介绍及生成与验证

    1)私钥格式 Bitcoin私钥(或其他加密货币私钥)有32 bytes,(或256个bit),或者其他形式表示,Base64 string、a WIF key、助记词 2)为什么是32bytes 3)生成方法 3.1)原生方法 该方法不适合用于加密货币,因为该方法不安全;该方法基于随机数种子生成,如果知道生成时的时间,容

    2024年02月15日
    浏览(45)
  • PoA以太私链搭建

    学习记录 根据需要下载相应版本的geth。 这里我用的是64位Windows版本,也就是图片上第三个。下载完成后,点开,在电脑上完成安装,并根据需要进行环境变量的配置。 (1)验证geth是否安装完成 win+R打开cmd窗口,输入 如果安装成功,就会出现如下显示 (2)创建账户 由于我

    2024年02月01日
    浏览(82)
  • 【使用go开发区块链】之获取链上数据(01)

    在我们实际开发项目中,很多时候都需要从链上获取区块数据,将数据加工处理后存入到数据库中,本章开始,我们来学习一下如何从链上获取数据(主动拉取)并存储到数据库中 本系列文章 1、【使用go开发区块链】之获取链上数据(01) 2、【使用go开发区块链】之获取链

    2024年01月22日
    浏览(44)
  • 【使用go开发区块链】之获取链上数据(04)

    上一篇文章,我们完成了go连接区块链的操作,本章我们将要完成获取链上数据,并持久化到数据库的功能开发 本系列文章 1、【使用go开发区块链】之获取链上数据(01) 2、【使用go开发区块链】之获取链上数据(02) 3、【使用go开发区块链】之获取链上数据(03) 4、【使

    2024年02月12日
    浏览(49)
  • go语言操作以太坊智能合约

    操作中要注意版本问题 geth版本、golang版本等 在remix环境中写好合约后,进行编译得到abi文件 简单举例 Hello.sol合约 编译后abi文件(Hello.abi)内容 然后需要一个 abigen工具 可以将abi、bin等编译后的智能合约文件内容生成go代码 abigen可以在geth官网下载geth的时候下载GethTools版本

    2024年02月09日
    浏览(37)
  • 【以太坊】私链搭上后无法MetaMask无法访问localhost8545的问题

    私链搭好在Linux中,配置好ChianID和networkid等参数之后,使用MetaMask连接localhost8545仍然无法访问: 这个问题找了很久的资料,最后发现学习的资料是一年前的,文档更新的速度赶不上以太坊更新的速度,原因是跑私链的命令行中缺失浏览器限制访问项,之前的命令: 改之后的

    2024年02月11日
    浏览(42)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包