Add possibility to sign calls via cli (#2549)

* Add possibility to sign calls via cli

* Update subkey/README.adoc

Co-Authored-By: Robert Habermeier <rphmeier@gmail.com>
This commit is contained in:
Michael Müller
2019-05-13 21:18:14 +02:00
committed by Gavin Wood
parent e5b0a98f1a
commit 7f3d71d306
3 changed files with 90 additions and 0 deletions
+15
View File
@@ -53,3 +53,18 @@ You can use the included vanity generator to find a seed that provides an addres
```bash
subkey vanity 1337
```
=== Signing a transaction
Sign a transaction from an encoded `Call`.
```bash
subkey sign-transaction \
--call <call-as-hex> \
--nonce 0 \
--suri <secret-uri> \
--password <password> \
--prior-block-hash <prior-block-hash-as-hex>
```
Will output a signed and encoded `UncheckedMortalCompactExtrinsic` as hex.
+33
View File
@@ -92,3 +92,36 @@ subcommands:
help: Number of keys to generate
takes_value: true
default_value: "1"
- sign-transaction:
about: Sign transaction from encoded Call. Returns a signed and encoded UncheckedMortalCompactExtrinsic as hex.
args:
- call:
short: c
long: call
help: The call, hex-encoded.
takes_value: true
required: true
- nonce:
short: n
long: nonce
help: The nonce.
takes_value: true
required: true
- suri:
long: suri
short: s
help: The secret key URI.
takes_value: true
required: true
- password:
short: p
long: password
takes_value: true
help: The password for the key.
required: true
- prior-block-hash:
short: h
long: prior-block-hash
help: The prior block hash, hex-encoded.
takes_value: true
required: true
+42
View File
@@ -223,6 +223,48 @@ fn execute<C: Crypto<Seed=[u8; 32]>>(matches: clap::ArgMatches) where
);
println!("0x{}", hex::encode(&extrinsic.encode()));
}
("sign-transaction", Some(matches)) => {
let s = matches.value_of("suri")
.expect("secret URI parameter is required; thus it can't be None; qed");
let signer = Sr25519::pair_from_suri(s, password);
let index = matches.value_of("nonce")
.expect("nonce is required; thus it can't be None; qed");
let index = str::parse::<Index>(index)
.expect("Invalid 'index' parameter; expecting an integer.");
let call = matches.value_of("call")
.expect("call is required; thus it can't be None; qed");
let function: Call = hex::decode(&call).ok()
.and_then(|x| Decode::decode(&mut &x[..])).unwrap();
let h = matches.value_of("prior-block-hash")
.expect("prior-block-hash is required; thus it can't be None; qed");
let prior_block_hash: Hash = hex::decode(h).ok()
.and_then(|x| Decode::decode(&mut &x[..]))
.expect("Invalid prior block hash");
let era = Era::immortal();
let raw_payload = (Compact(index), function, era, prior_block_hash);
let signature = raw_payload.using_encoded(|payload|
if payload.len() > 256 {
signer.sign(&blake2_256(payload)[..])
} else {
signer.sign(payload)
}
);
let extrinsic = UncheckedExtrinsic::new_signed(
index,
raw_payload.1,
signer.public().into(),
signature.into(),
era,
);
println!("0x{}", hex::encode(&extrinsic.encode()));
}
("verify", Some(matches)) => {
let sig_data = matches.value_of("sig")
.expect("signature parameter is required; thus it can't be None; qed");