Skip to content

Commit

Permalink
Merge pull request #50 from BitskiCo/fix/json-contract-inputs
Browse files Browse the repository at this point in the history
Fix parsing of JSON ABI with fallback functions
  • Loading branch information
Koray Koska authored Jul 22, 2018
2 parents c0739b2 + 3293202 commit 229c67c
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 6 deletions.
13 changes: 13 additions & 0 deletions Example/Tests/ContractTests/JSONContractTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -187,5 +187,18 @@ class DynamicContractTests: QuickSpec {
}
}

describe("JSON Contract with fallback function") {
let provider = MockWeb3Provider()
stubResponses(provider: provider)
let web3 = Web3(provider: provider)
guard let data = loadStub(named: "Fallback") else { fail("Could not find stub for contract"); return }
do {
let contract = try web3.eth.Contract(json: data, abiKey: "abi", address: .testAddress)
expect(contract).toNot(beNil())
} catch {
fail(error.localizedDescription)
}
}

}
}
197 changes: 197 additions & 0 deletions Example/Tests/Stubs/Fallback.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
{
"contractName": "ERC721",
"abi": [
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_from",
"type": "address"
},
{
"indexed": true,
"name": "_to",
"type": "address"
},
{
"indexed": false,
"name": "_tokenId",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"name": "_owner",
"type": "address"
},
{
"indexed": true,
"name": "_approved",
"type": "address"
},
{
"indexed": false,
"name": "_tokenId",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"constant": true,
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"name": "_totalSupply",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"name": "_balance",
"type": "uint256"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_tokenId",
"type": "uint256"
}
],
"name": "ownerOf",
"outputs": [
{
"name": "_owner",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_tokenId",
"type": "uint256"
}
],
"name": "approve",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [
{
"name": "_tokenId",
"type": "uint256"
}
],
"name": "getApproved",
"outputs": [
{
"name": "_approved",
"type": "address"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_from",
"type": "address"
},
{
"name": "_to",
"type": "address"
},
{
"name": "_tokenId",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_to",
"type": "address"
},
{
"name": "_tokenId",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "implementsERC721",
"outputs": [
{
"name": "_implementsERC721",
"type": "bool"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"payable": true,
"stateMutability": "payable",
"type": "fallback"
}
]
}
4 changes: 4 additions & 0 deletions Example/Web3.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
0EA5D3F32039123A0037C2BE /* UInt+BytesRepresentableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA5D3F22039123A0037C2BE /* UInt+BytesRepresentableTests.swift */; };
0EA5D3F7203912790037C2BE /* Web3HttpTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EA5D3F6203912790037C2BE /* Web3HttpTests.swift */; };
E54BAE94B0A9A8565CD31D93 /* Pods_Web3_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FD5947923E8841F929DE0AE8 /* Pods_Web3_Tests.framework */; };
E807E53D20F5247A009CC575 /* Fallback.json in Resources */ = {isa = PBXBuildFile; fileRef = E807E53C20F5247A009CC575 /* Fallback.json */; };
E85B782520D1ED3F0069E3B4 /* JSONContractTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E85B781620D1ED3E0069E3B4 /* JSONContractTests.swift */; };
E85B782720D1ED3F0069E3B4 /* ContractTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E85B781820D1ED3F0069E3B4 /* ContractTests.swift */; };
E85B782820D1ED3F0069E3B4 /* getBlock2.json in Resources */ = {isa = PBXBuildFile; fileRef = E85B781A20D1ED3F0069E3B4 /* getBlock2.json */; };
Expand Down Expand Up @@ -72,6 +73,7 @@
607FACEA1AFB9204008FA782 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
746C365C55131A708ACBAB71 /* Web3.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Web3.podspec; path = ../Web3.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; };
DA16060729F56349F6C9ADD3 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; };
E807E53C20F5247A009CC575 /* Fallback.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = Fallback.json; sourceTree = "<group>"; };
E85B781620D1ED3E0069E3B4 /* JSONContractTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONContractTests.swift; sourceTree = "<group>"; };
E85B781820D1ED3F0069E3B4 /* ContractTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContractTests.swift; sourceTree = "<group>"; };
E85B781A20D1ED3F0069E3B4 /* getBlock2.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = getBlock2.json; sourceTree = "<group>"; };
Expand Down Expand Up @@ -248,6 +250,7 @@
E85B781C20D1ED3F0069E3B4 /* call_tuple.json */,
E85B781D20D1ED3F0069E3B4 /* sendTransaction.json */,
E85B781E20D1ED3F0069E3B4 /* ERC721.json */,
E807E53C20F5247A009CC575 /* Fallback.json */,
E85B781F20D1ED3F0069E3B4 /* call_getBalance.json */,
E85B782020D1ED3F0069E3B4 /* LimitedMintableNonFungibleToken.json */,
E85B782120D1ED3F0069E3B4 /* TupleExample.json */,
Expand Down Expand Up @@ -334,6 +337,7 @@
E85B782920D1ED3F0069E3B4 /* getBlock3.json in Resources */,
E85B783020D1ED3F0069E3B4 /* estimateGas.json in Resources */,
E85B783120D1ED3F0069E3B4 /* getTransactionReceipt.json in Resources */,
E807E53D20F5247A009CC575 /* Fallback.json in Resources */,
E85B782D20D1ED3F0069E3B4 /* call_getBalance.json in Resources */,
E85B782A20D1ED3F0069E3B4 /* call_tuple.json in Resources */,
E85B782820D1ED3F0069E3B4 /* getBlock2.json in Resources */,
Expand Down
2 changes: 1 addition & 1 deletion Web3/Classes/ContractABI/Contract/ABIObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public struct ABIObject: Codable {
let constant: Bool?

// input parameters
let inputs: [Parameter]
let inputs: [Parameter]?

// output parameters
let outputs: [Parameter]?
Expand Down
2 changes: 1 addition & 1 deletion Web3/Classes/ContractABI/Contract/SolidityEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public struct SolidityEvent {
public init?(abiObject: ABIObject) {
guard abiObject.type == .event, let name = abiObject.name else { return nil }
self.anonymous = abiObject.anonymous ?? false
self.inputs = abiObject.inputs.compactMap { Parameter($0) }
self.inputs = abiObject.inputs?.compactMap { Parameter($0) } ?? []
self.name = name
}

Expand Down
8 changes: 4 additions & 4 deletions Web3/Classes/ContractABI/Contract/SolidityFunction.swift
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ public class SolidityConstantFunction: SolidityFunction {
guard abiObject.type == .function, abiObject.stateMutability?.isConstant == true else { return nil }
guard let name = abiObject.name else { return nil }
self.name = name
self.inputs = abiObject.inputs.compactMap { SolidityFunctionParameter($0) }
self.inputs = abiObject.inputs?.compactMap { SolidityFunctionParameter($0) } ?? []
self.outputs = abiObject.outputs?.compactMap { SolidityFunctionParameter($0) }
self.handler = handler
}
Expand Down Expand Up @@ -126,7 +126,7 @@ public class SolidityPayableFunction: SolidityFunction {
guard abiObject.type == .function, abiObject.stateMutability == .payable else { return nil }
guard let name = abiObject.name else { return nil }
self.name = name
self.inputs = abiObject.inputs.compactMap { SolidityFunctionParameter($0) }
self.inputs = abiObject.inputs?.compactMap { SolidityFunctionParameter($0) } ?? []
self.handler = handler
}

Expand All @@ -153,7 +153,7 @@ public class SolidityNonPayableFunction: SolidityFunction {
guard abiObject.type == .function, abiObject.stateMutability == .nonpayable else { return nil }
guard let name = abiObject.name else { return nil }
self.name = name
self.inputs = abiObject.inputs.compactMap { SolidityFunctionParameter($0) }
self.inputs = abiObject.inputs?.compactMap { SolidityFunctionParameter($0) } ?? []
self.handler = handler
}

Expand All @@ -176,7 +176,7 @@ public class SolidityConstructor {

public init?(abiObject: ABIObject, handler: SolidityFunctionHandler) {
guard abiObject.type == .constructor else { return nil }
self.inputs = abiObject.inputs.compactMap { SolidityFunctionParameter($0) }
self.inputs = abiObject.inputs?.compactMap { SolidityFunctionParameter($0) } ?? []
self.handler = handler
self.payable = abiObject.payable ?? false
}
Expand Down

0 comments on commit 229c67c

Please sign in to comment.