使用go与智能合约交互之abi调用

news2024/11/17 23:43:46

上一篇文章,我们讲解了go如何使用函数选择器的方式进行智能合约的调用,接下来让我们一起学习一下如何使用abi的方式进行智能合约的调用

本系列课程:

第一节:使用go与智能合约交互之函数选择器调用

第二节:使用go与智能合约交互之abi调用

第三节:使用go与智能合约交互之使用abigen生成合约go文件进行调用

1、首先我们安装一下go-ethereum

go get -u github.com/ethereum/go-ethereum


2、新建main.go文件,添加依赖

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"
)


3、定义常量

const (
    privateKey      = "你的钱包私钥"
    contractAddress = "调用合约地址"
    toAddress       = "接收转账地址" //这里我使用transfer方法作为案例,所以需要一个接收转账地址
)


4、定义调用函数

func transfer(client *ethclient.Client, privateKey, toAddress, contract string) (string, error) {}


4.1、先从私钥推导出公钥,再从公钥推导出钱包地址

  //从私钥推导出 公钥
    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())

4.2、构造请求参数

这里就跟使用函数选择器的方式不一样了,也是本篇文章的重点介绍内容

4.2.1、准备好合约的abi文件 abi.json

不会获取合约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"
  },
  .....
]

4.2.2、读取abi文件

//读取abi文件
	abiData, err := os.ReadFile("./part2/abi.json")
	if err != nil {
		fmt.Println("os.ReadFile error ,", err)
		return "", err
	}

4.2.3、将abi数据转成合约abi对象

contractAbi, err := abi.JSON(bytes.NewReader(abiData))
	if err != nil {
		fmt.Println("abi.JSON error ,", err)
		return "", err
	}

4.2.4、合约abi对象打包要调用的方法和参数

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...)

4.3、构造交易对象

    //获取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,
	})

4.4、交易签名/发送交易

    // 获取当前区块链的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
	}

4.5、main函数里来调用函数

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)

}

 5、执行main方法

 我们的代码已经成功执行了,让我们去区块链浏览器了看一下

 

可以看到区块链已经确认了我们的本次交易

本次教程,我们学会了如何使用go调用合约abi的方式与智能合约进行交互,如果在学习的过程中有任何问题可以在公众号给我留言,看到我会第一时间回复你的,另外公众号也会不定期分享关于区块链、web3的前沿信息,感兴趣的朋友可以保持关注

 请关注公众号:外柏叁布道者(web3_preacher,回复 “go合约调用” 领取完整代码

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/804095.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

堆喷射的小例子

引自&#xff1a;https://blog.csdn.net/lixiangminghate/article/details/53413863 照着作者的意思&#xff0c;自己的测试代码&#xff1a; #include <iostream> #include <windows.h> #include <stdio.h>class base {char m_buf[8]; public:virtual int…

上传图片到腾讯云对象存储桶cos

1、首先登录腾讯云官网控制台 进入对象存储页面 2、找到跨越访问CIRS设置 配置规则 点击添加规则 填写信息 3、书写代码 这里用VUE3书写 <template><div><input type"file" change"handleFileChange" /></div> </template&g…

JS学习之ES6

一、ES简介 ES6是一个泛指&#xff0c;指EDMAJavaScript之后的版本。它是JS的语言标准。 Nodejs 简介&#xff1a;它是一个工具&#xff0c;主攻服务器&#xff0c;使得利用JS也可以完成服务器代码的编写。 安装&#xff1a; 安装Nodejs的同时&#xff0c;会附带一个npm命令…

QT--day4(定时器事件、鼠标事件、键盘事件、绘制事件、实现画板、QT实现TCP服务器)

QT实现tcpf服务器代码&#xff1a;&#xff08;源文件&#xff09; #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//给服务器指针实例化空间server new QTc…

无涯教程-jQuery - show( )方法函数

show()方法仅显示匹配元素中的每个元素(如果隐藏)。此方法还有另一种形式&#xff0c;可以控制动画的速度。 show( ) - 语法 selector.show( ); show( ) - 示例 以下是一个简单的示例&#xff0c;简单说明了此方法的用法- <html><head><title>The jQuer…

PostgreSQL-Centos7源码安装

卸载服务器上的pg13 本来是想删除原来的postgis重新源码安装就行,但是yum安装的PostgreSQL不能直接使用,会提示以下问题: 之前服务是用yum安装的,现在需要删除 -- 删除数据的postgis插件 drop extension postgis; drop extension postgis cascade;删除相关安装包 # 查询…

Ubuntu Server版 之 apache系列 常用配置 以及 隐藏 版本号 IP、Port 搭建服务案例

查看版本 旧的 用 httpd -v 新的 用 apache2 -v 配置检测 旧的 httpd -t 新的 apachectl configtest window用的apache 是 httpd -t Linux 中 apachectl configtest 主配置文件 之前旧版apache 是httpd 现在都改成 apache2 /etc/apache2/apache2.conf window中 httpd.con…

leetcode 2141. Maximum Running Time of N Computers(N台计算机的最大运行时间)

有n台电脑&#xff0c;数组batteries代表每块电池的电量。 每台电脑每次只能放入一块电池&#xff0c;然后电池可以任意交换&#xff0c;但电池不能充电。 所有电脑必须同时运行。 问n台电脑最多可以同时运行几分钟。 思路&#xff1a; 乍一看很复杂&#xff0c;复杂的电池交…

使用Feign出现空指针异常

说明&#xff1a;本文记录一次偶然出现的空指针异常&#xff0c;在微服务架构中&#xff0c;一个服务在调用另一个服务时&#xff0c;出现了空指针异常。 业务描述&#xff1a;在做订单超时功能时&#xff0c;大家都知道&#xff0c;可以使用RabbitMQ延迟队列&#xff0c;下单…

【视觉SLAM入门】4.3. (非线性最小二乘问题)优化算法实现-ceres和g2o, 图优化理论

"天道不争而善胜" 1. Ceres库1.1 名词解释1.2 具体例子1.3 C实现1. 定义代价函数2. 构建最小二乘问题3. 配置求解器&#xff0c;开始优化4. 优化完毕&#xff0c;查看结果 2. G2O(General Graphic Optimization)2.1 图优化2.2 具体例子2.3 C实现1. 定义顶点2. 定义边…

Redis实战(3)——缓存模型与缓存更新策略

1 什么是缓存? 缓存就是数据交换的缓冲区&#xff0c; 是存贮数据的临时区&#xff0c;一般读写性能较高 \textcolor{red}{是存贮数据的临时区&#xff0c;一般读写性能较高} 是存贮数据的临时区&#xff0c;一般读写性能较高。缓存可在多个场景下使用 以一次 w e b 请求为例…

论文总结《Neural Collaborative Filtering(NCF)》

原文链接 Neural Collaborative Filtering(NCF) Motivation 传统的矩阵分解通过latent features的内积来估计user与item的交互&#xff0c;而内积仅仅只能表示latent features的线性关系 contributions 引入MLP来替代latent features的内积&#xff0c;从而增加矩阵分解的非…

Kaggle (2) :Bike Sharing Demand 共享单车需求预测

Kaggle (2) :Bike Sharing Demand 共享单车需求预测 题目链接&#xff1a;https://www.kaggle.com/competitions/bike-sharing-demand import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt import warnings warnings.filterwarni…

Selenium自动化元素定位方式与浏览器测试脚本

Selenium八大元素定位方法 Selenium可以驱动浏览器完成各种操作&#xff0c;比如模拟点击等。要想操作一个元素&#xff0c;首先应该识别这个元素。人有各种的特征&#xff08;属性&#xff09;&#xff0c;我们可以通过其特征找到人&#xff0c;如通过身份证号、姓名、家庭住…

力扣 738. 单调递增的数字

题目来源&#xff1a;https://leetcode.cn/problems/monotone-increasing-digits/description/ C题解&#xff1a;像1234就可以直接返回1234&#xff0c;像120需要从个位往高位遍历&#xff0c;2比0大&#xff0c;那么2减一成为1&#xff0c;0变成9&#xff0c;变成119。 clas…

商品分类中如何调整商品的顺序

为了更好的展示效果&#xff0c;商家可能经常需要在商品分类中&#xff0c;重新移动产品的顺序&#xff0c;比如将某个商品上移、下移、移动到顶部等。那么&#xff0c;在商品分类中如何进行这样的调整设置呢&#xff1f; 步骤一&#xff1a;查询分类下面的商品 在商品管理中…

计算机视觉(四)神经网络与典型的机器学习步骤

文章目录 神经网络生物神经元人工神经元激活函数导数 人工神经网络“层”的通俗理解 前馈神经网络Delta学习规则前馈神经网络的目标函数梯度下降输出层权重改变量 误差方向传播算法误差传播迭代公式简单的BP算例随机梯度下降&#xff08;SGD&#xff09;Mini-batch Gradient De…

随笔03 考研笔记整理

图源&#xff1a;文心一言 上半年的博文整理&#xff0c;下半年依然会更新考研类的文章&#xff0c;有需要的小伙伴看向这里~~&#x1f9e9;&#x1f9e9; 另外&#xff0c;这篇文章可能是我上半年的努力成果之一&#xff0c;因此仅关注博主的小伙伴能够查看它~~&#x1f9e…

Hum Brain Mapp:脑电图中的性别相关模式及其在机器学习分类器中的相关性

导读 深度学习越来越多地用于从脑电图(EEG)数据中检测神经和精神疾病&#xff0c;但该方法容易无意中纳入训练数据的偏差并利用不合理的模式。最近的研究表明&#xff0c;深度学习可以通过EEG检测性别&#xff0c;这意味着在基于深度学习的疾病检测器中可能存在与性别相关的偏…

【Three.js】Three.js中的纹理—图像应用和属性调整

写在前面&#xff1a; Three.js是一种强大的JavaScript库&#xff0c;用于创建基于Web的交互式3D图形和动画。在Three.js中&#xff0c;纹理是一项重要的功能&#xff0c;它允许我们将图像应用到几何体对象上&#xff0c;并通过调整纹理的属性来实现更丰富的视觉效果。 本文将介…