laalaguer / thor-requests.py

Easy to use Python SDK that talks to VeChain Thor blockchain like a pro. Covers most topic on contract interaction, vet transfer and transaction debug.
GNU General Public License v3.0
18 stars 5 forks source link

Right format of the ABI file #9

Closed wernerliechti closed 2 years ago

wernerliechti commented 2 years ago

I wanted to call a Smart Contract function but got this error:

Traceback (most recent call last):
  File "C:\Users\WernerLiechti\Documents\GitHub\TreeGenerator\main.py", line 11, in <module>
    res = connector.call(
  File "C:\Users\WernerLiechti\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\thor_requests\connect.py", line 389, in call
    clause = self.clause(contract, func_name, func_params, to, value)
  File "C:\Users\WernerLiechti\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\thor_requests\connect.py", line 365, in clause
    return Clause(to, contract, func_name, func_params, value)
  File "C:\Users\WernerLiechti\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\thor_requests\clause.py", line 44, in __init__
    f = contract.get_function_by_name(func_name, strict_mode=True)
  File "C:\Users\WernerLiechti\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\thor_requests\contract.py", line 64, in get_function_by_name
    abi_dict = self.get_abi(func_name)
  File "C:\Users\WernerLiechti\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\thor_requests\contract.py", line 48, in get_abi
    abis = self.get_abis()
  File "C:\Users\WernerLiechti\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\thor_requests\contract.py", line 44, in get_abis
    return self.contract_meta["abi"]
TypeError: list indices must be integers or slices, not str

The ABI was generated with truffle, unsure how to solve the error. ABI looks like this:

[
  {
    "inputs": [],
    "name": "last_completed_migration",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function",
    "constant": true
  },
  {
    "inputs": [],
    "name": "owner",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function",
    "constant": true
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "completed",
        "type": "uint256"
      }
    ],
    "name": "setCompleted",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "_name",
        "type": "string"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "messageId",
        "type": "uint256"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "ownerAddress",
        "type": "address"
      },
      {
        "components": [
          {
            "internalType": "address",
            "name": "owner",
            "type": "address"
          },
          {
            "internalType": "string",
            "name": "x",
            "type": "string"
          },
          {
            "internalType": "string",
            "name": "y",
            "type": "string"
          },
          {
            "internalType": "string",
            "name": "message",
            "type": "string"
          }
        ],
        "indexed": false,
        "internalType": "struct Tree.Message",
        "name": "message",
        "type": "tuple"
      }
    ],
    "name": "MessageAdded",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "messageId",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "address",
        "name": "ownerAddress",
        "type": "address"
      }
    ],
    "name": "MessageDeleted",
    "type": "event"
  },
  {
    "inputs": [],
    "name": "UNAUTHORIZED",
    "outputs": [
      {
        "internalType": "string",
        "name": "",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function",
    "constant": true
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "addressToMessages",
    "outputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "internalType": "string",
        "name": "x",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "y",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "message",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function",
    "constant": true
  },
  {
    "inputs": [],
    "name": "currentMessageCount",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function",
    "constant": true
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "name": "messages",
    "outputs": [
      {
        "internalType": "address",
        "name": "owner",
        "type": "address"
      },
      {
        "internalType": "string",
        "name": "x",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "y",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "message",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function",
    "constant": true
  },
  {
    "inputs": [],
    "name": "owner",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function",
    "constant": true
  },
  {
    "inputs": [
      {
        "internalType": "string",
        "name": "x",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "y",
        "type": "string"
      },
      {
        "internalType": "string",
        "name": "message",
        "type": "string"
      }
    ],
    "name": "addMessage",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "uint256",
        "name": "messageId",
        "type": "uint256"
      }
    ],
    "name": "deleteMessage",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  }
]

This is how I call the function:

_contract_addr = '0x6f7BeC0AFcfF5d87d1817d6a3291E96CbD156944'
_contract = Contract.fromFile("ContractJson/ABI.json")

res = connector.call(
    caller='0x17ACC76e4685AEA9d574705163E871b83e36697f', # fill in your caller address or all zero address
    contract=_contract,
    func_name="currentMessageCount",
    func_params=[],
    to=_contract_addr,
)

Not quite sure how to solve the error. Thanks for any help in advance. :D

laalaguer commented 2 years ago

Hi,

The Contract.fromFile("ContractJson/ABI.json") reads in a compiled contract json file.

This files includes many fields like "abi", "bytecode", etc.

If you only have ABI information of the smart contract, you can have your file structured like this:

{
   "abi": [.... the content you posted as abi]
}

Simply add a "abi" key and follow with the abi content.

You can refer to what I did for the VTHO smart contract: https://github.com/laalaguer/thor-requests.py/blob/main/tests/VTHO.json

wernerliechti commented 2 years ago

So happy that it worked! Thank you so much!