polkascan / py-substrate-interface

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

Unable to get democracy.vote call #221

Closed frmz closed 2 years ago

frmz commented 2 years ago

I am currently trying to use a proxy to do a democracy.vote() call in KSM, i currently call:

self._api.compose_call(
            call_module='Proxy',
            call_function='proxy',
            call_params={
                'real': address,
                'force_proxy_type': proxy_type,
                'call': call_args,
            }
        )

Then as an argument i use compose call again this way:

self._api.compose_call(
            call_module='Democracy',
            call_function='vote',
            call_params={
                'ref_index': ref_index,
                'vote': {
                    "Standard": {
                        "vote": {
                            "aye": yes,
                            "conviction": 'None',
                        },
                        "balance": self.float_to_amount(amount),
                    }
                }
            }
        ).value

Parameters are correct however all i get is: ValueError: Value for enum with type_mapping can only have one value

The exact same call via JS works

arjanz commented 2 years ago

The format of the call_params looks very similar as PolkadotJS, but do has a few differences. So some adjustments have to be made:

call = substrate.compose_call(
            call_module='Democracy',
            call_function='vote',
            call_params={
                'ref_index': 208,
                'vote': {'Standard': ({'aye': True, 'conviction': 'Locked2x'}, 1100000000000)}
            }
        )

I agree a better helper function should be available to format those call function args better (like for storage functions ), until then I think the best way is the fetch an existing extrinsic on-chain and examine the format, for example:

extrinsic_receipt = substrate.retrieve_extrinsic_by_identifier("13174772-2")
print(extrinsic_receipt.extrinsic.value['call']['call_args'])
# [{'name': 'ref_index', 'type': 'ReferendumIndex', 'value': 208}, {'name': 'vote', 'type': 'AccountVote<BalanceOf>', 'value': {'Standard': ({'aye': True, 'conviction': 'Locked2x'}, 1100000000000)}}]
frmz commented 2 years ago

Wow thanks, this was fast, it works, thanks for the tip, i was looking at the extrinsic payload on subscan but i should have checked the output with the library as well and reverse engineer from there. Most likely this ticket will save some time to anyone else searching :)

Again thanks, awesome library! I have been working with substrate clients in golang and other languages and outside JS this is by far the easiest to use.