为了账号安全,请及时绑定邮箱和手机立即绑定

如何获取交易结果和状态

如何获取交易结果和状态

Go
慕田峪4524236 2023-07-31 17:08:18
我正在尝试使用以太坊区块链和 Solidity 合约。我目前正在部署合约并对其执行一些操作,但我想知道如何获取特定交易的一些“反馈/回调/返回”。例如,有没有办法将事务的状态设置为 0(错误)并仍然获取事件?if (id.length <= 0) {    emit Result("KO", "1");    revert();} 这不起作用(无事件),因为我恢复了所有内容,但状态将设置为 0if (id.length <= 0) {    emit Result("KO", "1");    return;} 我会收到一些事件,但状态将保持 1if (id.length <= 0) {    revert("KO_1");} 状态将为0,但我不会有任何事件这是我执行该操作的代码:func    testFunction(id []byte) {    //...    //...    tx, err := instance.Action(opt, id)    if (errors.HasError(err)) {        return    }    callbackValue := subscribeToContract(tx.Hash().Hex())    logs.Pretty(tx, callbackValue)    //...    //...}func    subscribeToContract(hashToRead string) myStruct {    query := ethereum.FilterQuery{        Addresses: []common.Address{address},    }    soc := make(chan types.Log)    sub, err := WssClient.SubscribeFilterLogs(context.Background(), query, soc)    if err != nil {        logs.Error(err)    }    for {        select {        case err := <-sub.Err():            logs.Info(`SOMETHING ERROR`)            logs.Error(err)        case vLog := <-soc:        logs.Info(`SOMETHING`)        contractAbi, _ := abi.JSON(strings.NewReader(string(SignABI)))          event := myStruct{}    contractAbi.Unpack(&event, "Result", vLog.Data)    logs.Info(`New Event from [` + vLog.TxHash.Hex() + `] : ` + event.Message)        }    }}如果id.length > 0,一切都好。但如果id.length <= 0,我没有来自该subscribeToContract函数的回调。有没有办法直接获得结果状态,或者应该循环tx, err := client.TransactionReceipt(context.Background(), txHash)直到获得状态?
查看完整描述

2 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

我没有找到任何方法来订阅事务的特定状态更改,但有一个解决方法:
go-ethereum包提供了 2 个函数SubscribeFilterLogsSubscribeNewHead. 我们可以使用第一个来获取日志(如果相关),第二个来获取块信息:

SubscribeNewHead 订阅有关给定通道上当前区块链头的通知。

当开采区块时,可以验证或拒绝/恢复交易,因此我们可以使用这个“技巧”

func checkTransactionReceipt(_txHash string) int {

    client, _ := getClient("https://ropsten.infura.io/v3/XXXXXX")

    txHash := common.HexToHash(_txHash)

    tx, err := client.TransactionReceipt(context.Background(), txHash)

    if (Error.HasError(err)) {

        return (-1)

    }

    return (int(tx.Status))

}


func    WaitForBlockCompletation(data EthData, hashToRead string) int {

    soc := make(chan *types.Header)

    sub, err := data.WssClient.SubscribeNewHead(context.Background(), soc)

    if (err != nil) {

        return -1

    }


    for {

        select {

            case err := <-sub.Err():

                _ = err

                return -1

            case header := <-soc:

                logs.Info(header.TxHash.Hex())

                transactionStatus := checkTransactionReceipt(hashToRead)

                if (transactionStatus == 0) {

                    //FAILURE

                    sub.Unsubscribe()

                    return 0

                } else if (transactionStatus == 1) {

                    //SUCCESS

                    sub.Unsubscribe()

                    return 1

                }

        }

    }

}

基本上我们正在等待区块被开采,然后如果交易尚未验证/拒绝,我们会检查TransactionReceipt失败并出现错误( )。not found然后,如果有交易,我们可以取消订阅并返回交易状态(0失败,1成功)。


不确定这是否是最差、最好、唯一的方法,但它确实有效!请随意改进此解决方案!


查看完整回答
反对 回复 2023-07-31
?
呼啦一阵风

TA贡献1802条经验 获得超6个赞

更简单/更新的解决方案:

我认为waitMined函数就是您正在寻找的函数。

bind.WaitMined(context.Background(), client, signedTx)
查看完整回答
反对 回复 2023-07-31
  • 2 回答
  • 0 关注
  • 98 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信