
我們需要監(jiān)聽某個(gè)事件 需要根據(jù)event 的topic[0] 來篩選。所以當(dāng)我們要去監(jiān)聽一個(gè) 日志時(shí)就需要知道topic[0]的值
List<EthLog.LogResult> logs = web3j.ethGetLogs(new EthFilter(DefaultBlockParameter.valueOf(new BigInteger(start.toString())), DefaultBlockParameter.valueOf(new BigInteger(end.toString()))
, contract).addOptionalTopics(transferTopic)).send().getLogs();
然后這個(gè)topic[0] 可以使用
List<TypeReference<?>> parameters = new ArrayList<>();
parameters.add(new TypeReference<Address>(true) {
});
parameters.add(new TypeReference<Address>(true) {
});
Event event = new Event("name", parameters);
topic[0] = EventEncoder.encode(event);
正常情況都是正常的 但是當(dāng)日志里面有一個(gè)我們自己定義的結(jié)構(gòu)體 就發(fā)現(xiàn)不對(duì)了
public static String encode(Event event) {
String methodSignature = buildMethodSignature(event.getName(), event.getParameters());
return buildEventSignature(methodSignature);
}
static <T extends Type> String buildMethodSignature(
String methodName, List<TypeReference<T>> parameters) {
StringBuilder result = new StringBuilder();
result.append(methodName);
result.append("(");
String params =
parameters.stream().map(p -> Utils.getTypeName(p)).collect(Collectors.joining(","));
result.append(params);
result.append(")");
return result.toString();
}
public static String buildEventSignature(String methodSignature) {
byte[] input = methodSignature.getBytes();
byte[] hash = Hash.sha3(input);
return Numeric.toHexString(hash);
}
看上面代碼發(fā)現(xiàn) 以event Transfer(address indexed from, address indexed to,uint256 indexed id ); 其實(shí)這個(gè)topic[0] = keccak256("Transfer(address, address,uint256)") 如果有自己定義的機(jī)構(gòu)體怎么表示?
如果我們用 EventEncoder.encode(event) 方法 ; Utils.getTypeName(p) 它會(huì)找到我們?cè)俅a里面定義的類名 然后拼接去 keccak256,這是不對(duì)的 。
因?yàn)?event的topic[0] 和方法簽名有點(diǎn)類似 就去看看方法簽名時(shí)怎么處理的 (DefaultFunctionEncoder)
public String encodeFunction(final Function function) {
final List<Type> parameters = function.getInputParameters();
final String methodSignature = buildMethodSignature(function.getName(), parameters);
final String methodId = buildMethodId(methodSignature);
final StringBuilder result = new StringBuilder();
result.append(methodId);
return encodeParameters(parameters, result);
}
protected static String buildMethodSignature(
final String methodName, final List<Type> parameters) {
final StringBuilder result = new StringBuilder();
result.append(methodName);
result.append("(");
final String params =
parameters.stream().map(Type::getTypeAsString).collect(Collectors.joining(","));
result.append(params);
result.append(")");
return result.toString();
}
這里拿的是 Type::getTypeAsString 方法
struct NFT {
address collection;
uint256 tokenId;
}
那 NFT 的getTypeAsString 的結(jié)果就是 (address,uint256) 如果是 NFT [] 那就是 (address,uint256)[] 如果是結(jié)構(gòu)體套結(jié)構(gòu)體就是一次遞歸。
event Name(address user,NFT[] nfts);
那么 Name 的 topic[0] 就是 keccak256("Name(address,(address,uint256)[])");
其實(shí)文檔有寫 但是寫的不太明白 我沒有看懂!