polkascan / py-substrate-interface

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

How to solve Element "asset_id" of struct is missing in given value #203

Closed Jackwumingjie closed 2 years ago

Jackwumingjie commented 2 years ago

I want to send a rmrk transaction in statemine by substate-interface. I get the keypair and call call_module = "Assets" call_function = 'transfer' call_params = { "id": 8, "target": target, 'amount': amount, } call = _substrate.compose_call( call_module=call_module, call_function=call_function, call_params=call_params ) use the func _substrate.create_signed_extrinsic to sign. but the result is raise ValueError('Element "{}" of struct is missing in given value'.format(key)) ValueError: Element "asset_id" of struct is missing in given value Is there any example to teleport coin by substrate-interface and estimate the fee?

arjanz commented 2 years ago

It seems the ChargeAssetTxPayment extrinsic extension is unaccounted for https://github.com/polkascan/py-scale-codec/blob/d80aa8e3adaa2fc13059f63e626ff4b0d22eda43/scalecodec/types.py#L2582

I haven't tested on Statemint/Statemine thoroughly yet, but what you can try is to set the tip_asset_id=0 on create_signed_extrinsic to force the asset_id to be set:

extrinsic = substrate.create_signed_extrinsic(call=call, keypair=keypair, tip_asset_id=0)
arjanz commented 2 years ago

Are you sure you have the latest version of packages substrate-interface==1.2.2 and scalecodec==1.0.34?

Because I can remember older versions of scalecodec don't have the 'signed_extensions' support that is included in the metadata and Statemine has the ChargeAssetTxPayment extension.

I was successfully able to transfer an asset on Statemine with the following code:

keypair = Keypair.create_from_mnemonic(mnemonic)
substrate = SubstrateInterface(
    url="wss://statemine-rpc.polkadot.io"
)

call = substrate.compose_call(
    call_module="Assets",
    call_function="transfer",
    call_params={'id': asset_id, 'target': account_id, 'amount': amount}
)

extrinsic = substrate.create_signed_extrinsic(call=call, keypair=keypair)

result = substrate.submit_extrinsic(extrinsic, wait_for_inclusion=True)