Documentation
¶
Overview ¶
Package w3 implements a blazing fast and modular Ethereum JSON RPC client with first-class ABI support.
Index ¶
- Variables
- func A(hexAddress string) (addr common.Address)
- func APtr(hexAddress string) *common.Address
- func B(hexBytes ...string) (bytes []byte)
- 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 ¶
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) BigGwei = big.NewInt(1_000000000) BigEther = big.NewInt(1_000000000_000000000) BigMaxUint256 = new(big.Int).Sub(new(big.Int).Lsh(Big1, 256), 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/meltingclock/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/meltingclock/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 ¶
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.
Example ¶
package main
import (
"errors"
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/meltingclock/w3"
"github.com/meltingclock/w3/module/eth"
"github.com/meltingclock/w3/w3types"
)
func main() {
client := w3.MustDial("https://rpc.ankr.com/eth")
defer client.Close()
funcSymbol := w3.MustNewFunc("symbol()", "string")
// list of addresses that might be an ERC20 token
potentialTokens := []common.Address{
w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
w3.A("0x00000000219ab540356cBB839Cbe05303d7705Fa"),
}
// build symbol()-call for each potential ERC20 token
tokenSymbols := make([]string, len(potentialTokens))
rpcCalls := make([]w3types.RPCCaller, len(potentialTokens))
for i, addr := range potentialTokens {
rpcCalls[i] = eth.CallFunc(addr, funcSymbol).Returns(&tokenSymbols[i])
}
// execute batch request
var errs w3.CallErrors
if err := client.Call(rpcCalls...); errors.As(err, &errs) {
// handle call errors
} else if err != nil {
// handle other errors
fmt.Printf("Request failed: %v\n", err)
return
}
for i, addr := range potentialTokens {
var symbol string
if errs == nil || errs[i] == nil {
symbol = tokenSymbols[i]
} else {
symbol = fmt.Sprintf("unknown symbol: %v", errs[i].Error())
}
fmt.Printf("%s: %s\n", addr, symbol)
}
}
Output: 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2: WETH 0x00000000219ab540356cBB839Cbe05303d7705Fa: unknown symbol: execution reverted
func (CallErrors) Error ¶
func (e CallErrors) Error() string
func (CallErrors) Is ¶
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 ¶
package main
import (
"fmt"
"math/big"
"github.com/meltingclock/w3"
"github.com/meltingclock/w3/module/eth"
)
func main() {
addr := w3.A("0x0000000000000000000000000000000000000000")
// 1. Connect to an RPC endpoint
client, err := w3.Dial("https://rpc.ankr.com/eth")
if err != nil {
// handle error
}
defer client.Close()
// 2. Make a batch request
var (
balance big.Int
nonce uint64
)
if err := client.Call(
eth.Balance(addr, nil).Returns(&balance),
eth.Nonce(addr, nil).Returns(&nonce),
); err != nil {
// handle error
}
fmt.Printf("balance: %s\nnonce: %d\n", w3.FromWei(&balance, 18), nonce)
}
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().
Example (BalanceOf) ¶
package main
import (
"fmt"
"math/big"
"github.com/meltingclock/w3"
"github.com/meltingclock/w3/module/eth"
)
func main() {
// Connect to RPC endpoint (or panic on error) and
// close the connection when you are done.
client := w3.MustDial("https://rpc.ankr.com/eth")
defer client.Close()
var (
addr = w3.A("0x000000000000000000000000000000000000dEaD")
weth9 = w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")
// Declare a Smart Contract function using Solidity syntax,
// no "abigen" and ABI JSON file needed.
balanceOf = w3.MustNewFunc("balanceOf(address)", "uint256")
// Declare variables for the RPC responses.
ethBalance big.Int
weth9Balance big.Int
)
// Do batch request (both RPC requests are send in the same
// HTTP request).
if err := client.Call(
eth.Balance(addr, nil).Returns(ðBalance),
eth.CallFunc(weth9, balanceOf, addr).Returns(&weth9Balance),
); err != nil {
fmt.Printf("Request failed: %v\n", err)
return
}
fmt.Printf("Combined balance: %v wei",
new(big.Int).Add(ðBalance, &weth9Balance),
)
}
Example (NonceAndBalance) ¶
package main
import (
"fmt"
"math/big"
"github.com/meltingclock/w3"
"github.com/meltingclock/w3/module/eth"
)
func main() {
client := w3.MustDial("https://rpc.ankr.com/eth")
defer client.Close()
var (
addr = w3.A("0x000000000000000000000000000000000000c0Fe")
nonce uint64
balance big.Int
)
if err := client.Call(
eth.Nonce(addr, nil).Returns(&nonce),
eth.Balance(addr, nil).Returns(&balance),
); err != nil {
fmt.Printf("Request failed: %v\n", err)
return
}
fmt.Printf("%s: Nonce: %d, Balance: ♦%s\n", addr, nonce, w3.FromWei(&balance, 18))
}
Example (SendERC20transferTx) ¶
package main
import (
"fmt"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/params"
"github.com/meltingclock/w3"
"github.com/meltingclock/w3/module/eth"
)
func main() {
client := w3.MustDial("https://rpc.ankr.com/eth")
defer client.Close()
var (
weth9 = w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")
receiver = w3.A("0x000000000000000000000000000000000000c0Fe")
eoaPrv, _ = crypto.GenerateKey()
)
funcTransfer := w3.MustNewFunc("transfer(address receiver, uint256 amount)", "bool")
input, err := funcTransfer.EncodeArgs(receiver, w3.I("1 ether"))
if err != nil {
fmt.Printf("Failed to encode args: %v\n", err)
return
}
signer := types.LatestSigner(params.MainnetChainConfig)
var txHash common.Hash
if err := client.Call(
eth.SendTx(types.MustSignNewTx(eoaPrv, signer, &types.DynamicFeeTx{
Nonce: 0,
To: &weth9,
Data: input,
GasTipCap: w3.I("1 gwei"),
GasFeeCap: w3.I("100 gwei"),
Gas: 100_000,
})).Returns(&txHash),
); err != nil {
fmt.Printf("Failed to send tx: %v\n", err)
return
}
fmt.Printf("Sent tx: %s\n", txHash)
}
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 closes the RPC connection and cancels any in-flight requests.
Close implements the io.Closer interface.
func (*Client) Subscribe ¶
func (c *Client) Subscribe(s w3types.RPCSubscriber) (*rpc.ClientSubscription, error)
Subscribe is like Client.SubscribeCtx with ctx equal to context.Background().
Example ¶
package main
import (
"fmt"
"github.com/ethereum/go-ethereum/core/types"
"github.com/meltingclock/w3"
"github.com/meltingclock/w3/module/eth"
)
func main() {
client := w3.MustDial("wss://mainnet.gateway.tenderly.co")
defer client.Close()
txCh := make(chan *types.Transaction)
sub, err := client.Subscribe(eth.PendingTransactions(txCh))
if err != nil {
fmt.Printf("Failed to subscribe: %v\n", err)
return
}
for {
select {
case tx := <-txCh:
fmt.Printf("New pending tx: %s\n", tx.Hash())
case err := <-sub.Err():
fmt.Printf("Subscription error: %v\n", err)
return
}
}
}
func (*Client) SubscribeCtx ¶
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 ¶
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.
func MustNewEvent ¶
MustNewEvent is like NewEvent but panics if the signature parsing fails.
func NewEvent ¶
NewEvent returns a new Smart Contract event log decoder from the given Solidity event signature.
An error is returned if the signature parsing fails.
func (*Event) DecodeArgs ¶
DecodeArgs decodes the topics and data of the given log to the given args.
Example ¶
package main
import (
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/meltingclock/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
type Func ¶
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.
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.
Example (BalanceOf) ¶
package main
import (
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/meltingclock/w3"
)
func main() {
// ABI binding to the balanceOf function of an ERC20 Token.
funcBalanceOf, _ := w3.NewFunc("balanceOf(address)", "uint256")
// Optionally names can be specified for function arguments. This is
// especially useful for more complex functions with many arguments.
funcBalanceOf, _ = w3.NewFunc("balanceOf(address who)", "uint256 amount")
// ABI-encode the functions args.
input, _ := funcBalanceOf.EncodeArgs(w3.A("0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B"))
fmt.Printf("balanceOf input: 0x%x\n", input)
// ABI-decode the functions args from a given input.
var (
who common.Address
)
funcBalanceOf.DecodeArgs(input, &who)
fmt.Printf("balanceOf args: %v\n", who)
// ABI-decode the functions output.
var (
output = w3.B("0x000000000000000000000000000000000000000000000000000000000000c0fe")
amount = new(big.Int)
)
funcBalanceOf.DecodeReturns(output, amount)
fmt.Printf("balanceOf returns: %v\n", amount)
}
Output: balanceOf input: 0x70a08231000000000000000000000000ab5801a7d398351b8be11c439e05c5b3259aec9b balanceOf args: 0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B balanceOf returns: 49406
Example (UniswapV4Swap) ¶
package main
import (
"fmt"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/meltingclock/w3"
)
func main() {
// ABI binding for the Uniswap v4 swap function.
funcSwap, _ := w3.NewFunc(`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
}
// ABI-encode the functions args.
input, _ := funcSwap.EncodeArgs(
&PoolKey{
Currency0: w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"),
Currency1: w3.A("0x6B175474E89094C44Da98b954EedeAC495271d0F"),
Fee: big.NewInt(0),
TickSpacing: big.NewInt(0),
},
&SwapParams{
ZeroForOne: false,
AmountSpecified: big.NewInt(0),
SqrtPriceLimitX96: big.NewInt(0),
},
[]byte{},
)
fmt.Printf("swap input: 0x%x\n", input)
}
Output: swap input: 0xf3cd914c000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc20000000000000000000000006b175474e89094c44da98b954eedeac495271d0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000000
func (*Func) DecodeArgs ¶
DecodeArgs ABI-decodes the given input to the given args.
func (*Func) DecodeReturns ¶
DecodeReturns ABI-decodes the given output to the given returns.
type Option ¶
type Option func(*Client)
An Option configures a Client.
func WithRateLimiter ¶
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.
Example ¶
package main
import (
"time"
"github.com/meltingclock/w3"
"golang.org/x/time/rate"
)
func main() {
// Limit the client to 30 requests per second and allow bursts of up to
// 100 requests.
client := w3.MustDial("https://rpc.ankr.com/eth",
w3.WithRateLimiter(rate.NewLimiter(rate.Every(time.Second/30), 100), nil),
)
defer client.Close()
}
Example (CostFunc) ¶
package main
import (
"time"
"github.com/meltingclock/w3"
"golang.org/x/time/rate"
)
func main() {
// Limit the client to 30 calls per second and allow bursts of up to
// 100 calls using a cost function. Batch requests have an additional charge.
client := w3.MustDial("https://rpc.ankr.com/eth",
w3.WithRateLimiter(rate.NewLimiter(rate.Every(time.Second/30), 100),
func(methods []string) (cost int) {
cost = len(methods) // charge 1 CU per call
if len(methods) > 1 {
cost += 1 // charge 1 CU extra for the batch itself
}
return cost
},
))
defer client.Close()
}
Directories
¶
| Path | Synopsis |
|---|---|
|
abi
Package abi implements a Solidity ABI lexer and parser.
|
Package abi implements a Solidity ABI lexer and parser. |
|
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. |
