Ethereum wallet with web3swift

SHIVANG PANDEY
Coinmonks
Published in
4 min readMay 16, 2018

--

This is the crucial time for Blockchain and as the internet is filling with this new technology. In Nowadays Ethereum Blockchain is growing faster than other Blockchain so many already platform(e.g.Web,desktop, and Android) implemented on Etherium blockchain with web3j or web3.js but when we found on iOS we got very complected implementation not like web3.js so I found excellent lib web3swift on GitHub.

● This is not official from Etherium so dont’t be confuse.

Prerequisites

Install CocoaPods using Homebrew by entering the following in a terminal:

$ brew install CocoaPods

Library Installation

First, create an Xcode iOS app project called Web3SwiftExample in your home directory. To integrate web3swift into your Xcode project using CocoaPods, first create a podfile.

$ cd ~/Web3Swift
$ pod init

Open the newly created Podfile with a text editor, and paste in the following in the pods section:

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

Your podfile should look like this:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
target 'Web3Swift' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for Web3Swift
pod 'web3swift', git: 'https://github.com/BANKEX/web3swift.git'
end

Then, run the following command:

$ pod update
$ pod install

Open the newly created .xcworkspacefile

Now story begain,

Generate new account:-

This lib provide us two types of Keystores.

  1. EthereumKeystoreV3 :-
do {
let keystore = try EthereumKeystoreV3.init(password: “Your Password”)
} catch {
print(error.localizedDescription)
}

2.BIP32Keystore(HD Keystore or HD wallet):-

let mnemonic = try! BIP39.generateMnemonics(bitsOfEntropy: 256)!let keystore = try! BIP32Keystore(mnemonics: mnemonic, password: password, mnemonicsPassword: “”))

Note : This will genrate 24 word Mnemonics. If you want to 12 words Mnemonics ,just replace 128 by 256.

Also you can save this keystore in Key.json file like this :

do{let userDir = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]let keystoreManager = KeystoreManager.managerForPath(userDir + “/keystore”)var ks: BIP32Keystore?if (keystoreManager?.addresses?.count == 0) {let mnemonic = try! BIP39.generateMnemonics(bitsOfEntropy: 256)!let keystore = try! BIP32Keystore(mnemonics: mnemonic, password: password, mnemonicsPassword: "")) ks = keystore
let keydata = try JSONEncoder().encode(ks?.keystoreParams)
FileManager.default.createFile(atPath: userDir + “/keystore”+”/key.json”, contents: keydata, attributes: nil)} else {ks = keystoreManager?.walletForAddress((keystoreManager?.addresses![0])!) as? BIP32Keystore}guard let myaddress= ks?.addresses?.first else {return}print(myaddress.address)}catch{print(error.localizedDescription)}

Getting Balance in Ether:-

let ethAdd = EthereumAddress(address)let balancebigint = web3Rinkeby?.eth.getBalance(address: ethAdd).valueprint("Ether Balance :\(String(describing: Web3.Utils.formatToEthereumUnits(balancebigint ?? 0)!))")

Note: In you can change web3Rinkeby to web3Main or your own sync node.

Transaction of Ether:-

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 = amlet 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 = estimatedGasvar 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)}

Note: Don’t confuse in this coldwallet ABI and contract.This is not part of smart contract.

Work with Smart Contract and ABI file :-

Create smart Contact object with ABI fie:

let contract = web3Rinkeby?.contract(Web3Utils.erc20ABI, at: contractAddress, abiVersion: 2)!

you also import your ABI file and parse but if you want create ERC20 token wallet this lib has include abi file so don’t import anything like ABI file.

Calling smart contract function:

Name function:

let intermediate = contract?.method("name", parameters:parameters,  options: options)guard let tokenNameRes = intermediate?.call(options: options) else {return}guard case .success(let result) = tokenNameRes else {return}print("token name",result["0"] as! String)

Getting Decimal value of Smart Contract:

let intermediatedecimal = contract?.method("decimals", parameters:parameters,  options: options)guard let decimal = intermediatedecimal?.call(options: options) else {return}guard case .success(let resultdeci) = decimal else {return}print("result is ",resultdeci["0"] as! BigUInt)

BalanceOf :

guard let bkxBalanceResult = contract?.method("balanceOf", parameters: [ethAdd] as [AnyObject], options: options)?.call(options: nil) else {return}guard case .success(let bkxBalance) = bkxBalanceResult, let bal = bkxBalance["0"] as? BigUInt else {return}let tokenBal = (Double(String(bal)) ?? 0.0)/pow(10, decimal value)print("token balance = ",tokenBal)

Transfer function of Smart Contract :

guard case .success(let gasPriceRinkeby)? = self.web3Rinkeby?.eth.getGasPrice() else {return}var tokenTransferOptions = Web3Options.defaultOptions()tokenTransferOptions.gasPrice = gasPriceRinkebytokenTransferOptions.from = self.bip32keystore?.addresses?.firsttokenTransferOptions.to = toaddresslet amoutDouble = (Double(amount) ?? 0.0)*decimalvaluelet amountStr = String(Int(amoutDouble))let amountBigUInt = BigUInt.init(amountStr)!let intermediateForTokenTransfer = self.contract?.method("transfer", parameters: [toaddress, amountBigUInt] as [AnyObject], options: tokenTransferOptions)!let tokenTransferResult = intermediateForTokenTransfer?.send(password: pass, options: tokenTransferOptions, onBlock: "latest")switch tokenTransferResult {case .success(let res)?:print("Token transfer successful",res)print(res)case .failure(let error)?:print(error)case .none:print("something went wrong",tokenTransferResult?.value)}

Export or Import using private key from Account :-

do {
//Exporting private key data
let privatekey = try keystoremanager?.UNSAFE_getPrivateKeyData(password: password, account: (keystoremanager?.addresses?.first))print("pkey",privatekey?.toHexString())//Import private key data.
let etheriumKeystore = try EthereumKeystoreV3.init(privateKey: privatekey!, password: newpass)
print("etherium address",etheriumKeystore?.addresses?.first?.address)} catch {print(error.localizedDescription)}

Note:-you can also use Mnemonics to restore wallet and explore your wallet.

Last but not least :- Who i am?

My name is Shivang Pandey and i’m iOS App developer at DevGenesis Private Limited currently working on Blockchain technology as well as in iOS app development.

Github Sample Project :- https://github.com/pandeyshivang/web3swiftSample

Github profile :- https://github.com/pandeyshivang

Linkedin Profile :https://goo.gl/oam7Ze

Also Read: Best Bitcoin Hardware Wallets

--

--