Skip to content

Commit 639696c

Browse files
Merge branch 'develop'
2 parents 16a2915 + dab2667 commit 639696c

30 files changed

+1087
-257
lines changed

CHANGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@
162162
- Update libs versions, Cartfile and Pods dependencies [\#334](https://github.com/skywinder/web3swift/pull/334) ([AnnaYatsun1](https://github.com/AnnaYatsun1))
163163
- fix crash when 'payable' nil [\#332](https://github.com/skywinder/web3swift/pull/332) ([xdozorx](https://github.com/xdozorx))
164164
- Update README.md [\#331](https://github.com/skywinder/web3swift/pull/331) ([Iysbaera](https://github.com/Iysbaera))
165-
- CrytoSwift update version 1.4.0 [\#327](https://github.com/skywinder/web3swift/pull/327) ([lzttxs](https://github.com/lzttxs))
165+
- CryptoSwift update version 1.4.0 [\#327](https://github.com/skywinder/web3swift/pull/327) ([lzttxs](https://github.com/lzttxs))
166166
- Update carthage libraries [\#325](https://github.com/skywinder/web3swift/pull/325) ([alex78pro](https://github.com/alex78pro))
167167
- Gas estimate fix [\#324](https://github.com/skywinder/web3swift/pull/324) ([frostiq](https://github.com/frostiq))
168168
- Update README.md [\#306](https://github.com/skywinder/web3swift/pull/306) ([manuG420](https://github.com/manuG420))
@@ -252,7 +252,7 @@
252252
- received transaction id from geth node server but not able to see that transaction id at etherscan.io [\#200](https://github.com/skywinder/web3swift/issues/200)
253253
- How do I fetch information such as balance, decimal,symbol and name of ERC20token ? [\#199](https://github.com/skywinder/web3swift/issues/199)
254254
- Starscream 3.1.0 not compatible with Swift 5.0 [\#195](https://github.com/skywinder/web3swift/issues/195)
255-
- How to Connect infuraWebsocket and subsribe particular event in swift? [\#193](https://github.com/skywinder/web3swift/issues/193)
255+
- How to Connect infuraWebsocket and subscribe particular event in swift? [\#193](https://github.com/skywinder/web3swift/issues/193)
256256
- Use of unresolved identifier 'Wallet' [\#192](https://github.com/skywinder/web3swift/issues/192)
257257
- V in Signed Message Hash not being calculated properly [\#191](https://github.com/skywinder/web3swift/issues/191)
258258
- Not possible to calculate fast, normal and cheap transaction fee ? [\#190](https://github.com/skywinder/web3swift/issues/190)

Example/myWeb3Wallet/myWeb3Wallet/ViewControllers/WalletController/WalletViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ class WalletViewController: UIViewController {
102102
}
103103
} catch {
104104
#if DEBUG
105-
print("error creating keyStrore")
105+
print("error creating keyStore")
106106
print("Private key error.")
107107
#endif
108108
let alert = UIAlertController(title: "Error", message: "Please enter correct Private key", preferredStyle: .alert)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
- [x]**Literally following the standards** (BIP, EIP, etc):
5959
- [x] **[BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) (HD Wallets), [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki) (Seed phrases), [BIP44](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki) (Key generation prefixes)**
6060
- [x] **[EIP-20](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md)** (Standard interface for tokens - ERC-20), **[EIP-67](https://github.com/ethereum/EIPs/issues/67)** (Standard URI scheme), **[EIP-155](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md)** (Replay attacks protection), **[EIP-2718](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-2718.md)** (Typed Transaction Envelope), **[EIP-1559](https://github.com/ethereum/EIPs/blob/master/EIPS/eip-1559.md)** (Gas Fee market change)
61-
- [x] **And many others** *(For details about this EIP's look at [Documentation page](https://github.com/web3swift-team/web3swift/blob/master/Documentation/))*: EIP-681, EIP-721, EIP-165, EIP-777, EIP-820, EIP-888, EIP-1400, EIP-1410, EIP-1594, EIP-1643, EIP-1644, EIP-1633, EIP-721, EIP-1155, EIP-1376, ST-20
61+
- [x] **And many others** *(For details about this EIP's look at [Documentation page](https://github.com/web3swift-team/web3swift/blob/master/Documentation/))*: EIP-165, EIP-681, EIP-721, EIP-777, EIP-820, EIP-888, EIP-1155, EIP-1376, EIP-1400, EIP-1410, EIP-1594, EIP-1633, EIP-1643, EIP-1644, EIP-4361 ([SIWE](https://eips.ethereum.org/EIPS/eip-4361)), ST-20
6262
- [x] **RLP encoding**
6363
- [x] Base58 encoding scheme
6464
- [x] Formatting to and from Ethereum Units

Sources/Web3Core/Contract/ContractProtocol.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -210,8 +210,8 @@ extension ContractProtocol {
210210

211211
func decodeInputData(_ data: Data) -> [String: Any]? {
212212
guard data.count >= 4 else { return nil }
213-
let methodId = data[0..<4].toHexString()
214-
let data = data[4...]
213+
let methodId = data[data.startIndex ..< data.startIndex + 4].toHexString()
214+
let data = data[(data.startIndex + 4)...]
215215
return decodeInputData(methodId, data: data)
216216
}
217217
}
@@ -333,14 +333,14 @@ extension DefaultContractProtocol {
333333

334334
public func decodeInputData(_ data: Data) -> [String: Any]? {
335335
guard data.count % 32 == 4 else { return nil }
336-
let methodSignature = data[0..<4].toHexString().addHexPrefix().lowercased()
336+
let methodSignature = data[data.startIndex ..< data.startIndex + 4].toHexString().addHexPrefix().lowercased()
337337

338338
guard let function = methods[methodSignature]?.first else { return nil }
339-
return function.decodeInputData(Data(data[4 ..< data.count]))
339+
return function.decodeInputData(Data(data[data.startIndex + 4 ..< data.startIndex + data.count]))
340340
}
341341

342342
public func getFunctionCalled(_ data: Data) -> ABI.Element.Function? {
343343
guard data.count >= 4 else { return nil }
344-
return methods[data[0..<4].toHexString().addHexPrefix()]?.first
344+
return methods[data[data.startIndex ..< data.startIndex + 4].toHexString().addHexPrefix()]?.first
345345
}
346346
}

Sources/Web3Core/EthereumABI/ABIDecoding.swift

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -34,27 +34,28 @@ extension ABIDecoder {
3434
guard let elementItself = elData, let nextElementPointer = nextPtr else {
3535
return (nil, nil)
3636
}
37+
let startIndex = UInt64(elementItself.startIndex)
3738
switch type {
3839
case .uint(let bits):
3940
guard elementItself.count >= 32 else {break}
4041
let mod = BigUInt(1) << bits
41-
let dataSlice = elementItself[0 ..< 32]
42+
let dataSlice = elementItself[startIndex ..< startIndex + 32]
4243
let v = BigUInt(dataSlice) % mod
4344
return (v, type.memoryUsage)
4445
case .int(let bits):
4546
guard elementItself.count >= 32 else {break}
4647
let mod = BigInt(1) << bits
47-
let dataSlice = elementItself[0 ..< 32]
48+
let dataSlice = elementItself[startIndex ..< startIndex + 32]
4849
let v = BigInt.fromTwosComplement(data: dataSlice) % mod
4950
return (v, type.memoryUsage)
5051
case .address:
5152
guard elementItself.count >= 32 else {break}
52-
let dataSlice = elementItself[12 ..< 32]
53+
let dataSlice = elementItself[startIndex + 12 ..< startIndex + 32]
5354
let address = EthereumAddress(dataSlice)
5455
return (address, type.memoryUsage)
5556
case .bool:
5657
guard elementItself.count >= 32 else {break}
57-
let dataSlice = elementItself[0 ..< 32]
58+
let dataSlice = elementItself[startIndex ..< startIndex + 32]
5859
let v = BigUInt(dataSlice)
5960
if v == BigUInt(36) ||
6061
v == BigUInt(32) ||
@@ -69,33 +70,33 @@ extension ABIDecoder {
6970
}
7071
case .bytes(let length):
7172
guard elementItself.count >= 32 else {break}
72-
let dataSlice = elementItself[0 ..< length]
73-
return (dataSlice, type.memoryUsage)
73+
let dataSlice = elementItself[startIndex ..< startIndex + length]
74+
return (Data(dataSlice), type.memoryUsage)
7475
case .string:
7576
guard elementItself.count >= 32 else {break}
76-
var dataSlice = elementItself[0 ..< 32]
77+
var dataSlice = elementItself[startIndex ..< startIndex + 32]
7778
let length = UInt64(BigUInt(dataSlice))
78-
guard elementItself.count >= 32+length else {break}
79+
guard elementItself.count >= 32 + length else {break}
7980
dataSlice = elementItself[32 ..< 32 + length]
8081
guard let string = String(data: dataSlice, encoding: .utf8) else {break}
8182
return (string, type.memoryUsage)
8283
case .dynamicBytes:
8384
guard elementItself.count >= 32 else {break}
84-
var dataSlice = elementItself[0 ..< 32]
85+
var dataSlice = elementItself[startIndex ..< startIndex + 32]
8586
let length = UInt64(BigUInt(dataSlice))
86-
guard elementItself.count >= 32+length else {break}
87-
dataSlice = elementItself[32 ..< 32 + length]
88-
return (dataSlice, nextElementPointer)
87+
guard elementItself.count >= 32 + length else {break}
88+
dataSlice = elementItself[startIndex + 32 ..< startIndex + 32 + length]
89+
return (Data(dataSlice), nextElementPointer)
8990
case .array(type: let subType, length: let length):
9091
switch type.arraySize {
9192
case .dynamicSize:
9293
if subType.isStatic {
9394
// uint[] like, expect length and elements
9495
guard elementItself.count >= 32 else {break}
95-
var dataSlice = elementItself[0 ..< 32]
96+
var dataSlice = elementItself[startIndex ..< startIndex + 32]
9697
let length = UInt64(BigUInt(dataSlice))
9798
guard elementItself.count >= 32 + subType.memoryUsage*length else {break}
98-
dataSlice = elementItself[32 ..< 32 + subType.memoryUsage*length]
99+
dataSlice = elementItself[startIndex + 32 ..< startIndex + 32 + subType.memoryUsage*length]
99100
var subpointer: UInt64 = 32
100101
var toReturn = [Any]()
101102
for _ in 0 ..< length {
@@ -108,10 +109,10 @@ extension ABIDecoder {
108109
} else {
109110
// in principle is true for tuple[], so will work for string[] too
110111
guard elementItself.count >= 32 else {break}
111-
var dataSlice = elementItself[0 ..< 32]
112+
var dataSlice = elementItself[startIndex ..< startIndex + 32]
112113
let length = UInt64(BigUInt(dataSlice))
113114
guard elementItself.count >= 32 else {break}
114-
dataSlice = Data(elementItself[32 ..< elementItself.count])
115+
dataSlice = Data(elementItself[startIndex + 32 ..< UInt64(elementItself.count)])
115116
var subpointer: UInt64 = 0
116117
var toReturn = [Any]()
117118
for _ in 0 ..< length {
@@ -179,21 +180,21 @@ extension ABIDecoder {
179180
}
180181
case .function:
181182
guard elementItself.count >= 32 else {break}
182-
let dataSlice = elementItself[8 ..< 32]
183-
return (dataSlice, type.memoryUsage)
183+
let dataSlice = elementItself[startIndex + 8 ..< startIndex + 32]
184+
return (Data(dataSlice), type.memoryUsage)
184185
}
185186
return (nil, nil)
186187
}
187188

188189
fileprivate static func followTheData(type: ABI.Element.ParameterType, data: Data, pointer: UInt64 = 0) -> (elementEncoding: Data?, nextElementPointer: UInt64?) {
189190
if type.isStatic {
190191
guard data.count >= pointer + type.memoryUsage else {return (nil, nil)}
191-
let elementItself = data[pointer ..< pointer + type.memoryUsage]
192+
let elementItself = data[data.startIndex + Int(pointer) ..< data.startIndex + Int(pointer + type.memoryUsage)]
192193
let nextElement = pointer + type.memoryUsage
193194
return (Data(elementItself), nextElement)
194195
} else {
195196
guard data.count >= pointer + type.memoryUsage else {return (nil, nil)}
196-
let dataSlice = data[pointer ..< pointer + type.memoryUsage]
197+
let dataSlice = data[data.startIndex + Int(pointer) ..< data.startIndex + Int(pointer + type.memoryUsage)]
197198
let bn = BigUInt(dataSlice)
198199
if bn > UInt64.max || bn >= data.count {
199200
// there are ERC20 contracts that use bytes32 instead of string. Let's be optimistic and return some data
@@ -209,7 +210,8 @@ extension ABIDecoder {
209210
return (nil, nil)
210211
}
211212
let elementPointer = UInt64(bn)
212-
let elementItself = data[elementPointer ..< UInt64(data.count)]
213+
let startIndex = UInt64(data.startIndex)
214+
let elementItself = data[startIndex + elementPointer ..< startIndex + UInt64(data.count)]
213215
let nextElement = pointer + type.memoryUsage
214216
return (Data(elementItself), nextElement)
215217
}

Sources/Web3Core/EthereumABI/ABIElements.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -397,9 +397,9 @@ extension ABI.Element.Function {
397397
/// 4) `messageLength` is used to determine where message bytes end to decode string correctly.
398398
/// 5) The rest of the `data` must be 0 bytes or empty.
399399
if data.bytes.count >= 100,
400-
Data(data[0..<4]) == Data.fromHex("08C379A0"),
401-
BigInt(data[4..<36]) == 32,
402-
let messageLength = Int(Data(data[36..<68]).toHexString(), radix: 16),
400+
Data(data[data.startIndex ..< data.startIndex + 4]) == Data.fromHex("08C379A0"),
401+
BigInt(data[data.startIndex + 4 ..< data.startIndex + 36]) == 32,
402+
let messageLength = Int(Data(data[data.startIndex + 36 ..< data.startIndex + 68]).toHexString(), radix: 16),
403403
let message = String(bytes: data.bytes[68..<(68+messageLength)], encoding: .utf8),
404404
(68+messageLength == data.count || data.bytes[68+messageLength..<data.count].reduce(0) { $0 + $1 } == 0) {
405405
return ["_success": false,
@@ -410,11 +410,11 @@ extension ABI.Element.Function {
410410

411411
if data.count >= 4,
412412
let errors = errors,
413-
let customError = errors[data[0..<4].toHexString().stripHexPrefix()] {
413+
let customError = errors[data[data.startIndex ..< data.startIndex + 4].toHexString().stripHexPrefix()] {
414414
var errorResponse: [String: Any] = ["_success": false, "_abortedByRevertOrRequire": true, "_error": customError.errorDeclaration]
415415

416416
if (data.count > 32 && !customError.inputs.isEmpty),
417-
let decodedInputs = ABIDecoder.decode(types: customError.inputs, data: Data(data[4..<data.count])) {
417+
let decodedInputs = ABIDecoder.decode(types: customError.inputs, data: Data(data[data.startIndex + 4 ..< data.startIndex + data.count])) {
418418
for idx in decodedInputs.indices {
419419
errorResponse["\(idx)"] = decodedInputs[idx]
420420
if !customError.inputs[idx].name.isEmpty {

Sources/Web3Core/EthereumNetwork/RequestParameter/RequestParameter+RawRepresentable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ extension RequestParameter: RawRepresentable {
1313
/// to encode mixed type values array in JSON.
1414
///
1515
/// This protocol is used to implement custom `encode` method for that enum,
16-
/// which encodes an array of self-assosiated values.
16+
/// which encodes an array of self-associated values.
1717
///
1818
/// You're totally free to use explicit and more convenience member init as `RequestParameter.int(12)` in your code.
1919
/// - Parameter rawValue: one of the supported types like `Int`, `UInt` etc.

Sources/Web3Core/KeystoreManager/BIP32HDNode.swift

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,31 @@ extension UInt32 {
2222
}
2323

2424
public class HDNode {
25+
private static var maxIterationIndex = UInt32(1) << 31
26+
27+
/// Contains private and public prefixes for serialization.
28+
/// See [BIP-32's serialization format](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#serialization-format) for more info.
2529
public struct HDversion {
26-
// swiftlint:disable force_unwrapping
27-
public var privatePrefix: Data = Data.fromHex("0x0488ADE4")!
28-
public var publicPrefix: Data = Data.fromHex("0x0488B21E")!
29-
// swiftlint:enable force_unwrapping
30-
public init() {}
30+
/// Mainnet public key prefix.
31+
/// Value `0x0488B21E` is a string `xpub` encoded as Base-58 and later as hexadecimal.
32+
public static let publicPrefix: Data! = Data.fromHex("0x0488B21E")
33+
34+
/// Mainnet private key prefix.
35+
/// Value `0x0488ADE4` is a string `xprv` encoded as Base-58 and later as hexadecimal.
36+
public static let privatePrefix: Data! = Data.fromHex("0x0488ADE4")
37+
38+
public let publicPrefix: Data
39+
public let privatePrefix: Data
40+
41+
/// Default values for `publicPrefix` and `privatePrefix` are
42+
/// `HDversion.publicPrefix` and `HDversion.privatePrefix` respectively.
43+
public init(public publicPrefix: Data = HDversion.publicPrefix,
44+
private privatePrefix: Data = HDversion.privatePrefix) {
45+
self.publicPrefix = publicPrefix
46+
self.privatePrefix = privatePrefix
47+
}
3148
}
49+
3250
public var path: String? = "m"
3351
public var privateKey: Data?
3452
public var publicKey: Data
@@ -37,14 +55,10 @@ public class HDNode {
3755
public var parentFingerprint: Data = Data(repeating: 0, count: 4)
3856
public var childNumber: UInt32 = UInt32(0)
3957
public var isHardened: Bool {
40-
childNumber >= (UInt32(1) << 31)
58+
childNumber >= Self.maxIterationIndex
4159
}
4260
public var index: UInt32 {
43-
if self.isHardened {
44-
return childNumber - (UInt32(1) << 31)
45-
} else {
46-
return childNumber
47-
}
61+
childNumber - (isHardened ? Self.maxIterationIndex : 0)
4862
}
4963
public var hasPrivate: Bool {
5064
privateKey != nil
@@ -65,7 +79,7 @@ public class HDNode {
6579
guard data.count == 82 else { return nil }
6680
let header = data[0..<4]
6781
var serializePrivate = false
68-
if header == HDNode.HDversion().privatePrefix {
82+
if header == HDversion.privatePrefix {
6983
serializePrivate = true
7084
}
7185
depth = data[4..<5].bytes[0]
@@ -90,30 +104,30 @@ public class HDNode {
90104

91105
public init?(seed: Data) {
92106
guard seed.count >= 16 else { return nil }
93-
// swiftlint:disable force_unwrapping
94-
let hmacKey = "Bitcoin seed".data(using: .ascii)!
95-
let hmac = HMAC(key: hmacKey.bytes, variant: HMAC.Variant.sha2(.sha512))
107+
108+
guard let hmacKey = "Bitcoin seed".data(using: .ascii) else { return nil }
109+
let hmac = HMAC(key: hmacKey.bytes, variant: .sha2(.sha512))
110+
96111
guard let entropy = try? hmac.authenticate(seed.bytes), entropy.count == 64 else { return nil }
97112
let I_L = entropy[0..<32]
98113
let I_R = entropy[32..<64]
99114
chaincode = Data(I_R)
100115
let privKeyCandidate = Data(I_L)
101116
guard SECP256K1.verifyPrivateKey(privateKey: privKeyCandidate) else { return nil }
102117
guard let pubKeyCandidate = SECP256K1.privateToPublic(privateKey: privKeyCandidate, compressed: true) else { return nil }
103-
guard pubKeyCandidate.bytes[0] == 0x02 || pubKeyCandidate.bytes[0] == 0x03 else { return nil }
118+
guard pubKeyCandidate.bytes.first == 0x02 || pubKeyCandidate.bytes.first == 0x03 else { return nil }
104119
publicKey = pubKeyCandidate
105120
privateKey = privKeyCandidate
106121
depth = 0x00
107122
childNumber = UInt32(0)
108123
}
109124

110-
private static var curveOrder = BigUInt("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", radix: 16)!
111-
// swiftlint:enable force_unwrapping
112-
public static var defaultPath: String = "m/44'/60'/0'/0"
113-
public static var defaultPathPrefix: String = "m/44'/60'/0'"
114-
public static var defaultPathMetamask: String = "m/44'/60'/0'/0/0"
115-
public static var defaultPathMetamaskPrefix: String = "m/44'/60'/0'/0"
116-
public static var hardenedIndexPrefix: UInt32 = (UInt32(1) << 31)
125+
private static let curveOrder = BigUInt("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", radix: 16)!
126+
public static let defaultPath = "m/44'/60'/0'/0"
127+
public static let defaultPathPrefix = "m/44'/60'/0'"
128+
public static let defaultPathMetamask = "m/44'/60'/0'/0/0"
129+
public static let defaultPathMetamaskPrefix = "m/44'/60'/0'/0"
130+
public static var hardenedIndexPrefix: UInt32 { Self.maxIterationIndex }
117131
}
118132

119133
extension HDNode {

0 commit comments

Comments
 (0)