You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Golang ABI包传递tuple调用合约报错:poolId字段未找到

解决Golang ABI传递Tuple参数时的字段未找到错误

问题根源

Go语言中首字母小写的结构体字段属于包私有,ABI包依赖反射机制解析结构体时无法访问这些私有字段,因此会抛出field poolId for tuple not found的错误。此外,若结构体字段名与合约ABI中定义的tuple字段名不匹配(包括大小写),也会导致匹配失败。

解决方案

  1. 将结构体的所有字段改为首字母大写的公开字段,确保反射可以访问;
  2. 给每个字段添加abi:"字段名"标签,明确指定与合约ABI中tuple对应的字段名称,避免命名匹配偏差。

修改后的代码示例

import (
    "math/big"
    "strings"
    "time"

    "github.com/ethereum/go-ethereum/accounts/abi"
    "github.com/ethereum/go-ethereum/common"
)

type SingleSwap struct {
    PoolId   []byte        `abi:"poolId"`
    Kind     *big.Int      `abi:"kind"`
    AssetIn  common.Address `abi:"assetIn"`
    AssetOut common.Address `abi:"assetOut"`
    Amount   *big.Int      `abi:"amount"`
    UserData []byte        `abi:"userData"`
}

type Funds struct {
    Sender              common.Address `abi:"sender"`
    FromInternalBalance bool           `abi:"fromInternalBalance"`
    Recipient           common.Address `abi:"recipient"`
    ToInternalBalance   bool           `abi:"toInternalBalance"`
}

// 初始化参数时注意PoolId的正确转换:去掉0x前缀后转字节
singleSwap := SingleSwap{
    PoolId:   common.Hex2Bytes("115001ccae84cf4435a48497a1bfe187ab561b5c000200000000000000000529"),
    Kind:     big.NewInt(0),
    AssetIn:  common.HexToAddress("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"),
    AssetOut: common.HexToAddress("0x94068ce82b96800a23072c34dbb470a56033be12"),
    Amount:   big.NewInt(100000000),
    UserData: []byte{}, // 空字节数组替代"0x"字符串,更符合合约预期
}

funds := Funds{
    Sender:              fromAddr,
    FromInternalBalance: false,
    Recipient:           fromAddr,
    ToInternalBalance:   false,
}

deadline := big.NewInt(time.Now().Add(10 * time.Minute).Unix())

snipABI, err := abi.JSON(strings.NewReader(balancerABI))
if err != nil {
    // 处理错误
}

data, err := snipABI.Pack("swap", singleSwap, funds, big.NewInt(0), deadline)
if err != nil {
    // 处理错误
}

额外提示

  • 原代码中poolId的赋值[]byte("0x...")会将字符串"0x..."直接转为字节数组,包含'0'和'x'字符,这不符合合约对poolId字节数据的预期,应使用common.Hex2Bytes()去掉0x前缀后转换;
  • userData的空值建议用[]byte{}而非[]byte("0x"),更贴合合约对空字节数据的定义。

内容的提问来源于stack exchange,提问作者Mr Wolf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 23:02:43