-
Notifications
You must be signed in to change notification settings - Fork 466
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)
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
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.
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
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?
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))
}
}
}
- 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.
- Set up all the options you want.
- 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.
- 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]
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.
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
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.
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
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
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
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.
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
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\"},]"
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
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).
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
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?
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
I know it wont be easy because its dependencies do not support Cartharge :( but any change?
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
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
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?
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
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?
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 #14: 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".
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
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?
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
For any references feel free to open an issue or ask on stackoverflow