-
Notifications
You must be signed in to change notification settings - Fork 458
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 = Web3Options.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 = Web3Options.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 = Web3Options.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))
}
}
}
For any references feel free to open an issue or ask on stackoverflow