polkascan / py-substrate-interface

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

signing transactions #10

Closed drandreaskrueger closed 4 years ago

drandreaskrueger commented 4 years ago

Signing transactions - some temporary fix:

Chat result, hooray: Shawn will give us some kind of a PolkadotJS wrapper: https://riot.im/app/#/room/#polkadot-watercooler:matrix.org/$1583868900119793gprSi:matrix.parity.io

then this code

import substrateinterface 
substrate = substrateinterface.SubstrateInterface(url="ws://127.0.0.1:9944/")

BOB_ADDRESS = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'

payload = substrate.compose_call(call_module='Balances',
                                 call_function='transfer',
                                 call_params={'dest': BOB_ADDRESS,
                                              'value': 1000000000000})
print (payload.replace("0x", ""))

should generate the unsigned input payload for that signing tool.

And Balance.transfer(dest, value) is just an example, I want to send a signed transaction to my own Module. But once that Balance transfer tx signing works ... we have made a big step foward, right?

drandreaskrueger commented 4 years ago

The current best version of node-template ... is this one:

git clone https://github.com/substrate-developer-hub/substrate-node-template sdh_node-template_v2
cd sdh_node-template_v2
git checkout 8b6fe666
nice cargo build --release

which is based on

git clone https://github.com/paritytech/substrate/ paritytech_substrate_v2
cd paritytech_substrate_v2/
git checkout 3e65111
nice cargo build --release

because that is "Current Stable Version ... pre-v2.0-3e65111" https://substrate.dev/en/versions

(and dunno whether that matters, but I am using node-template build-spec --chain local as the basis for my network.)

drandreaskrueger commented 4 years ago

When I run the above Python code, with such a node-template node connected, the payload for signing is:

a8040400ff8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48070010a5d4e8

Anyways, ANY signing tool probably needs these 4-5 inputs, so I am leaving that here for that purpose, that you have an example input for any signing tool:

subkey sign-transaction \
--call a8040400ff8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48070010a5d4e8
--nonce 0 \
--prior-block-hash 0xdbe8bc87e48ad7a17c28d7ac6116b7252d186ed4cda66ae6044358d7e95ccacd  \
--suri "//Alice" 
--password ""
drandreaskrueger commented 4 years ago

hooray, success:

docker run jacogr/polkadot-js-tools signer sign --type sr25519 --account //Alice --seed "//Alice" 0xa8040400ff8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48070010a5d4e8

Signature: 0x019ed139765d9eba74d977ac223aa6d4fde2cb447c2d6b9b0811ca979691af7b0cc3914187652ca8c730c72edec939f14d06ce41f6353f147c2a1b566906ca5282

drandreaskrueger commented 4 years ago

Hi @arjanz now that we finally know how to sign a transaction without subkey ... the last step needed is again the correct struct format and usage of the scalecodec, for submitting the extrinsic - right?

I have prepared as much as I could - the following code fully executes ... just with a node error returned, until the params=lalala is in the correct format for the "author_submitExtrinsic" call.

from pprint import pprint
import substrateinterface 
substrate = substrateinterface.SubstrateInterface(url="ws://127.0.0.1:9944/")

BOB_ADDRESS = '5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty'
payload = substrate.compose_call(call_module='Balances',
                                 call_function='transfer',
                                 call_params={'dest': BOB_ADDRESS,
                                              'value': 1000000000000})
print ("payload input: ", payload)
# 0xa8040400ff8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48070010a5d4e8

# docker run jacogr/polkadot-js-tools signer sign --type sr25519 --account //Alice --seed "//Alice" 0xa8040400ff8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48070010a5d4e8
# Signature: 0x019c9e11b24183d4864c401e267584fdeb08282eb0a7c21d0bd35fab99628d5f416c7c14ee94518579c4ff845508aee83f0006aab2e2c5ce091e2ba5006ee01081

signed = "0x019c9e11b24183d4864c401e267584fdeb08282eb0a7c21d0bd35fab99628d5f416c7c14ee94518579c4ff845508aee83f0006aab2e2c5ce091e2ba5006ee01081"
print ("payload signed:", signed)

extrinsic = {"signature": signed}

def encode_extrinsic(struct):
    # probably scale encoding again???
    # this might help: https://wiki.polkadot.network/docs/en/build-exchange-integration#transferring-balances
    return 0x0000

# result = substrate.rpc_request(method="rpc_methods", params=None)
method = "author_submitExtrinsic"; print ("RPC method:    ", method)
result = substrate.rpc_request(method=method, params=[encode_extrinsic(extrinsic)])
result = result["result"] if "result" in result.keys() else result["error"]
pprint (result, width=120)

please fill the 2 blanks extrinsic = {"signature": signed, ...: ...}and def encode_extrinsic()

Thanks a lot! Andreas

drandreaskrueger commented 4 years ago

Which is the official RPC endpoints documentation (that is valid for the current stable version of substrate / node-template), incl. the scale codec instructions for the exact parameters of that RPC endpoint? Anyone? Thanks.

emielsebastiaan commented 4 years ago

You can find a summary of the broader work in this development update: https://medium.com/polkadot-network/polkascan-development-update-5-58521f2c8d66 This summary references the various sets of documentation we have delivered related to this work.

Documentation can be found in the README.md files at the root of each independent repository. The documentation was written around 31 January 2020. Given the heavy flux of Substrate, we cannot guarantee that this documentation is up to date. That said, the documentation reflects the state of affairs at 31 January 2020.

Additionally our grant work was explicitly designed to support Kusama production networks. Although we aim to eventually provide turn key support for any substrate based network, our priorities are with supporting launched public production networks and launched public test networks. These priorities are primarily driven by our Block Explorer use case.

Please note that our documentation does not necessarily cover official end-points that are provided by a Substrate-node. You should refer to Parity Technology or Web3 Foundation resources for official Substrate RPC documentation.

I hope this helps.

drandreaskrueger commented 4 years ago

Oh I am sorry, emiel, that was a misunderstanding. I did not mean YOUR library's endpoints. But that of substrate/node-template. There are always so many versions, and some outdated, that it helps to ask which is uptodate.

In these issues here on github, people are collaborating to solve the problems - so I asked in several places. Then we can then use that info to hopefully make the next micro step forwards ;-)

And yes, I had also asked there: https://github.com/paritytech/substrate/issues/5180#issuecomment-597738404

arjanz commented 4 years ago

Hi @drandreaskrueger, good work finding a usable workaround to make signing already possible! The encoding of all SCALE-types is done via the 'encode()' functions and an extrinsic is also a type (named ExtrinsicsDecoder). Our main focus is now on some other subjects, but if I have some time to spare I'll try to make an initial attempt.

drandreaskrueger commented 4 years ago

Congrats !!

_Remark
| First extrinsic created, signed and submitted with py-substrate-interface! :)

https://polkascan.io/pre/kusama/transaction/0x746fe24a6e8f209f8a380b133660c2bb23a57297f4de035b73a6e9d64751b848

Thanks to @EdwardAThomson for notifying on twitter.

arjanz commented 4 years ago

Thanks :) We will make this available very soon

arjanz commented 4 years ago

Good news, today we've released a first version which makes signing possible: https://github.com/polkascan/py-substrate-interface#create-and-send-signed-extrinsics