zksync-sdk / zksync2-go

zksync2-go is a geth library adapted to work with the zkSync Era.
Apache License 2.0
87 stars 36 forks source link

error happened when call contract #6

Closed atomstaker closed 8 months ago

atomstaker commented 1 year ago

Hello: I want to use this SDK to call a swap contract, there are always happen error.Could you please help me to check what is the problem is? Thanks in advance.

My code is as following:

func Swap(user *zksync2.Wallet) error {

swapabi, err := abi.JSON(strings.NewReader(SWAP_ABI_TEST))
if err != nil {
    return err
}
token0 := common.HexToAddress("0x0000000000000000000000000000000000000000")
token1 := common.HexToAddress("0x3355df6D4c9C3035724Fd0e3914dE96A5a83aaf4")

    path := []common.Address{token0, token1}
    //function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
    calldata, err := swapabi.Pack("swapExactETHForTokens", big.NewInt(0), path, user, big.NewInt(time.Now().Unix()+300))
    if err != nil {
        return err
    }
    fmt.Println(calldata)

    hash, err := Execute(user, common.HexToAddress("0x2da10A1e27bF85cEdD8FFb1AbBe97e53391C0295"), calldata, nil, big.NewInt(1e14))
    if err != nil {
        fmt.Println(err)
        return err
    }
    fmt.Println("swap Tx hash", hash)

return nil

}

func Execute(user zksync2.Wallet, contract common.Address, calldata []byte, nonce big.Int, ethval *big.Int) (string, error) {

var err error
if nonce == nil {
    nonce, err = user.GetNonce()
    if err != nil {
        return "", fmt.Errorf("failed to get nonce: %w", err)
    }
}
tx := zksync2.CreateFunctionCallTransaction(
    user.GetAddress(),
    contract,
    big.NewInt(0),
    big.NewInt(0),
    ethval,
    calldata,
    nil, nil,
)

hash, err := user.EstimateAndSend(tx, nonce)

return hash.Hex(), err

}

the error will be returned after call user.EstimateAndSend(tx, nonce) the error is: failed to EstimateGas: failed to query eth_estimateGas: Failed to submit transaction: cannot estimate gas


and I add funtion mimic EstimateAndSend in wallet to remove EstimateGas as following

func (w Wallet) TxSend(tx Transaction, nonce big.Int, gasLimit big.Int) (common.Hash, error) {

chainId := w.es.GetDomain().ChainId
gasPrice, err := w.zp.GetGasPrice()
if err != nil {
    return common.Hash{}, fmt.Errorf("failed to GetGasPrice: %w", err)
}
prepared := NewTransaction712(
    chainId,
    nonce,
    gasLimit,
    tx.To,
    tx.Value.ToInt(),
    tx.Data,
    big.NewInt(100000000), // TODO: Estimate correct one
    gasPrice,
    tx.From,
    tx.Eip712Meta,
)
signature, err := w.es.SignTypedData(w.es.GetDomain(), prepared)
rawTx, err := prepared.RLPValues(signature)
return w.zp.SendRawTransaction(rawTx)

}

replace hash, err := user.EstimateAndSend(tx, nonce) with hash, err = user.TxSend(tx, nonce, big.NewInt(200000)) in my code the error is: failed to call eth_sendRawTransaction: Failed to submit transaction: failed to validate the transaction. reason: Validation revert: Account validation error: Error function_selector = 0x, data = 0x

-----------------------------------------------abi------------------------------------------------------------------ var SWAP_ABI_TEST = [{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_WETH","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"WETH","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"amountADesired","type":"uint256"},{"internalType":"uint256","name":"amountBDesired","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amountTokenDesired","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"addLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"},{"internalType":"uint256","name":"liquidity","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"depositProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"getAmountIn","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"reserveIn","type":"uint256"},{"internalType":"uint256","name":"reserveOut","type":"uint256"},{"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"getAmountOut","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsIn","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"getAmountsOut","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"reserveA","type":"uint256"},{"internalType":"uint256","name":"reserveB","type":"uint256"}],"name":"quote","outputs":[{"internalType":"uint256","name":"amountB","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidity","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETH","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"removeLiquidityETHSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"removeLiquidityETHWithPermit2","outputs":[{"internalType":"uint256","name":"amountToken","type":"uint256"},{"internalType":"uint256","name":"amountETH","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountTokenMin","type":"uint256"},{"internalType":"uint256","name":"amountETHMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"removeLiquidityETHWithPermitSupportingFeeOnTransferTokens2","outputs":[{"internalType":"uint256","name":"amountETH","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"tokenA","type":"address"},{"internalType":"address","name":"tokenB","type":"address"},{"internalType":"uint256","name":"liquidity","type":"uint256"},{"internalType":"uint256","name":"amountAMin","type":"uint256"},{"internalType":"uint256","name":"amountBMin","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bool","name":"approveMax","type":"bool"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"removeLiquidityWithPermit2","outputs":[{"internalType":"uint256","name":"amountA","type":"uint256"},{"internalType":"uint256","name":"amountB","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"rescueERC20","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"rescueETH","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"onBehalf","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"stakeProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapETHForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactETHForTokensSupportingFeeOnTransferTokens","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForETHSupportingFeeOnTransferTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"amountOutMin","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapExactTokensForTokensSupportingFeeOnTransferTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactETH","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"amountInMax","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"payable":false,"stateMutability":"nonpayable","type":"function"}]

VickMellon commented 1 year ago

Hi, did you use latest version of SDK? Release v0.1.0 was just yesterday, also dev branch is actual, other/older versions is out of date.

atomstaker commented 1 year ago

yes,I use the lastest version. I check it today I test transfer eth. it works,no problem. But for contract calling, it is not ok:(

Covsj commented 1 year ago

I use the latest sdk, and there is also an mv error, can someone help me, this is the hash https://goerli.etherscan.io/tx/0xa38468afa725c4f3f3a14e3c1ec71b4941d232ac77f97682fd0e23deec23bf0b

atomstaker commented 1 year ago

I checked zkSync chain core RUST code, the code for the contract calling error is as following: the function selector and corresponding data should be given according to the logic.

but there are no corresponding message ,what is got in SDK is this one:

failed to call eth_sendRawTransaction: Failed to submit transaction: failed to validate the transaction. reason: Validation revert: Account validation error: Error function_selector = 0x, data = 0x

function_selector and data is missed

Thanks

impl Display for VmRevertReason {

fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
    use VmRevertReason::{General, InnerTxError, Unknown, VmError};
    match self {
        General { msg } => write!(f, "{}", msg),
        VmError => write!(f, "VM Error",),
        InnerTxError => write!(f, "Bootloader-based tx failed"),
        Unknown {
            function_selector,
            data,
        } => write!(
            f,
            "Error function_selector = 0x{}, data = 0x{}",
            hex::encode(function_selector),
            hex::encode(data)
        ),
    }
}

}

VickMellon commented 1 year ago

@atomstaker let me suppose that problem might be in this current smart contract itself..

AFAIK, zkSynk EVM doesn't have fully backward compatibility with classic Ethereum EVM, so some sc can didn't work properly as is (even if was successfully deployed). Please, check this doc https://era.zksync.io/docs/dev/building-on-zksync/contracts/contract-development.html#evm-compatibility and related.

If this is your SC, you can try to Verify Smart Contract and then try to Execute this method by explorer..

VickMellon commented 1 year ago

@Covsj

I use the latest sdk, and there is also an mv error, can someone help me, this is the hash https://goerli.etherscan.io/tx/0xa38468afa725c4f3f3a14e3c1ec71b4941d232ac77f97682fd0e23deec23bf0b

Hmm, this is some new (for me) behaviour of Deposit flow.. Quick debug lead me to some workaround - try to specify GasPrice by options parameter. Also I'd pushed fix to dev branch (to use SuggestGasPrice by default), you can try this version also.

atomstaker commented 1 year ago

@VickMellon the contract: 0x2da10A1e27bF85cEdD8FFb1AbBe97e53391C0295 is SyncSwapRouter from https://syncswap.xyz/ which already run on zlSync Era Mainnet

I use matemask wallet to interact with it already,there is no problem

Chief-Alchemist commented 1 year ago

Have just tried with the latest version and am getting the same error as the OP: failed to EstimateGas: failed to query eth_estimateGas: Failed to submit transaction: cannot estimate gas

Any further updates?

danijelTxFusion commented 1 year ago

Have just tried with the latest version and am getting the same error as the OP: failed to EstimateGas: failed to query eth_estimateGas: Failed to submit transaction: cannot estimate gas

Any further updates?

Gas estimation had problems in the past. I should work on testnet correctly, but mainnet still has some issues.

danijelTxFusion commented 8 months ago

I have just tested the gas estimation using the following code with v0.3.1 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:  []

I executed the example of smart contract deployment using smart contracts generated with abigen on mainnet: