Skip to content
Kristenlike1234 edited this page Oct 10, 2022 · 44 revisions

Question #1: Why does “Use of unresolved identifier” error occurs only for Device Archive Builds?

I've been working with CocoaPods using several dependencies, and I have tested my project and it works perfectly using the simulator, but I'm unable to build my project for a real device with the error: "Use of unresolved identifier". The Pod that's causing the problem is web3swift and there are a number of Classes that the compiler can't find when I try to build for a device, ie.

let contract = web3.contract(contractABI, at EthereumAdress(Rinkeby.address))  

Error: Use of unresolved identifier " EthereumAdress" I have no idea why this problem occurs exclusively when I try to build/archive for a real device. I'm hopeless about this issue as it goes beyond my knowledge, I'd really appreciate your help (the solutions from StackOverflow that I've tried did not work for me)

ANSWER:

This issue has been resolved for the latest versions of web3_swift, since this issue is quite old now

[TODO - Answer @ José Estrella Campaña] source:https://stackoverflow.com/questions/48939394/why-does-use-of-unresolved-identifier-error-occurs-only-for-device-archive-bui

Question #2: Sign any message with the user’s private key and verify the signature on Ethereum

I'm trying to explore Ethereum and creating a app which let user sign message and validate the message. I'm using web3swift framework for this and what I have tried so far is as follows -

let web3Rinkeby = Web3.InfuraRinkebyWeb3()
    let msgStr = "This is my first Ethereum App";
    let data = msgStr.data(using: .utf8)
    let signMsg = web3Rinkeby.wallet.signPersonalMessage(data!, account: address);

    print(signMsg);

but I'm not sure if this is right and how to validate any message as well. Please help.

ANSWER:

let web3Rinkeby = Web3.InfuraRinkebyWeb3()
/// 
    let keystore = try! EthereumKeystoreV3(password: "")
    let keystoreManager = KeystoreManager([keystore!])
    web3Rinkeby.addKeystoreManager(keystoreManager)
    let address = keystoreManager.addresses![0]
///
let msgStr = "This is my first Ethereum App";
let data = msgStr.data(using: .utf8)
let signMsg = web3Rinkeby.wallet.signPersonalMessage(data!, account: address);
print(signMsg);

Here is an example, how to sign transactions in the tests of the project: [TODO - Answer @skywinder] source: https://stackoverflow.com/questions/52455188/sign-any-message-with-the-user-s-private-key-and-verify-the-signature-on-ethereu/52600931#52600931

Question #3 Interacting with custom smart contract using web3swift

I am using the web3swift library and I managed to do some transactions, mostly gets (balanceOf, owner etc). I read the whole readme(documentation), but I am not quite sure, can we use this library to call functions from our custom smart contracts? For example I have store smart contract and I want to call the buy function from it? I saw that we can transfer eth and ERC20 tokens but that is not enough for me. Any help on this?

ANSWER:

Yes, you can call any function on your custom smart contract. Here is an example.

let infura = Web3.InfuraMainnetWeb3()
        // 1
        let contract = infura.contract(someABI, at: ethContractAddress, abiVersion: 2)
        // 2
        var options = TransactionOptions.defaultOptions
        options.from = address
        // 3 
        let transactionIntermediate = contract?.method("accountExists", parameters:[address] as [AnyObject], options: options)
        // 4
        let result = transactionIntermediate!.call(options: options)
        switch result {
        // 5    
        case .success(let res):
            let ans = res["0"] as! Bool
            DispatchQueue.main.async {
                completion(Result.Success(ans))
            }
        case .failure(let error):
            DispatchQueue.main.async {
                completion(Result.Error(error))
            }
        }
    }  
  1. Setting up the contract and ABI. You need contract address for this in Data or String format. let ethContractAddress = EthereumAddress("0xfa28eC7198028438514b49a3CF353BcA5541ce1d")! You can get the ABI of your contract directly from Remix IDE.
  2. Set up all the options you want.
  3. Probably one of the main parts of the answer - here you create the transaction with contract method name and put into it all the parameters this method needs. 4.Here you can either call or send the transaction. call method is for methods with view identifier in solidity, so you won't pay for it and method send() is for the methods of smart contract that should be paid with gas for execution.
  4. Here you just parse the result, returned by the method. You should know data types of the variables you want to obtain from the concrete method in order to parse them correctly.

[TODO - Answer @ Georgy Fesenko]

source: https://stackoverflow.com/questions/51307215/interacting-with-custom-smart-contract-using-web3swift/51965276#51965276

Question #4 How to sign personal message with the personal extension of web3?

I'm making a Dapp with web3swift by matter inc. One method I come across is one of the web3.Personal extension:

public func signPersonalMessage(message: Data, from: 
    web3swift.EthereumAddress, password: String = default) -> 
    Result.Result<Data, web3swift.Web3Error>

I was trying like this:

let web3 = Web3.InfuraMainnetWeb3()
let res = web3.personal.signPersonalMessage(message: msgHash!, 
    from: self.keystore.getAddress()!, password: password)

but what I got was always a Web3ConnectionError. There must not be in the right way I guess. So, any tip to get a usable instance of web3.Personal, and to call the signPersonalMessage method? Thanks :)

By the way, Web3.Utils.signPersonalMessage method is not what I am looking for.

ANSWER:

Please do check that you have a keystore attached to the web3 object. If there is no local keystore than the message is sent to the remote node for signing, but Infura nodes do not contain any private keys.

If a problem persists please open an issue on gitHub repo.

[TODO - Answer @skywinder] source:https://stackoverflow.com/questions/50794445/how-to-sign-personal-message-with-the-personal-extension-of-web3/51115496#51115496

Question #5 How to create raw transaction using web3swift?

I'm working on a project related to blockchain and need to figure out how raw transaction can be possible. I got no reference for this as of now.

I have tried matterinc/web3swift but unable to get exact thing.

ANSWER:

    var options = TransactionOptions.defaultOptions

    options.gasLimit = BigUInt(21000)

    options.from = self.bip32keystore?.addresses?.first!

    let amountDouble = Int((Double(amount) ?? 0.0)*pow(10, 18))

    let am = BigUInt.init(amountDouble)

    options.value = am

    let estimatedGasResult =   self.web3Rinkeby?.contract(Web3.Utils.coldWalletABI, at: toaddress)!.method(options: options)!.estimateGas(options: nil)

    guard case .success(let estimatedGas)? = estimatedGasResult else {return}

    options.gasLimit = estimatedGas

    var intermediateSend = self.web3Rinkeby?.contract(Web3.Utils.coldWalletABI, at: toaddress, abiVersion: 2)!.method(options: options)!

    intermediateSend = self.web3Rinkeby?.contract(Web3.Utils.coldWalletABI, at: toaddress, abiVersion: 2)!.method(options: options)!

    let sendResult = intermediateSend?.send(password: pass)

    switch sendResult {

        case .success(let r)?:

        print("Sucess",r)

      case .failure(let err)?:

      print("Eroor",err)

     case .none:

     print("sendResultBip32",sendResult)

     }     

[TODO - Answer @anton] source: https://stackoverflow.com/questions/48877073/how-to-create-raw-transaction-using-web3swift

Question #6 Compile error when trying to import web3swift

I am trying to import web3swift into one of my Swift files, but get the compiler !Error - No such module 'web3swift'".

The import statements look like this:

import Geth
import web3swift

In my pod file, I have:

pod 'web3swift', :git => 'https://github.com/MercuryProtocol/web3.swift.git'

I have also tried the following fix which hasn't worked:

  • Go to swift Build Settings
  • Search swift Framework Search Paths (case sensitive)
  • Double click on swift <Multiple values>
  • Click the swift +
  • swift Add $(SRCROOT) and set it to recursive

ANSWER:

According to your question - probably you are using another repo. Please, kindly check actual version 0.7.0

Installation web3swift is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'web3swift', git: 'https://github.com/matterinc/web3swift'

Run swift pod install from the command line

It should work fine after that. If you still have problems, feel free to open issue

[TODO - Answer @skywinder] source: https://stackoverflow.com/questions/49859007/compile-error-when-trying-to-import-web3swift/50613486#50613486

Question #7 Sign any message with the user’s private key and verify the signature on Ethereum

I'm trying to explore Ethereum and creating a app which let user sign message and validate the message. I'm using web3swift framework for this and what I have tried so far is as follows

    let web3Rinkeby = Web3.InfuraRinkebyWeb3()
    let msgStr = "This is my first Ethereum App";
    let data = msgStr.data(using: .utf8)
    let signMsg = web3Rinkeby.wallet.signPersonalMessage(data!, account: address);

    print(signMsg);

but I'm not sure if this is right and how to validate any message as well. Please help.

Answer:

Seems, that you didn't specify exact address. Here is an example:

let web3Rinkeby = Web3.InfuraRinkebyWeb3()

/// 
    let keystore = try! EthereumKeystoreV3(password: "")
    let keystoreManager = KeystoreManager([keystore!])
    web3Rinkeby.addKeystoreManager(keystoreManager)
    let address = keystoreManager.addresses![0]
///

let msgStr = "This is my first Ethereum App";
let data = msgStr.data(using: .utf8)
let signMsg = web3Rinkeby.wallet.signPersonalMessage(data!, account: address);

print(signMsg);

Here is an example, how to sign transactions in the tests of the project: https://github.com/matterinc/web3swift/blob/develop/web3swiftTests/web3swift_rinkeby_personalSignature_Tests.swift#L20

Question #8 How to use custom json contract with web3swift

How can I use a JSON contract local, for example something like this:

let jsonString = "[{\"constant\":true,\"inputs\":[],\"name\":\"name\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"approve\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"totalSupply\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_from\",\"type\":\"address\"},{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transferFrom\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"decimals\",\"outputs\":[{\"name\":\"\",\"type\":\"uint8\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"version\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"}],\"name\":\"balanceOf\",\"outputs\":[{\"name\":\"balance\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"symbol\",\"outputs\":[{\"name\":\"\",\"type\":\"string\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_to\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"transfer\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":false,\"inputs\":[{\"name\":\"_spender\",\"type\":\"address\"},{\"name\":\"_value\",\"type\":\"uint256\"},{\"name\":\"_extraData\",\"type\":\"bytes\"}],\"name\":\"approveAndCall\",\"outputs\":[{\"name\":\"success\",\"type\":\"bool\"}],\"payable\":false,\"type\":\"function\"},{\"constant\":true,\"inputs\":[{\"name\":\"_owner\",\"type\":\"address\"},{\"name\":\"_spender\",\"type\":\"address\"}],\"name\":\"allowance\",\"outputs\":[{\"name\":\"remaining\",\"type\":\"uint256\"}],\"payable\":false,\"type\":\"function\"},{\"inputs\":[{\"name\":\"_initialAmount\",\"type\":\"uint256\"},{\"name\":\"_tokenName\",\"type\":\"string\"},{\"name\":\"_decimalUnits\",\"type\":\"uint8\"},{\"name\":\"_tokenSymbol\",\"type\":\"string\"}],\"type\":\"constructor\"},{\"payable\":false,\"type\":\"fallback\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_from\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_to\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Transfer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"name\":\"_owner\",\"type\":\"address\"},{\"indexed\":true,\"name\":\"_spender\",\"type\":\"address\"},{\"indexed\":false,\"name\":\"_value\",\"type\":\"uint256\"}],\"name\":\"Approval\",\"type\":\"event\"},]"

ANSWER:

You can use swift it in let contract = Web3.InfuraMainnetWeb3().contract(<abiString: String>, at: <EthereumAddress?>, abiVersion: <Int>)

Also you should call its needed method: swift let transaction = contract.method(<method: String>, parameters: <[AnyObject]>, extraData: <Data>, options: <Web3Options?>)

Example of preparing transaction function:

func prepareTransaction(parameters: Data, gasLimit: BigUInt = 27500, completion: @escaping (Result<TransactionIntermediate>) -> Void) {
    DispatchQueue.global().async {
        guard let addressFrom: String = <YOURS WALLET ADDRESS> else {return}
        guard let ethAddressFrom = EthereumAddress(addressFrom) else {return}

        let yourContractAddress = "<YOUR CONTRACT ETH ADDRESS>"
        guard let ethContractAddress = EthereumAddress(contractAddress) else {return}

        let web3 = Web3.InfuraMainnetWeb3() //or any test network
        web3.addKeystoreManager(KeystoreManager.defaultManager)

        var options = TransactionOptions.defaultOptions
        options.from = ethAddressFrom
        options.value = 0 // or any other value you want to send

        guard let contract = web3.contract(yourContractJsonABI, at: ethContractAddress, abiVersion: 2) else {return}

        guard let gasPrice = web3.eth.getGasPrice().value else {return}
        options.gasPrice = gasPrice
        options.gasLimit = gasLimit

        guard let transaction = contract.method("<METHOD OF CONTRACT YOU WANT TO CALL>", parameters: [parameters] as [AnyObject], options: options) else {return}
        guard case .success(let estimate) = transaction.estimateGas(options: options) else {return} //here is estimated gas - something like confirming that you made a transaction correctly
        print("estimated cost: \(estimate)")

        DispatchQueue.main.async {
            completion(Result.Success(transaction))
        }
    }
}

[TODO - Answer @Anton Grigorev] source: https://stackoverflow.com/questions/50761595/how-to-use-custom-json-contract-with-web3swift

Question #9 Export mnemonics function in web3swift library

I have a problem interacting with web3swift. I need to show mnemonics to my users when they want it. Is there a way to do it? I did a little research and found out that in trust wallet this could be done just with code:

String(data: decryptedPK, encoding: .utf8)

However, in web3swift even the length in bytes of decryptedPK is different(82 in web3swift, 73 in Trust).

ANSWER:

In web3swift there is no backward conversion from PK to the mnemonic. Also it is theoretically impossible to recover a phrase from a PK.

When the user is creating his keystore you should ask him if he wants to save a passphrase. After seed phrase is converted to some initial entropy the “master key is derived” and the initial entropy is discarded.

The simplest solution is to encrypt the phrase using users pincode and save it in some keystore.

Hope I've answered your question!

[TODO - Answer @ Anton Grigorev] source:https://stackoverflow.com/questions/51963782/export-mnemonics-function-in-web3swift-library

Question #10 Generating 12-word mnemonic from private key

Hey all, I would like to get a mnemonic representation of a private key. Right now, I am getting 24 words by doing the following:

    private func generateKey() -> String {
        let userDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        var ks: EthereumKeystoreV3?
        ks = try! EthereumKeystoreV3(password: "PASSWORD")
        let keydata = try! JSONEncoder().encode(ks!.keystoreParams)
        FileManager.default.createFile(atPath: userDir + "/keystore"+"/key.json", contents: keydata, attributes: nil)
        var mnemonic: String = ""
        do {
            if let pk = try ks?.UNSAFE_getPrivateKeyData(password: "PASSWORD", account: (ks?.addresses?.first)!) {
                print("pk to hex: \(pk.toHexString())")
                let entropy = Data(hex: pk.toHexString())
                mnemonic = Mnemonic.create(entropy: entropy)
                print("pk hex to menmonic: \(mnemonic)")
            }
        } catch {print("Error with getting private key: \(error)")}
        return mnemonic
    }

I am using the Mnemonic helper class found here: https://github.com/essentiaone/HDWallet/blob/develop/HDWalletKit/Mnemonic/Mnemonic.swift

This is the Mnemonic.create function:

    public static func create(entropy: Data, language: WordList = .english) -> String {
        let entropybits = String(entropy.flatMap { ("00000000" + String($0, radix: 2)).suffix(8) })
        let hashBits = String(entropy.sha256().flatMap { ("00000000" + String($0, radix: 2)).suffix(8) })
        let checkSum = String(hashBits.prefix((entropy.count * 8) / 32))
        
        let words = language.words
        let concatenatedBits = entropybits + checkSum
        
        var mnemonic: [String] = []
        for index in 0..<(concatenatedBits.count / 11) {
            let startIndex = concatenatedBits.index(concatenatedBits.startIndex, offsetBy: index * 11)
            let endIndex = concatenatedBits.index(startIndex, offsetBy: 11)
            let wordIndex = Int(strtoul(String(concatenatedBits[startIndex..<endIndex]), nil, 2))
            mnemonic.append(String(words[wordIndex]))
        }
        
        return mnemonic.joined(separator: " ")
    }

A couple questions:

Would the user still be able to derive their private key from this mnemonic? Also, instead of generating a 24-word mnemonic, is it possible to generate a 12-word mnemonic?

ANSWER:

I was able to generate a 12-word mnemonic by changing the following:

        for index in 0..<(concatenatedBits.count / 11) {
            ...

Changed to:

        for index in 0..<(concatenatedBits.count / 22) {
            ...

swift concatenatedBits.count is equal to 264. By dividing by 22, the for loop index now runs from 0 to 11. [TODO - Answer @barrasso ] source: https://github.com/matterinc/web3swift/issues/79

Question #11 please support Carthage

I know it wont be easy because its dependencies do not support Cartharge :( but any change?

ANSWER:

I'll have a look what is the simplest way to make it work. Worst case I'll have to provide a custom repository for libsodium.

[TODO - Answer @shamatar] source: https://github.com/matterinc/web3swift/issues/44

Question #12: How to get all the tokenids I own in a contract address?

ANSWER:

You should use external service for that or ask that for every block in chain.

[TODO - Answer @sunxxg] source: https://github.com/skywinder/web3swift/issues/567

Question #13: How to get my wallet's transaction history list, gas price and token 's detail?

Hi all, I m working on a wallet project, and found some problem that I can't handle with web3swift doc. I can get transID after each transaction, but how to get my wallet's transaction history list? Almost every dapp will show gasprice with high, average and slow speed when prepare to send a transaction. Where can I get the gas price? How to get unit price, symbol name and icon for a token? Btw, where do you guys get monetary exchange rate?I 've read all functions in Web3+Eth.swift, looks like there 's no function that satisfied my needs. And I also confused with :* let block = try! web3.eth.getBlockByNumber(blockNumber, fullTransactions: false) ``let transactionInBlockArr : [TransactionInBlock] = block.transactions let transactionInBlock : TransactionInBlock = transactionInBlockArr.first! *What exactly mean for block.transactions? Is it transaction records for the block?

ANSWER:

You have to cycle through all transactions. Get list of tx hash's. For each Gas price is web3.eth.gasPrice I believe. Exchange rate is your choice, I use kucoin api and update my own database. Token details are called through call transactions.

[TODO - Answer @JJBFC] source: https://github.com/skywinder/web3swift/issues/377

Question #14: How can I get tx hashs with my address and the token address, still not found it.

For web3.eth.gasPrice only return one price, so how can I calculate the high speed price and slow speed price? For token details, I need to show the token unit price before transactions even in my homepage, what should I do. If you can show me the code that would be great! I can get tx hash after finishing a transaction. So how can I get tx's hash list when I import a wallet without doing transations which almost every dapp can do?

ANSWER:

I do the transaction sync on the server. I use filters and cycle through the blocks. I think there is even a GitHub repo if you search. I went the long way though. Here is the docs for web3 python. Learn More Gas Price is just an estimate. Its an arbitrary number. In the beginning there was no high or slow. It was one number and we started just "estimating". There are some calculators out there. You could use python web3 I know they return the prices. Or there's likely another api. And I use the kucoin api for prices. Learn More

[TODO - Answer @JJBFC] source: https://github.com/skywinder/web3swift/issues/377

Question #15: I tried some api from Infura. eth_getTransactionCount should return the count that my wallet made, but only the count. eth_getTransactionByHash should return the whole detail for one tx. I tried to combine this two method to get my history list but still not found how to get every hash for my tx. The getLogs *api looks like can show the whole logs with my wallet address, but I don't really know how to set the "fromBlock" and "toBlock".

ANSWER:

Please see #576 issue. Spoiler: you're too use some external services for both tasks.

[TODO - Answer @JJBFC] source: https://github.com/skywinder/web3swift/issues/377

Question #16: How can I get the hash value in TransactionInBlock?

TransactionInBlock to hash data or string. How can I convert it? That is I have get the transaction block number ,can I get transaction details by using transaction block?

ANSWER:

If the transaction is completed for same blockl

let blockNumber = BigUInt("yourBlockNumber")
let ethAdd = EthereumAddress(yourAddress)
let fullTx = try? wInstance.eth.getBlockByNumber(ethAdd, fullTransactions: true)
print(fullTx, "is transaction detail with Block number if you are the creator of block")
or you can Directly pass your block Number as it is BigUInt

The response You will get :

Optional(web3swift.Block(number: 8329255, hash: 32 bytes, parentHash: 32 bytes, nonce: Optional(8 bytes), sha3Uncles: 32 bytes, logsBloom: Optional(web3swift.EthereumBloomFilter(bytes: 256 bytes)), transactionsRoot: 32 bytes, stateRoot: 32 bytes, receiptsRoot: 32 bytes, miner: Optional(0x0000000000000000000000000000000000000000), difficulty: 54, totalDifficulty: 240834883, extraData: 97 bytes, size: 791, gasLimit: 84000000, gasUsed: 21000, timestamp: 2020-12-23 06:56:29 +0000, transactions: [web3swift.TransactionInBlock.transaction(Transaction Nonce: 12 Gas price: 250000000 Gas limit: 51993 To: 0x30f0bc2b30A36814C1C96aff8Ac221762c739E43 Value: 99987001750000000 Data: v: 28 r: 88414629294957954135223318033644220767680734761987916978592294065679295027734 s: 34433966693919024161425876030718683640418465163901476606695063733879920573501 Intrinsic chainID: nil Infered chainID: nil sender: Optional("0x77c95e25b937b83135e0E5b91fF9E1f957Ffcf01") hash: Optional(32 bytes))], uncles: [])) is transaction detail with Block number if you are the creator of block

it has most of the details

You can get these detail from transactions:

Transaction Nonce: 12
Value: 99987001750000000
To: 0x30f0bc2b30A36814C1C96aff8Ac221762c739E43
sender: Optional("0x77c95e25b937b83135e0E5b91fF9E1f957Ffcf01")
Gas price: 250000000 Gas limit: 51993

[TODO - Answer @jesuasir007] source: https://github.com/skywinder/web3swift/issues/370

Question #17: BEP20 Contract

How to interact with smart contract method for BEP20 token. When I try to access contract for https://api-testnet.bscscan.com/api?`module=contract&action=getabi&address=0xc6E070BCb7823E483164bB41D2297DCd8b1FAb25&apikey=`

guard let contract = web3.contract(contractAbi, at: EthereumAddress("0xc6E070BCb7823E483164bB41D2297DCd8b1FAb25"), abiVersion: 2) else {
return
}

ANSWER:

You have to set a custom endpoint (Networks.Custom(networkID: BigUInt(networkID) and provide a BSC settings there.

P.S. If you are interested in grants: You can make a PR with default parameters for BSC since there is lack of documentation for this method: write documentation on how to do this. |I'll make a bounty for this.

[TODO - Answer @RajKumar7777] source: https:github.com/skywinder/web3swift/issues/361

Question #18: BEP20 Contract

I have done this (Networks.Custom(networkID: BigUInt(networkID)it works as expected. I can able to send the transaction for BSC and BEP20 Tokens successfully. But Interacting with smart contract method is not working for BEP20 Tokens..It supports only ERC Token. Please check on this.

ANSWER:

I'd be more than happy to merge a PR adding this feature, it seems like it would be useful for sure.

[TODO - Answer @RajKumar7777] source: https:github.com/skywinder/web3swift/issues/361

Question #19: Can we use this for Tron (Trx) chain? Suggest one.

ANSWER:

There is no such feature yet. If it's EVM compatible, you can add it as custom network.

[TODO - Answer @akhilccrb] source: https:github.com/skywinder/web3swift/issues/350

Question #20: BEP20

This library work with BEP20 contract?

ANSWER:

Looks like it's the same as Ethereum. You just have to change RPC there is no support binance chain. P.S. Feel free to add missing functionality to the library and I will issue a bounty for this improvement.

[TODO - Answer @DorenBoust] source: https://github.com/skywinder/web3swift/issues/343

Question #21: Dapp Browser

Am integrating a Dapp browser into my ETH wallet following your documentation. I just downloaded your example project web3swiftBrowser and tried to work with.Only https://app.compound.finance this link is connecting and working. I want to connect my wallet to https://uniswap.org. When I open "https://app.compound.finance", demo can auto connect wallet. But when I open "https://app.uniswap.org/#/swap", demo cannot auto connect wallet. Check with alpha wallet app when you open "https://app.uniswap.org/#/swap" it will auto connect wallet.

ANSWER:

This is low level library. This question is not related to this functionality.

[TODO - Answer @RajKumar7777] source: https://github.com/skywinder/web3swift/issues/303

Question #22: Dapps metamask Issue

Hi am integrating Dapp browser to my app following the example provided by you. Am trying to load the link: https://portal.openalexa.io/auth in webview. When I try to connect it shows the error as please provide connection permission window.ethereum.enable is not a function. Please check the attached image.

ANSWER:

Can you check log messages in console please?

[TODO - Answer @RajKumar7777] source: https://github.com/skywinder/web3swift/issues/302

Question #23: How to use Web3.Utils.formatToEthereumUnits() to parse a BigUint?

If I get a token's decimal, and a BigUInt balance, how to format it to a string?

ANSWER:

You can use your own unit using web3Units:

Create Your Unit let myUnit = Web3Units(rawValue: your deciamal Unit)

Fetch balance with web3 instance and your address let balance = try? wInstance.eth.getBalance(address: yourEthAddress)

Convert balance in to string let balanceString = Web3.Utils.formatToEthereumUnits(balance ?? "0", toUnits: myUnit, decimals: 4)

[TODO - Answer @AlleniCode] source: https://github.com/skywinder/web3swift/issues/294

Question #24: Failed to fetch gas estimate

My code:

let keystore = try! EthereumKeystoreV3(privateKey: "MyPrivateKey", password: "MyPassword")!
let name = "New Wallet"
let keyData = try! JSONEncoder().encode(keystore.keystoreParams)
let address = keystore.addresses!.first!.address
let wallet = Wallet(address: address, data: keyData, name: name, isHD: false)

let web3 = Web3.InfuraMainnetWeb3(accessToken: "fdde8c95e4704489aac3c8b014871980")
let contractAdddress = EthereumAddress("0x7a9E457991352F8feFB90AB1ce7488DF7cDa6ed5")
let keystoreManager = KeystoreManager([EthereumKeystoreV3(wallet.data)!])
web3.addKeystoreManager(keystoreManager)

let amount = "1.0"
var options = TransactionOptions.defaultOptions
options.value = Web3.Utils.parseToBigUInt(amount, units: .eth)
options.from = EthereumAddress(wallet.address)
options.gasPrice = . automatic
options.gasLimit = .automatic

let contract = web3.contract("MyABI", at: contractAdddress, abiVersion: 2)
let parameters = [EthereumAddress("0x000000000000000000000000000000000000000E"), Web3.Utils.parseToBigUInt(amount, units: .eth)] as [AnyObject]
let transaction = contract?.write("deposit",
                                               parameters: parameters,
                                               extraData: Data(),
                                               transactionOptions: options)

let result  = try transaction?.send(password: "MyPassword", transactionOptions: options)

In 'Web3+MutatingTransaction.swift' file, line 102, printing description of results: expression produced error: error: /var/folders/z0/89zqhrn56hn16zv5y_h4vhlr0000gn/T/expr5-4bebed..swift:1:102: error: 'BigUInt' is not a member type of 'BigInt' Swift._DebuggerSupport.stringForPrintObject(Swift.UnsafePointer<Swift.Array<PromiseKit.Result<BigInt.BigUInt>>>(bitPattern: 0x110307d20)!.pointee)

ANSWER:

This is typically an issue with your "parameters". If "0x000000000000000000000000000000000000000E" is an address it needs to be EthereumAddress(whateverAddress). You're putting the value of the transaction and the value of the parameters as the same. Most likely you want one or the other? Or you wrote a bad sc. You can always get the msg.value in the contract, so why are you passing the value in?

[TODO - Answer @AlleniCode] source: https://github.com/skywinder/web3swift/issues/292

Question #25: Set ChainID?

So when I call the chainID in python I get 1111 however, when I call chain ID in swift I get 32414... Can I set the chainID? or am I doing something wrong? I'm running a private chain.

ANSWER:

I got it to work by setting the chainID after building the transaction but before sending.

[TODO - Answer @dangell7] source: https://github.com/skywinder/web3swift/issues/280

Question #26: Still Maintained?

I wanted to gather some info on the repo. I use it in a few POCs that are likely making their way to funding. Is this repo maintained? Will this repo continue into 2.0? Do you need help?

ANSWER:

Yes, this repo is supported, although it is not a priority for our team. We would be very grateful for your help in maintaining it. If you're willing to help, we can even reward GitCoin for features and updates to web3swift. You can found more information about this here: https://gitcoin.co/grants/358/web3swift

[TODO - Answer @dangell7] source: https://github.com/skywinder/web3swift/issues/271

Question #27: How to add eth_getLogs?

How to add eth_getLogs?

ANSWER:

Please have a look at this example: https://github.com/matter-labs/web3swift/blob/e36e767eb2de26decb0c157aeef2d023a1175076/Sources/web3swift/Web3/Web3%2BEventParser.swift#L254 If it doesn't help, please provide more details about your case.

[TODO - Answer @PeterCore] source: https://github.com/skywinder/web3swift/issues/270

Question #28: encodeFunctionCall

I'm trying to replicate some code made on Ionic, which uses web3.js. At a certain point, it calls web3.eth.abi.encodeFunctionCall but as far as I've looked throught the library it doesn't contain any similar feature. Here's the snippet I'm trying to mirror:

const transaction = Object.assign({}, config_1.config.basicTransaction);
    transaction.gasLimit = 600000;
    const publicKeyCallData = web3.eth.abi.encodeFunctionCall(config_1.config.contractsAbi.registry.addKey, [publicKey]);
    transaction.data = web3.eth.abi.encodeFunctionCall(config_1.config.contractsAbi.manager.identity, [publicKeyCallData]);
    transaction.to = config_1.config.manager;
    return transaction;

So far I have this, trying to replicate the first encodeFunctionCall:

 let walletAddress = EthereumAddress(walletAddress)! // Your wallet address
        let contractMethod = "addKey" // Contract method you want to write
        let contractABI = """
<JSON with ABI>
"""
        let contractAddress = EthereumAddress("<Address>")!
        let abiVersion = 2 // Contract ABI version
        let parameters : [AnyObject] = [publicKey.toHexString() as AnyObject] // Parameters for contract method
        let extraData: Data = Data() // Extra data for contract method
        let contract = w3.contract(contractABI, at: contractAddress, abiVersion: abiVersion)!
        var options = TransactionOptions.defaultOptions
        options.from = walletAddress
        options.gasPrice = .manual(BigUInt(0))
        options.gasLimit = .manual(BigUInt(600000))
        let tx = contract.method(contractMethod, parameters: parameters, extraData: extraData, transactionOptions: options)
        
if let ethTransaction = try? tx?.assemble(), let hashSignature = ethTransaction.encode(forSignature: true, chainID: nil)?.toHexString(){
            print(hashSignature)
            return hashSignature
        }else {
            throw Error.pubKeyData
        }

I've tried to use assemble and encode the transaction trying to replicate encodeFunctionCall, which then I need to add as parameter to the second method, but this fails with "Failed to fetch gas estimate" and I'm clueless wether this is an issue with how I coded that function or with the Ionic - Swift translation I'm developing. Can you elaborate on how to use web3.eth.abi.encodeFunctionCall on this library or if it's not supported at all?

ANSWER:

Hello. Now you can use this function: https://github.com/matter-labs/web3swift/blob/e36e767eb2de26decb0c157aeef2d023a1175076/Sources/web3swift/EthereumABI/ABIEncoding.swift#L136

[TODO - Answer @rextremotabaresDtt] source: https://github.com/skywinder/web3swift/issues/269

Question #29: Send ETH to contract address

I need to send ETH to contract address..But am getting issue as failed to fetch gas estimate.

My code: let walletAddress = keystoreManager.addresses![0]

let contractABI = Web3Utils.erc20ABI // Contract ABI
let contractAddressVal = EthereumAddress(contractAddress)!
let abiVersion = 2 // Contract ABI version
let contract = web3Main.contract(contractABI, at: contractAddressVal, abiVersion: abiVersion)!
let amount = Web3.Utils.parseToBigUInt(value, units: .eth)
var options = TransactionOptions.defaultOptions
options.value = amount
options.from = walletAddress
options.gasPrice = .manual(BigUInt("10000000000"))
options.gasLimit = .manual(BigUInt("70000"))

let tx = contract.write()!
  
do {
    let transaction = try tx.send(password: "", transactionOptions: options)
    print("output", transaction)
} catch(let err) {
  print("err", err)
}

ANSWER:

Hi Please check below code

Convert receiver address into Ethereum string

            `let toaddress = EthereumAddress(self.receiverAddressString ?? "")`

Create web3 options

            `var sendTransactionIntermediateOptions = Web3Options.defaultOptions()`

Convert amount into BIGINT

            `let amountDouble = BigInt((Double(sendigTokenCount) ?? 1.0)*pow(10, 18))`
            `print("Total amount in double value : ", amountDouble)`

Convert amount in BigUInt

            `let amount = BigUInt.init(amountDouble)`

get gas price let estimateGasPrice = try wInstance.eth.getGasPrice() guard let contractString = self.contractAddressString else { print("Unable to get contract address") return }

Create your contract address as EthereumAddress

           `let contractAddress = EthereumAddress(contractString)
            guard let eGasReult = self.estimatedGasResult else {
                print("Unable to find gas")
                return
            }`

Get nonce

            print("estimated gas : ", eGasReult)
            let fee = estimateGasPrice * eGasReult
            print("Is the Transaction fees ", fee)
             adding
             - sender address
             - Gas Result
             - Gas price
             - amount
             

            `sendTransactionIntermediateOptions.from = senderEthAddress`
            `sendTransactionIntermediateOptions.gasLimit = eGasReult`
            `sendTransactionIntermediateOptions.gasPrice = estimateGasPrice`

Strat your Transaction with contract

            `var tokenTransactionIntermediate: TransactionIntermediate!`

tokenTransactionIntermediate = try wInstance.contract(Web3.Utils.yourABIString, at: contractAddress).method("transfer", args: toaddress, amount, options: sendTransactionIntermediateOptions)

[TODO - Answer @rachkumar] source: https://github.com/skywinder/web3swift/issues/259

Question #30: Please tell me where the password is obtained?

Please tell me where the password is obtained? Send Transaction Write

let password = "web3swift"
let result = try! transaction.send(password: password)

ANSWER:

It's a hard coded value.

[TODO - Answer @suusofttruongnv] source: https://github.com/skywinder/web3swift/issues/255

Question #31: Send ERC-20 Token error

let value: String = amountStr
let walletAddress = EthereumAddress(wallet.address)! // Your wallet address
let toAddress = EthereumAddress(toAddressStr)!
let erc20ContractAddress = EthereumAddress("0xaB8Ad2d7f39A54960Be8b71e01276a9E897833eE", ignoreChecksum:true)!
let contract = self.web3.contract(Web3.Utils.erc20ABI, at: erc20ContractAddress, 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 method = "transfer"
let tx = contract.write(
method,
parameters: [toAddress, amount] as [AnyObject],
extraData: Data(),
transactionOptions: options)!
let res = try tx.send(password: password, transactionOptions: options)
            print(res.hash)
back:
processingError(desc: "Failed to fetch gas estimate")

I also get an error when I try to send the token to a different address

let web3 = getWeb3()
    let walletAddress = EthereumAddress(wallet_token.address)! // Your wallet address
    let toAddress = EthereumAddress(toAddressString)!
    let erc20ContractAddress = EthereumAddress(token.address)!
    let contract = web3.contract( Web3.Utils.erc20ABI, at: erc20ContractAddress, abiVersion: 2)! 
    let amount = Web3.Utils.parseToBigUInt(value, decimals: token.decimals)
    var options = TransactionOptions.defaultOptions
    options.value = amount
    options.from = walletAddress
    options.gasPrice = .automatic
    options.gasLimit = .automatic
    let method = "transfer"
    let tx = contract.write(
        method,
        parameters: [toAddress, amount] as [AnyObject],
        extraData: Data(),
        transactionOptions: options)!
    
    do {
        let result = try tx.send(password: "web3swift")
        print("\(TAG) result")
        return result
    } catch let error {
        print("\(TAG) error" + error.localizedDescription)
        throw error
    }

It appears an error like this:

PromiseKit: warning: wait() called on main thread! error The operation couldn’t be completed. (web3swift.Web3Error error 2.)

Please help me, what do I have to do to fix it, and send my ERC token smoothly?

ANSWER:

Change: options.value = Web3.Utils.parseToBigUInt("0", decimals: token.decimals)

[TODO - Answer @CYC666] source: https://github.com/skywinder/web3swift/issues/251

Question #32: How to get public key After generating a wallet?

How to get public key After generating a wallet?

ANSWER:

If you saved your data in KeystoreManager, try this

let privateKey = try! keystoreManager.UNSAFE_getPrivateKeyData(password: password, account: ethereumAddress)
let publicKey = Web3.Utils.privateToPublic(privateKey, compressed: false)!

[TODO - Answer @amirhossein7] source: https://github.com/skywinder/web3swift/issues/233

Question #33: How to know when another person send eth for me?

I try to send ETH in Ropsten. I connect to WebSockets follow document and I don't know how to get amount ETH another person send for me? Can you help me? I need example.

ANSWER:

Please, have a look at documentation in this section: https://github.com/matter-labs/web3swift/blob/master/Documentation/Usage.md#create-a-new-subscription-over-particular-events

And here is test, where you can see example in action: https://github.com/matter-labs/web3swift/blob/develop/Tests/web3swiftTests/web3swift_Websockets_Tests.swift#L72-L94

[TODO - Answer @tuanYasuo] source: https://github.com/skywinder/web3swift/issues/215

Question #34: Encrypt Decrypt using generated EC Key Pair

Is there any function here to encrypt and decrypt using the generated key pair using this library?

ANSWER:

Please, have a look for tests for examples: https://github.com/matter-labs/web3swift/blob/df45360ac4c9741cf43a0828bdbb296d374acf0f/Carthage/Checkouts/CryptoSwift/Tests/CryptoSwiftTests/ExtensionsTest.swift#L74

[TODO - Answer @tentenponce] source: https://github.com/skywinder/web3swift/issues/211

Question #35: Where is "web3swiftExample"?

I want to run "example" app, but I faild to move "web3swiftExample" described in "https://github.com/matter-labs/web3swift#example-project" If it is not possible, can I get any simple example of web3swift.

ANSWER:

You can run it from Exmaple folder.

[TODO - Answer @surida] source: https://github.com/skywinder/web3swift/issues/194

Question #36: Is there any function to calculate minimum amount needed to perform ethereum transaction?

I wanted to know is there any function in web3swift to validate minimum amount required to make transaction?

ANSWER:

Think you need estimateGas function. It estimates a minimal amount of gas required to run a transaction. To do it the Ethereum node tries to run it and counts how much gas it consumes for computations. Setting the transaction gas limit lower than the estimate will most likely result in a failing transaction. Usage example:

let web3 = Web3.InfuraMainnetWeb3()
let sendToAddress = EthereumAddress("recepient_address")
let keystore = try! EthereumKeystoreV3(password: "")
let keystoreManager = KeystoreManager([tempKeystore!])
web3.addKeystoreManager(keystoreManager)
let contract = web3.contract(Web3.Utils.coldWalletABI, at: sendToAddress, abiVersion: 2)
guard let writeTX = contract?.write("fallback") else {return} // you can use any other tx method
writeTX.transactionOptions.from = tempKeystore!.addresses?.first // its your address
writeTX.transactionOptions.value = BigUInt("1.0", .eth) // value in eth
let estimate = try writeTX.estimateGasPromise().wait()
print(estimate) // here you'll get gas estimation

[TODO - Answer @DiwakarThapa] source: https://github.com/skywinder/web3swift/issues/134

Question #37: Generating 12-word mnemonic from private key

I would like to get a mnemonic representation of a private key. Right now, I am getting 24 words by doing the following:

 private func generateKey() -> String {
        let userDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
        var ks: EthereumKeystoreV3?
        ks = try! EthereumKeystoreV3(password: "PASSWORD")
        let keydata = try! JSONEncoder().encode(ks!.keystoreParams)
        FileManager.default.createFile(atPath: userDir + "/keystore"+"/key.json", contents: keydata, attributes: nil)
        var mnemonic: String = ""
        do {
            if let pk = try ks?.UNSAFE_getPrivateKeyData(password: "PASSWORD", account: (ks?.addresses?.first)!) {
                print("pk to hex: \(pk.toHexString())")
                let entropy = Data(hex: pk.toHexString())
                mnemonic = Mnemonic.create(entropy: entropy)
                print("pk hex to menmonic: \(mnemonic)")
            }
        } catch {print("Error with getting private key: \(error)")}
        return mnemonic
    }

I am using the Mnemonic helper class found here: https://github.com/essentiaone/HDWallet/blob/develop/HDWalletKit/Mnemonic/Mnemonic.swift

This is the Mnemonic.create function: public static func create(entropy: Data, language: WordList = .english) -> String { let entropybits = String(entropy.flatMap { ("00000000" + String(, radix: 2)).suffix(8) }) let hashBits = String(entropy.sha256().flatMap { ("00000000" + String(, radix: 2)).suffix(8) }) let checkSum = String(hashBits.prefix((entropy.count * 8) / 32))

    let words = language.words
    let concatenatedBits = entropybits + checkSum
    
    var mnemonic: [String] = []
    for index in 0..<(concatenatedBits.count / 11) {
        let startIndex = concatenatedBits.index(concatenatedBits.startIndex, offsetBy: index * 11)
        let endIndex = concatenatedBits.index(startIndex, offsetBy: 11)
        let wordIndex = Int(strtoul(String(concatenatedBits[startIndex..<endIndex]), nil, 2))
        mnemonic.append(String(words[wordIndex]))
    }
    
    return mnemonic.joined(separator: " ")
}

A couple questions:

Would the user still be able to derive their private key from this mnemonic? Also, instead of generating a 24-word mnemonic, is it possible to generate a 12-word mnemonic?

ANSWER:

I was able to generate a 12-word mnemonic by changing the following: ```

for index in 0..<(concatenatedBits.count / 11) {
            ...

Changed to:

 for index in 0..<(concatenatedBits.count / 22) {
            ...

[TODO - Answer @barrasso] source: https://github.com/skywinder/web3swift/issues/79

Question #38: How to signed Transaction

Facing problem how to sign Transaction and get token then sent to server.

ANSWER:

// transactionSign func transactionSign(nonce :String,gasPrice :String,gasLimit :String,toAddress :String,value :String,privateKeyData :Data,chainID :String,templateData :Data) -> Data {

var transaction = EthereumTransaction(nonce: BigUInt(nonce)!,
                                          gasPrice: BigUInt(gasPrice)!,
                                          gasLimit: BigUInt(gasLimit)!,
                                          to: EthereumAddress(toAddress)!,
                                          value: BigUInt(value)!,
                                          data: templateData,
                                          v: BigUInt(0),
                                          r: BigUInt(0),
                                          s: BigUInt(0))
    transaction.UNSAFE_setChainID(BigUInt(chainID)!)
    print(transaction)
    try! Web3Signer.EIP155Signer.sign(transaction: &transaction, privateKey: privateKeyData, useExtraEntropy: false)
    print(transaction)
    let encoded:Data? = transaction.encode()
    return encoded!
}

[TODO - Answer @kirti301290] source: https://github.com/skywinder/web3swift/issues/61

Question #39: How to custom nonce?

Create two transaction in a short time,will cause replacement error due to same nonce,so how to create custom nonce transcation?

ANSWER:

Right now you have to assemble a transactions manually or by help of transaction intermediate and then set the nonce.

 guard case .success(let tx) = transactionIntermediate.assemble(options: someOptions, onBlock: "pending") // may fail, that would mean that gas estimation failed, for example
  var txCopy = tx
  txCopy.nonce = BigUInt(1337)
  let result = web3.eth.sendTransaction(txCopy, options: someOptions, password: "web3swift")

[TODO - Answer @cctanfujun] source: https://github.com/skywinder/web3swift/issues/37

Question #40: New account

Can have an example of creating a new account?

ANSWER:

Here is "How to create account" example in readme: https://github.com/matterinc/web3swift#create-account

Here's an example for a password protected keystore called EthereumKeystoreV3 ... you'll need to sort out the optionals and preferably remove the fatalError calls.

//First you need a `KeystoreManager` instance:
guard let userDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first,
    let keystoreManager = KeystoreManager.managerForPath(userDirectory + "/keystore")
else {
    fatalError("Couldn't create a KeystoreManager.")
}

//Next you create the a new Keystore:

let newKeystore = try? EthereumKeystoreV3(password: "YOUR_PASSWORD")

// Then you save the created keystore to the file system:

let newKeystoreJSON = try? JSONEncoder().encode(newKeystore.keystoreParams)
FileManager.default.createFile(atPath: "\(keystoreManager.path)/keystore.json", contents: newKeystoreJSON, attributes: nil)

// Later you can retreive it:

if let address = keystoreManager.addresses?.first,
let retrievedKeystore = keystoreManager.walletForAddress(address) as? EthereumKeystoreV3 {
    return retrievedKeystore
}

[TODO - Answer @soulCorw] source: https://github.com/skywinder/web3swift/issues/29

Question #41: Is there any functions to get pending transactions list?

I want to check the transactions is in pending,is there any functions to get pending transactions list likes python supportted https://web3py.readthedocs.io/en/stable/web3.txpool.html or is there any way to check the tx_hash is in pending?

ANSWER:

Monitoring of transaction satus could be useful feature. Probably we can do a convenience method like:

enum TxStatus {
  case Completed
  case Rejected
  case Pending
}
func checkTransacion(timeout : Int , repeat_interval :Int) -> (TxStatus) {
    ...
}

[TODO - Answer @tiantianyuan] source: https://github.com/skywinder/web3swift/issues/28

Question #42: PromiseKit example

Could you please provide an example of how to use the async functions. For example web3.eth.getGasPricePromise().then { ???? }

Whatever I do with what comes from autocomplete gives a build-time error.

ANSWER:

There is a good example in code

self.assemblePromise(options: options, onBlock: onBlock).then(on: queue) { transaction throws -> Promise<TransactionSendingResult> in
            guard let mergedOptions = Web3Options.merge(self.options, with: options) else {
                throw Web3Error.inputError(desc: "Provided options are invalid")
            }
            var cleanedOptions = Web3Options()
            cleanedOptions.from = mergedOptions.from
            cleanedOptions.to = mergedOptions.to
            return self.web3.eth.sendTransactionPromise(transaction, options: cleanedOptions, password: password)
        }

If you call then - your internal closure should return a Promise If you call map - you can return a normal value that will be wrapped into the Promise for further chaining

[TODO - Answer @matijakregar] source: https://github.com/skywinder/web3swift/issues/23

Question #43: When can I use ERC721?

When can I use ERC721?

ANSWER:

ERC20 support is already implemented. we are currently working on support of erc721 as well.

[TODO - Answer @coderybxuu] source: https://github.com/skywinder/web3swift/issues/20

Question #44: How to listen the contract event?

I don't know where the event listener.

ANSWER:

Me(@skywinder) and Alex (@shamatar) as main maintainers are moving our development to the new repo ➡️ https://github.com/matterinc/web3swift

[TODO - Answer @BlueFlicker] source: https://github.com/skywinder/web3swift/issues/18

Question #45: How to import wallet by keystore and password?

I want to import wallet by keystore and password. what should I do?

ANSWER:

If you want to export the private key - just use the public func UNSAFE_getPrivateKeyData(password: String, account: EthereumAddress) throws -> Data Otherwise if you follow the normal workflow for sending ETH, tokens or interacting with a smart-contract you can use an encrypted keystore and only supply a password to decrypt it when sending a transaction.

[TODO - Answer @chenshuai0710] source: https://github.com/skywinder/web3swift/issues/9

Question #46: Calling a payable function with parameters

I'm struggling to find an example to use a payable function with parameters.

let's say i've an function in my Smart Contract:

 function doSomething(address[] _adresses, address[] _groups, uint[] _percentages)
        public
        payable
        returns(address) {

How do i call this SC and send ethers to it & pass parameters and get the return value?

ANSWER:

Please, check our new documentation, here is well explained how to use library: https://github.com/matterinc/web3swift/blob/develop/Documentation/Usage.md

[TODO - Answer @ungaro] source: https://github.com/skywinder/web3swift/issues/8

Question #47: How to decode input data from transaction?

I have fetched transactions list from etherscan.io API. I need to decode input data to get the value and the token receiver address for ERC20Token transaction.

for example, the following input data 0xa9059cbb000000000000000000000000066a46470fd976e89303f501b704f73016da101e0000000000000000000000000000000000000000000000000de0b6b3a7640000

ANSWER:

Please refer to the web3swift_contractV2_Tests in the source code, it has two examples of how to decode the input data. Those examples are for ERC20 input data actually.

[TODO - Answer @runryan] source: https://github.com/skywinder/web3swift/issues/6

Question #48: Calling a payable function with parameters?

I'm struggling to find an example to use a payable function with parameters.

let's say i've an function in my Smart Contract:

 function doSomething(address[] _adresses, address[] _groups, uint[] _percentages)
        public
        payable
        returns(address) {

How do i call this SC and send ethers to it & pass parameters and get the return value?

ANSWER:

First of all you should understand that if the function is mutating (like one above) you are not guaranteed that a return value will in fact be the same when you check for it and when transaction executes.

how to get a return value: encode the parameters into the “TransactionIntermediate”. Please check the various examples in tests use the “call” method on this intermediate and supply required options (Web3Options struct) into the call. One of the field in options is “value” - it’s an amount of Wei (1 ETH = 10^18 wei) attached to the transaction upon execution you will get returned parameters to send a transaction make an intermediate use the “send” method and supply the options I recommend you to go through the tests of web3swift to check the examples.

[TODO - Answer @ungaro] source: https://github.com/skywinder/web3swift/issues/2

Question #49: How can we deploy smart contract using webe3swift?

In web3java, i can deploy a smart contract by following the methods

Create .bin and .abi files from solidity file using solcjs library. Create java file using .abi and .bin files. Java file contains deploy() method to deploy a smart contract on Ethereum network. Now in web3swift i don't see any method to deploy smart contract. I know there will be any other way of deploying but i don't know. can anyone please help in this regard?

ANSWER:

You can try using one of the following options. There is definitely an improvement for that API coming but I cannot tell when exactly that will be done.

Options:

  1. Create the whole transaction
`// Some smart contract instance`
`let contract = web3Instance.contract(...)`
``// A transaction ready to be signed and executed``
``let writeTransaction = contract.prepareDeploy(bytecode: yourScBytecode)``
``...``
  1. Create only encoded data - how a transaction object will be created is up to you.
// It throws only if you give two functions with exactly the same name and input but different output.
// That's an invalid overloading of a function. We're safe here thus using `try!`.
let contract = try! EthereumContract(abi: [])`
// There is also an option to pass constructor and input arguments
let encodedData = contract.deploy(smartContractBytecode)
...

[TODO - Answer @ShoaibKakal] source: https://github.com/skywinder/web3swift/issues/612

Question #50: SPM Package Not Working With 3.0.0 Version

I created a project from scratch and tried to use SPM 3.0.0 version. I just tried a simple implementation: let walletAddress = try? BIP32Keystore(mnemonics: "" , prefixPath: "") I am getting this error: Cannot find 'BIP32Keystore' in scope

I can't access anything inside the library.

ANSWER:

You have to add import Core alongside to import Web3Swift to your sources to make it works.

[TODO - Answer @rocxteady] source: https://github.com/skywinder/web3swift/issues/629

Question #51: How to read internal transaction?

I write a transaction with a smart contract,but the result what I want to retrieve is inside Internal Transactions. so How can I get the internal transactions? If I can use ‘eth_call’ method to get a tx information? And how can I make it in this repo? Thanks for answering.

ANSWER:

As long as you have the TransactionHash you can use web3.eth.getTransactionDetails() to retrieve the transaction itself. getTransactionDetails returns a structure with a meber called .transaction which is the decoded transaction. From there you have access to all the parameters and data that was encoded within the transaction. Note that if the transaction was a contract call, you will need to do some further decoding of the data field to get at that data, as that will be contract specific.

[TODO - Answer @KittenYang] source: https://github.com/skywinder/web3swift/issues/597

Question #52: Deprecated description for Send ERC-20 Token

https://github.com/skywinder/web3swift#send-erc-20-token

When send ERC-20 Token not needed line - "options.value = amount" because method "transfer" in erc20ABI is not "payable"

ANSWER:

Generally speaking ALL transactions need a value, even if not payable. So if the transaction has no value, set value to 0. The requirement for it to be set in options is there because value is a required field for a transaction on the chain.

[TODO - Answer @6od9i] source: https://github.com/skywinder/web3swift/issues/568

Question #53: Best way to test smart contracts using this library

I'm new in ethereum development and I found out that there is only one way to effectively test smart contracts is using 'truffle'. Truffle requires javascript knowledge and I don't really want to learn javascript.

Can I use this library to interact with truffle (somehow) or directly with 'ganache' to effectively test smart contracts and work with them in production not using javascript? I need to know should I really learn javascript to become professional smart contract developer or not.

Thanks!

ANSWER:

While you can test contracts using web3Swift, you'll likely find it easier and more efficient to use something like Remix for the contract development side, then transition to something like Web3Swift when you get to the application side of things.

[TODO - Answer @xbladesub] source: https://github.com/skywinder/web3swift/issues/538

Question #54: Creating a new wallet is too slow

macos Version :12.3 xcode Version : 13.3 cocospod Version:1.11.3 Installing BigInt (5.2.0) Installing CryptoSwift (1.4.3) Installing PromiseKit (6.15.3) Installing Starscream (4.0.4) Installing secp256k1.c (0.1.2) Installing web3swift (2.6.0) image Creating a new wallet is too slow, 5 seconds to print information image

image

Get private key is too slow,5 seconds to print information The speed of creating wallet in web3swift version 2.3.0 is normal

ANSWER:

I can confirm that the issue lies between debug and release builds. I created a simple test app to create a private key.

Debug Build/Run: 7.790989995002747 Release Build/Run: 0.10214793682098389

The issue is also exclusively when building via SPM, as SPM builds everything from source, using the app's build settings. XCode projects include the libraries as frameworks, which are built separately in release mode, so even a debug app, does not see the same performance hit.

This not really an issue as it affects debugging only, and there is nothing we can really do about it. This is a known issue with CryptoSwift, you can follow the link posted in https://github.com/skywinder/web3swift/issues/535 if you want to know more.

This issue should probably be closed at this point.

[TODO - Answer @xhzth70911] source: https://github.com/skywinder/web3swift/issues/532

Question #55: nodeError(desc: "transaction underpriced")

I make the transaction from json:

["object": {
    data = 0x7ff36ab500000000000000000000000000000000000000000000000000034039a4aab0bf0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000dcafb08f535d986c72ac254fe0bb225ccc0f77fc00000000000000000000000000000000000000000000000000000000c44d75b900000000000000000000000000000000000000000000000000000000000000030000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12700000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063000000000000000000000000831753dd7087cac61ab5644b308642cc1c33dc13;
    from = 0xdcafb08f535d986c72ac254fe0bb225ccc0f77fc;
    gas = 0x50315;
    to = 0xa5e0829caced8ffdd4de3c43696c57f7d7a678ff;
    value = 0x16345785d8a0000;
}, "name": signTransaction, "id": 1646704788011]

` TransactionOptions(to: Optional(web3swift.EthereumAddress(_address: "0xa5e0829caced8ffdd4de3c43696c57f7d7a678ff", type: web3swift.EthereumAddress.AddressType.normal)), from: Optional(web3swift.EthereumAddress(_address: "0xdcafb08f535d986c72ac254fe0bb225ccc0f77fc", type: web3swift.EthereumAddress.AddressType.normal)), gasLimit: Optional(web3swift.TransactionOptions.GasLimitPolicy.manual(328469)), gasPrice: Optional(web3swift.TransactionOptions.GasPricePolicy.manual(1845490560)), value: Optional(100000000000000000), nonce: Optional(web3swift.TransactionOptions.NoncePolicy.latest), callOnBlock: Optional(web3swift.TransactionOptions.CallingBlockPolicy.pending))

Transaction Nonce: 68 Gas price: 1845490560 Gas limit: 328469 To: 0xa5E0829CaCEd8fFDD4De3c43696c57F7D7A678ff Value: 100000000000000000 Data: 0x7ff36ab500000000000000000000000000000000000000000000000000034039a4aab0bf0000000000000000000000000000000000000000000000000000000000000080000000000000000000000000dcafb08f535d986c72ac254fe0bb225ccc0f77fc00000000000000000000000000000000000000000000000000000000c44d75b900000000000000000000000000000000000000000000000000000000000000030000000000000000000000000d500b1d8e8ef31e21c99d1db9a6444d3adf12700000000000000000000000008f3cf7ad23cd3cadbd9735aff958023239c6a063000000000000000000000000831753dd7087cac61ab5644b308642cc1c33dc13 v: 1 r: 0 s: 0 Intrinsic chainID: Optional(137) Infered chainID: Optional(1) sender: nil `

// Polygon Mainnet
let web333 = web3(provider: Web3HttpProvider(URL(string: "https://polygon-mainnet.g.alchemy.com/v2/X7YSnkDc6on7md1Tabt2ECssPYtJ4wCm")!, network: Networks.Custom(networkID: BigUInt(137)))!)

let options = TransactionOptions.fromJSON(dic)
var transaction = EthereumTransaction.fromJSON(dic)
let pendingNonce = try web333.eth.getTransactionCount(address: walletAdd, onBlock: "pending")
let latestNonce = try web333.eth.getTransactionCount(address: walletAdd, onBlock: "latest")
let selectedNonce = max(pendingNonce, latestNonce)
transaction.nonce = selectedNonce
transaction.UNSAFE_setChainID(BigUInt(137))
let result = try web333.eth.sendTransaction(transaction, transactionOptions: options, password: password)

ANSWER:

A number of changes have been made around Transactions since this was posted. Unfortunately the fromJSON functions were prematurely removed from the API along the way. (Though I've now restored them in https://github.com/skywinder/web3swift/pull/558)

Can you try testing now using https://github.com/skywinder/web3swift/pull/558 as your base, to see if the issue has been resolved? Barring any issues, the PR should be merged in early next week with the next 2.x release.

If you use SPM you can repoint it to use the PR temporarily for testing: .package(url: "https://github.com/skywinder/web3swift.git", branch: "pull/558/head")

[TODO - Answer @AlleniCode] source: https://github.com/skywinder/web3swift/issues/476

Question #56: Generics.swift:17:28: 'exported: true' has no effect in '_specialize' attribute

I have facing this issues when running ,this issues found in crypto swift frame work please check and fix it pod 'web3swift', :git => 'https://github.com/lvyikai/web3swift'

I have used but it's fixed ,it's show some bugs Cannot find 'keystoreManager' in scope let pkData = try! keystoreManager.UNSAFE_getPrivateKeyData(password: pw, account: ethereumAddress).toHexString() keystoreManager not found

ANSWER:

update your Podfile pod 'web3swift', :git => 'https://github.com/skywinder/web3swift.git' then pod update This is a good solution and will work when you use Podfile in a project whose dependencies are managed by CocoaPods

Here is the same issue but in a different place. When developing a framework and using *.podspec there is no option to specify the source URL (correct me if I'm wrong) making it impossible to use web3swift as a dependency because it fails on pod lib lint. https://github.com/CocoaPods/CocoaPods/issues/4921#issuecomment-801286927

Note that there is an Unreleased version of the web3swift in CocoaPods repository that will solve this issue: https://cocoapods.org/pods/web3swift#changelog image

Here is my podspec:

Pod::Spec.new do |s|
    s.name             = 'my-framework'
    s.version          = '0.1.0'
    s.summary          = 'My first framework'
    s.description      = <<-DESC
    My first framework: the main goal is to learn.
    DESC
    
    s.homepage         = 'https://github.com/JeneaVn/my-framework'
    s.license          = { :type => 'MIT', :file => 'LICENSE' }
    s.author           = { 'Evghenii Vranceanu (JeneaVn)' => 'jeneavranceanu@gmail.com' }
    s.source           = { :git => 'https://github.com/JeneaVn/my-framework.git', :tag => s.version.to_s }
    s.ios.deployment_target = '11.0'
    s.swift_version = '5.0'
    s.source_files = 'my-framework/Classes/**/*'
    
    s.dependency 'Alamofire', '~> 5.4'
    s.dependency 'web3swift', '~> 2.3.0'
    
end

Here is the output of pod lib lint --no-clean:

$ pod lib lint --no-clean

 -> my-framework (0.1.0)
    - ERROR | [iOS] xcodebuild: Returned an unsuccessful exit code. You can use `--verbose` for more information.
    - NOTE  | xcodebuild:  note: Using new build system
    - NOTE  | xcodebuild:  note: Building targets in parallel
    - NOTE  | xcodebuild:  note: Using codesigning identity override: -
    - NOTE  | xcodebuild:  note: Build preparation complete
    - NOTE  | [iOS] xcodebuild:  note: Planning build
    - NOTE  | [iOS] xcodebuild:  note: Analyzing workspace
    - NOTE  | [iOS] xcodebuild:  note: Constructing build description
    - NOTE  | [iOS] xcodebuild:  Pods.xcodeproj: warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.5.99. (in target 'Starscream' from project 'Pods')
    - NOTE  | [iOS] xcodebuild:  Pods.xcodeproj: warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.5.99. (in target 'secp256k1.c' from project 'Pods')
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/Generics.swift:17:28: error: 'exported: true' has no effect in '_specialize' attribute
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/Generics.swift:35:28: error: 'exported: true' has no effect in '_specialize' attribute
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/Generics.swift:36:28: error: 'exported: true' has no effect in '_specialize' attribute
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/Generics.swift:37:28: error: 'exported: true' has no effect in '_specialize' attribute
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/Generics.swift:38:28: error: 'exported: true' has no effect in '_specialize' attribute
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/Generics.swift:39:28: error: 'exported: true' has no effect in '_specialize' attribute
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/Generics.swift:40:28: error: 'exported: true' has no effect in '_specialize' attribute
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/UInt16+Extension.swift:18:32: error: 'exported: true' has no effect in '_specialize' attribute
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/UInt16+Extension.swift:23:32: error: 'exported: true' has no effect in '_specialize' attribute
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/UInt32+Extension.swift:27:32: error: 'exported: true' has no effect in '_specialize' attribute
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/UInt32+Extension.swift:32:32: error: 'exported: true' has no effect in '_specialize' attribute
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/UInt64+Extension.swift:18:32: error: 'exported: true' has no effect in '_specialize' attribute
    - ERROR | [iOS] xcodebuild:  CryptoSwift/Sources/CryptoSwift/UInt64+Extension.swift:23:32: error: 'exported: true' has no effect in '_specialize' attribute
    - NOTE  | [iOS] xcodebuild:  warning: Skipping code signing because the target does not have an Info.plist file and one is not being generated automatically. (in target 'App' from project 'App')
    - NOTE  | [iOS] xcodebuild:  Pods.xcodeproj: warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.5.99. (in target 'PromiseKit' from project 'Pods')
    - NOTE  | [iOS] xcodebuild:  Pods.xcodeproj: warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.5.99. (in target 'CryptoSwift' from project 'Pods')
    - NOTE  | [iOS] xcodebuild:  Pods.xcodeproj: warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.5.99. (in target 'BigInt' from project 'Pods')

Pods workspace available at `/var/folders/3z/855j620160l9bh2l3tfq547r0000gn/T/CocoaPods-Lint-20210908-87862-1tgfi88-my-framework/App.xcworkspace` for inspection.

[!] my-framework did not pass validation, due to 14 errors.

[TODO - Answer @jesuasir007] source: https://github.com/skywinder/web3swift/issues/363

Clone this wiki locally