Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

通过ABICodec.decodeEvent方法解析EventLog抛异常(sdk v2.9.3) #859

Closed
13813385093 opened this issue Dec 30, 2023 · 10 comments
Closed

Comments

@13813385093
Copy link

pragma solidity 0.8.11;

contract Asset {
    event TransferEvent(address indexed user, uint256 indexed id, uint256 value);

    function transfer(uint256 id, uint256 value) public {
        emit TransferEvent(msg.sender, id, value);
    }
}

采用一个简单的合约做测试,编译成Java文件后,通过EventCallback监听交易事件。实例代码如下:

eventSubscribe.subscribeEvent(params, new EventCallback() {
    @Override
    public void onReceiveLog(int status, List<EventLog> logs) {
        if(status == 0 && logs != null) {
            for(EventLog el : logs) {
                try {
                    List<Object> objs = abiCodec.decodeEvent(Asset.ABI, "TransferEvent", el);
                    log.info("abiCodec:{}", objs);
                } catch (ABICodecException e) {
                    log.error(e.getMessage());
                }
            }
        }
    }
});

abiCodec.decodeEvent(Asset.ABI, "TransferEvent", el) 抛出异常如下:

exception in decodeEventToObject : arraycopy: last source index 32 out of bounds for byte[0]
cannot decode in decodeEventToObject with appropriate interface ABI
@kyonRay
Copy link
Member

kyonRay commented Jan 2, 2024

可以尝试使用2.10.0-SNAPSHOT的包,目前Java SDK 2.10.0版本正在测试中,欢迎反馈问题。

@13813385093
Copy link
Author

2.10.0-SNAPSHOT这个包从哪里获取?官方并没有提供这个包

@kyonRay
Copy link
Member

kyonRay commented Jan 3, 2024

2.10.0-SNAPSHOT这个包从哪里获取?官方并没有提供这个包

直接将Java sdk的版本改成2.10.0-SNAPSHOT重新编译即可。

@13813385093
Copy link
Author

你好,我的项目是通过maven引入的。至少目前在maven中央仓库是没有这个版本的,我用maven也获取不到依赖。

<dependency>
        <groupId>org.fisco-bcos.java-sdk</groupId>
        <artifactId>fisco-bcos-java-sdk</artifactId>
        <version>2.10.0-SNAPSHOT</version>
</dependency>

image

@kyonRay
Copy link
Member

kyonRay commented Jan 3, 2024

在maven源中加上这两个再试一次:

    maven { url "https://oss.sonatype.org/service/local/staging/deploy/maven2" }
    maven { url "https://oss.sonatype.org/content/repositories/snapshots" }

@kyonRay
Copy link
Member

kyonRay commented Jan 3, 2024

#809

@13813385093
Copy link
Author

我已经将SDK版本换成了2.10.0-SNAPSHOT
我使用的测试合约是:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.11;

contract Asset {
    event TransferEvent(address indexed user, uint256 indexed id, uint256 value);

    function transfer(uint256 id, uint256 value) public {
        // 逻辑处理
        emit TransferEvent(msg.sender, id, value);
    }
}

调用过程如下:

"[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"user\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"TransferEvent\",\"outputs\":[],\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"id\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"
List<TransactionReceipt.Logs> logs = receipt.getResult().getLogs();
for(TransactionReceipt.Logs txLog : logs) {
	if(txLog.getAddress().equals(contractAddress)) {
		try {
			abiCodec.decodeEvent(abi, "TransferEvent", txLog.toEventLog());
		} catch (ABICodecException e) {
			e.printStackTrace();
		}
	}
}

抛出异常:

org.fisco.bcos.sdk.abi.ABICodecException:  cannot decode in decodeEventToObject with appropriate interface ABI

请问是我调用方式不对还是SDK的异常?

@13813385093
Copy link
Author

顺带提以下,我看到你们的对于事件的解析仅仅依靠abi,我觉得是解析不出来的。因为EventLog的data数据,是不会将indexed编码到里面的,而参数是否位indexed无法通过abi解码出来。

@13813385093
Copy link
Author

我已经找到问题的原因了:合约编译的abi不能直接作为参数传入AbiCode对象作为入参,因为里面缺少indexed的说明,需要从metadata里面重新解析abi信息,再作为函数的入参才可以使用。

@helloHKTK
Copy link

我已经找到问题的原因了:合约编译的abi不能直接作为参数传入AbiCode对象作为入参,因为里面缺少indexed的说明,需要从metadata里面重新解析abi信息,再作为函数的入参才可以使用。

能否举例说明一下

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants