mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-29 04:27:57 +00:00
bc53b9a03a
* Change copyright year to 2023 from 2022 * Fix incorrect update of copyright year * Remove years from copy right header * Fix remaining files * Fix typo in a header and remove update-copyright.sh
127 lines
3.5 KiB
Rust
127 lines
3.5 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
//! Implementation of the `sign` subcommand
|
|
use crate::{
|
|
error, params::MessageParams, utils, with_crypto_scheme, CryptoSchemeFlag, KeystoreParams,
|
|
};
|
|
use array_bytes::bytes2hex;
|
|
use clap::Parser;
|
|
use sp_core::crypto::SecretString;
|
|
use std::io::{BufRead, Write};
|
|
|
|
/// The `sign` command
|
|
#[derive(Debug, Clone, Parser)]
|
|
#[command(name = "sign", about = "Sign a message, with a given (secret) key")]
|
|
pub struct SignCmd {
|
|
/// The secret key URI.
|
|
/// If the value is a file, the file content is used as URI.
|
|
/// If not given, you will be prompted for the URI.
|
|
#[arg(long)]
|
|
suri: Option<String>,
|
|
|
|
#[allow(missing_docs)]
|
|
#[clap(flatten)]
|
|
pub message_params: MessageParams,
|
|
|
|
#[allow(missing_docs)]
|
|
#[clap(flatten)]
|
|
pub keystore_params: KeystoreParams,
|
|
|
|
#[allow(missing_docs)]
|
|
#[clap(flatten)]
|
|
pub crypto_scheme: CryptoSchemeFlag,
|
|
}
|
|
|
|
impl SignCmd {
|
|
/// Run the command
|
|
pub fn run(&self) -> error::Result<()> {
|
|
let sig = self.sign(|| std::io::stdin().lock())?;
|
|
std::io::stdout().lock().write_all(sig.as_bytes())?;
|
|
Ok(())
|
|
}
|
|
|
|
/// Sign a message.
|
|
///
|
|
/// The message can either be provided as immediate argument via CLI or otherwise read from the
|
|
/// reader created by `create_reader`. The reader will only be created in case that the message
|
|
/// is not passed as immediate.
|
|
pub(crate) fn sign<F, R>(&self, create_reader: F) -> error::Result<String>
|
|
where
|
|
R: BufRead,
|
|
F: FnOnce() -> R,
|
|
{
|
|
let message = self.message_params.message_from(create_reader)?;
|
|
let suri = utils::read_uri(self.suri.as_ref())?;
|
|
let password = self.keystore_params.read_password()?;
|
|
|
|
with_crypto_scheme!(self.crypto_scheme.scheme, sign(&suri, password, message))
|
|
}
|
|
}
|
|
|
|
fn sign<P: sp_core::Pair>(
|
|
suri: &str,
|
|
password: Option<SecretString>,
|
|
message: Vec<u8>,
|
|
) -> error::Result<String> {
|
|
let pair = utils::pair_from_suri::<P>(suri, password)?;
|
|
Ok(bytes2hex("0x", pair.sign(&message).as_ref()))
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod test {
|
|
use super::*;
|
|
|
|
const SEED: &str = "0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a";
|
|
|
|
#[test]
|
|
fn sign_arg() {
|
|
let cmd = SignCmd::parse_from(&[
|
|
"sign",
|
|
"--suri",
|
|
&SEED,
|
|
"--message",
|
|
&SEED,
|
|
"--password",
|
|
"12345",
|
|
"--hex",
|
|
]);
|
|
let sig = cmd.sign(|| std::io::stdin().lock()).expect("Must sign");
|
|
|
|
assert!(sig.starts_with("0x"), "Signature must start with 0x");
|
|
assert!(array_bytes::hex2bytes(&sig).is_ok(), "Signature is valid hex");
|
|
}
|
|
|
|
#[test]
|
|
fn sign_stdin() {
|
|
let cmd = SignCmd::parse_from(&[
|
|
"sign",
|
|
"--suri",
|
|
SEED,
|
|
"--message",
|
|
&SEED,
|
|
"--password",
|
|
"12345",
|
|
]);
|
|
let sig = cmd.sign(|| SEED.as_bytes()).expect("Must sign");
|
|
|
|
assert!(sig.starts_with("0x"), "Signature must start with 0x");
|
|
assert!(array_bytes::hex2bytes(&sig).is_ok(), "Signature is valid hex");
|
|
}
|
|
}
|