diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 4a7e3ccca..7fa78b60c 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -265,3 +265,4 @@ - [`addr`](./cheatcodes/addr.md) - [`sign`](./cheatcodes/sign.md) - [`label`](./cheatcodes/label.md) +- [Misc](./misc/README.md) diff --git a/src/misc/README.md b/src/misc/README.md new file mode 100644 index 000000000..7544c729f --- /dev/null +++ b/src/misc/README.md @@ -0,0 +1,3 @@ +## Misc + +- [Struct encoding](./struct-encoding.md) diff --git a/src/misc/struct-encoding.md b/src/misc/struct-encoding.md new file mode 100644 index 000000000..b412e5dcd --- /dev/null +++ b/src/misc/struct-encoding.md @@ -0,0 +1,63 @@ +## Struct Encoding + +Structs are user defined types that can group several variables: + +```solidity +struct MyStruct { + address addr; + uint256 amount; +} +``` + +Only the new [ABI coder v2](https://docs.soliditylang.org/en/latest/layout-of-source-files.html#abi-coder-pragma) can encode and decode arbitrarily nested arrays and structs. Since Solidity 0.8.0 it is activated by default, prior to that it needs to be activated via `pragma experimental ABIEncoderV2`. + +Solidity structs map to the ABI type "tuple". For more information on how Solidity types map to ABI types see [Mapping Solidity to ABI types](https://docs.soliditylang.org/en/latest/abi-spec.html#mapping-solidity-to-abi-types) in the Solidity documentation. + +Structs are therefore encoded and decodes as tuples. So the struct we defined above, `MyStruct`, maps to the tuple `(address,uint256)` in terms of the ABI. + +Let's see how this works in a contract: + +```solidity +pragma solidity =0.8.15; + + +contract Test { + struct MyStruct { + address addr; + uint256 amount; + } + function f(MyStruct memory t) public pure {} +} +``` + +The ABI of the `f` function in this contract is: + +```json +{ + "inputs": [ + { + "components": [ + { + "internalType": "address", + "name": "addr", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "internalType": "struct Test.MyStruct", + "name": "t", + "type": "tuple" + } + ], + "name": "f", + "outputs": [], + "stateMutability": "pure", + "type": "function" +} +``` + +which reads: The function `f` takes 1 input of type `tuple` with two components of type `address` and `uint256`. diff --git a/src/reference/cast/cast-send.md b/src/reference/cast/cast-send.md index 3953a8834..6c234a8a7 100644 --- a/src/reference/cast/cast-send.md +++ b/src/reference/cast/cast-send.md @@ -52,6 +52,23 @@ The destination (*to*) can be an ENS name or an address. cast send --ledger 0x... "deposit(address,uint256)" 0x... 1 ``` +3. Call a function that expects a `struct`: + + ```solidity + contract Test { + struct MyStruct { + address addr; + uint256 amount; + } + function myfunction(MyStruct memory t) public pure {} + } + ``` + + Structs are encoded as tuples (see [struct encoding](./reference/common/struct-encoding.md)) + + ```sh + cast send "myfunction((address,uint256))" 0x... "(0x...,1)" + ``` ### SEE ALSO -[cast](./cast.md), [cast call](./cast-call.md), [cast publish](./cast-publish.md), [cast receipt](./cast-receipt.md) +[cast](./cast.md), [cast call](./cast-call.md), [cast publish](./cast-publish.md), [cast receipt](./cast-receipt.md), [struct encoding](./misc/struct-encoding.md) diff --git a/src/reference/cast/cast-sig.md b/src/reference/cast/cast-sig.md index 8217749de..11f5f7666 100644 --- a/src/reference/cast/cast-sig.md +++ b/src/reference/cast/cast-sig.md @@ -25,6 +25,23 @@ The signature (*sig*) is a fragment in the form `()`. cast sig "transfer(address,uint256)" ``` +2. Get the selector for a function that expects a `struct`: + + ```solidity + contract Test { + struct MyStruct { + address addr; + uint256 amount; + } + function myfunction(MyStruct memory t) public pure {} + } + ``` + + Structs are encoded as tuples (see [struct encoding](./reference/common/struct-encoding.md)). + + ```sh + cast sig "myfunction((address,uint256))" + ``` ### SEE ALSO -[cast](./cast.md) +[cast](./cast.md), [struct encoding](./misc/struct-encoding.md)