web3j 解码bytes[]

2 篇文章 0 订阅
1 篇文章 0 订阅

前言

在使用Java解析UniswapV3链上Input Data数据的时候遇到方法函数multicall(bytes[] calldata data)的解析失败。后面查找web3.js的方法尝试理解Java的解析。

Tx:

https://etherscan.io/tx/0xecb398ee0e00ec3b3f1bc4d3d34c69153c2abeef995d39a69c1f30300330c18e

Input Data:

0xac9650d800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000104414bf389000000000000000000000000c5e7703d4647ff77bc733bb56d120471b83382e2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006507f7280000000000000000000000000000000000000000000000000001d6c3ef643800000000000000000000000000000000000000000000000000014fcd4e1e5ce130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004449404b7c000000000000000000000000000000000000000000000000014fcd4e1e5ce13000000000000000000000000019edc2f769ac416c725e1c4032be50c1d4b3bd3a00000000000000000000000000000000000000000000000000000000

web3.js解码

let calls = web3.eth.abi.decodeParameters(['bytes[]'], calldata)[0];
console.log(`calls1:${calls}`)

console

0x414bf389000000000000000000000000c5e7703d4647ff77bc733bb56d120471b83382e2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006507f7280000000000000000000000000000000000000000000000000001d6c3ef643800000000000000000000000000000000000000000000000000014fcd4e1e5ce1300000000000000000000000000000000000000000000000000000000000000000
,
0x49404b7c000000000000000000000000000000000000000000000000014fcd4e1e5ce13000000000000000000000000019edc2f769ac416c725e1c4032be50c1d4b3bd3a

Java 解码

package com.hlf;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import net.osslabz.evm.abi.decoder.AbiDecoder;
import net.osslabz.evm.abi.decoder.DecodedFunctionCall;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.FunctionReturnDecoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.*;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.http.HttpService;
import org.web3j.utils.Numeric;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
 * @ClassName: DecodeV3Test
 * @Author: lfhuang
 * @CreateDate: 2023/9/18 3:13 PM
 * @Description:
 * @Version: 1.0
 **/
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class DecodeV3Test {
    public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, NoSuchMethodException, InstantiationException, IllegalAccessException, IOException {

        // 解析uniswap v3的multicall(bytes[] data)函数
        // https://github.com/Uniswap/v3-periphery/blob/v1.0.0/contracts/base/Multicall.sol

        // https://etherscan.io/tx/0xecb398ee0e00ec3b3f1bc4d3d34c69153c2abeef995d39a69c1f30300330c18e
        // 原input数据
        String callData = "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000104414bf389000000000000000000000000c5e7703d4647ff77bc733bb56d120471b83382e2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006507f7280000000000000000000000000000000000000000000000000001d6c3ef643800000000000000000000000000000000000000000000000000014fcd4e1e5ce130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004449404b7c000000000000000000000000000000000000000000000000014fcd4e1e5ce13000000000000000000000000019edc2f769ac416c725e1c4032be50c1d4b3bd3a00000000000000000000000000000000000000000000000000000000";

        /**
         * 解析后的数据1 exactInputSingle((address,address,uint24,address,uint256,uint256,uint256,uint160))
         * 0x414bf389000000000000000000000000c5e7703d4647ff77bc733bb56d120471b83382e2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006507f7280000000000000000000000000000000000000000000000000001d6c3ef643800000000000000000000000000000000000000000000000000014fcd4e1e5ce1300000000000000000000000000000000000000000000000000000000000000000
         * 414bf389
         * 000000000000000000000000c5e7703d4647ff77bc733bb56d120471b83382e2
         * 000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2
         * 0000000000000000000000000000000000000000000000000000000000000bb8
         * 0000000000000000000000000000000000000000000000000000000000000000
         * 000000000000000000000000000000000000000000000000000000006507f728
         * 0000000000000000000000000000000000000000000000000001d6c3ef643800
         * 000000000000000000000000000000000000000000000000014fcd4e1e5ce130
         * 0000000000000000000000000000000000000000000000000000000000000000
         * 解析后的数据2 unwrapWETH9(uint256, address)
         * 0x49404b7c000000000000000000000000000000000000000000000000014fcd4e1e5ce13000000000000000000000000019edc2f769ac416c725e1c4032be50c1d4b3bd3a
         * 49404b7c
         * 000000000000000000000000000000000000000000000000014fcd4e1e5ce130
         * 00000000000000000000000019edc2f769ac416c725e1c4032be50c1d4b3bd3a
         */

        List list = new ArrayList();
        int index = 64;//32字节
        int length = callData.length() / index;
        int beginIndex = 0;
        int endIndex = 64;
        for (int i = 0; i < length; i++) {
            list.add(Numeric.hexStringToByteArray(callData.substring(beginIndex, endIndex)));
            beginIndex = beginIndex + index;
            endIndex = endIndex + index;
        }

        Function function = new Function("multicall", Arrays.<Type>asList(new DynamicArray<DynamicBytes>(DynamicBytes.class, org.web3j.abi.Utils.typeMap(list, DynamicBytes.class))), Arrays.<TypeReference<?>>asList(new TypeReference<DynamicArray<DynamicBytes>>() {
        }));
        System.out.println("encoded:" + FunctionEncoder.encode(function));

        List<Type> decode = FunctionReturnDecoder.decode(callData, function.getOutputParameters());
        List<DynamicBytes> decodeList = (List<DynamicBytes>) decode.get(0).getValue();

        String currentDirectory = System.getProperty("user.dir");
        AbiDecoder abiDecoder = new AbiDecoder(currentDirectory + "/robot-monitor/abi/SwapV3Router.json");

        for (DynamicBytes dynamicBytes1 : decodeList) {
            String data = Numeric.toHexString(dynamicBytes1.getValue());
            System.out.println("decode:" + data);
            DecodedFunctionCall decodedFunctionCall1 = abiDecoder.decodeFunctionCall(data);
            System.out.println("解析对应abi数据:" + JSON.toJSONString(decodedFunctionCall1));
        }
    }
}

console

encoded:0xac9650d8000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000028000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000340000000000000000000000000000000000000000000000000000000000000038000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000000000000000000000000000048000000000000000000000000000000000000000000000000000000000000004c000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000000540000000000000000000000000000000000000000000000000000000000000058000000000000000000000000000000000000000000000000000000000000005c000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000000000000000068000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000180000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000001040000000000000000000000000000000000000000000000000000000000000020414bf389000000000000000000000000c5e7703d4647ff77bc733bb56d1204710000000000000000000000000000000000000000000000000000000000000020b83382e2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead90800000000000000000000000000000000000000000000000000000000000000203c756cc200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000bb8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000206507f7280000000000000000000000000000000000000000000000000001d6c30000000000000000000000000000000000000000000000000000000000000020ef643800000000000000000000000000000000000000000000000000014fcd4e00000000000000000000000000000000000000000000000000000000000000201e5ce130000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000000000002049404b7c000000000000000000000000000000000000000000000000014fcd4e00000000000000000000000000000000000000000000000000000000000000201e5ce13000000000000000000000000019edc2f769ac416c725e1c4032be50c10000000000000000000000000000000000000000000000000000000000000020d4b3bd3a00000000000000000000000000000000000000000000000000000000
decode:0x414bf389000000000000000000000000c5e7703d4647ff77bc733bb56d120471b83382e2000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006507f7280000000000000000000000000000000000000000000000000001d6c3ef643800000000000000000000000000000000000000000000000000014fcd4e1e5ce1300000000000000000000000000000000000000000000000000000000000000000
解析对应abi数据:{"name":"exactInputSingle","paramList":[{"name":"params","type":"tuple","value":["0xc5e7703d4647ff77bc733bb56d120471b83382e2","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",3000,"0x0000000000000000000000000000000000000000",1695020840,517612000000000,94519852598616368,0]}],"params":[{"$ref":"$.paramList[0]"}],"size":1}
decode:0x49404b7c000000000000000000000000000000000000000000000000014fcd4e1e5ce13000000000000000000000000019edc2f769ac416c725e1c4032be50c1d4b3bd3a
解析对应abi数据:{"name":"unwrapWETH9","paramList":[{"name":"amountMinimum","type":"uint256","value":94519852598616368},{"name":"recipient","type":"address","value":"0x19edc2f769ac416c725e1c4032be50c1d4b3bd3a"}],"params":[{"$ref":"$.paramList[0]"},{"$ref":"$.paramList[1]"}],"size":2}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值