I'm trying to test a piece of generic solidity code, I'm trying to figure out how to encode data properly for bytes parameters.
I have a function in a smart contract which looks like so:
function validateAdditionalCalldata(bytes calldata resolverOptions) external view;
function resolve(uint256 amountIn, bytes calldata resolverOptions) public override returns (uint256 amountOut) {
// Decode the additional calldata as a SwapResolverOptions struct
(SwapResolverOptions memory swapResolverOptions) = abi.decode(resolverOptions, (SwapResolverOptions));
return resolveImplementation(amountIn, swapResolverOptions);
}
This solidity code will generate code which takes in a PromiseOrValue<BytesLike>
:
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>;
};
I'm wondering how I can encode a specific parameter so I can pass it along to ethers. In typescript I have a set of options that looks like this:
const resolverOptions: SwapResolverOptionsStruct = {
path: '0x00',
//This parameter will be removed in the next deployment
deadline: BigNumber.from(1000),
amountIn: BigNumber.from(100000000),
amountOutMinimum: BigNumber.from(0),
inputTokenAddress: WMATIC_MUMBAI,
destinationAddress: owner.address,
targetAddress: ADDRESS_ZERO,
};
I'm trying to encode this parameters in the following way:
import { defaultAbiCoder } from "@ethersproject/abi";
encodedResolverOptions = defaultAbiCoder.encode(
['SwapResolverOptionsStruct'],
[resolverOptions]
);
However when I try to encode it gets and error:
Error: invalid type (argument="type", value="SwapResolverOptionsStruct",
Note: in my paticular use case I cannot just encoded the whole function call.
I would like to pass my data to the validateAdditionalCalldata
how ever the parameter is PromiseOrValue<BytesLike>
How can I encoded my resolverOptions
so I can pass it as bytes?
I figured out a few way to do this. I'll list each one:
Resolve the type params using ethers and get function. (if there is a function which has your type in it)
const functionFragment = swapResolverInterface.getFunction("resolveImplementation");
encodedResolverOptions = defaultAbiCoder.encode(
[functionFragment.inputs[1]],
[resolverOptions]
);
Resolve it from an object and a method signature with parameter names:
encodedResolverOptions = defaultAbiCoder.encode(
["(bytes path,uint256 deadline,uint256 amountIn,uint256 amountOutMinimum,address inputTokenAddress,address destinationAddress,address targetAddress)"],
[resolverOptions]
);
Resolve it as an array from the method signature without names Note: this assumes the object was declared in the same order as the parameters, alternatively you can manually construct the array:
encodedResolverOptions = defaultAbiCoder.encode(
["(bytes,uint256,uint256,uint256,address,address,address)"],
[Object.values(resolverOptions)]
);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.