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

如何使用Ethers将SwapResolverOptions结构体编码为Bytes参数

Solidity结构体编码为Bytes的解决方案

问题描述

我在测试一段Solidity代码,需要为bytes类型参数正确编码数据。合约包含以下函数:

function validateAdditionalCalldata(bytes calldata resolverOptions) external view;
function resolve(uint256 amountIn, bytes calldata resolverOptions) public override returns (uint256 amountOut) {
    // 将额外calldata解码为SwapResolverOptions结构体
    (SwapResolverOptions memory swapResolverOptions) = abi.decode(resolverOptions, (SwapResolverOptions));
    return resolveImplementation(amountIn, swapResolverOptions);
}

对应的TypeScript生成代码中,resolve函数接收PromiseOrValue<BytesLike>类型的resolverOptions参数:

resolve(
  amountIn: PromiseOrValue<BigNumberish>,
  resolverOptions: PromiseOrValue<BytesLike>,
  overrides?: Overrides & { from?: PromiseOrValue<string> }
): Promise<ContractTransaction>;

export type SwapResolverOptionsStruct = {
  path: PromiseOrValue<BytesLike>;
  deadline: PromiseOrValue<BigNumberish>;
  amountIn: PromiseOrValue<BigNumberish>;
  amountOutMinimum: PromiseOrValue<BigNumberish>;
  inputTokenAddress: PromiseOrValue<string>;
  targetAddress: PromiseOrValue<string>;
  destinationAddress: PromiseOrValue<string>;
};

我在TypeScript中定义了参数实例:

const resolverOptions: SwapResolverOptionsStruct = {
  path: '0x00',
  // 该参数将在下一版本部署中移除
  deadline: BigNumber.from(1000),
  amountIn: BigNumber.from(100000000),
  amountOutMinimum: BigNumber.from(0),
  inputTokenAddress: WMATIC_MUMBAI,
  destinationAddress: owner.address,
  targetAddress: ADDRESS_ZERO,
};

尝试用以下方式编码时触发错误:

import { defaultAbiCoder } from "@ethersproject/abi";

encodedResolverOptions = defaultAbiCoder.encode(
  ['SwapResolverOptionsStruct'],
  [resolverOptions]
);

错误信息:

Error: invalid type (argument="type", value="SwapResolverOptionsStruct",

注意:我无法直接编码整个函数调用,必须将编码后的数据传给validateAdditionalCalldata函数,其参数类型为PromiseOrValue<BytesLike>。需要明确如何正确将resolverOptions编码为bytes类型。

解决方案

问题核心是defaultAbiCoder不识别TypeScript自定义类型,必须使用Solidity原生类型字符串来描述结构体字段。

步骤1:确认Solidity结构体定义

根据TypeScript类型反推,你的Solidity中SwapResolverOptions结构体应为:

struct SwapResolverOptions {
    bytes path;
    uint256 deadline;
    uint256 amountIn;
    uint256 amountOutMinimum;
    address inputTokenAddress;
    address targetAddress;
    address destinationAddress;
}

步骤2:使用Solidity类型列表编码

在TypeScript中,按结构体字段顺序传入类型列表和对应值即可完成编码:

import { defaultAbiCoder } from "@ethersproject/abi";

// 对应Solidity结构体的原生类型列表
const structTypeList = [
    'bytes',
    'uint256',
    'uint256',
    'uint256',
    'address',
    'address',
    'address'
];

// 按顺序提取结构体实例的字段值
const structValueList = [
    resolverOptions.path,
    resolverOptions.deadline,
    resolverOptions.amountIn,
    resolverOptions.amountOutMinimum,
    resolverOptions.inputTokenAddress,
    resolverOptions.targetAddress,
    resolverOptions.destinationAddress
];

// 执行编码
const encodedResolverOptions = defaultAbiCoder.encode(structTypeList, structValueList);

关键注意事项

  • 类型列表和值列表的顺序必须严格匹配Solidity结构体的字段顺序,否则解码时会出现数据错乱。
  • 编码后的encodedResolverOptions直接符合BytesLike类型要求,可直接传入validateAdditionalCalldata或resolve函数的参数中。

内容的提问来源于stack exchange,提问作者Ritzy Dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 17:16:08