polkascan / py-substrate-interface

Python Substrate Interface
https://polkascan.github.io/py-substrate-interface/
Apache License 2.0
240 stars 114 forks source link

TypeError: cannot unpack non-iterable NoneType object #118

Closed srinjoychakravarty closed 3 years ago

srinjoychakravarty commented 3 years ago

When uploading simple flipper or incrementer ink contracts to a canvas node

_ContractCode.create_from_contractfiles seems to work fine...

but when trying to upload a simple erc20 ink contract _ContractCode.create_from_contractfiles throws an error:

TypeError: cannot unpack non-iterable NoneType object

No idea why this is as all 3 params for _.create_from_contractfiles are populated correctly:

Screenshot:

Screenshot from 2021-06-25 05-00-10

Ink Tests:

The simple erc20 ink contract tests pass successfully

Screenshot from 2021-06-25 05-06-57

Ink Compilation:

and the simple erc20 ink contract also compiles to wasm and optimized by binaryen successfully

Screenshot from 2021-06-25 05-05-38

@arjanz @carumusan @kianenigma @emielvanderhoek Please help šŸ˜” šŸ˜Ÿ

arjanz commented 3 years ago

What is the runtime id of the canvas node you used? Could you attach the metadata.json and erc20.wasm so I can run some tests?

srinjoychakravarty commented 3 years ago

@arjanz Thanks for the quick response. The logs from the canvas node I am using:

2021-06-25 13:24:50 Canvas Node 2021-06-25 13:24:50 āœŒļø version 0.1.0-713090b-x86_64-linux-gnu 2021-06-25 13:24:50 ā¤ļø by Canvas, 2020-2021 2021-06-25 13:24:50 šŸ“‹ Chain specification: Development 2021-06-25 13:24:50 šŸ· Node name: Canvas01 2021-06-25 13:24:50 šŸ‘¤ Role: AUTHORITY 2021-06-25 13:24:50 šŸ’¾ Database: RocksDb at /tmp/substratee12TRO/chains/dev/db 2021-06-25 13:24:50 ā›“ Native runtime: canvas-12 (canvas-0.tx1.au1)

Here's the metadata.json and erc20.wasm attached as zip file.

[TypeError: cannot unpack non-iterable NoneType object

118.zip](https://github.com/polkascan/py-substrate-interface/files/6717917/TypeError.cannot.unpack.non-iterable.NoneType.object.118.zip)

arjanz commented 3 years ago

I tried the following code with the files you supplied and it seem to work for me:

from substrateinterface.contracts import ContractCode, ContractInstance
from substrateinterface import SubstrateInterface, Keypair

import logging
logging.basicConfig(level=logging.DEBUG)

with SubstrateInterface(
    url="ws://127.0.0.1:9944",
    # url="wss://canvas-rpc.parity.io",
    type_registry_preset="canvas"
) as substrate:
    contracts = substrate.query_map("Contracts", "ContractInfoOf")

    for contract_address, contract_info in contracts:
        print(contract_address.value, contract_info.value)

    print(list(contracts))

    keypair = Keypair.create_from_uri('//Alice')

    # Upload WASM code
    code = ContractCode.create_from_contract_files(
        metadata_file=os.path.join(os.path.dirname(__file__), 'erc20.json'),
        wasm_file=os.path.join(os.path.dirname(__file__), 'erc20.wasm'),
        substrate=substrate
    )

    # Deploy contract
    contract = code.deploy(
        keypair=keypair,
        endowment=10 ** 15,
        gas_limit=1000000000000,
        constructor="new",
        args={'initial_supply': 6666},
        upload_code=True
    )

    print(f'Deployed @ {contract.contract_address}')

    # To instantiate when already deployed
    # contract = ContractInstance.create_from_address(
    #     contract_address=contract.contract_address,
    #     metadata_file=os.path.join(os.path.dirname(__file__), 'erc20.json'),
    #     substrate=substrate
    # )

    result = contract.read(keypair, 'total_supply')

    print('Total supply:', result.contract_result_data)

    result = contract.read(keypair, 'balance_of', {'owner': keypair.ss58_address})

    print('Balance:', result.contract_result_data)
srinjoychakravarty commented 3 years ago

@arjanz

Thank you for the swift response and it totally works... However any idea why SubstrateInterface is not able to detect Events?

For exampe, the same erc20 contract that you tested is supposed to emit the "Transfer" event defined to be:

    pub struct Transfer {
        #[ink(topic)]
        from: Option<AccountId>,
        #[ink(topic)]
        to: Option<AccountId>,
        #[ink(topic)]
        value: Balance,
    }

but this is not picked up by the substrateinterface api as contract events returns an empty array back from the execution of the Transfer extrinsic in my bash terminal:

Events triggered in contract: []

even the transfer of tokens themselves is successful (I can see the sender's balance is decremented properly) Python Sourceode:

    # Do a gas estimation of a token transfer
    transfer_amount = 3
    bob_keypair = Keypair.create_from_uri('//Bob')
    bob_public_key = bob_keypair.public_key
    gas_predit_result = erc20_contract.read(alice_keypair, 'transfer', args = {'to': bob_public_key, 'value': transfer_amount})
    print(f"Gas: {gas_predit_result}")
    dry_run = gas_predit_result.contract_result_data
    print(f"\nāš™ļø  Result of dry-run: {dry_run}")
    gas_estimate = gas_predit_result.gas_consumed
    print(f"\nā›½ļø Gas estimate: {gas_estimate}")

    # Do the actual transfer
    print(f"Transferring {transfer_amount} MBR to Bob: {bob_public_key}")
    contract_receipt = erc20_contract.exec(alice_keypair, 'transfer', args = {'to': bob_public_key, 'value': transfer_amount}, gas_limit = gas_estimate)
    print(f'Events triggered in contract: {contract_receipt.contract_events}')

    # Check the sender's tokens have been decremented properly
    deployer_balance = erc20_contract.read(alice_keypair, 'balance_of', {'owner': alice_keypair.public_key}).contract_result_data
    print('Deployer balance:', deployer_balance)

Any idea how to better detech ink events?

arjanz commented 3 years ago

@srinjoychakravarty This was due to an unnoticed event rename in Substrate contracts pallet and fixed in https://github.com/polkascan/py-substrate-interface/commit/5e7c6d8fabea820e0c88a28c565c70cb7febf599

contract_receipt.contract_events should work again in the just released version 0.13.9

srinjoychakravarty commented 3 years ago

Thank you @arjanz you're the real deal! Closing this issue now!