Skip to content

Commit ad5d8dd

Browse files
Merge branch 'develop' into feature/gas-prediction
2 parents 03f55e2 + e30d812 commit ad5d8dd

File tree

17 files changed

+451
-317
lines changed

17 files changed

+451
-317
lines changed

.swiftlint.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
excluded:
2+
- Carthage
3+
- Pods
4+
- .build
5+
- Build
6+
- DerivedData
7+
8+
disabled_rules:
9+
- type_name
10+
- identifier_name
11+
- line_length
12+
- multiple_closures_with_trailing_closure
13+
- todo
14+
15+
opt_in_rules:
16+
- weak_delegate
17+
- unused_import
18+
- unneeded_parentheses_in_closure_argument
19+
- trailing_closure
20+
- static_operator
21+
- redundant_nil_coalescing
22+
- override_in_extension
23+
- legacy_objc_type
24+
- implicitly_unwrapped_optional
25+
- force_unwrapping
26+
- empty_string
27+
- closure_body_length
28+
- fallthrough
29+
- indentation_width
30+
31+
# force warnings
32+
force_cast: error
33+
force_try: error
34+
35+
custom_rules:
36+
commented_out_code:
37+
included: ".*\\.swift" # regex that defines paths to include during linting. optional.
38+
excluded: ".*Test(s)?\\.swift" # regex that defines paths to exclude during linting. optional
39+
name: "Commented out code" # rule name. optional.
40+
regex: "^\\/\\/\\s*(@|\\.?([a-z]|(\\})))" # matching pattern
41+
capture_group: 0 # number of regex capture group to highlight the rule violation at. optional.
42+
match_kinds: # SyntaxKinds to match. optional.
43+
- comment
44+
message: "No commented code in devel branch allowed." # violation message. optional.
45+
severity: warning # violation severity. optional.

Sources/web3swift/Contract/EthereumContract.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public struct EthereumContract: ContractProtocol {
3333
var toReturn = [String: ABI.Element]()
3434
for m in self._abi {
3535
switch m {
36-
case .function(let function):
36+
case .function(let function):
3737
guard let name = function.name else {continue}
3838
toReturn[name] = m
3939
default:
@@ -50,7 +50,7 @@ public struct EthereumContract: ContractProtocol {
5050
break
5151
}
5252
switch m {
53-
case .constructor(_):
53+
case .constructor(_):
5454
toReturn = m
5555
break
5656
default:
@@ -68,10 +68,10 @@ public struct EthereumContract: ContractProtocol {
6868
var toReturn = [String: ABI.Element.Event]()
6969
for m in self._abi {
7070
switch m {
71-
case .event(let event):
71+
case .event(let event):
7272
let name = event.name
7373
toReturn[name] = event
74-
default:
74+
default:
7575
continue
7676
}
7777
}

Sources/web3swift/Convenience/Base58.swift

Lines changed: 18 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ struct Base58 {
5656
}
5757

5858
for b in base58 {
59-
// str = "\(str)\(base58Alphabet[String.Index(encodedOffset: Int(b))])"
6059
str = "\(str)\(base58Alphabet[String.Index(utf16Offset: Int(b), in: base58Alphabet)])"
6160
}
6261

@@ -67,23 +66,27 @@ struct Base58 {
6766
static func bytesFromBase58(_ base58: String) -> [UInt8] {
6867
// remove leading and trailing whitespaces
6968
let string = base58.trimmingCharacters(in: CharacterSet.whitespaces)
70-
7169
guard !string.isEmpty else { return [] }
7270

73-
var zerosCount = 0
74-
var length = 0
71+
// count leading ASCII "1"'s [decodes directly to binary zero bytes]
72+
var leadingZeros = 0
7573
for c in string {
7674
if c != "1" { break }
77-
zerosCount += 1
75+
leadingZeros += 1
7876
}
7977

80-
let size = string.lengthOfBytes(using: String.Encoding.utf8) * 733 / 1000 + 1 - zerosCount
81-
var base58: [UInt8] = Array(repeating: 0, count: size)
78+
// calculate the size of the decoded output, rounded up
79+
let size = (string.lengthOfBytes(using: String.Encoding.utf8) - leadingZeros) * 733 / 1000 + 1
80+
81+
// allocate a buffer large enough for the decoded output
82+
var base58: [UInt8] = Array(repeating: 0, count: size + leadingZeros)
83+
84+
// decode what remains of the data
85+
var length = 0
8286
for c in string where c != " " {
8387
// search for base58 character
84-
guard let base58Index = base58Alphabet.index(of: c) else { return [] }
88+
guard let base58Index = base58Alphabet.firstIndex(of: c) else { return [] }
8589

86-
// var carry = base58Index.encodedOffset
8790
var carry = base58Index.utf16Offset(in: base58Alphabet)
8891
var i = 0
8992
for j in 0...base58.count where carry != 0 || i < length {
@@ -97,20 +100,16 @@ struct Base58 {
97100
length = i
98101
}
99102

100-
// skip leading zeros
101-
var zerosToRemove = 0
102-
103+
// calculate how many leading zero bytes we have
104+
var totalZeros = 0
103105
for b in base58 {
104106
if b != 0 { break }
105-
zerosToRemove += 1
107+
totalZeros += 1
106108
}
107-
base58.removeFirst(zerosToRemove)
109+
// remove the excess zero bytes
110+
base58.removeFirst(totalZeros - leadingZeros)
108111

109-
var result: [UInt8] = Array(repeating: 0, count: zerosCount)
110-
for b in base58 {
111-
result.append(b)
112-
}
113-
return result
112+
return base58
114113
}
115114
}
116115

@@ -158,11 +157,4 @@ extension String {
158157
return bytes
159158
}
160159

161-
// public var littleEndianHexToUInt: UInt {
162-
// let data = Data.fromHex(self)!
163-
// let revensed =
164-
// return UInt(sel)
165-
// return UInt(self.dataWithHexString().bytes.reversed().fullHexString, radix: 16)!
166-
// }
167-
168160
}

Sources/web3swift/EthereumABI/ABIElements.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
//
1+
//
22
// Created by Alex Vlasov on 25/10/2018.
33
// Copyright © 2018 Alex Vlasov. All rights reserved.
4-
//
4+
//
55

66
import Foundation
77
import BigInt

Sources/web3swift/EthereumABI/ABIEncoding.swift

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
//
1+
//
22
// Created by Alex Vlasov on 25/10/2018.
33
// Copyright © 2018 Alex Vlasov. All rights reserved.
4-
//
4+
//
55

66
import Foundation
77
import BigInt
@@ -383,3 +383,75 @@ extension ABIEncoder {
383383
return nil
384384
}
385385
}
386+
387+
// MARK: - SoliditySHA3 implementation based on web3js
388+
389+
public extension ABIEncoder {
390+
/**
391+
A convenience implementation of web3js [soliditySha3](https://web3js.readthedocs.io/en/v1.2.11/web3-utils.html?highlight=soliditySha3#soliditysha3)
392+
that is based on web3swift [`ABIEncoder`](https://github.com/skywinder/web3swift/blob/develop/Sources/web3swift/EthereumABI/ABIEncoding.swift ).
393+
*/
394+
static func soliditySha3(_ values: [Any]) throws -> Data {
395+
try abiEncode(values).sha3(.keccak256)
396+
}
397+
398+
static func soliditySha3(_ value: Any) throws -> Data {
399+
if let values = value as? [Any] {
400+
return try abiEncode(values).sha3(.keccak256)
401+
} else {
402+
return try abiEncode(value).sha3(.keccak256)
403+
}
404+
}
405+
406+
/// Using AnyObject any number can be represented as Bool and Bool can be represented as number.
407+
/// That will lead to invalid hash output. DO NOT USE THIS FUNCTION.
408+
/// This function will exist to intentionally throw an error that will raise awareness that the hash output can be potentially,
409+
/// and most likely will be, wrong.
410+
/// - Parameter values: to hash
411+
/// - Returns: solidity sha3 hash
412+
static func soliditySha3(_ values: [AnyObject]) throws -> Data {
413+
throw Web3Error.inputError(desc: "AnyObject creates ambiguity and does not guarantee that the output will be correct. Please, use `soliditySha3(Any) or soliditySha3([Any]) instead.`")
414+
}
415+
416+
/// See docs for ``soliditySha3(_ values: [AnyObject])``
417+
static func soliditySha3(_ value: AnyObject) throws -> Data {
418+
throw Web3Error.inputError(desc: "AnyObject creates ambiguity and does not guarantee that the output will be correct. Please, use `soliditySha3(Any) or soliditySha3([Any]) instead.`")
419+
}
420+
421+
static func abiEncode(_ values: [Any]) throws -> Data {
422+
return try values.map {
423+
try abiEncode($0)
424+
}.reduce(into: Data()) { partialResult, nextElement in
425+
partialResult.append(nextElement)
426+
}
427+
}
428+
429+
static func abiEncode(_ value: Any) throws -> Data {
430+
if let v = value as? Bool {
431+
return Data(v ? [0b1] : [0b0])
432+
} else if let v = value as? Int {
433+
return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 256)! as AnyObject)!
434+
} else if let v = value as? Int8 {
435+
return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 8) as AnyObject)!
436+
} else if let v = value as? Int16 {
437+
return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 16)! as AnyObject)!
438+
} else if let v = value as? Int32 {
439+
return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 32)! as AnyObject)!
440+
} else if let v = value as? Int64 {
441+
return ABIEncoder.convertToData(BigInt(exactly: v)?.abiEncode(bits: 64)! as AnyObject)!
442+
} else if let v = value as? UInt {
443+
return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 256)! as AnyObject)!
444+
} else if let v = value as? UInt8 {
445+
return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 8)! as AnyObject)!
446+
} else if let v = value as? UInt16 {
447+
return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 16)! as AnyObject)!
448+
} else if let v = value as? UInt32 {
449+
return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 32)! as AnyObject)!
450+
} else if let v = value as? UInt64 {
451+
return ABIEncoder.convertToData(BigUInt(exactly: v)?.abiEncode(bits: 64)! as AnyObject)!
452+
} else if let data = ABIEncoder.convertToData(value as AnyObject) {
453+
return data
454+
}
455+
throw Web3Error.inputError(desc: "SoliditySha3: `abiEncode` accepts an Int/UInt (any of 8, 16, 32, 64 bits long), HEX string, Bool, Data, BigInt or BigUInt instance. Given value is of type \(type(of: value)).")
456+
}
457+
}

Sources/web3swift/Tokens/ERC1155/Web3+ERC1155.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,8 @@ public class ERC1155: IERC1155 {
8585
self._hasReadProperties = true
8686
}.wait()
8787
}
88-
89-
func safeTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, id: BigUInt, value: BigUInt, data: [UInt8]) throws -> WriteTransaction {
88+
89+
public func safeTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, id: BigUInt, value: BigUInt, data: [UInt8]) throws -> WriteTransaction {
9090
let contract = self.contract
9191
var basicOptions = TransactionOptions()
9292
basicOptions.from = from
@@ -95,8 +95,8 @@ public class ERC1155: IERC1155 {
9595
let tx = contract.write("safeTransferFrom", parameters: [originalOwner, to, id, value, data] as [AnyObject], transactionOptions: basicOptions)!
9696
return tx
9797
}
98-
99-
func safeBatchTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, ids: [BigUInt], values: [BigUInt], data: [UInt8]) throws -> WriteTransaction {
98+
99+
public func safeBatchTransferFrom(from: EthereumAddress, to: EthereumAddress, originalOwner: EthereumAddress, ids: [BigUInt], values: [BigUInt], data: [UInt8]) throws -> WriteTransaction {
100100
let contract = self.contract
101101
var basicOptions = TransactionOptions()
102102
basicOptions.from = from
@@ -105,17 +105,17 @@ public class ERC1155: IERC1155 {
105105
let tx = contract.write("safeBatchTransferFrom", parameters: [originalOwner, to, ids, values, data] as [AnyObject], transactionOptions: basicOptions)!
106106
return tx
107107
}
108-
109-
func balanceOf(account: EthereumAddress, id: BigUInt) throws -> BigUInt {
108+
109+
public func balanceOf(account: EthereumAddress, id: BigUInt) throws -> BigUInt {
110110
let contract = self.contract
111111
var transactionOptions = TransactionOptions()
112112
transactionOptions.callOnBlock = .latest
113113
let result = try contract.read("balanceOf", parameters: [account, id] as [AnyObject], extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
114114
guard let res = result["0"] as? BigUInt else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
115115
return res
116116
}
117-
118-
func setApprovalForAll(from: EthereumAddress, operator user: EthereumAddress, approved: Bool, scope: Data) throws -> WriteTransaction {
117+
118+
public func setApprovalForAll(from: EthereumAddress, operator user: EthereumAddress, approved: Bool, scope: Data) throws -> WriteTransaction {
119119
let contract = self.contract
120120
var basicOptions = TransactionOptions()
121121
basicOptions.from = from
@@ -124,17 +124,17 @@ public class ERC1155: IERC1155 {
124124
let tx = contract.write("setApprovalForAll", parameters: [user, approved, scope] as [AnyObject], transactionOptions: basicOptions)!
125125
return tx
126126
}
127-
128-
func isApprovedForAll(owner: EthereumAddress, operator user: EthereumAddress, scope: Data) throws -> Bool {
127+
128+
public func isApprovedForAll(owner: EthereumAddress, operator user: EthereumAddress, scope: Data) throws -> Bool {
129129
let contract = self.contract
130130
var basicOptions = TransactionOptions()
131131
basicOptions.callOnBlock = .latest
132132
let result = try contract.read("isApprovedForAll", parameters: [owner, user, scope] as [AnyObject], extraData: Data(), transactionOptions: self.transactionOptions)!.call(transactionOptions: transactionOptions)
133133
guard let res = result["0"] as? Bool else {throw Web3Error.processingError(desc: "Failed to get result of expected type from the Ethereum node")}
134134
return res
135135
}
136-
137-
func supportsInterface(interfaceID: String) throws -> Bool {
136+
137+
public func supportsInterface(interfaceID: String) throws -> Bool {
138138
let contract = self.contract
139139
var transactionOptions = TransactionOptions()
140140
transactionOptions.callOnBlock = .latest

Sources/web3swift/Web3/Web3+Contract.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extension web3 {
1717
/// Web3 instance bound contract instance.
1818
public class web3contract {
1919
var contract: EthereumContract
20-
var web3 : web3
20+
var web3: web3
2121
public var transactionOptions: TransactionOptions? = nil
2222

2323
/// Initialize the bound contract instance by supplying the Web3 provider bound object, ABI, Ethereum address and some default

0 commit comments

Comments
 (0)