Closed roccomuso closed 3 years ago
I tried some examples with an ed25519 account myself and realised it's working but not very user-friendly (yet). The library cannot 'autodetect' if the signature is generated by Ed25519, Sr25519 or Ecdsa when the "signature version byte" is not supplied and therefor defaults to Sr25519.
This "signature version byte" can be supplied though to prefix the signature with 00
(for ed25519, 01
is sr25519 and 02
is ecdsa).
In this case your example would be:
[
"132AuLCVno4NcyEy5AWdRWKAAeYimEwsGbSaZJTF2ZcwwQ1G",
"Balances",
"transfer",
{
"dest": "16C32b3YaXdDhCnDXn5BEEfCcsf919Hw7VNU63psWToxjXNT",
"value": 100000
},
"0x00d18435f3971cc2adc94092f1eba811654bd5a6d086048ddc5e9d8ec85b1581ab9003d9e6e66966658279ad07c17c0cc14a40808d451519c1f93d6a049076100b"
]
I tested this with the library https://github.com/polkascan/py-substrate-interface itself as followed:
substrate = SubstrateInterface(
url="wss://rpc.polkadot.io",
address_type=0,
type_registry_preset='polkadot'
)
keypair = Keypair(ss58_address="13Rfiutv3JGWJDntux2chFcR9RuoU4MWaEKgggrMdKfsRCU1")
balance_info = substrate.get_runtime_state(
module='System',
storage_function='Account',
params=[keypair.ss58_address],
).get('result')
print('Balance info', balance_info)
call = substrate.compose_call(
call_module='Balances',
call_function='transfer',
call_params={
'dest': '12nV9cr7Xr31ef3QTHmF3r4gVzAvjQZNBqi5Pk86NH7emyoN',
'value': 100000000
}
)
extrinsic = substrate.create_signed_extrinsic(
call=call,
keypair=keypair,
signature='0x0058445b5b191645220b3a5251ecc0181b89395d5f50a6f1805798728b29267ef1327bf386f0cc74d7c6b533817a201278689afa60383a228efb38d3c615197d0d')
try:
result = substrate.submit_extrinsic(extrinsic)
print('Extrinsic "{}" included in block "{}"'.format(
result['extrinsic_hash'], result.get('block_hash')
))
except SubstrateRequestException as e:
print("Failed to send: {}".format(e))
Resulted in transaction: https://polkascan.io/polkadot/transaction/0x8e66bc32a7727dc46d8a33046bafdefb54c94153880068729e0689785a9367bd
This is definitely not user-friendly and we will plan some modifications to the library and substrate-api to supply which curve is being used. I guess this was not an issue yet because sr25519 is kind of the default within Substrate.
Let me know if this is working for you..
Thanks for the explanation!
I tried prepending 0x00
but still getting a bad signature error. Then I noticed that I was basically providing a signature instead of the extrinsic to the runtime_submitExtrinsic
rpc without calling first runtime_createExtrinsic
.
I've now called runtime_createExtrinsic
with the right ed25519 signature and got this extrinsic:
0x2d0284595d0bd94c9cb9f002399f6af8d931a275ac0bb83d7bf94a4a859aafd4fd01c600dd89bac79c3e7390bbc035697ac1f33ea02dbb033b82bd98dee02aea20404ee5a84477e0a4d7e53ea725764f41d41f57c456bb45e494d9c7dd7d79b12ce9c2040000000500e597b100e3d58ae8c6f301f63a739585b42c5539146761bf7a1f90d059bd156002093d00
Then I tried submitting this with runtime_submitExtrinsic
:
[
"132AuLCVno4NcyEy5AWdRWKAAeYimEwsGbSaZJTF2ZcwwQ1G",
"Balances",
"transfer",
{
"dest": "16C32b3YaXdDhCnDXn5BEEfCcsf919Hw7VNU63psWToxjXNT",
"value": 1000000
},
"0x2d0284595d0bd94c9cb9f002399f6af8d931a275ac0bb83d7bf94a4a859aafd4fd01c600dd89bac79c3e7390bbc035697ac1f33ea02dbb033b82bd98dee02aea20404ee5a84477e0a4d7e53ea725764f41d41f57c456bb45e494d9c7dd7d79b12ce9c2040000000500e597b100e3d58ae8c6f301f63a739585b42c5539146761bf7a1f90d059bd156002093d00"
]
and got this error: Value should start with \"0x\" and should be 64 bytes long
Sounds like an ecoding issue, maybe I gotta first encode that 1000000
when calling this rpc? This is not the case for the other rpc calls though.
Ah I see you put the whole extrinsic payload as 4th param, but it should be the signature only (which is 64 bytes/ 128 hexbytes long)
To follow up on this, as discussed in chat problem was runtime_createExternalSignerPayload
is just for parity signer.
In my case the right rpc call is runtime_createSignaturePayload
that returns a good payload. Then after locally signing the payload, I've put 0x00
as prefix (00 for ed25519 curve) and using runtime_submitExtrinsic
with the signature is enough to create and submit the extrinsic.
Worked fine!
@roccomuso It's solved, can you close this one?
I'm trying to create a transaction using substrate-interface-api and getting a bad signature error.
Here's my steps:
runtime_createExternalSignerPayload
to create the initial payload:That gives me this payload:
I sign the raw hex payload using my private key generated with the
ed25519
curve (I also verify the signature and it's valid). And returns me a signature:I use
runtime_submitExtrinsic
with these params:At this point I get a bad signature error, with multiple attempts you'd result in a
Transaction is temporarily banned
error.Could you help me debug the issue? Am I missing something? I don't know if this https://github.com/polkascan/substrate-interface-api/blob/master/app/resources/jsonrpc.py#L263 could possibly alterate my payload (invalidating the signature). Or if I'm missing any param.
Thanks