Documentation
¶
Overview ¶
Package w3 is your toolbelt for integrating with Ethereum in Go. Closely linked to go-ethereum, it provides an ergonomic wrapper for working with RPC, ABI's, and the EVM.
Index ¶
- Variables
- func A(hexAddr string) (addr common.Address)
- func APtr(hexAddress string) *common.Address
- func B(hexBytes ...string) (bytes []byte)
- func BigMax(a, b *big.Int) *big.Int
- func BigMin(a, b *big.Int) *big.Int
- func FromWei(wei *big.Int, decimals uint8) string
- func H(hexHash string) (hash common.Hash)
- func I(strInt string) *big.Int
- type CallErrors
- type Client
- func (c *Client) Call(calls ...w3types.RPCCaller) error
- func (c *Client) CallCtx(ctx context.Context, calls ...w3types.RPCCaller) error
- func (c *Client) Close() error
- func (c *Client) Subscribe(s w3types.RPCSubscriber) (*rpc.ClientSubscription, error)
- func (c *Client) SubscribeCtx(ctx context.Context, s w3types.RPCSubscriber) (*rpc.ClientSubscription, error)
- type Event
- type Func
- type Option
Examples ¶
- Client (BatchBlocks)
- Client (BatchCallFunc)
- Client (BatchCallFuncUniswapQuoter)
- Client (BatchEOAState)
- Client (BatchHandleError)
- Client (BatchTxDetails)
- Client (CallFunc)
- Client (CallFuncWithStateOverride)
- Client (RateLimitByComputeUnits)
- Client (RateLimitByRequest)
- Client (SendETHTransfer)
- Client (SendTokenTransfer)
- Client (SubscribeToPendingTransactions)
- Event (DecodeTransferEvent)
- FromWei
- Func (BalanceOf)
- Func (Erc20)
- Func (UniswapV4Swap)
- Func.DecodeReturns (GetReserves)
- I
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidABI = errors.New("w3: invalid ABI") ErrArgumentMismatch = errors.New("w3: argument mismatch") ErrReturnsMismatch = errors.New("w3: returns mismatch") ErrInvalidType = errors.New("w3: invalid type") ErrEvmRevert = errors.New("w3: evm reverted") )
var ( Big0 = new(big.Int) Big1 = big.NewInt(1) Big2 = big.NewInt(2) Big10 = big.NewInt(10) BigGwei = big.NewInt(1_000000000) BigEther = big.NewInt(1_000000000_000000000) // Max Uint Values. BigMaxUint256 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 256), Big1) BigMaxUint248 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 248), Big1) BigMaxUint240 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 240), Big1) BigMaxUint232 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 232), Big1) BigMaxUint224 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 224), Big1) BigMaxUint216 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 216), Big1) BigMaxUint208 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 208), Big1) BigMaxUint200 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 200), Big1) BigMaxUint192 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 192), Big1) BigMaxUint184 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 184), Big1) BigMaxUint176 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 176), Big1) BigMaxUint168 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 168), Big1) BigMaxUint160 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 160), Big1) BigMaxUint152 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 152), Big1) BigMaxUint144 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 144), Big1) BigMaxUint136 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 136), Big1) BigMaxUint128 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 128), Big1) BigMaxUint120 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 120), Big1) BigMaxUint112 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 112), Big1) BigMaxUint104 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 104), Big1) BigMaxUint96 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 96), Big1) BigMaxUint88 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 88), Big1) BigMaxUint80 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 80), Big1) BigMaxUint72 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 72), Big1) BigMaxUint64 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 64), Big1) BigMaxUint56 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 56), Big1) BigMaxUint48 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 48), Big1) BigMaxUint40 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 40), Big1) BigMaxUint32 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 32), Big1) BigMaxUint24 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 24), Big1) BigMaxUint16 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 16), Big1) BigMaxUint8 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 8), Big1) )
Common big.Int's.
var ( Addr0 common.Address Hash0 common.Hash )
Zero Values.
Functions ¶
func A ¶
A returns an address from a hexstring or panics if the hexstring does not represent a valid address.
Use common.HexToAddress to get the address from a hexstring without panicking.
func APtr ¶
APtr returns an address pointer from a hexstring or panics if the hexstring does not represent a valid address.
func B ¶
B returns a byte slice from a hexstring or panics if the hexstring does not represent a valid byte slice.
Use common.FromHex to get the byte slice from a hexstring without panicking.
func FromWei ¶
FromWei returns the given Wei as decimal with the given number of decimals.
Example ¶
package main import ( "fmt" "math/big" "github.com/lmittmann/w3" ) func main() { wei := big.NewInt(1_230000000_000000000) fmt.Printf("%s Ether\n", w3.FromWei(wei, 18)) }
Output: 1.23 Ether
func H ¶
H returns a hash from a hexstring or panics if the hexstring does not represent a valid hash.
Use common.HexToHash to get the hash from a hexstring without panicking.
func I ¶
I returns a big.Int from a hexstring or decimal number string (with optional unit) or panics if the parsing fails.
I supports the units "ether" or "eth" and "gwei" for decimal number strings. E.g.:
w3.I("1 ether") -> 1000000000000000000 w3.I("10 gwei") -> 10000000000
Fractional digits that exceed the units maximum number of fractional digits are ignored. E.g.:
w3.I("0.000000123456 gwei") -> 123
Example ¶
package main import ( "fmt" "github.com/lmittmann/w3" ) func main() { fmt.Printf("%v wei\n", w3.I("0x1111d67bb1bb0000")) fmt.Printf("%v wei\n", w3.I("1230000000000000000")) fmt.Printf("%v wei\n", w3.I("1.23 ether")) fmt.Printf("%v wei\n", w3.I("1.23 gwei")) }
Output: 1230000000000000000 wei 1230000000000000000 wei 1230000000000000000 wei 1230000000 wei
Types ¶
type CallErrors ¶ added in v0.10.0
type CallErrors []error
CallErrors is an error type that contains the errors of multiple calls. The length of the error slice is equal to the number of calls. Each error at a given index corresponds to the call at the same index. An error is nil if the corresponding call was successful.
func (CallErrors) Error ¶ added in v0.10.0
func (e CallErrors) Error() string
func (CallErrors) Is ¶ added in v0.10.0
func (e CallErrors) Is(target error) bool
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client represents a connection to an RPC endpoint.
Example (BatchBlocks) ¶
Fetch 1000 blocks in batches.
package main import ( "crypto/ecdsa" "fmt" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" "github.com/lmittmann/w3/w3types" ) var client = w3.MustDial("https://rpc.ankr.com/eth") func main() { const ( startBlock = 20_000_000 nBlocks = 1000 batchSize = 100 ) blocks := make([]*types.Block, nBlocks) calls := make([]w3types.RPCCaller, batchSize) for i := 0; i < nBlocks; i += batchSize { for j := 0; j < batchSize; j++ { blockNumber := new(big.Int).SetUint64(uint64(startBlock + i + j)) calls[j] = eth.BlockByNumber(blockNumber).Returns(&blocks[i+j]) } if err := client.Call(calls...); err != nil { // ... } fmt.Printf("Fetched %d blocks\n", i+batchSize) } }
Output:
Example (BatchCallFunc) ¶
Call the name, symbol, decimals, and balanceOf functions of the Wrapped Ether in a single batch.
package main import ( "crypto/ecdsa" "fmt" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" ) var ( funcName = w3.MustNewFunc("name()", "string") funcSymbol = w3.MustNewFunc("symbol()", "string") funcDecimals = w3.MustNewFunc("decimals()", "uint8") funcBalanceOf = w3.MustNewFunc("balanceOf(address)", "uint256") addrWETH = w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") client = w3.MustDial("https://rpc.ankr.com/eth") ) func main() { blockNumber := big.NewInt(20_000_000) var ( name, symbol string decimals uint8 balance big.Int ) if err := client.Call( eth.CallFunc(addrWETH, funcName).Returns(&name), eth.CallFunc(addrWETH, funcSymbol).Returns(&symbol), eth.CallFunc(addrWETH, funcDecimals).Returns(&decimals), eth.CallFunc(addrWETH, funcBalanceOf, addrWETH).AtBlock(blockNumber).Returns(&balance), ); err != nil { // ... } fmt.Printf("%s's own balance: %s %s\n", name, w3.FromWei(&balance, decimals), symbol) }
Output: Wrapped Ether's own balance: 748.980125465356473638 WETH
Example (BatchCallFuncUniswapQuoter) ¶
Call the Uniswap V3 Quoter for quotes on swapping 100 WETH for DAI in pools of all fee tiers in a single batch.
package main import ( "crypto/ecdsa" "fmt" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" ) var ( addrWETH = w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") addrDAI = w3.A("0x6B175474E89094C44Da98b954EedeAC495271d0F") client = w3.MustDial("https://rpc.ankr.com/eth") ) func main() { blockNumber := big.NewInt(20_000_000) var ( addrUniswapV3Quoter = w3.A("0xb27308f9F90D607463bb33eA1BeBb41C27CE5AB6") addrTokenIn = addrWETH addrTokenOut = addrDAI funcQuote = w3.MustNewFunc(`quoteExactInputSingle( address tokenIn, address tokenOut, uint24 fee, uint256 amountIn, uint160 sqrtPriceLimitX96clear )`, "uint256 amountOut") ) var ( amountIn = w3.I("100 ether") amountOut100 *big.Int amountOut500 *big.Int amountOut3000 *big.Int amountOut10000 *big.Int ) if err := client.Call( eth.CallFunc(addrUniswapV3Quoter, funcQuote, addrTokenIn, addrTokenOut, big.NewInt(100), amountIn, w3.Big0).AtBlock(blockNumber).Returns(&amountOut100), eth.CallFunc(addrUniswapV3Quoter, funcQuote, addrTokenIn, addrTokenOut, big.NewInt(500), amountIn, w3.Big0).AtBlock(blockNumber).Returns(&amountOut500), eth.CallFunc(addrUniswapV3Quoter, funcQuote, addrTokenIn, addrTokenOut, big.NewInt(3000), amountIn, w3.Big0).AtBlock(blockNumber).Returns(&amountOut3000), eth.CallFunc(addrUniswapV3Quoter, funcQuote, addrTokenIn, addrTokenOut, big.NewInt(10000), amountIn, w3.Big0).AtBlock(blockNumber).Returns(&amountOut10000), ); err != nil { // ... } fmt.Println("Swap 100 WETH for DAI:") fmt.Printf("Pool with 0.01%% fee: %s DAI\n", w3.FromWei(amountOut100, 18)) fmt.Printf("Pool with 0.05%% fee: %s DAI\n", w3.FromWei(amountOut500, 18)) fmt.Printf("Pool with 0.3%% fee: %s DAI\n", w3.FromWei(amountOut3000, 18)) fmt.Printf("Pool with 1%% fee: %s DAI\n", w3.FromWei(amountOut10000, 18)) }
Output: Swap 100 WETH for DAI: Pool with 0.01% fee: 0.840975419471618588 DAI Pool with 0.05% fee: 371877.453117609415215338 DAI Pool with 0.3% fee: 378532.856217317782434539 DAI Pool with 1% fee: 3447.634026125332130689 DAI
Example (BatchEOAState) ¶
Fetch the nonce and balance of an EOA in a single batch.
package main import ( "crypto/ecdsa" "fmt" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" ) var ( addrA = common.Address{0x0a} client = w3.MustDial("https://rpc.ankr.com/eth") ) func main() { var ( nonce uint64 balance *big.Int ) if err := client.Call( eth.Nonce(addrA, nil).Returns(&nonce), eth.Balance(addrA, nil).Returns(&balance), ); err != nil { // ... } fmt.Printf("Nonce: %d\nBalance: %d\n", nonce, balance) }
Output:
Example (BatchHandleError) ¶
Handle errors of individual calls in a batch.
package main import ( "crypto/ecdsa" "errors" "fmt" "github.com/ethereum/go-ethereum/common" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" "github.com/lmittmann/w3/w3types" ) var ( funcSymbol = w3.MustNewFunc("symbol()", "string") addrA = common.Address{0x0a} addrB = common.Address{0x0b} addrWETH = w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") client = w3.MustDial("https://rpc.ankr.com/eth") ) func main() { tokens := []common.Address{addrWETH, addrA, addrB} symbols := make([]string, len(tokens)) // build rpc calls calls := make([]w3types.RPCCaller, len(tokens)) for i, token := range tokens { calls[i] = eth.CallFunc(token, funcSymbol).Returns(&symbols[i]) } var batchErr w3.CallErrors if err := client.Call(calls...); errors.As(err, &batchErr) { } else if err != nil { // all calls failed } for i, symbol := range symbols { if len(batchErr) > 0 && batchErr[i] != nil { symbol = "call failed" } fmt.Printf("%s: %s\n", tokens[i], symbol) } }
Output: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2: WETH 0x0a00000000000000000000000000000000000000: call failed 0x0B00000000000000000000000000000000000000: call failed
Example (BatchTxDetails) ¶
Fetch a transaction and its receipt in a single batch.
package main import ( "crypto/ecdsa" "fmt" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" ) var client = w3.MustDial("https://rpc.ankr.com/eth") func main() { txHash := w3.H("0xc31d7e7e85cab1d38ce1b8ac17e821ccd47dbde00f9d57f2bd8613bff9428396") var ( tx *types.Transaction receipt *types.Receipt ) if err := client.Call( eth.Tx(txHash).Returns(&tx), eth.TxReceipt(txHash).Returns(&receipt), ); err != nil { // ... } fmt.Printf("Tx: %#v\nReceipt: %#v\n", tx, receipt) }
Output:
Example (CallFunc) ¶
Fetch the token balance of an address.
package main import ( "crypto/ecdsa" "fmt" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" ) var ( funcBalanceOf = w3.MustNewFunc("balanceOf(address)", "uint256") addrA = common.Address{0x0a} addrWETH = w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") client = w3.MustDial("https://rpc.ankr.com/eth") ) func main() { var balance *big.Int if err := client.Call( eth.CallFunc(addrWETH, funcBalanceOf, addrA).Returns(&balance), ); err != nil { // ... } fmt.Printf("Balance: %s WETH\n", w3.FromWei(balance, 18)) }
Output: Balance: 0 WETH
Example (CallFuncWithStateOverride) ¶
Fetch the token balance of an address, with state override.
package main import ( "crypto/ecdsa" "fmt" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" "github.com/lmittmann/w3/w3types" ) var ( funcBalanceOf = w3.MustNewFunc("balanceOf(address)", "uint256") addrA = common.Address{0x0a} addrWETH = w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") client = w3.MustDial("https://rpc.ankr.com/eth") ) func main() { var balance *big.Int if err := client.Call( eth.CallFunc(addrWETH, funcBalanceOf, addrA).Overrides(w3types.State{ addrWETH: {Storage: w3types.Storage{ w3vm.WETHBalanceSlot(addrA): common.BigToHash(w3.I("100 ether")), }}, }).Returns(&balance), ); err != nil { // ... } fmt.Printf("Balance: %s WETH\n", w3.FromWei(balance, 18)) }
Output: Balance: 100 WETH
Example (RateLimitByComputeUnits) ¶
Rate Limit the number of requests to 300 compute units (CUs) per second, with bursts of up to 300 CUs. An individual CU can be charged per RPC method call.
package main import ( "fmt" "time" "github.com/lmittmann/w3" "golang.org/x/time/rate" ) func main() { // cu returns the CU cost for all method calls in a batch. cu := func(methods []string) (cost int) { for _, method := range methods { switch method { case "eth_blockNumber": cost += 5 case "eth_getBalance", "eth_getBlockByNumber", "eth_getCode", "eth_getStorageAt", "eth_getTransactionByHash", "eth_getTransactionReceipt": cost += 15 case "eth_call": cost += 20 case "eth_getTransactionCount": cost += 25 default: panic(fmt.Sprintf("unknown costs for %q", method)) } } return cost } client, err := w3.Dial("https://rpc.ankr.com/eth", w3.WithRateLimiter(rate.NewLimiter(rate.Every(time.Second/300), 300), cu), ) if err != nil { // ... } defer client.Close() }
Output:
Example (RateLimitByRequest) ¶
Rate Limit the number of requests to 10 per second, with bursts of up to 20 requests.
package main import ( "time" "github.com/lmittmann/w3" "golang.org/x/time/rate" ) func main() { client, err := w3.Dial("https://rpc.ankr.com/eth", w3.WithRateLimiter(rate.NewLimiter(rate.Every(time.Second/10), 20), nil), ) if err != nil { // ... } defer client.Close() }
Output:
Example (SendETHTransfer) ¶
Send Ether transfer.
package main import ( "crypto/ecdsa" "fmt" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" ) var ( addrA = common.Address{0x0a} addrB = common.Address{0x0b} prvA *ecdsa.PrivateKey client = w3.MustDial("https://rpc.ankr.com/eth") ) func main() { var ( nonce uint64 gasPrice *big.Int ) if err := client.Call( eth.Nonce(addrA, nil).Returns(&nonce), eth.GasPrice().Returns(&gasPrice), ); err != nil { // ... } signer := types.LatestSigner(params.MainnetChainConfig) tx := types.MustSignNewTx(prvA, signer, &types.LegacyTx{ Nonce: nonce, Gas: 21_000, GasPrice: gasPrice, To: &addrB, Value: w3.I("1 ether"), }) var txHash common.Hash if err := client.Call(eth.SendTx(tx).Returns(&txHash)); err != nil { // ... } fmt.Printf("Sent tx: %s\n", txHash) }
Output:
Example (SendTokenTransfer) ¶
Send ERC20 token transfer (Wrapped Ether).
package main import ( "crypto/ecdsa" "fmt" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" ) var ( addrA = common.Address{0x0a} addrB = common.Address{0x0b} prvA *ecdsa.PrivateKey addrWETH = w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") client = w3.MustDial("https://rpc.ankr.com/eth") ) func main() { var ( nonce uint64 gasPrice *big.Int ) if err := client.Call( eth.Nonce(addrA, nil).Returns(&nonce), eth.GasPrice().Returns(&gasPrice), ); err != nil { // ... } funcTransfer := w3.MustNewFunc("transfer(address receiver, uint256 amount)", "bool") data, err := funcTransfer.EncodeArgs(addrB, w3.I("1 ether")) if err != nil { // ... } signer := types.LatestSigner(params.MainnetChainConfig) tx := types.MustSignNewTx(prvA, signer, &types.LegacyTx{ Nonce: nonce, Gas: 100_000, GasPrice: gasPrice, To: &addrWETH, Data: data, }) var txHash common.Hash if err := client.Call(eth.SendTx(tx).Returns(&txHash)); err != nil { // ... } fmt.Printf("Sent tx: %s\n", txHash) }
Output:
Example (SubscribeToPendingTransactions) ¶
Subscribe to pending transactions.
package main import ( "fmt" "github.com/ethereum/go-ethereum/core/types" "github.com/lmittmann/w3" "github.com/lmittmann/w3/module/eth" ) func main() { client, err := w3.Dial("wss://mainnet.gateway.tenderly.co") if err != nil { // ... } defer client.Close() pendingTxCh := make(chan *types.Transaction) sub, err := client.Subscribe(eth.PendingTransactions(pendingTxCh)) if err != nil { // ... } for { select { case tx := <-pendingTxCh: fmt.Printf("New pending tx: %s\n", tx.Hash()) case err := <-sub.Err(): fmt.Printf("Subscription error: %v\n", err) return } } }
Output:
func Dial ¶
Dial returns a new Client connected to the URL rawurl. An error is returned if the connection establishment fails.
The supported URL schemes are "http", "https", "ws" and "wss". If rawurl is a file name with no URL scheme, a local IPC socket connection is established.
func (*Client) Call ¶
Call is like Client.CallCtx with ctx equal to context.Background().
func (*Client) CallCtx ¶
CallCtx creates the final RPC request, sends it, and handles the RPC response.
An error is returned if RPC request creation, networking, or RPC response handling fails.
func (*Client) Close ¶
Close the RPC connection and cancel all in-flight requests.
Close implements the io.Closer interface.
func (*Client) Subscribe ¶ added in v0.16.4
func (c *Client) Subscribe(s w3types.RPCSubscriber) (*rpc.ClientSubscription, error)
Subscribe is like Client.SubscribeCtx with ctx equal to context.Background().
func (*Client) SubscribeCtx ¶ added in v0.16.4
func (c *Client) SubscribeCtx(ctx context.Context, s w3types.RPCSubscriber) (*rpc.ClientSubscription, error)
SubscribeCtx creates a new subscription and returns a rpc.ClientSubscription.
type Event ¶ added in v0.3.0
type Event struct { Signature string // Event signature Topic0 common.Hash // Hash of event signature (Topic 0) Args abi.Arguments // Arguments // contains filtered or unexported fields }
Event represents a Smart Contract event decoder.
Example (DecodeTransferEvent) ¶
package main import ( "fmt" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/lmittmann/w3" ) func main() { var ( eventTransfer = w3.MustNewEvent("Transfer(address indexed from, address indexed to, uint256 value)") log = &types.Log{ Address: w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), Topics: []common.Hash{ w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"), w3.H("0x000000000000000000000000000000000000000000000000000000000000c0fe"), w3.H("0x000000000000000000000000000000000000000000000000000000000000dead"), }, Data: w3.B("0x0000000000000000000000000000000000000000000000001111d67bb1bb0000"), } from common.Address to common.Address value big.Int ) if err := eventTransfer.DecodeArgs(log, &from, &to, &value); err != nil { fmt.Printf("Failed to decode event log: %v\n", err) return } fmt.Printf("Transferred %s WETH9 from %s to %s", w3.FromWei(&value, 18), from, to) }
Output: Transferred 1.23 WETH9 from 0x000000000000000000000000000000000000c0Fe to 0x000000000000000000000000000000000000dEaD
func MustNewEvent ¶ added in v0.3.0
MustNewEvent is like NewEvent but panics if the signature parsing fails.
type Func ¶ added in v0.1.1
type Func struct { Signature string // Function signature Selector [4]byte // 4-byte selector Args abi.Arguments // Arguments (input) Returns abi.Arguments // Returns (output) // contains filtered or unexported fields }
Func represents a Smart Contract function ABI binding.
Func implements the w3types.Func interface.
Example (BalanceOf) ¶
Encode and decode the arguments of the balanceOf function.
package main import ( "crypto/ecdsa" "fmt" "github.com/ethereum/go-ethereum/common" "github.com/lmittmann/w3" ) var ( funcBalanceOf = w3.MustNewFunc("balanceOf(address)", "uint256") addrA = common.Address{0x0a} ) func main() { // encode input, err := funcBalanceOf.EncodeArgs(addrA) if err != nil { // ... } fmt.Printf("encoded: 0x%x\n", input) // decode var who common.Address if err := funcBalanceOf.DecodeArgs(input, &who); err != nil { // ... } fmt.Printf("decoded: balanceOf(%s)\n", who) }
Output: encoded: 0x70a082310000000000000000000000000a00000000000000000000000000000000000000 decoded: balanceOf(0x0a00000000000000000000000000000000000000)
Example (Erc20) ¶
ABI bindings for the ERC20 functions.
package main import ( "github.com/lmittmann/w3" ) func main() { var ( funcTotalSupply = w3.MustNewFunc("totalSupply()", "uint256") funcBalanceOf = w3.MustNewFunc("balanceOf(address)", "uint256") funcTransfer = w3.MustNewFunc("transfer(address to, uint256 amount)", "bool") funcAllowance = w3.MustNewFunc("allowance(address owner, address spender)", "uint256") funcApprove = w3.MustNewFunc("approve(address spender, uint256 amount)", "bool") funcTransferFrom = w3.MustNewFunc("transferFrom(address from, address to, uint256 amount)", "bool") ) _ = funcTotalSupply _ = funcBalanceOf _ = funcTransfer _ = funcAllowance _ = funcApprove _ = funcTransferFrom }
Output:
Example (UniswapV4Swap) ¶
ABI bindings for the Uniswap v4 swap function.
package main import ( "crypto/ecdsa" "fmt" "math/big" "github.com/ethereum/go-ethereum/common" "github.com/lmittmann/w3" ) var ( addrWETH = w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") addrDAI = w3.A("0x6B175474E89094C44Da98b954EedeAC495271d0F") ) func main() { funcSwap := w3.MustNewFunc(`swap( (address currency0, address currency1, uint24 fee, int24 tickSpacing, address hooks) key, (bool zeroForOne, int256 amountSpecified, uint160 sqrtPriceLimitX96) params, bytes hookData )`, "int256 delta") // ABI binding for the PoolKey struct. type PoolKey struct { Currency0 common.Address Currency1 common.Address Fee *big.Int TickSpacing *big.Int Hooks common.Address } // ABI binding for the SwapParams struct. type SwapParams struct { ZeroForOne bool AmountSpecified *big.Int SqrtPriceLimitX96 *big.Int } // encode input, _ := funcSwap.EncodeArgs( &PoolKey{ Currency0: addrWETH, Currency1: addrDAI, Fee: big.NewInt(0), TickSpacing: big.NewInt(0), }, &SwapParams{ ZeroForOne: false, AmountSpecified: big.NewInt(0), SqrtPriceLimitX96: big.NewInt(0), }, []byte{}, ) fmt.Printf("encoded: 0x%x\n", input) }
Output: encoded: 0xf3cd914c000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000
func MustNewFunc ¶
MustNewFunc is like NewFunc but panics if the signature or returns parsing fails.
func NewFunc ¶
NewFunc returns a new Smart Contract function ABI binding from the given Solidity function signature and its returns.
An error is returned if the signature or returns parsing fails.
func (*Func) DecodeArgs ¶ added in v0.1.1
DecodeArgs ABI-decodes the given input to the given args.
func (*Func) DecodeReturns ¶ added in v0.1.1
DecodeReturns ABI-decodes the given output to the given returns.
Example (GetReserves) ¶
package main import ( "fmt" "math/big" "github.com/lmittmann/w3" ) func main() { funcGetReserves := w3.MustNewFunc("getReserves()", "uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast") output := w3.B( "0x00000000000000000000000000000000000000000000003635c9adc5dea00000", "0x0000000000000000000000000000000000000000000000a2a15d09519be00000", "0x0000000000000000000000000000000000000000000000000000000064373057", ) var ( reserve0, reserve1 *big.Int blockTimestampLast uint32 ) if err := funcGetReserves.DecodeReturns(output, &reserve0, &reserve1, &blockTimestampLast); err != nil { // ... } fmt.Println("Reserve0:", reserve0) fmt.Println("Reserve1:", reserve1) fmt.Println("BlockTimestampLast:", blockTimestampLast) }
Output: Reserve0: 1000000000000000000000 Reserve1: 3000000000000000000000 BlockTimestampLast: 1681338455
type Option ¶ added in v0.12.0
type Option func(*Client)
An Option configures a Client.
func WithRateLimiter ¶ added in v0.12.0
WithRateLimiter sets the rate limiter for the client. Set the optional argument costFunc to nil to limit the number of requests. Supply a costFunc to limit the the number of requests based on individual RPC calls for advanced rate limiting by e.g. Compute Units (CUs). Note that only if len(methods) > 1, the calls are sent in a batch request.
Directories
¶
Path | Synopsis |
---|---|
abi
Package abi implements a Solidity ABI lexer and parser.
|
Package abi implements a Solidity ABI lexer and parser. |
fourbyte
Code generated by "go generate"; DO NOT EDIT.
|
Code generated by "go generate"; DO NOT EDIT. |
module
|
|
debug
Package debug implements RPC API bindings for methods in the "debug" namespace.
|
Package debug implements RPC API bindings for methods in the "debug" namespace. |
eth
Package eth implements RPC API bindings for methods in the "eth" namespace.
|
Package eth implements RPC API bindings for methods in the "eth" namespace. |
txpool
Package txpool implements RPC API bindings for methods in the "txpool" namespace.
|
Package txpool implements RPC API bindings for methods in the "txpool" namespace. |
web3
Package web3 implements RPC API bindings for methods in the "web3" namespace.
|
Package web3 implements RPC API bindings for methods in the "web3" namespace. |
Package rpctest provides utilities for testing RPC methods.
|
Package rpctest provides utilities for testing RPC methods. |
Package w3types implements common types.
|
Package w3types implements common types. |
Package w3vm provides a VM for executing EVM messages.
|
Package w3vm provides a VM for executing EVM messages. |