golang调用智能合约,获取合约函数的返回值

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

如果不是只读取数据的合约函数,需要异步的执行,因此并不能直接获取到合约函数的返回值,需要等到交易执行完毕,得到确认后才能获取到合约函数的返回值。而且合约函数返回值一般是通过事件日志获取到的。

这里给出一个例子来展示我是如何获取合约函数返回值的。
我使用的以太坊版本为:github.com/ethereum/go-ethereum v1.13.0

solidity合约:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract StoreString {
  event ItemSetStr(bytes32 indexed hash,string key,string value);
  
  mapping (string => string) public itemstr;

  function setItemstr(string memory _key, string memory _value) external returns(bytes32){
    itemstr[_key] = _value;
    bytes32 hash=sha256(abi.encodePacked(_key,_value));
    emit ItemSetStr(hash,_key,_value);
    return hash;
  }
}

这是一个存储键值对的合约,利用函数setItemstr向map中存储键值对,并通过key,value计算哈希值,要求返回哈希值。通过事件ItemSetStr将哈希值(返回值)、key、value记录下来。

将合约的abi编码通过abigen工具生成go代码后。
以下是测试获取合约函数返回值的代码:

func TestSetStoreString(t *testing.T) {
	url="" //节点链接
	client, err := ethclient.Dial(url)
	if err != nil {
		log.Fatal(err)
	}

	//合约地址
	contractAddress := common.HexToAddress("0xd9Ed5E352F84E182eB499ae1b5F9935C06d78Ddb")

	privateKeyStr := "" //私钥字符串

	auth := InitAuth(privateKeyStr, client, nil)
	
	//得到合约实例
	storeString, err := NewStoreString(contractAddress, client)
	if err != nil {
		log.Fatal("NewStoreString: ", err)
	}
	
	tx, err := storeString.SetItemstr(auth, "key10", "9900")
	if err != nil {
		log.Fatal("SetItemstr: ", err)
	}
	
	//等待交易确认,获取到交易的收据
	receipt, err := bind.WaitMined(context.Background(), client, tx)
	if err != nil {
		log.Fatal("WaitMined: ", err)
	}
	
	//如果交易成功
	if receipt.Status == 1 {
		//解析该交易收据里包含的日志
		eventItemSetStr, err := storeString.ParseItemSetStr(*receipt.Logs[0])
		if err != nil {
			log.Fatal("ParseItemSetStr: ", err)
		}
		fmt.Println("交易成功!")
		fmt.Println("txHash:", tx.Hash().Hex())
		fmt.Println("返回值:", eventItemSetStr.Hash)
		fmt.Println("日志Key:", eventItemSetStr.Key)
		fmt.Println("日志Value:", eventItemSetStr.Value)
	} else {
		t.Error("交易失败")
	}

}


func InitAuth(privateKeyStr string, client *ethclient.Client, value *big.Int) *bind.TransactOpts {
	privateKeyECDSA, err := crypto.HexToECDSA(privateKeyStr)
	if err != nil {
		log.Fatal("crypto.HexToECDSA: ", err)
	}

	chainID, err := client.ChainID(context.Background())
	if err != nil {
		log.Fatal("ChainID: ", err)
	}

	auth, err := bind.NewKeyedTransactorWithChainID(privateKeyECDSA, chainID)
	if err != nil {
		log.Fatal("NewKeyedTransactorWithChainID: ", err)
	}

	//设置交易参数,例如gas费等,这里全部由区块链系统评估决定
	auth.GasFeeCap = big.NewInt(1).Mul(big.NewInt(10), big.NewInt(1000000000)) // maxFee Per Gas:100gwei

	//获取平均小费
	gasTipCap, err := client.SuggestGasTipCap(context.Background())
	if err != nil {
		log.Fatal("SuggestGasTipCap: ", err)
	}
	auth.GasTipCap = gasTipCap //priorityfee Per Gas:
	auth.GasLimit = uint64(3000000)

	//还需要设置锁定金额
	auth.Value = value
	return auth
}

返回值并不能立马获得,需要等待交易成功上链。再从事件日志中解析出返回值。因此这个过程中用到了两个重要代码:

bind包下的WaitMined:等待tx交易的确认,并获取其收据,该收据中必然包含我们想要的日志

func WaitMined(ctx context.Context, b DeployBackend, tx *types.Transaction) (*types.Receipt, error)

合约代码自动生成的go文件中的ParseItemSetStr,传入日志即可解析出信息。文章来源地址https://www.toymoban.com/news/detail-838391.html

func (_StoreString *StoreStringFilterer) ParseItemSetStr(log types.Log) (*StoreStringItemSetStr, error)

到了这里,关于golang调用智能合约,获取合约函数的返回值的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 关于web3.js中与交易发送、交易签名、智能合约函数调用相关api的理解

    web3.js中有一些与交易发送、签名、合约函数调用相关的api,初学者(如me)常常搞不清什么情况下应该调用哪个,以及它们之间的区别。现将个人浅见记录如下,备忘。 sendTransaction web3.eth.sendTransaction(transactionObject [, callback]) transactionObject对象设置交易的各种参数(不包括签名r,

    2023年04月09日
    浏览(125)
  • 调用合约方法创建子合约后获取子合约地址

    在通过调用合约的方法创建合约后,不能直接得到子合约地址。不便于单元测试。如下方法可解决: 合约: 单元测试:

    2024年02月15日
    浏览(36)
  • 智能合约:从 Python 调用智能合约

    以太坊带来了智能合约的进步,其是可公开验证的代码。如果我们改变合约状态,我们将花费一些gas。现在,让我们创建一个Python程序,它可以在以太坊上调用智能合约。因为我们不想实验中支付费用,所以我们将运行Ganache,这是一个本地以太坊实例。 首先,我们去Remix.e

    2024年01月19日
    浏览(64)
  • 智能合约中如何调用其他智能合约

    智能合约是区块链技术中的一项关键功能,它可以让开发者编写代码来自动执行一系列的操作,从而实现各种复杂的业务逻辑。在许多应用场景中,一个智能合约可能需要调用另一个智能合约来完成某些任务。本文将介绍智能合约如何调用其他智能合约,并提供一些实例来帮

    2024年02月11日
    浏览(42)
  • Java智能合约工具包|Java调用智能合约|Java调用ERC20、ERC721、ERC1155合约

    Magician-ContractsTools是一个用于调用智能合约的工具包,你可以非常容易地在Java程序中调用智能合约进行查询和写入操作。 有三个内置的标准合约模板,分别是ERC20、ERC721和ERC1155,如果你需要调用这三个合约中的标准函数,可以帮助你非常快速地完成工作。除了内置的合同模板

    2024年02月11日
    浏览(55)
  • 使用 Solidity 创建返回所有者地址和余额的智能合约

    问题: 创建一个名为 MyContract 的智能合约,拥有一个状态变量作为所有者。创建一个构造函数以从 msg 中获取所有者的地址并将其保存到状态变量 owner 中。另外,创建一个函数 getBalance() 来显示所有者的当前余额。   解决方案: 每个智能合约都由一个称为所有者的地址拥有

    2024年02月05日
    浏览(87)
  • 智能合约安全分析,针对 ERC777 任意调用合约 Hook 攻击

    Safful发现了一个有趣的错误,有可能成为一些 DeFi 项目的攻击媒介。这个错误尤其与著名的 ERC777 代币标准有关。此外,它不仅仅是众所周知的黑客中常见的简单的重入问题。 这篇文章对 ERC777 进行了全面的解释,涵盖了所有必要的细节。深入研究 ERC777 代币的具体细节的资源

    2024年02月04日
    浏览(40)
  • 四:调用部署在ganache的智能合约

    如果朋友有代码,工具,使用流程等不太清楚的,可用去专栏看看,专栏中有文章中所提及的具体使用方式。不太明白的朋友可以自己去看看~~ 瞬移专栏 实验目的 实验原理 ether.js中提供了我们对智能合约进行调用的方法,使用ether.js能很方便我们和智能合约进行交互。 js代码

    2023年04月09日
    浏览(35)
  • RPC远程调用加密方法获取返回值

    从混淆的加密JS中还原了加密参数的具体生成流程,结果想从JS转python的过程中第一步就卡住了。开头密钥JS代码如下,但是水平有限不知道如何转为python实现(如果有大佬知道希望可以评论指点)。利用execjs+jsdom来执行简化还原后的JS代码依旧无法实现。所以只能通过RPC的方式来

    2024年02月08日
    浏览(42)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包