Skip to content

Commit 2cfc5ce

Browse files
Merge pull request #11 from BaldyAsh/erc888
Added erc888
2 parents a659b97 + 30cc7f4 commit 2cfc5ce

File tree

3 files changed

+157
-0
lines changed

3 files changed

+157
-0
lines changed

web3swift.xcodeproj/project.pbxproj

+12
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,7 @@
216216
E279C9F521C47B4A0081695F /* Web3+ERC777.swift in Sources */ = {isa = PBXBuildFile; fileRef = E279C9F421C47B4A0081695F /* Web3+ERC777.swift */; };
217217
E279C9F821C47CD00081695F /* Web3+ERC820.swift in Sources */ = {isa = PBXBuildFile; fileRef = E279C9F721C47CD00081695F /* Web3+ERC820.swift */; };
218218
E279C9FB21C4860F0081695F /* Web3+ERC1400.swift in Sources */ = {isa = PBXBuildFile; fileRef = E279C9FA21C4860F0081695F /* Web3+ERC1400.swift */; };
219+
E279C9FE21C48A570081695F /* Web3+ERC888.swift in Sources */ = {isa = PBXBuildFile; fileRef = E279C9FD21C48A570081695F /* Web3+ERC888.swift */; };
219220
E2DCA653218C875100F94FBA /* web3swift_ENS_Tests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 81A7B2782143C978004CD2C7 /* web3swift_ENS_Tests.swift */; };
220221
E2DCA654218C879900F94FBA /* ENS.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2E668CD214F8A7B00C3CC2D /* ENS.swift */; };
221222
E2DCA655218C879900F94FBA /* ENSResolver.swift in Sources */ = {isa = PBXBuildFile; fileRef = B219DC162154F3EE0035BF94 /* ENSResolver.swift */; };
@@ -400,6 +401,7 @@
400401
E279C9F421C47B4A0081695F /* Web3+ERC777.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Web3+ERC777.swift"; sourceTree = "<group>"; };
401402
E279C9F721C47CD00081695F /* Web3+ERC820.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Web3+ERC820.swift"; sourceTree = "<group>"; };
402403
E279C9FA21C4860F0081695F /* Web3+ERC1400.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Web3+ERC1400.swift"; sourceTree = "<group>"; };
404+
E279C9FD21C48A570081695F /* Web3+ERC888.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Web3+ERC888.swift"; sourceTree = "<group>"; };
403405
E2C590752152835400FF53D3 /* JSONRPCrequestDispatcher+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "JSONRPCrequestDispatcher+ObjC.swift"; sourceTree = "<group>"; };
404406
E2E94C5F217788E0005F54A0 /* Web3+ERC721.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Web3+ERC721.swift"; sourceTree = "<group>"; };
405407
FB43EC035C593F9E5A3644B6 /* Pods-web3swift-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-web3swift-macOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-web3swift-macOS/Pods-web3swift-macOS.debug.xcconfig"; sourceTree = "<group>"; };
@@ -620,6 +622,7 @@
620622
8159C50921343EF900197B91 /* PrecompiledContracts */ = {
621623
isa = PBXGroup;
622624
children = (
625+
E279C9FC21C48A430081695F /* ERC888 */,
623626
E279C9F921C484400081695F /* ERC1400 */,
624627
E279C9F621C47CC10081695F /* ERC820 */,
625628
E279C9F321C47B3B0081695F /* ERC777 */,
@@ -991,6 +994,14 @@
991994
path = ERC1400;
992995
sourceTree = "<group>";
993996
};
997+
E279C9FC21C48A430081695F /* ERC888 */ = {
998+
isa = PBXGroup;
999+
children = (
1000+
E279C9FD21C48A570081695F /* Web3+ERC888.swift */,
1001+
);
1002+
path = ERC888;
1003+
sourceTree = "<group>";
1004+
};
9941005
E2E94C5E2177886C005F54A0 /* ERC721 */ = {
9951006
isa = PBXGroup;
9961007
children = (
@@ -1352,6 +1363,7 @@
13521363
8113D2CE1FD7E1590074282C /* EthereumTransaction.swift in Sources */,
13531364
81A1821F20D676BC0016741F /* Promise+Web3+Eth+GetTransactionCount.swift in Sources */,
13541365
81A1821520D5A2700016741F /* Promise+Web3+Eth+GetBalance.swift in Sources */,
1366+
E279C9FE21C48A570081695F /* Web3+ERC888.swift in Sources */,
13551367
81A1823C20D79C270016741F /* Promise+Web3+Eth+Call.swift in Sources */,
13561368
);
13571369
runOnlyForDeploymentPostprocessing = 0;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
//
2+
// Web3+ERC888.swift
3+
// web3swift-iOS
4+
//
5+
// Created by Anton Grigorev on 15/12/2018.
6+
// Copyright © 2018 The Matter Inc. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import BigInt
11+
import EthereumAddress
12+
import PromiseKit
13+
14+
protocol IERC888 {
15+
func getBalance(account: EthereumAddress) throws -> BigUInt
16+
func transfer(from: EthereumAddress, to: EthereumAddress, amount: String) throws -> WriteTransaction
17+
}
18+
19+
// This namespace contains functions to work with ERC888 tokens.
20+
// variables are lazyly evaluated or global token information (name, ticker, total supply)
21+
// can be imperatively read and saved
22+
public class ERC888: IERC888 {
23+
24+
@available(*, deprecated, renamed: "transactionOptions")
25+
public var options: Web3Options = .init()
26+
27+
private var _name: String? = nil
28+
private var _symbol: String? = nil
29+
private var _decimals: UInt8? = nil
30+
private var _hasReadProperties: Bool = false
31+
32+
public var transactionOptions: TransactionOptions
33+
public var web3: web3
34+
public var provider: Web3Provider
35+
public var address: EthereumAddress
36+
37+
lazy var contract: web3.web3contract = {
38+
let contract = self.web3.contract(Web3.Utils.erc888ABI, at: self.address, abiVersion: 2)
39+
precondition(contract != nil)
40+
return contract!
41+
}()
42+
43+
public init(web3: web3, provider: Web3Provider, address: EthereumAddress) {
44+
self.web3 = web3
45+
self.provider = provider
46+
self.address = address
47+
var mergedOptions = web3.transactionOptions
48+
mergedOptions.to = address
49+
self.transactionOptions = mergedOptions
50+
}
51+
52+
public var name: String {
53+
self.readProperties()
54+
if self._name != nil {
55+
return self._name!
56+
}
57+
return ""
58+
}
59+
60+
public var symbol: String {
61+
self.readProperties()
62+
if self._symbol != nil {
63+
return self._symbol!
64+
}
65+
return ""
66+
}
67+
68+
public var decimals: UInt8 {
69+
self.readProperties()
70+
if self._decimals != nil {
71+
return self._decimals!
72+
}
73+
return 255
74+
}
75+
76+
public func readProperties() {
77+
if self._hasReadProperties {
78+
return
79+
}
80+
let contract = self.contract
81+
guard contract.contract.address != nil else {return}
82+
var transactionOptions = TransactionOptions.defaultOptions
83+
transactionOptions.callOnBlock = .latest
84+
guard let namePromise = contract.read("name", parameters: [] as [AnyObject], extraData: Data(), transactionOptions: transactionOptions)?.callPromise() else {return}
85+
86+
guard let symbolPromise = contract.read("symbol", parameters: [] as [AnyObject], extraData: Data(), transactionOptions: transactionOptions)?.callPromise() else {return}
87+
88+
guard let decimalPromise = contract.read("decimals", parameters: [] as [AnyObject], extraData: Data(), transactionOptions: transactionOptions)?.callPromise() else {return}
89+
90+
let allPromises = [namePromise, symbolPromise, decimalPromise]
91+
let queue = self.web3.requestDispatcher.queue
92+
when(resolved: allPromises).map(on: queue) { (resolvedPromises) -> Void in
93+
guard case .fulfilled(let nameResult) = resolvedPromises[0] else {return}
94+
guard let name = nameResult["0"] as? String else {return}
95+
self._name = name
96+
97+
guard case .fulfilled(let symbolResult) = resolvedPromises[1] else {return}
98+
guard let symbol = symbolResult["0"] as? String else {return}
99+
self._symbol = symbol
100+
101+
guard case .fulfilled(let decimalsResult) = resolvedPromises[2] else {return}
102+
guard let decimals = decimalsResult["0"] as? BigUInt else {return}
103+
self._decimals = UInt8(decimals)
104+
105+
self._hasReadProperties = true
106+
}.wait()
107+
}
108+
109+
public func getBalance(account: EthereumAddress) throws -> BigUInt {
110+
let contract = self.contract
111+
var transactionOptions = TransactionOptions()
112+
transactionOptions.callOnBlock = .latest
113+
let result = try contract.read("balanceOf", parameters: [account] as [AnyObject], extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
114+
guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
115+
return res
116+
}
117+
118+
public func transfer(from: EthereumAddress, to: EthereumAddress, amount: String) throws -> WriteTransaction {
119+
let contract = self.contract
120+
var basicOptions = TransactionOptions()
121+
basicOptions.from = from
122+
basicOptions.to = self.address
123+
basicOptions.callOnBlock = .latest
124+
125+
// get the decimals manually
126+
let callResult = try contract.read("decimals", transactionOptions: basicOptions)!.call()
127+
var decimals = BigUInt(0)
128+
guard let dec = callResult["0"], let decTyped = dec as? BigUInt else {
129+
throw Web3Error.inputError(desc: "Contract may be not ERC20 compatible, can not get decimals")}
130+
decimals = decTyped
131+
132+
let intDecimals = Int(decimals)
133+
guard let value = Web3.Utils.parseToBigUInt(amount, decimals: intDecimals) else {
134+
throw Web3Error.inputError(desc: "Can not parse inputted amount")
135+
}
136+
let tx = contract.write("transfer", parameters: [to, value] as [AnyObject], transactionOptions: basicOptions)!
137+
return tx
138+
}
139+
140+
}
141+

web3swift/Web3/Classes/Web3+Utils.swift

+4
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ extension Web3.Utils {
6969
/// Precoded "cold wallet" (private key controlled) address. Basically - only a payable fallback function.
7070
public static var coldWalletABI = "[{\"payable\":true,\"type\":\"fallback\"}]"
7171

72+
/// TODO: - Need to make it right
73+
/// Precoded ERC888 contracts ABI. Output parameters are named for ease of use.
74+
public static var erc888ABI = "[{\"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\"},]"
75+
7276
/// Precoded ERC20 contracts ABI. Output parameters are named for ease of use.
7377
public static var erc20ABI = "[{\"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\"},]"
7478

0 commit comments

Comments
 (0)