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

news2024/9/25 17:21:56

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、构造请求参数

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

methodName :这个就是我们想要调用的合约方法的函数选择器,这个定义的含义就是 用keccak256方法对调用方法(不包含定义字段和空格)进行加密,并取前4个字节,示例格式:0xa9059cbb

paddedToAddress :是先将toAddress转成address类型,然后用0在左侧填充到32位,示例格式:0000000000000000000000002228e53c4642dedae43f498eeda78b23571b84d8

amount :定义了一个 10进制的大数,也就是我们需要转账的金额,这里是 1000 * 10^18,这个要看转账token定义的decimal是多少位

paddedAmount:paddedToAddress一样,也是用0在左侧填充到32位,示例格式:0000000000000000000000000000000000000000000000056bc75e2d63100000

最后再将methodName、paddedToAddress、paddedAmount追加到字节数组 组成最终的data参数

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,
	})

这里我们用了DynamicFeeTx结构体来构建交易对象,它主要是支持EIP-1559协议可以动态设置Max Priority(矿工小费)以及Max Gas Fee(最大gas费用)

其中Value,表示原生币要转账的数量(比如我们在eth主网,那就是代币要转账的eth数量)

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
	}

因为我们使用的是DynamicFeeTx创建交易对象,所以这里 signer我们需要使用NewLondonSigner来构建

4.5、main函数里来调用函数

func main() {
	client, err := ethclient.Dial("区块链rpc地址")
	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("transfer tx : ", tx)

}

区块链rpc地址 填入你要调用的链的具体节点地址,如果没有可以通过 INFURA 进行创建

5、执行main方法

我这里使用的以太坊的 goerli测试链 进行测试的,看上面我们的代码已经成功执行了,让我们去区块链浏览器了看一下

 

 

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

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

 请关注公众号,回复 “go合约调用” 领取完整代码


 

 我的公众号

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

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

相关文章

KEIL 软件学习魔法棒

Device 芯片选型 Target : 晶振设置 Output: 选择中间文件的生成路径 Objects (创建文件夹之后再选择) ,创建hex文件 Listing : 创建文件夹之后再选择 USER:改变生成的 hex 文件路径 C/C :宏定义 和 路径选择 (目前使用到的&#…

压力测试-商场项目

1.压力测试 压力测试是给软件不断加压,强制其在极限的情况下运行,观察它可以运行到何种程度,从而发现性能缺陷,是通过搭建与实际环境相似的测试环境,通过测试程序在同一时间内或某一段时间内,向系统发送预…

陪诊小程序软件|陪诊系统定制|医院陪诊小程序

开发一个陪诊小程序需要投入一定的费用,具体金额会因项目的复杂程度、功能需求和推广政策而有所差异在投入资金之前,建议进行市场调研和需求分析,制定出合理的预算,并选择专业的开发团队进行合作,那么开发陪诊小程序需…

KingFunsion工程开发规范——关系库使用规范

KingFunsion工程开发规范——关系库使用规范 2023-07-07 20:10雷工笔记 哈喽,大家好,我是雷工。 今天学习KingFunsion工程开发规范之关系库使用规范。 第一章 统一规范 1.1.表字符集默认使用utf8; 1.2.禁止在数据库中存储大文件&#xff0…

新的CoolSiC™槽沟MOSFET技术,用于低栅氧化物应力和高性能

标题:The new CoolSiC™ Trench MOSFET Technology for Low Gate Oxide Stress and High Performance UPS(Uninterruptible Power Supply)系统也称不间断电源系统,是一种能够提供电力备用的设备,当主电源出现故障或停…

无涯教程-jQuery - jQuery.post( url, data, callback, type)方法函数

jQuery.post(url,[data],[callback],[type])方法使用POST HTTP请求从服务器加载页面。 该方法返回XMLHttpRequest对象。 jQuery.post( url, [data], [callback], [type] ) - 语法 $.post( url, [data], [callback], [type] ) 这是此方法使…

3秒钟教你如何配置vscode中的vue3代码快速生成模版

1.首先点击你的vscode左下角的齿轮设置按钮,然后点击配置用户代码片段。 2.输入vue搜索vue.json这个文件,然后点击这个文件 3.接下来只需在原有的注释之下输入粘贴如下代码即可 代码如下: "vue3": {"prefix": "vue3…

前后端分离开发,使用Nginx部署Vue

nginx相关的命令(要在nginx报下打开cmd执行相应的命令) 开启nginx:start nginx 关闭nginx:nginx.exe -s quit 怎么把现有的前端环境部署在nginx上 安装并配置好Nginx后,您可以通过以下步骤来访问项目的前端页面&#…

软件安全测试:软件产品高质量的守门员

软件安全测试是保障软件产品高质量的重要环节,它扮演着守门员的角色,为软件产品提供安全性与稳定性的保护。在互联网与信息化时代,软件产品的需求日益增长,同时也伴随着对软件安全的重视。 1、软件安全测试的定义与重要性 软件安…

智能网关实现混凝土搅拌机无人自动化

“以前的搅拌站生产时,是需要人工巡检的,运送物料和搅拌时产生的大量粉尘污染和噪音,让工人苦不堪言。但是如果有了物联网搅拌站监测系统智慧园区项目落地后,工人也不用去现场忍受噪音和粉尘了。” 行业痛点 传统模式下的混泥土…

【代码随想录day21】二叉搜索树中的插入操作

题目 给定二叉搜索树(BST)的根节点 root 和要插入树中的值 value ,将值插入二叉搜索树。 返回插入后二叉搜索树的根节点。 输入数据 保证 ,新值和原始二叉搜索树中的任意节点值都不同。 注意,可能存在多种有效的插入…

二叉树(C++,代码)

例子&#xff1a;前序输入 AB##CDF#G#E#### (#表示空&#xff0c;不存在&#xff09; #include<iostream> using namespace std; typedef struct BiNode {char data;struct BiNode* lchild, * rchild; }BiNode,*Bitree; char ch; int m, n; t…

(小白必看)详解yolov5训练自己的数据集 使用香烟数据集训练yolov5识别香烟

数据集资源 https://download.csdn.net/download/qq_42864343/88110620?spm1001.2014.3001.5503 https://download.csdn.net/download/qq_42864343/88110686?spm1001.2014.3001.5501 创建数据集目录 在YOLOv5根目录下创建mydata文件夹&#xff08;名字可以自定义&#xf…

如何少走弯路?蚓链助力零售企业实现数字化转型

基于大环境下的数据驱动&#xff0c;创新业务模式成为了后疫情时代下零售企业冲破困局、拓展业务的必然趋势&#xff0c;新零售概念应运而生。新零售结合数字化应用技术为传统零售企业打造线上营销生态链&#xff0c;帮助企业积累数据&#xff0c;盘活数据实现更大营收价值。 …

CTFshow web入门 爆破

web21 bp 攻击模块的迭代器 输入账号密码 抓包 发现下面存在一个base64编码 我输入的是 123 123 发现就是base加密 账号 密码 那我们怎么通过intruder模块 自动变为 base64呢 然后去payload------>custom iterator(自定义迭代器) 位置1导入admin 因为是 账号:密码 这…

三维虚拟电子沙盘数字沙盘态势推演教程第12课

三维虚拟电子沙盘数字沙盘态势推演教程第12课 设置system.ini 如下内容 Server122.112.229.220 userGisTest Passwordchinamtouch.com 该数据库中只提供 成都市火车南站附近的数据请注意&#xff0c;104.0648,30.61658 SDK中自带了一套 导航系统&#xff0c;用的是比较详细的…

一种分解多种信号模式非线性线性调频的方法研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

值得关注的五个先进代码补全服务

效率、代码质量和生产力在编程中都是至关重要的组成部分。因此&#xff0c;开发人员不断寻求能够加快编程过程的工具&#xff0c;以提高其工作效率和质量。 在编程这个不断发展的领域&#xff0c;目前最具革命性的进展之一就是AI驱动的代码补全服务。这些工具不仅简化了编程过程…

小程序获取手机号要开始收费了!

收费说明 自2023年8月26日起&#xff0c;手机号实时验证组件将需要付费使用。 手机号快速验证组件 手机号快速验证组件 | 微信开放文档 新版本组件不再需要提前调用wx.login进行登录。 代码示例 <button open-type"getPhoneNumber" bindgetphonenumber"ge…

机器学习02-再识K邻近算法(自定义数据集训练及测试)

定义&#xff1a; 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别&#xff0c;则该样本也属于这个类别。简单的说就是根据你的“邻居”来推断出你的类别。 用个成语就是物以类聚 思想&#xff1a; 如果一个样本在特征空间中的K个最…