Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expected to decode Array<Any> but found a dictionary instead. #128

Closed
baquedano opened this issue Mar 12, 2019 · 2 comments
Closed

Expected to decode Array<Any> but found a dictionary instead. #128

baquedano opened this issue Mar 12, 2019 · 2 comments

Comments

@baquedano
Copy link

baquedano commented Mar 12, 2019

Hi, I'm currently trying to send a transaction to a contract and I'm getting the following error:

▿ DecodingError
  ▿ typeMismatch : 2 elements
    - .0 : Swift.Array<Any>
    ▿ .1 : Context
      - codingPath : 0 elements
      - debugDescription : "Expected to decode Array<Any> but found a dictionary instead."
      - underlyingError : nil

The way I'm sending the transaction is:

 public func send (method name: String, // <---- "AddCandidate"
                                    taking arguments: [AnyObject], // <--- ["This is a string"] as [AnyObject]
                                    extra data:Data = Data(),
                                    from sender: EthereumAddress,
                                    unlocksWith passphrase: String,
                                    completion handler: ((EthereumTransaction?, Bool, Error?)->())? ) {
        var txOptions = TransactionOptions()

        txOptions.gasLimit = TransactionOptions.GasLimitPolicy.automatic
        txOptions.gasPrice = TransactionOptions.GasPricePolicy.automatic
        
        txOptions.from = sender
        
        guard let writeTx = self.web3Contract.write(name, parameters: arguments, transactionOptions: txOptions) else {
            handler? (nil, false, nil)
            return
        }
        let promise = writeTx.sendPromise(password: passphrase, transactionOptions: txOptions)
        
        _ = promise.done(on: DispatchQueue.main, { (results) in
            handler? (writeTx.transaction, true, nil)
        }).catch(on: DispatchQueue.main, { (error) in
            handler? (writeTx.transaction, false, error)
        })
 
    }

and this is the ABI of that method:

{"constant":false,"inputs":[{"name":"candidate","type":"string"}],"name":"AddCandidate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}

After following a bit around the lib I found that the place where it gets the error is on Promise+Batching.swift --> Batch class --> trigger func --> Line 82, when it calls sendAsync the JSONRPCRequest batch, more specifically the error message comes on Promise+HTTPProvider.swift --> post func --> Line 92, this is the request that is being sent:

(lldb) po request
▿ JSONRPCrequestBatch
  ▿ requests : 1 element
    ▿ 0 : JSONRPCrequest
      - jsonrpc : "2.0"
      ▿ method : Optional<JSONRPCmethod>
        - some : Web3swift.JSONRPCmethod.sendTransaction
      ▿ params : Optional<JSONRPCparams>
        ▿ some : JSONRPCparams
          ▿ params : 1 element
            ▿ 0 : TransactionParameters
              ▿ data : Optional<String>
                - some : "0x7e54b8e20000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001054686973206973206120737472696e6700000000000000000000000000000000"
              ▿ from : Optional<String>
                - some : "0xf92901dbdfec2a0599ee5108808c5ec85244eaf9"
              ▿ gas : Optional<String>
                - some : "0x15b5f"
              ▿ gasPrice : Optional<String>
                - some : "0x3b9aca00"
              ▿ to : Optional<String>
                - some : "0x11e8e870d72b5fbc46f886f865aa98470d01e249"
              ▿ value : Optional<String>
                - some : "0x0"
      - id : 32

Edit: after inspecting a little more I found that the actual data we get back is:

(lldb) po JSONSerialization.jsonObject(with: data, options: []) 
▿ 2 elements
  ▿ 0 : 2 elements
    - key : jsonrpc
    - value : 2.0
  ▿ 1 : 2 elements
    - key : error
    ▿ value : 2 elements
      ▿ 0 : 2 elements
        - key : message
        - value : The method eth_sendTransaction does not exist/is not available
      ▿ 1 : 2 elements
        - key : code
        - value : -32601

and indeed eth_sendTransaction doesn't exist in infura API, we have eth_sendRawTransaction.

Edit2: Found the issue, it was that I forgot to provide the keystoreManager to the client so it could locally sign the transactions, errors were quite misleading.

@TonioMacaronio
Copy link
Collaborator

@baquedano It's great that you were able to solve the problem. I'll close this issue.
If you have more questions - open it again

@DiwakarThapa
Copy link

I am having same problem while sending token

{
    error =     {
        code = "-32601";
        message = "The method eth_sendTransaction does not exist/is not available";
    };
    id = 7;
    jsonrpc = "2.0";
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants