diff --git a/Sources/web3swift/EthereumABI/ABIDecoding.swift b/Sources/web3swift/EthereumABI/ABIDecoding.swift index 215922c3a..2dca6cf06 100755 --- a/Sources/web3swift/EthereumABI/ABIDecoding.swift +++ b/Sources/web3swift/EthereumABI/ABIDecoding.swift @@ -23,7 +23,7 @@ extension ABIDecoder { var toReturn = [AnyObject]() var consumed: UInt64 = 0 for i in 0 ..< types.count { - let (v, c) = decodeSignleType(type: types[i], data: data, pointer: consumed) + let (v, c) = decodeSingleType(type: types[i], data: data, pointer: consumed) guard let valueUnwrapped = v, let consumedUnwrapped = c else {return nil} toReturn.append(valueUnwrapped) consumed = consumed + consumedUnwrapped @@ -32,7 +32,7 @@ extension ABIDecoder { return toReturn } - public static func decodeSignleType(type: ABI.Element.ParameterType, data: Data, pointer: UInt64 = 0) -> (value: AnyObject?, bytesConsumed: UInt64?) { + public static func decodeSingleType(type: ABI.Element.ParameterType, data: Data, pointer: UInt64 = 0) -> (value: AnyObject?, bytesConsumed: UInt64?) { let (elData, nextPtr) = followTheData(type: type, data: data, pointer: pointer) guard let elementItself = elData, let nextElementPointer = nextPtr else { return (nil, nil) @@ -117,7 +117,7 @@ extension ABIDecoder { var subpointer: UInt64 = 32; var toReturn = [AnyObject]() for _ in 0 ..< length { - let (v, c) = decodeSignleType(type: subType, data: elementItself, pointer: subpointer) + let (v, c) = decodeSingleType(type: subType, data: elementItself, pointer: subpointer) guard let valueUnwrapped = v, let consumedUnwrapped = c else {break} toReturn.append(valueUnwrapped) subpointer = subpointer + consumedUnwrapped @@ -134,7 +134,7 @@ extension ABIDecoder { var toReturn = [AnyObject]() // print("Dynamic array sub element itself: \n" + dataSlice.toHexString()) for _ in 0 ..< length { - let (v, c) = decodeSignleType(type: subType, data: dataSlice, pointer: subpointer) + let (v, c) = decodeSingleType(type: subType, data: dataSlice, pointer: subpointer) guard let valueUnwrapped = v, let consumedUnwrapped = c else {break} toReturn.append(valueUnwrapped) if (subType.isStatic) { @@ -152,7 +152,7 @@ extension ABIDecoder { var toReturn = [AnyObject]() var consumed:UInt64 = 0 for _ in 0 ..< length { - let (v, c) = decodeSignleType(type: subType, data: elementItself, pointer: consumed) + let (v, c) = decodeSingleType(type: subType, data: elementItself, pointer: consumed) guard let valueUnwrapped = v, let consumedUnwrapped = c else {return (nil, nil)} toReturn.append(valueUnwrapped) consumed = consumed + consumedUnwrapped @@ -170,10 +170,28 @@ extension ABIDecoder { var toReturn = [AnyObject]() var consumed:UInt64 = 0 for i in 0 ..< subTypes.count { - let (v, c) = decodeSignleType(type: subTypes[i], data: elementItself, pointer: consumed) + let (v, c) = decodeSingleType(type: subTypes[i], data: elementItself, pointer: consumed) guard let valueUnwrapped = v, let consumedUnwrapped = c else {return (nil, nil)} toReturn.append(valueUnwrapped) - consumed = consumed + consumedUnwrapped + /* + When decoding a tuple that is not static or an array with a subtype that is not static, the second value in the tuple returned by decodeSignleType is a pointer to the next element, NOT the length of the consumed element. So when decoding such an element, consumed should be set to consumedUnwrapped, NOT incremented by consumedUnwrapped. + */ + switch subTypes[i] { + case .array(type: let subType, length: _): + if !subType.isStatic { + consumed = consumedUnwrapped + } else { + consumed = consumed + consumedUnwrapped + } + case .tuple(types: _): + if !subTypes[i].isStatic { + consumed = consumedUnwrapped + } else { + consumed = consumed + consumedUnwrapped + } + default: + consumed = consumed + consumedUnwrapped + } } // print("Tuple element is: \n" + String(describing: toReturn)) if type.isStatic { @@ -253,11 +271,11 @@ extension ABIDecoder { let data = logs[i+1] let input = indexedInputs[i] if !input.type.isStatic || input.type.isArray || input.type.memoryUsage != 32 { - let (v, _) = ABIDecoder.decodeSignleType(type: .bytes(length: 32), data: data) + let (v, _) = ABIDecoder.decodeSingleType(type: .bytes(length: 32), data: data) guard let valueUnwrapped = v else {return nil} indexedValues.append(valueUnwrapped) } else { - let (v, _) = ABIDecoder.decodeSignleType(type: input.type, data: data) + let (v, _) = ABIDecoder.decodeSingleType(type: input.type, data: data) guard let valueUnwrapped = v else {return nil} indexedValues.append(valueUnwrapped) } diff --git a/Sources/web3swift/Transaction/TransactionSigner.swift b/Sources/web3swift/Transaction/TransactionSigner.swift index 6b2a8b28a..e19fb1524 100755 --- a/Sources/web3swift/Transaction/TransactionSigner.swift +++ b/Sources/web3swift/Transaction/TransactionSigner.swift @@ -51,7 +51,7 @@ public struct Web3Signer { guard let unmarshalledSignature = SECP256K1.unmarshalSignature(signatureData: serializedSignature) else { return false } - let originalPublicKey = SECP256K1.privateToPublic(privateKey: privateKey) + guard let originalPublicKey = SECP256K1.privateToPublic(privateKey: privateKey) else { return false } var d = BigUInt(0) if unmarshalledSignature.v >= 0 && unmarshalledSignature.v <= 3 { d = BigUInt(35) @@ -64,7 +64,7 @@ public struct Web3Signer { transaction.r = BigUInt(Data(unmarshalledSignature.r)) transaction.s = BigUInt(Data(unmarshalledSignature.s)) let recoveredPublicKey = transaction.recoverPublicKey() - if (!(originalPublicKey!.constantTimeComparisonTo(recoveredPublicKey))) { + if !(originalPublicKey.constantTimeComparisonTo(recoveredPublicKey)) { return false } return true @@ -89,7 +89,7 @@ public struct Web3Signer { guard let unmarshalledSignature = SECP256K1.unmarshalSignature(signatureData: serializedSignature) else { return false } - let originalPublicKey = SECP256K1.privateToPublic(privateKey: privateKey) + guard let originalPublicKey = SECP256K1.privateToPublic(privateKey: privateKey) else { return false } transaction.chainID = nil var d = BigUInt(0) var a = BigUInt(0) @@ -104,7 +104,7 @@ public struct Web3Signer { transaction.r = BigUInt(Data(unmarshalledSignature.r)) transaction.s = BigUInt(Data(unmarshalledSignature.s)) let recoveredPublicKey = transaction.recoverPublicKey() - if (!(originalPublicKey!.constantTimeComparisonTo(recoveredPublicKey))) { + if !(originalPublicKey.constantTimeComparisonTo(recoveredPublicKey)) { return false } return true diff --git a/Sources/web3swift/Web3/Web3+Structures.swift b/Sources/web3swift/Web3/Web3+Structures.swift index eb7e7f2ca..c4b26ac89 100755 --- a/Sources/web3swift/Web3/Web3+Structures.swift +++ b/Sources/web3swift/Web3/Web3+Structures.swift @@ -52,13 +52,13 @@ extension TransactionOptions: Decodable { public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) - if let gasLimit = try decodeHexToBigUInt(container, key: .gas) { + if let gasLimit = try decodeHexToBigUInt(container, key: .gas, allowOptional:true) { self.gasLimit = .manual(gasLimit) } else { self.gasLimit = .automatic } - if let gasPrice = try decodeHexToBigUInt(container, key: .gasPrice) { + if let gasPrice = try decodeHexToBigUInt(container, key: .gasPrice, allowOptional:true) { self.gasPrice = .manual(gasPrice) } else { self.gasPrice = .automatic @@ -85,13 +85,13 @@ extension TransactionOptions: Decodable { let value = try decodeHexToBigUInt(container, key: .value) self.value = value - if let nonce = try decodeHexToBigUInt(container, key: .nonce) { + if let nonce = try decodeHexToBigUInt(container, key: .nonce, allowOptional:true) { self.nonce = .manual(nonce) } else { self.nonce = .pending } - if let callOnBlock = try decodeHexToBigUInt(container, key: .nonce) { + if let callOnBlock = try decodeHexToBigUInt(container, key: .callOnBlock, allowOptional:true) { self.callOnBlock = .exactBlockNumber(callOnBlock) } else { self.callOnBlock = .pending