Giter Site home page Giter Site logo

w3's People

Contributors

danpopenko avatar dependabot[bot] avatar joel-u410 avatar lmittmann avatar rtunazzz avatar virtualvizier avatar wesraph avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

w3's Issues

NewFunc fails when signature contains tuples without names

Example code that illustrates the issue:

w3.MustNewFunc("test((address, uint256))", "")

Result:

panic: w3: invalid ABI: syntax error: unexpected ",", want name

I have function signatures without names, e.g. as returned by openchain.xyz, and I would like to be able to decode args from them. I don't care as much about actually extracting the tuple values, and will likely just provide nil for any tuples in the args I pass to DecodeArgs. But, I would still like the function to be successfully created.

That said, I am working on implementing this in such a way that you can decode tuples into []any slices, which will allow unnamed tuple fields to be supported and actually decodable. I'll open the PR soon!

DecodeArgs - panic: runtime error: slice bounds out of range

Hello, i'm trying to decode transfer(address recipient, uint256 amount) function and sometimes i'm get this error:

github.com/lmittmann/w3.(*Func).DecodeArgs(...)
        C:/Users/James/go/pkg/mod/github.com/lmittmann/[email protected]/func.go:88
main.main.func1({0x12, 0x26, 0xa8, 0xc7, 0x8d, 0xa0, 0x1, 0xf0, 0x7a, 0x9b, ...})

I dont know which transaction makes this error.

It is possible CallFunc().Returns into struct?

There's my case: I need make a call with many output (like slot0) and when I try something like c.Call(eth.CallFunc(w3.MustNewFunc("signature", "output fields"), address).Returns(&myStruct))
I receive an error

invalid type: can not copy *big.Int to *myStruct

But ok, I could then map fields into a structure, but the problems start when I need make a multicall one function and the number of calls can be dynamic. Example:

c.Call(
  eth.CallFunc(w3.MustNewFunc("signature", "output fields"), address1).Returns(???),
  eth.CallFunc(w3.MustNewFunc("signature", "output fields"), address2).Returns(???),
  eth.CallFunc(w3.MustNewFunc("signature", "output fields"), address3).Returns(???),
)

How make the correct return? Do I understand correctly that such cases are left out yet in the library interface/unfinished?

[FEATURE] Handle individual batch call errors the same way return values are being handled right now

Introduction

If one of the calls from a batch request fails, return values from the following calls won't be returned (even if they are executed successfully).

I personally think it would be better if w3 returned an error when the batch request fails (network error, etc.) but NOT if one of the calls inside the batch request fails. Something similar to how go-ethereum handles their batch request calls.

Proposal

I propose we add a .Errors method to the CallFuncFactory, allowing us to specify where the error would get saved the same .Returns does.

Example

Consider the following snippet:

err := client.Call(
	eth.CallFunc(nonExistentFunc, w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2")).
		Errors(targetErr1).
		Returns(res1),
	eth.CallFunc(funcBalanceOf, w3.A("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"), w3.A("0x000000000000000000000000000000000000c0Fe")).
		Errors(targetErr2).
		Returns(res2),
)

The caller would then be able to check the particular call errors via the targetErr1 and targetErr2 variables in this particular example. If targetErr2 == nil, I would then expect res2 hold the expected return value.


Thoughts?

Add support for L2 networks like Arbitrum/Optimism

Many L2s have differences from the standard rpc endpoints available in geth. In most cases, I don't this is an issue, additional fields and the like, are ignored during serialization.

https://docs.arbitrum.io/arbitrum-ethereum-differences#json-rpc-api

For example, Optimism and Arbitrum have some additional transaction types that do not break the rpc spec but do break when serializing into geth types.

For example:

client.CallCtx(ctx, eth.BlockByNumber(head).Returns(block))

will return

panic: w3: call failed: transaction type not supported

How to get Transaction from address?

var tx types.Transaction
err = client.Call(eth.Tx(common.HexToHash("0x35360e885766d3e26207f248da7ce5656a2d526f6669a52e234af6dfde7a6851")).Returns(&tx))
if err != nil {
	panic(err)
}
// How to get Transaction from address?

debug.CallTrace example

Could you provide an example of debug.CallTrace? When attempting to use it, I receive the following error:

err := e.client.Call(debug.CallTraceTx(txHash, w3types.State{}).Returns(&trace))

ERR = w3: call failed: the method debug_traceTransaction does not exist

Example of how to decode input data in transaction

how to decode input data in transaction?I just found it more convenient to take data from input data than from logs, because to get the receipt you need to send another additional request.

Forgive me in advance if this question seems simple. I am a beginner.

how to pass bytes32 as a parameter to CallFunc?

how to pass bytes32 as a parameter? The examples includes only primitive types. would be a nice to see a complex one (involving dynamic size types etc)

var contractAddress common.Address
resolverFunc := w3.MustNewFunc("resolver(bytes32)", "address")
resolverCall := eth.CallFunc(w3.A(registryAddr), resolverFunc, []byte("hello.xyz")).Returns(&contractAddress)
err := w3Client.Call(resolverCall)
if err != nill {
  log.Println("error occurred during the resolver call: ", err)
}
fmt.Println(contractAddress)

I get the below error

error occurred during the resolver call:  abi: cannot use slice as type array as argument

Treat `;` (End of statement) as an EOF in the lexer

It is common for event signatures definitions in Solidity to end in a semicolon. A test such as:

		{
			Signature: "Transfer(address,address,uint256);",
			WantEvent: &w3.Event{
				Signature: "Transfer(address,address,uint256)",
				Topic0:    w3.H("0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"),
			},
		},

should pass.

However this test will result in a panic. I think a quick fix is to assume a semicolon is an EOF type character in the lexer.

Failed to estimate gas

var gasLimit uint64

err = chain.Client.Call(
		eth.EstimateGas(&w3types.Message{
	        To:   &contractAddress,
		Func: funcTransfer,
		From: address,
		Args: []any{&recipient, &token.Balance},
	}, nil).Returns(&gasLimit),
)

Returns w3: call failed: too many arguments, want at most 1

`examples/token_balance` does not work

The token balance example is not working as expected:

After running go run main.go inside the folder, I receive the following output:

Call failed: w3: response handling failed: invalid argument 0: json: cannot unmarshal non-string into Go struct field CallArgs.nonce of type hexutil.Uint64

I noticed that downgrading back to 0.8.1 fixes this issue.

Support encoding constructor arguments

The ABI parser expects any function to be named. In some cases it would be useful to encode constructor args. (address) for example doesn't work. One way would be to reserve the constructor keyword in the lexer.

constructorFunc, err := w3.NewFunc("constructor(address)", "")
if err != nil {
	return nil, err
}

constructorArgs := []any{w3.A(0x765DE816845861e75A25fCA122bb6898B8B1282a)}

constructorBytecode, err := constructorFunc.EncodeArgs(constructorArgs...)
if err != nil {
	return nil, err
}

// Should return bytearray representing 000000000000000000000000765de816845861e75a25fca122bb6898b8b1282a

Not sure if this is within scope of w3 or should the abi package (abi.Pack) from geth be used instead.

Arrays of tuples aren't supported?

The following code currently panics:

package main

import (
	"fmt"

	"github.com/lmittmann/w3"
)

// we have the following structs and function in solidity:
/*
struct Recipient {
    address to;
}

struct testFnParam {
    Recipient[] recipients;
}

function testFn(testFnParam param) {
    // .
    // .
    // .
}
*/

func main() {
	// panic: w3: invalid ABI: unexpected token '[', want ')', ',' or EOF
	fn := w3.MustNewFunc(
		"testFn(((address to)[] recipients) param)",
		"", // returns
	)

	fmt.Println(fn)
}

It looks like the combined usage of tuple arrays are not supported currently.

Unable to parse ENS NameRegistered event

Hi! First of all, love the lib. Thanks for taking the time to work on it!

Issue

I can't seem to get log parsing for the ENS NameRegistered event to work. I suspect it's because of the indexed keyword.

Here's the contract source and here's a snippet referencing the event of my interest:

event NameRegistered(string name, bytes32 indexed label, address indexed owner, uint cost, uint expires);

Copying the event source string straight from solidity:

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() {
	// from https://etherscan.io/tx/0xbba96a6bc0c49cfb4607c02670affffad64a58cd7789d6843a774e5fcd851c4a#eventlog
	l := &types.Log{
		Address: w3.A("0x283Af0B28c62C092C9727F1Ee09c02CA627EB7F5"),
		Topics: []common.Hash{
			w3.H("0xca6abbe9d7f11422cb6ca7629fbf6fe9efb1c621f71ce8f02b9f2a230097404f"),
			w3.H("0x4e59ffc7ae105a2b19f7f29b63e9f9c5ac28e27bce744a330804c6a89269cec0"),
			w3.H("0x000000000000000000000000bd08f39b2523426cc1d6961e2d6a9744b3b432b5"),
		},
		Data: w3.B("0x000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000165a7d3a3e48ad0000000000000000000000000000000000000000000000000000000066e4d0a50000000000000000000000000000000000000000000000000000000000000009656c666172657373690000000000000000000000000000000000000000000000"),
	}

	e := w3.MustNewEvent("NameRegistered(string name, bytes32 label, address owner, uint cost, uint expires)")
	args := []any{new(string), new(common.Hash), new(common.Address), new(big.Int), new(big.Int)}
	err := e.DecodeArgs(l, args...)
	if err == nil {
		fmt.Println(args)
	} else {
		fmt.Println(err)
	}
}

Produces:

panic: w3: invalid ABI: unexpected token ' ', want ')', ',' or EOF

After removing indexed keywords from MustNewEvent call

e := w3.MustNewEvent("NameRegistered(string name, bytes32 label, address owner, uint cost, uint expires)")

Produces:

abi: cannot marshal in to go slice: offset 35439416906938938518729653100551098276713131344231382706165141882278127455968 would go over slice boundary (len=224)

Any ideas what the issue could be?

How to get errors back with w3 api?

How can I get error back with this interface/api? for example say I want to do this

var latestBlockNumber big.Int
eth.BlockNumber().Returns(&latestBlockNumber)

what happens if this network call fails? would the block number be -1 or something? I can eth.BlockNumber().Returns(&latestBlockNumber).createRequest() but then I am batch BatchElem and ethClient API which is not great. The w3 API looks really good and would be nice if it can also returns errors

Unable to EstimateGas for transfer func

client := w3.MustDial("https://rpc.ankr.com/eth")
contractAddress := w3.A("0xdAC17F958D2ee523a2206206994597C13D831ec7")
tokenTransferFunc := w3.MustNewFunc("transfer(address recipient, uint256 amount)", "bool success")
var tokenTransferGas uint64
err := client.Call(
	eth.EstimateGas(&w3types.Message{
		To:   &contractAddress,
		Func: tokenTransferFunc,
	}, nil).Returns(&tokenTransferGas),
)
if err != nil {
	log.Fatal(err)
}

Error:

argument count mismatch: got 0 for 2

How does MustNewFunc handle functions that return multiple values?

I'm trying to read a smart contract that has a getReserves() function that returns 3 values - reserve0, reserve1 and blockTimestampLast. How should that get coded?

    getReserves := w3.MustNewFunc("getReserves()", "uint112, uint112, uint32")
    var reserves big.Int 

    err := client.Call(eth.CallFunc(getReserves, tokenPairAddress).Returns(&reserves))
    if err != nil {
        log.Fatal(err)
    }

The above code is getting the following result:
{false [12569833997705177805 642440]}

balanceOf error

#16 same issue.
Trying to get balance of BUSD on Binance Smart Chain

        client := w3.MustDial("https://rpc.ankr.com/bsc")
	err = client.Call(
		eth.CallFunc(funcBalanceOf, contractAddress, address).Returns(&tokenBalance),
	)
	if err != nil {
		log.Fatal(err)
	}

It returns

w3: response handling failed: invalid argument 0: json: cannot unmarshal non-string into Go struct field CallArgs.gas of type hexutil.Uint64

Semver

Hi,

Great library btw.

I noticed v0.10.0 deprecated some methods. go get -u github.com/lmittmann/w3 will upgrade any 0.x to this version and break any existing code which used the deprecated methods. I propose this library use https://semver.org so that safe dependency upgrades either manually or via @dependabot can be done.

Transaction gets sent but can be found on etherscan

I am trying to interact with a smart contract using the package, and it seem to work.
But i can not find it on etherscan after it has been sent. I have tried 2 different RPC's but cant seem to get it working

Here is the code im using to test it. Fill in your own PRIVATE_KEY and RPC to run it.

package main

import (
	"fmt"
	"math/big"

	"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/lmittmann/w3"
	"github.com/lmittmann/w3/module/eth"
)

const PRIVATE_KEY = "Fill in a private key for a wallet with goerli eth"
const CONTRACT_ADDRESS = "0x42c7d192696481710b99979ef9647382816ac2ab"
const SELECTED_FUNCTION = "mint(uint256)"
const RETURN_VALUE = ""

func main() {
	var client = w3.MustDial("https://eth-goerli.g.alchemy.com/v2/yourAlchemyApiKeyHere")
	defer client.Close()

	// Make a variable named privateKey with the type ecdsa key from the string wallet
	privKey, err := crypto.HexToECDSA(PRIVATE_KEY)

	if err != nil {
		fmt.Println(err)
		return
	}

	selectedFunc, err := w3.NewFunc(SELECTED_FUNCTION, RETURN_VALUE)

	// Print the public key from privKey
	fmt.Println("Address: ", crypto.PubkeyToAddress(privKey.PublicKey).Hex())

	if err != nil {
		fmt.Println(err)
		return
	}

	contractAddress := common.HexToAddress(CONTRACT_ADDRESS)

	var balance big.Int
	var nonce uint64

	err2 := client.Call(
		eth.Nonce(contractAddress, nil).Returns(&nonce),
		eth.Balance(crypto.PubkeyToAddress(privKey.PublicKey), nil).Returns(&balance),
	)

	if err2 != nil {
		fmt.Println(err2)
		return
	}

	fmt.Println("Balance: ", balance.String())

	signer := types.LatestSigner(params.GoerliChainConfig)

	input, err3 := selectedFunc.EncodeArgs(w3.I("1"))
	if err3 != nil {
		fmt.Println(err3)
		return
	}

	tx := types.MustSignNewTx(privKey, signer, &types.DynamicFeeTx{
		To:        &contractAddress,
		Nonce:     nonce,
		Data:      input,
		Gas:       300000,
		GasFeeCap: w3.I("15 gwei"),
		GasTipCap: w3.I("1 gwei"),
		Value:     w3.I("0 gwei"),
	})

	var txHash common.Hash
	err4 := client.Call(
		eth.SendTransaction(tx).Returns(&txHash),
	)

	if err4 != nil {
		fmt.Println(err4)
		return
	}

	fmt.Println("Tx Hash: ", txHash.String())
}

Logs out this in my case

Address:  0x598aa6f8D6377629C1B933754019a01Bd89931f8
Balance:  250000000000000000
Tx Hash:  0x5d98e4104c5300711a2243780bb1336e69fd26168a71967b875dc75cc27bf928

Hope some of you know what the issue is!
And thanks for providing this great package.

abi: cannot use []hexutil.Bytes as type [0]array as argument

I want to execute contract function that requires bytes32[]
I have this array in json:

"proof":["0xdac2beda9cd88c89679f4c41539e8196b29fd38407219841f936f0b6b7e8ff1a","0x22eb93710252e79914d1d4ec15716071ed5fe64b0b0c7e7e1badbce95b386442","0x7d463be3ff9f50f990b008c19834d74bf916fa71b4db3855bd54491b8b07bea7","0xb6577628cd0917349f8d6d059a5f33e8a6b2e2e8e9e95cd005ed7e0981a4a713","0x2b7733395a061fcf4c05a866e05142035f370a4a088969bb560c3761620e57e8","0x5a467b8b8aad5b144e01c349a0a3380ca8ce0829863afa03d99cff8a9b613273","0xe024adad50aa103636a4c42c0fb428c82e154bff3501d84dc5695f70cf32639d","0xc8c9fed8ed870eb1e8462d19a6e107d55c8df05528e81fa9e90af548bf985f30","0x9841222888c5a80644cf54b7d877b85efcd5789e2c2ae8388475f7871f6a1bf7","0x9a046dc08506268e16603452a33ea179b4932eeae59338dd3fee75685cc490f1","0xacba6c0ed0c90792bb6f9f696ad1417efe0032bb0e86b6927234ce419628e24c","0x0d577b40b8956166e4d21cba88b58b32dec0a00b2864e8ed4ac5d7be6683f5f2","0x97aaf35d6ca208a954554f4ab14a1ca973daf13e7c1dad49db82611f4dadf2a3","0xc32355753f5e11ba88adc0d27f10ad32ad4904bfd782c15693c6795b047124fc","0xcd0f927a7dda89206be7ad613644d02a622c3f30f5de40d052b4c3e10ef02a18","0x107e7a23a7abca2aacc0bf854e247569f822013a86927b10f772b7b13fbc8732"]

I unmarshal it into []hexutil.Bytes and when i'm passing this slice into function i get this error:

abi: cannot use []hexutil.Bytes as type [0]array as argument

Unable to parse solidity 2d array return values

I am trying to use w3.MustNewFunc on a smart contract function with the following header:
function getPairsByIndexRange(UniswapV2Factory _uniswapFactory, uint256 _start, uint256 _stop) external view returns (address[3][] memory)

This is how I am calling w3.MustNewFunc:
funcGetPairsByIndexRange := w3.MustNewFunc("getPairsByIndexRange(address, uint256, uint256)", "address[3][]")

I get the following error:

panic: w3: invalid ABI: unknown type ""

goroutine 1 [running]:
github.com/lmittmann/w3.MustNewFunc(...)
	/home/user/go/pkg/mod/github.com/lmittmann/[email protected]/func.go:71

I think I am getting this because MustNewFunc is unable to parse 2d arrays, when I changed it to a one dimensional array it worked as expected.

Any idea how to fix or workaround this issue? I need to use 2d arrays for my specific use case.

Adding proxies to client requests

How about adding proxy requests to the client? It's just that free RPCs have limitations. With a proxy, this problem can be solved.

Allow BlockByNumber to only return transaction hashes and not full transactions

Hi, I noticed that in refactoring the HeaderByNumber, and dropping the RPCHeader type, I am now not able to get a header with only the transaction hashes.
It would help if either HeaderByNumber could return either a types.Header or types.Block, or for BlockByNumber to return a hydrated or not hydrated list of transactions in the block

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.