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` |