Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to send ether using send function #279

Closed
iamjaggusam opened this issue Oct 2, 2020 · 9 comments
Closed

Unable to send ether using send function #279

iamjaggusam opened this issue Oct 2, 2020 · 9 comments
Labels
ready for review issue is resolved, a final review is needed before closing

Comments

@iamjaggusam
Copy link

iamjaggusam commented Oct 2, 2020

How to send ether using below code

its skipping at - transaction.send(password: password)

let value: String = "1.0" // In Ether
let walletAddress = EthereumAddress(wallet.address)! // Your wallet address
let toAddress = EthereumAddress(toAddressString)!
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 password = "web3swift"
let result = try! transaction.send(password: password)
@dangell7
Copy link

dangell7 commented Oct 3, 2020

Whats the error you are getting?

@iamjaggusam
Copy link
Author

iamjaggusam commented Oct 3, 2020

@dangell7 I am getting just a nil, I have tried on Kovan network its just failing.

@skywinder
Copy link
Collaborator

@iamjaggusam please provide details.
so it's hard to say, what exactly cause the problem by this part of code.
what the reslut contains?
can you print internal transaction details before send method?
how do you initiate web3?
probably there is wrong initialisation of wallet.

@skywinder skywinder added question Further information is requested wait for reply labels Oct 5, 2020
@iamjaggusam
Copy link
Author

iamjaggusam commented Oct 5, 2020

@skywinder @dsemenovsky @andresousa

I have imported the account using private key, and here is the public address of my account :

0x3D7D50a99244078fF282F050f96f272Ec07f88A2

and I am trying to send the ether of 0.00000033 to the address :

0x3E85A3EC67aDf24a7831019D74F2111a6fEce614

But I am getting nil when I hit sendEther Function. I don't know what i am missing here.

Please help me out.

import Foundation
import UIKit
import web3swift
class HomeScreen: UIViewController{
    let web3 = Web3.InfuraKovanWeb3()
    let privateKey = "" //Hard coded
    override func viewDidLoad() {
        super.viewDidLoad()
        
        do{
            let formattedKey = privateKey.trimmingCharacters(in: .whitespacesAndNewlines)
            let dataKey = Data.fromHex(formattedKey)!
            let keystore = try EthereumKeystoreV3(privateKey: dataKey, password: "")!
            let keyData = try JSONEncoder().encode(keystore.keystoreParams)
            let address = keystore.addresses!.first!.address
            let wallet = Wallet(address: address, data: keyData, name: "", isHD: false)
            print(wallet.address)
            
            //Calling send ether after getting address importing the account using privatekey
            SendEther(fromAddress: wallet.address, toAddress: "0x3E85A3EC67aDf24a7831019D74F2111a6fEce614")
        }catch{
            print("Something wrong")
        }
    }
    
    
    func SendEther(fromAddress: String, toAddress: String){
        let value: String = "0.000000033" // In Ether
        let walletAddress = EthereumAddress(fromAddress)! // Your wallet address
        let toAdres = EthereumAddress(toAddress)!
        let contract = web3.contract(Web3.Utils.coldWalletABI, at: toAdres, 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("transfer", parameters: [AnyObject](), extraData: Data(), transactionOptions: options)
        do {
            let transaction = try tx?.send()
            print("output", transaction?.transaction.description as Any)
        } catch(let err) {
          print("err", err)
        }
    
    }
}

@hakumai-iida
Copy link
Contributor

Please try this codes.

class HomeScreen: UIViewController{
    let web3 = Web3.InfuraKovanWeb3()
    let privateKey = "" //Hard coded
    
    //@@@ add password(use it 2 times)
    let passKey = "" //Hard coded
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        do{
            let formattedKey = privateKey.trimmingCharacters(in: .whitespacesAndNewlines)
            let dataKey = Data.fromHex(formattedKey)!
            
            // @@@ use [passKey]
            let keystore = try EthereumKeystoreV3(privateKey: dataKey, password: self.passKey/*""*/)!
            
            let keyData = try JSONEncoder().encode(keystore.keystoreParams)
            let address = keystore.addresses!.first!.address
            let wallet = Wallet(address: address, data: keyData, name: "", isHD: false)
            print(wallet.address)
            
            // @@@ attach [keystore] to the manager
            self.web3.addKeystoreManager( KeystoreManager( [keystore] ) )
            
            //Calling send ether after getting address importing the account using privatekey
            SendEther(fromAddress: wallet.address, toAddress: "0x3E85A3EC67aDf24a7831019D74F2111a6fEce614")
        }catch{
            print("Something wrong")
        }
    }
            
    func SendEther(fromAddress: String, toAddress: String){
        let value: String = "0.000000033" // In Ether
        let walletAddress = EthereumAddress(fromAddress)! // Your wallet address
        let toAdres = EthereumAddress(toAddress)!
        let contract = web3.contract(Web3.Utils.coldWalletABI, at: toAdres, 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

        // @@@ use [fallback](see [web3swift/Web3/Web3+Utils.swift])
        let tx = contract.write("fallback"/*"transfer"*/, parameters: [AnyObject](), extraData: Data(), transactionOptions: options)

        do {
            // @@@ write transaction requires password, because it consumes gas
            let transaction = try tx?.send( password: self.passKey )
            
            print("output", transaction?.transaction.description as Any)
        } catch(let err) {
          print("err", err)
        }
    }
}

Comments with @@@ are the fixed ones

  1. use "fallback" function instead of "transfer"
    (The reason why [output] is nil is because [tx] is nil, becaus [Web3.Utils.coldWalletABI] does not have "transfer" function)

  2. keystore requires to be attached the manager

  3. sending ether transaction requires password, because it consume gas

I hope this helps.

@iamjaggusam
Copy link
Author

Hey firstly thank you for reply @hakumai-iida and now I am getting this error

"err nodeError(desc: "Transaction gas price supplied is too low. There is another transaction with same nonce in the queue. Try increasing the gas price or incrementing the nonce.")"

I tried doing like this

options.gasPrice = .manual(21000) instead options.gasPrice = .automatic

even I am getting same error

gained I tried increasing gasprice to options.gasPrice = .manual(28000)

but same error.

@iamjaggusam
Copy link
Author

They yeah bro thanks, its working now I got successful transaction!!

and one more question how to get previous nonce to do next transaction ? like need to increase nonce right so

and special thanks to @skywinder and @hakumai-iida

@hakumai-iida
Copy link
Contributor

hakumai-iida commented Oct 9, 2020

There is another transaction with same nonce in the queue

I think you got this error because you issued a new transaction before the transaction was processed(A nonce is like a transaction processing number).

If the gas price is too low, the transaction will be pending and will not be processed at worst.
Try a larger gas price.

Let's review the terms.

1.GAS is a unit price to exec something on EVM.
ex) "ADD" op-code takes 3 GAS.

2.GAS PRICE is the price of Ethereum for 1 GAS,
and the value considers gwei as the unit price.
(gwei = GIGA wei = 1,000,000,000 wei)

ex) if you apply gas price as 10gwei, "ADD" op-code wastes 3*10gwei.

3.GAS LIMIT is the maximum amount of GAS that you can consume during a transaction,
and the default value is 21,000

ex) if the gas limit is 21,000, "ADD" op-code can be processed 7,000 times.

As a test i tried the codes on kovan with ".automatic", the gas price was "11000000000".
So kovan network recommends 11gwei for the gas price.

Also i tried "9000000000"(9gwei), the transakuction was processed.

I hope this helps.
(I'm sorry for strange English)

@hakumai-iida
Copy link
Contributor

I'm glad your code was working.
And i appolgize my reply was crossed.

how to get previous nonce to do next transaction ? like need to increase nonce right so

I think the blockchain will automatically number it, so I don't think you need to specify it manually.

@Iysbaera Iysbaera added ready for review issue is resolved, a final review is needed before closing and removed question Further information is requested labels Jun 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready for review issue is resolved, a final review is needed before closing
Projects
None yet
Development

No branches or pull requests

5 participants