github.com/lmittmann/w3@v0.20.0/docs/pages/helper-abi.mdx (about)

     1  # ABI Bindings
     2  
     3  ABI bindings allow the encoding and decoding of Smart Contract function calls or the decoding of events.
     4  In `w3` ABI bindings are defined for individual functions or events at runtime using Solidity syntax.
     5  
     6  * **Easy to write:** Creating an ABI binding only requires the Solidity function signature. No need
     7    to firstly generate an ABI json file using `solc` and secondly generate ABI bindings using `abigen`.
     8  * **Flexible:** ABI bindings for a function or event can be used with any Smart Contract. No need to
     9    generate overlapping bindings for multiple Smart Contracts.
    10  
    11  
    12  ## Functions
    13  
    14  Function ABI bindings can be defined using
    15  * `func NewFunc(signature, returns string) (*Func, error)`, or
    16  * `func MustNewFunc(signature, returns string) *Func` which panics on error.
    17  
    18  ### Syntax
    19  
    20  Function signatures are defined using Solidity syntax. Arguments and returns can optionally be named. While naming is optional, it is recommended for more complex functions or tuple variables. Alias types, such as `uint` for `uint256`, are supported.
    21  
    22  #### Example: ERC20 `balanceOf`
    23  
    24  ABI binding for the ERC20 `balanceOf` function ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-NewFunc-BalanceOf)):
    25  
    26  ```solidity filename="Solidity"
    27  interface IERC20 {
    28      function balanceOf(address account) external view returns (uint256);
    29      // ...
    30  }
    31  ```
    32  
    33  ```go filename="Go"
    34  var funcBalanceOf = w3.MustNewFunc("balanceOf(address)", "uint256")
    35  // or
    36  var funcBalanceOf = w3.MustNewFunc("balanceOf(address who)", "uint256 amount")
    37  ```
    38  
    39  #### Example: QuoterV2 `quoteExactInputSingle`
    40  
    41  ABI binding for the Uniswap QuoterV2 `quoteExactInputSingle` function with a tuple parameter (Solidity `struct`):
    42  
    43  ```solidity filename="Solidity"
    44  interface QuoterV2 {
    45  
    46      struct QuoteExactInputSingleParams {
    47          address tokenIn;
    48          address tokenOut;
    49          uint256 amountIn;
    50          uint24 fee;
    51          uint160 sqrtPriceLimitX96;
    52      }
    53  
    54      function quoteExactInputSingle(QuoteExactInputSingleParams memory params)
    55          external
    56          returns (
    57              uint256 amountOut,
    58              uint160 sqrtPriceX96After,
    59              uint32 initializedTicksCrossed,
    60              uint256 gasEstimate
    61          );
    62      // ...
    63  }
    64  ```
    65  
    66  ```go filename="Go"
    67  type QuoteExactInputSingleParams struct {
    68      TokenIn           common.Address
    69      TokenOut          common.Address
    70      AmountIn          *big.Int
    71      Fee               *big.Int `abitype:"uint24"`
    72      SqrtPriceLimitX96 *big.Int `abitype:"uint160"`
    73  }
    74  
    75  var funcQuoteExactInputSingle = w3.MustNewFunc(
    76      `quoteExactInputSingle(QuoteExactInputSingleParams params)`,
    77      `uint256 amountOut,
    78       uint160 sqrtPriceX96After,
    79       uint32 initializedTicksCrossed,
    80       uint256 gasEstimate`,
    81      QuoteExactInputSingleParams{}, // Pass struct type as tuple definition
    82  )
    83  ```
    84  
    85  ##### Alternative: Inline Tuple Definition
    86  
    87  For simple cases or when you prefer not to define separate structs, you can use inline tuple definitions:
    88  
    89  ```go filename="Go"
    90  var funcQuoteExactInputSingle = w3.MustNewFunc(
    91      `quoteExactInputSingle((
    92          address tokenIn,
    93          address tokenOut,
    94          uint256 amountIn,
    95          uint24 fee,
    96          uint160 sqrtPriceLimitX96
    97      ) params)`,
    98      `uint256 amountOut,
    99       uint160 sqrtPriceX96After,
   100       uint32 initializedTicksCrossed,
   101       uint256 gasEstimate`,
   102  )
   103  ```
   104  
   105  ### Tuples (Solidity `struct`'s)
   106  
   107  Tuple types need to be embedded in parentheses, with comma-separated fields. Fields must be named, so they can be mapped to the fields of a Go struct.
   108  
   109  To map a tuple type to a Go struct, the struct must be defined manually with each tuple field being mapped to a Go struct field. Field names need to match, but Go field names must always start with an uppercase letter. E.g. the tuple field `address tokenIn{:solidity}` must be matched to the Go struct field `TokenIn common.Address{:go}`.
   110  
   111  <Callout type="info">
   112      See [Type Mappings](#type-mappings) for more information on how to map primitive Solidity types to Go types and vice versa.
   113  </Callout>
   114  
   115  ### `EncodeArgs`
   116  
   117  The `EncodeArgs` method of a `Func` ABI encodes a Solidity function call. Each argument of the Solidity function must be matched by a corresponding Go value.
   118  
   119  ### `DecodeArgs` and `DecodeReturns`
   120  
   121  The `DecodeArgs` and `DecodeReturns` methods of a `Func` ABI decode the arguments and returns of a Solidity function call. The Go values that should hold the decoded data must be defined beforehand, and passed as pointers to the decode methods. Values that should not be decoded can be passed as `nil`. Tailing `nil` values can be omitted.
   122  
   123  #### Example: Uniswap Pair `getReserves`
   124  
   125  ABI decode the output of the Uniswap Pair `getReserves` function ([Playground](https://pkg.go.dev/github.com/lmittmann/w3#example-Func.DecodeReturns-GetReserves)):
   126  
   127  ```go filename="Go"
   128  var (
   129      funcGetReserves = w3.MustNewFunc("getReserves()", "uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast")
   130      output []byte   = w3.B("0x00…")
   131  )
   132  
   133  var (
   134      reserve0, reserve1 *big.Int
   135      blockTimestampLast uint32
   136  )
   137  if err := funcGetReserves.DecodeReturns(output, &reserve0, &reserve1, &blockTimestampLast); err != nil {
   138      // ...
   139  }
   140  ```
   141  
   142  In case only the reserves should be decoded, the `blockTimestampLast` can be ignored using `funcGetReserves.DecodeReturns(output, &reserve0, &reserve1, nil){:go}`, which is equivalent to `funcGetReserves.DecodeReturns(output, &reserve0, &reserve1){:go}`.
   143  
   144  
   145  ## Events
   146  
   147  Event ABI bindings can be defined using
   148  * `func NewEvent(signature string) (*Event, error)`, or
   149  * `func MustNewEvent(signature string) *Event` which panics on error.
   150  
   151  #### Example: ERC20 `Transfer`
   152  
   153  ABI binding for the ERC20 `Transfer` event:
   154  
   155  ```solidity filename="Solidity"
   156  interface IERC20 {
   157      event Transfer(address indexed from, address indexed to, uint256 value);
   158      // ...
   159  }
   160  ```
   161  
   162  ```go filename="Go"
   163  var evtTransfer = w3.MustNewEvent("Transfer(address indexed from, address indexed to, uint256 value)")
   164  ```
   165  
   166  
   167  ## Type Mappings
   168  
   169  | **Solidity Type**                                    | **Go Type**                 |
   170  |:-----------------------------------------------------|:----------------------------|
   171  | `bool`                                               | `bool`                      |
   172  | `int8`                                               | `int8`                      |
   173  | `int16`                                              | `int16`                     |
   174  | `int32`                                              | `int32`                     |
   175  | `int64`                                              | `int64`                     |
   176  | `int24`,`int40`…`int56`,`int72`…`int256`,`int`       | `*big.Int`                  |
   177  | `uint8`                                              | `uint8`                     |
   178  | `uint16`                                             | `uint16`                    |
   179  | `uint32`                                             | `uint32`                    |
   180  | `uint64`                                             | `uint64`                    |
   181  | `uint24`,`uint40`…`uint56`,`uint72`…`uint256`,`uint` | `*big.Int`                  |
   182  | `bytes`                                              | `[]byte`                    |
   183  | `bytes1`…`bytes32`                                   | `[1]byte`…`[32]byte`        |
   184  | `address`                                            | `common.Address`/`[20]byte` |
   185  | `bytes32`                                            | `common.Hash`/`[32]byte`    |
   186  
   187  ### Arrays and Slices
   188  
   189  Solidity arrays and slices are mapped to Go arrays and slices respectively and vice versa.
   190  
   191  | **Solidity Type** | **Go Type** |
   192  |:------------------|:------------|
   193  | `type[n]`         | `[n]type`   |
   194  | `type[]`          | `[]type`    |