Closed KillerJi closed 8 months ago
Every time I call the method of reading the contract, an error will be reported, panic: failed to EstimateGas: failed to query eth_estimateGas: Failed to submit transaction: cannot estimate gas
The examples for go sdk (including smart contract deployment) are available here.
Every time I call the method of reading the contract, an error will be reported, panic: failed to EstimateGas: failed to query eth_estimateGas: Failed to submit transaction: cannot estimate gas
There was a bug on zkSync node related on gas estimation. The bug has been patched and has been deployed on test nad mainnet
The examples for go sdk (including smart contract deployment) are available here.
hello sir What I need is an example of reading contract variables, not examples of transaction transfer and execution contracts. I have read the examples you mentioned, but they are not what I need. For example, I deploy a contract and I need to read the value of the B variable.What should I do? What I need is this example.
I you want to read the data from smart contract just call the appropriate get function (example of get function, and how it's called in program) . In case where public
modifier for some variable is used, abigen
generates method with exact same name as the variable. Here's the example of smart contract that has public
modifier for owner
variable:
contract ToDo {
address public owner;
constructor(){
owner = msg.sender;
}
}
In order to get owner
value in program, do the following:
todoContract, err := todo.NewTodo(common.HexToAddress(Contract), zp.Client)
if err != nil {
log.Panic(err)
}
owner, err := todoContract.Owner(nil)
if err != nil {
log.Panic(err)
}
fmt.Println("Owner address: ", owner)
zkSyncProvider, err := zksync2.NewDefaultProvider("https://zksync2-mainnet.zksync.io/")
if err != nil {
log.Fatal(err)
}
add := common.HexToAddress("0x621425a1Ef6abE91058E9712575dcc4258F8d091")
q, _ := pool.NewPool(add, zkSyncProvider.Client)
a, err := q.GetReserves(nil)
if err != nil {
log.Fatal(err)
}
yes i'm using this way but always getting log error “execution reverted”, above is my code i don't know what's wrong,This is a code to read the balance of the currency pair pool, but it always reports an error
Have you tried the read action of the mainnet node?
Read on mainnet network does work. In following example decimals()
method of USDC token is called:
zp, _ := zksync2.NewDefaultProvider("https://mainnet.era.zksync.io/")
address := common.HexToAddress("3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4")
data, err := zp.CallContract(
context.Background(),
ethereum.CallMsg{
From: *new(common.Address),
To: &address,
Data: crypto.Keccak256([]byte("decimals()"))[:4],
},
nil)
if err != nil {
log.Panic(err)
}
decimals := new(big.Int)
decimals.SetBytes(data)
fmt.Println("Decimals:", decimals) // Decimals: 6
But when I try to execute your example I get the same error as you: execution reverted
.
zp, _ := zksync2.NewDefaultProvider("https://mainnet.era.zksync.io/")
add := common.HexToAddress("621425a1Ef6abE91058E9712575dcc4258F8d091")
value, err := zp.CallContract(
context.Background(),
ethereum.CallMsg{
From: *new(common.Address),
To: &add,
Data: crypto.Keccak256([]byte("getReserves()"))[:4],
},
nil)
if err != nil {
log.Panic(err) // execution reverted
}
fmt.Println("Value:", value)
I guess error is related to smart contract it self, perhaps getReserves()
does not exist on smart contract. Or version of ABI does not match with deployed smart contract.
Have you tried to execute other methods from smart contracts?
Thank you for your example. I changed the contract address and it can be successfully read. I still have two questions. 1. Is it possible to obtain the gas estimate for executing the transaction? 2 If it is available, does it support modifying the gas limit?
Specifying gas limit is supported:
// Create instance of Storage smart contract
storageContract, err := storage.NewStorage(contractAddress, zp.Client)
if err != nil {
log.Panic(err)
}
// Read the private key
privateKey, err := crypto.ToECDSA(common.Hex2Bytes(PrivateKey))
if err != nil {
log.Panic(err)
}
// Start configuring transaction parameters opts, err := bind.NewKeyedTransactorWithChainID(privateKey, w.GetEthSigner().GetDomain().ChainId) if err != nil { log.Panic(err) } // GasLimit opts.GasLimit = 30_000
// GasTipCap is required to be set, otherwise following error occurs: Method not found !!! opts.GasTipCap = big.NewInt(300)
// Execute Set method from storage smart contract with configured transaction parameters tx, err := storageContract.Set(opts, big.NewInt(200)) if err != nil { log.Panic(err) }
thanks.May I ask in the next go version update, will there be an operation to add this estimated gas? Without this method, it is meaningless to modify the gas limit
SDK already supports gas limit estimation. When opts.GasLimit
is not specified, the SDK calls eth_estimateGas
RPC endpoint to fetch gas limit. The problem is that eth_estimateGas
does not work on mainnet. Temporary solution whould be to run gas estimation on testnet and use it on mainnet.
I think this needs to be fixed, because the network is different and the gas is not the same, do you have a plan to fix it?
This has been fixed for a while on both networks (mainnet, testnet)
I executed the example of smart contract deployment using smart contracts generated with abigen
on mainnet:
I have tested the gas estimation using the following code with the v0.3.1
version on mainnet and testnet.
var (
PrivateKey = os.Getenv("PRIVATE_KEY")
ZkSyncEraProvider = "https://zksync2-mainnet.zksync.io"
//ZkSyncEraProvider = "https://testnet.era.zksync.dev"
contractAddress = common.HexToAddress("0x99B4da9890d62eC523851A345e2b216f1216EDB4")
)
client, err := clients.Dial(ZkSyncEraProvider)
if err != nil {
log.Panic(err)
}
defer client.Close()
wallet, err := accounts.NewWallet(common.Hex2Bytes(PrivateKey), &client, nil)
if err != nil {
log.Panic(err)
}
abi, err := storage.StorageMetaData.GetAbi()
if err != nil {
log.Panic(err)
}
setArguments, err := abi.Pack("set", big.NewInt(700))
if err != nil {
log.Panic(err)
}
gas, err := client.EstimateGasL2(context.Background(), types.CallMsg{
CallMsg: ethereum.CallMsg{
To: &contractAddress,
From: wallet.Address(),
Data: setArguments,
},
})
if err != nil {
log.Panic(err)
}
fmt.Println("Gas: ", gas)
result, err := wallet.CallContract(context.Background(), accounts.CallMsg{
To: &contractAddress,
Data: setArguments,
}, nil)
if err != nil {
log.Panic(err)
}
fmt.Println("Result: ", result)
Output:
Gas: 558302
Result: []
Does it use github.com/zksync-sdk/zksync2-go/ContractDeployer? but I got err when go mod tidy : github.com/zksync-sdk/zksync2-go/ContractDeployer: module github.com/zksync-sdk/zksync2-go@latest found (v0.1.1), but does not contain package github.com/zksync-sdk/zksync2-go/ContractDeploye