Boilertalk / Web3.swift

A pure swift Ethereum Web3 library
MIT License
639 stars 188 forks source link

Loading Dynamic Contract: "Expected to decode Array<Any> but found a dictionary instead." #64

Open fflach opened 6 years ago

fflach commented 6 years ago

Hey Ybrin, I am currently working with your example for dynamic contracts (Boilertalk - Dynamic Contracts) but I get an error when I am trying to load the contract.

 // Reading json ABI
    if let path = Bundle.main.path(forResource: "BlockRunner", ofType: "json") {
        do {
            let web3 = Web3(rpcURL: RPC)
            let contractAddress = try! EthereumAddress(hex: "--------", eip55: false)
            let data = try String(contentsOf: URL(fileURLWithPath: path))
            let contractJsonABI = data.data(using: .utf8)!
            // Line where the error occurs
            // type(of: contractJsonABI) = Foundation.Data
            let contract = try! web3.eth.Contract(json: contractJsonABI, abiKey: nil, address: contractAddress)

Error: Swift.DecodingError.typeMismatch(Swift.Array, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array but found a dictionary instead.", underlyingError: nil))

fflach commented 6 years ago

So I could solve this error by following the loadStub function. Unfortunately I ran directly in a new problem I can´t solve. It seems to be an issue with the json file:

debugDescription: "No value associated with key CodingKeys(stringValue: \"inputs\", intValue: nil) (\"inputs\")."

Thank you!

if let path = Bundle.main.path(forResource: "BlockRunner", ofType: "json") {
        do {
            let web3 = Web3(rpcURL: RPC)
            let contractAddress = try! EthereumAddress(hex: "-------", eip55: false)
            let url = URL(fileURLWithPath: path)
            let data = try? Data(contentsOf: url)
            // Line where also the new error occurs
            let contract = try! web3.eth.Contract(json: data!, abiKey: "abi", address: contractAddress)

Complete Error: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "inputs", intValue: nil), Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 1", intValue: 1)], debugDescription: "No value associated with key CodingKeys(stringValue: \"inputs\", intValue: nil) (\"inputs\").", underlyingError: nil))

JSON Structure:

{
  "contractName": "BlockRunner",
  "abi": [
    {
      "inputs": [],
      "payable": false,
      "stateMutability": "nonpayable",
      "type": "constructor"
    },
    {
      "payable": true,
      "stateMutability": "payable",
      "type": "fallback"
    },
    {
      "constant": false,
      "inputs": [
        {
          "name": "date",
          "type": "uint256"
        },
        {
          "name": "numberOfSteps",
          "type": "uint256"
        }
      ],
      "name": "newSteps",
      "outputs": [],
      "payable": false,
      "stateMutability": "nonpayable",
      "type": "function"
    },
    {
      "constant": false,
      "inputs": [
        {
          "name": "addr",
          "type": "address"
        },
        { ......
koraykoska commented 6 years ago

Hey @fflach

Which version of Web3 are you using in your example above? I'm gonna look into this in detail tomorrow...

fflach commented 6 years ago

Thank you for your quick response! When installing the pod the listed version is Web3 (0.3.0) . I deployed the contract with the current version of truffle. The contract is written in solidity version 0.4.23.

koraykoska commented 6 years ago

I think this is a bug in the ABIObject decoder.

In this line decode should be replaced with decodeIfPresent to make inputs really optional.

I couldn't test it yet as I can't directly reproduce the error. @fflach Could you send me either the full json abi or an example project?

@pixelmatrix What do you think? Is this the cause for this error?

@fflach In the meantime you could try and add empty inputs arrays into all abi objects in your json and report back whether it resolves this bug or not.

pixelmatrix commented 6 years ago

@Ybrin has this PR been released yet? I believe this should fix the inputs issue on fallback functions: https://github.com/Boilertalk/Web3.swift/pull/50

koraykoska commented 6 years ago

@pixelmatrix Oh sorry, I missed that. I'm gonna release it now...

pixelmatrix commented 6 years ago

Awesome. Hopefully that will solve it. The original issue is because you need to pass "abi" as the key so it can find the abi inside the json. Might be worth updating the documentation to mention that since compiled Truffle artifacts always have the abi nested.

MrCodeHauler commented 6 years ago

I don't know how to use the Function or Event that In Contract,Please tell me In your free,Thank you very much

koraykoska commented 6 years ago

@Mr-Lin-Old Please join our Telegram chat with the link below if you have a question which is not an issue with the library.

https://t.me/joinchat/BPk3DE6CTFaiOolSIZNLyg