web3swift
web3swift copied to clipboard
Getting error while trying to send transaction "Failed to fetch nonce"
Previously I was getting error mentioned in https://github.com/skywinder/web3swift/issues/254 after that when I tried to run I'm getting -> processingError(desc: "Failed to fetch nonce")
let value: String = value
let walletAddress = EthereumAddress(walletAddress)!
let toAddress = EthereumAddress(toAddress)!
let endpoint = URL(string: "https://ropsten.infura.io/v3/fa38f7a943ae4c02a407220a4d442f5f")!
do {
let web3 = try Web3.new(endpoint)
web3.addKeystoreManager(KeystoreManager([globalKeystore]))
let contract = web3.contract(Web3.Utils.coldWalletABI, at: toAddress, abiVersion: 2)!
let amount = Web3.Utils.parseToBigUInt(value, units: .eth)
var options = TransactionOptions.defaultOptions
options.value = amount
options.from = walletAddress
options.gasPrice = .automatic
options.gasLimit = .automatic
let tx = contract.write(
"fallback",
parameters: [AnyObject](),
extraData: Data(),
transactionOptions: options)!
let mainTransaction = try tx.send(password: password)
print(mainTransaction.hash, "hash of transaction")
} catch {
print(error)
}
// Any help would be appreciated as I'm new to this repo.
is this still an issue as of 2.6.3? Is the sending address new, or has it made previous transactions?
Yes its an issue as of 2.6.3. The sending account has only one transaction in which it was received some ETH.
have you tried with the built-in Infura provider?
let web3 = InfuraRopstenWeb3()
Also have you validated that walletAddress and your other input parameters are what you expect. Try adding print(tx.transactionOptions) before the line where you call tx.send() to make sure.
Yes I have validated my walletAddress and other input parameters.
Thanks for the input, I have made changed to my code based on your inputs but now I get
inputError(desc: "Failed to locally sign a transaction")
as error.
I suspect your keystore/wallet is not set up correctly then. If you saw a change in behavior between the built-in provider and your original URL, there must be something wrong with your key, and it was resulting in the nonce error, because the node rejected your request.
I followed as per https://github.com/skywinder/web3swift/issues/285 and
let walletAddress = manager.addresses?.first?.address
I used this walletAddress to get ETH balance using https://api-ropsten.etherscan.io/api?module=account&action=txlist&address=walletAddress... which works completely fine. This is the same walletAddress I'm sending from. so I don't think the problem is with wallet address or Keystore. The url I used from infura is the same as they provided. Even when I used built-in provider as let web3 = Web3.InfuraRopstenWeb3() it throws the same error.
inputError(desc: "Failed to locally sign a transaction")
"Failed to locally sign a transaction" is an indicator that the public/private key pair don't match up. (hence my earlier comment about the wallet not being set-up correctly)
To elaborate: when web3swiftsigns a transaction, it attempts to recover the public address from the signature to verify. The error you see is what you get when that verification fails.
I tried with different wallet address and private key. Still the issue exists. Can you share a sample code on how to get the private key ? I used the following
func importWalletWith(privateKey: String){
let formattedKey = privateKey.trimmingCharacters(in: .whitespacesAndNewlines)
guard let dataKey = Data.fromHex(formattedKey) else {
self.showAlertMessage(title: "Error", message: "Please enter a valid Private key ", actionName: "Ok")
return
}
do {
let keystore = try EthereumKeystoreV3(privateKey: dataKey)
if let myWeb3KeyStore = keystore {
let manager = KeystoreManager([myWeb3KeyStore])
globalKeystore = myWeb3KeyStore
let address = keystore?.addresses?.first
#if DEBUG
print("Address :::>>>>> ", address as Any)
print("Address :::>>>>> ", manager.addresses as Any)
#endif
let walletAddress = manager.addresses?.first?.address
// self.walletAddressTF.text = walletAddress ?? "0x"
let vc = instantiateVC(identifier: "WalletDetailsVC") as! WalletDetailsVC
vc.walletAddress = walletAddress ?? "0x"
self.navigationController?.pushViewController(vc, animated: true)
print(walletAddress as Any)
} else {
print("error")
}
} catch {
#if DEBUG
print("error creating keyStrore")
print("Private key error.")
#endif
let alert = UIAlertController(title: "Error", message: "Please enter correct Private key", preferredStyle: .alert)
let okAction = UIAlertAction(title: "OK", style: .destructive)
alert.addAction(okAction)
self.present(alert, animated: true)
}