34

Evm解析交易中合约数据

 3 years ago
source link: https://learnblockchain.cn/article/1393
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

以太坊交易Input交易解析

以下是在以太坊部署Uniswap调用合约的TxHash。 https://cn.etherscan.com/tx/0x06e68f7061f4d7da8117dc0ed97cd9888305590002d05811baa6594b10eb9cd1/

此交易调用合约方法 swapETHForExactTokens ,通过解析Input可以拿到合约输入参数。

有如下要点

  • 加载合约ABI
  • 通过Input获取合约方法
  • Unpack解包输入参数

测试用例代码

func TestParseDepositInput(t *testing.T) {
	input := "fb3bdb41000000000000000000000000000000000000000000108b2a2c280290940000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000b634058bd3ac146b128824e4b9ab59561b0568b9000000000000000000000000000000000000000000000000000000005f3f6a000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000ed1199093b1abd07a368dd1c0cdc77d8517ba2a0"
	inputData, _ := hex.DecodeString(input)
	abiStaking, _ := abi.JSON(strings.NewReader(Json))
	methodName, err := abiStaking.MethodById(inputData)
	data := inputData[4:]
	args := struct {
		AmountOut *big.Int
		Path    []common.Address
		To    common.Address
		Deadline  *big.Int
	}{}
	method, _ := abiStaking.Methods[methodName.Name]

	err = method.Inputs.Unpack(&args, data)
	if err != nil {
		log.Error("Unpack deposit pubkey error", "err", err)
	}
	fmt.Println("AmountOut ", hex.EncodeToString(args.AmountOut.Bytes()), " Deadline ", hex.EncodeToString(args.Deadline.Bytes())," ",len(args.Path)," ",args.To.String())
}

以下是Uniswap的 factory abi json

const Json = `
[
	{
		"inputs": [
			{
				"internalType": "address",
				"name": "_factory",
				"type": "address"
			},
			{
				"internalType": "address",
				"name": "_WETH",
				"type": "address"
			}
		],
		"stateMutability": "nonpayable",
		"type": "constructor"
	},
	{
		"inputs": [],
		"name": "WETH",
		"outputs": [
			{
				"internalType": "address",
				"name": "",
				"type": "address"
			}
		],
		"stateMutability": "view",
		"type": "function"
	},
	{
		"inputs": [
			{
				"internalType": "address",
				"name": "token",
				"type": "address"
			},
			{
				"internalType": "uint256",
				"name": "amountTokenDesired",
				"type": "uint256"
			},
			{
				"internalType": "uint256",
				"name": "amountTokenMin",
				"type": "uint256"
			},
			{
				"internalType": "uint256",
				"name": "amountETHMin",
				"type": "uint256"
			},
			{
				"internalType": "address",
				"name": "to",
				"type": "address"
			},
			{
				"internalType": "uint256",
				"name": "deadline",
				"type": "uint256"
			}
		],
		"name": "addLiquidityETH",
		"outputs": [
			{
				"internalType": "uint256",
				"name": "amountToken",
				"type": "uint256"
			},
			{
				"internalType": "uint256",
				"name": "amountETH",
				"type": "uint256"
			},
			{
				"internalType": "uint256",
				"name": "liquidity",
				"type": "uint256"
			}
		],
		"stateMutability": "payable",
		"type": "function"
	},
	{
		"inputs": [],
		"name": "factory",
		"outputs": [
			{
				"internalType": "address",
				"name": "",
				"type": "address"
			}
		],
		"stateMutability": "view",
		"type": "function"
	},
]
`

以下是在以太坊部署Uniswap调用合约的TxHash。 https://cn.etherscan.com/tx/0x06e68f7061f4d7da8117dc0ed97cd9888305590002d05811baa6594b10eb9cd1/

此交易调用合约方法 swapETHForExactTokens ,通过解析Input可以拿到合约输入参数。

有如下要点

  • 加载合约ABI
  • 通过Input获取合约方法
  • Unpack解包输入参数

测试用例代码

func TestParseDepositInput(t *testing.T) {
    input := "fb3bdb41000000000000000000000000000000000000000000108b2a2c280290940000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000b634058bd3ac146b128824e4b9ab59561b0568b9000000000000000000000000000000000000000000000000000000005f3f6a000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000ed1199093b1abd07a368dd1c0cdc77d8517ba2a0"
    inputData, _ := hex.DecodeString(input)
    abiStaking, _ := abi.JSON(strings.NewReader(Json))
    methodName, err := abiStaking.MethodById(inputData)
    data := inputData[4:]
    args := struct {
        AmountOut *big.Int
        Path    []common.Address
        To    common.Address
        Deadline  *big.Int
    }{}
    method, _ := abiStaking.Methods[methodName.Name]

    err = method.Inputs.Unpack(&args, data)
    if err != nil {
        log.Error("Unpack deposit pubkey error", "err", err)
    }
    fmt.Println("AmountOut ", hex.EncodeToString(args.AmountOut.Bytes()), " Deadline ", hex.EncodeToString(args.Deadline.Bytes())," ",len(args.Path)," ",args.To.String())
}

以下是Uniswap的 factory abi json

const Json = `
[
    {
        "inputs": [
            {
                "internalType": "address",
                "name": "_factory",
                "type": "address"
            },
            {
                "internalType": "address",
                "name": "_WETH",
                "type": "address"
            }
        ],
        "stateMutability": "nonpayable",
        "type": "constructor"
    },
    {
        "inputs": [],
        "name": "WETH",
        "outputs": [
            {
                "internalType": "address",
                "name": "",
                "type": "address"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    },
    {
        "inputs": [
            {
                "internalType": "address",
                "name": "token",
                "type": "address"
            },
            {
                "internalType": "uint256",
                "name": "amountTokenDesired",
                "type": "uint256"
            },
            {
                "internalType": "uint256",
                "name": "amountTokenMin",
                "type": "uint256"
            },
            {
                "internalType": "uint256",
                "name": "amountETHMin",
                "type": "uint256"
            },
            {
                "internalType": "address",
                "name": "to",
                "type": "address"
            },
            {
                "internalType": "uint256",
                "name": "deadline",
                "type": "uint256"
            }
        ],
        "name": "addLiquidityETH",
        "outputs": [
            {
                "internalType": "uint256",
                "name": "amountToken",
                "type": "uint256"
            },
            {
                "internalType": "uint256",
                "name": "amountETH",
                "type": "uint256"
            },
            {
                "internalType": "uint256",
                "name": "liquidity",
                "type": "uint256"
            }
        ],
        "stateMutability": "payable",
        "type": "function"
    },
    {
        "inputs": [],
        "name": "factory",
        "outputs": [
            {
                "internalType": "address",
                "name": "",
                "type": "address"
            }
        ],
        "stateMutability": "view",
        "type": "function"
    },
]
`

本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

  • 发表于 21分钟前
  • 阅读 ( 11 )
  • 学分 ( 0 )
  • 分类:Geth

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK