Skip to content

Commit

Permalink
[rooch-networkgh-2381] modify sign command for signing.
Browse files Browse the repository at this point in the history
  • Loading branch information
Feliciss committed Sep 8, 2024
1 parent a0f1f33 commit 4959be4
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 87 deletions.
38 changes: 5 additions & 33 deletions crates/rooch-rpc-api/src/jsonrpc_types/account_sign_view.rs
Original file line number Diff line number Diff line change
@@ -1,46 +1,18 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0

use rooch_types::{crypto::Signature, framework::auth_payload::AuthPayload};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use super::BytesView;

#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct AccountSignView {
pub msg: String,
pub payload: AuthPayloadView,
}

#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct AuthPayloadView {
pub signature: BytesView,
pub message_prefix: BytesView,
pub message_info: BytesView,
pub public_key: BytesView,
pub from_address: String,
pub signature: Signature,
pub payload: AuthPayload,
}

impl AccountSignView {
pub fn new(msg: String, payload: AuthPayloadView) -> Self {
Self { msg, payload }
}
}

impl AuthPayloadView {
pub fn new(
signature: BytesView,
message_prefix: BytesView,
message_info: BytesView,
public_key: BytesView,
from_address: String,
) -> Self {
Self {
signature,
message_prefix,
message_info,
public_key,
from_address,
}
pub fn new(signature: Signature, payload: AuthPayload) -> Self {
Self { signature, payload }
}
}
3 changes: 2 additions & 1 deletion crates/rooch-types/src/framework/auth_payload.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use moveos_types::{
h256::{sha2_256_of, H256},
state::{MoveStructState, MoveStructType},
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use std::io;

Expand Down Expand Up @@ -94,7 +95,7 @@ impl Decodable for SignData {
}
}

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
pub struct AuthPayload {
// Message signature
pub signature: Vec<u8>,
Expand Down
106 changes: 66 additions & 40 deletions crates/rooch/src/commands/account/commands/sign.rs
Original file line number Diff line number Diff line change
@@ -1,74 +1,100 @@
// Copyright (c) RoochNetwork
// SPDX-License-Identifier: Apache-2.0

use crate::cli_types::{CommandAction, WalletContextOptions};
use crate::cli_types::{CommandAction, TransactionOptions, WalletContextOptions};
use anyhow::Result;
use async_trait::async_trait;
use clap::Parser;
use hex::ToHex;
use moveos_types::state::MoveState;
use move_command_line_common::types::ParsedStructType;
use move_core_types::language_storage::TypeTag;
use moveos_types::transaction::MoveAction;
use rooch_key::keystore::account_keystore::AccountKeystore;
use rooch_rpc_api::jsonrpc_types::{
account_sign_view::{AccountSignView, AuthPayloadView},
BytesView,
};
use rooch_types::{
address::ParsedAddress,
error::{RoochError, RoochResult},
error::RoochResult,
framework::auth_payload::{AuthPayload, SignData},
function_arg::{parse_function_arg, FunctionArg, ParsedFunctionId},
};
use std::str::FromStr;

/// Sign an msg with current account private key (sign_hashed)
///
/// This operation must be specified with -a or
/// --address to export only one address with a private key.
#[derive(Debug, Parser)]
pub struct SignCommand {
#[clap(short = 'a', long = "address", value_parser=ParsedAddress::parse, default_value = "")]
address: ParsedAddress,
/// Function name as `<ADDRESS>::<MODULE_ID>::<FUNCTION_NAME>`
/// Example: `0x42::message::set_message`, `rooch_framework::empty::empty`
#[clap(long, required = true)]
pub function: ParsedFunctionId,

/// TypeTag arguments separated by spaces.
///
/// Example: `0x1::M::T1 0x1::M::T2 rooch_framework::empty::Empty`
#[clap(
long = "type-args",
value_parser=ParsedStructType::parse,
)]
pub type_args: Vec<ParsedStructType>,

/// Arguments combined with their type separated by spaces.
///
/// Supported types [u8, u16, u32, u64, u128, u256, bool, object_id, string, address, vector<inner_type>]
///
/// Example: `address:0x1 bool:true u8:0 u256:1234 'vector<u32>:a,b,c,d'`
/// address and uint can be written in short form like `@0x1 1u8 4123u256`.
#[clap(long = "args", value_parser=parse_function_arg)]
pub args: Vec<FunctionArg>,

#[clap(flatten)]
tx_options: TransactionOptions,

#[clap(flatten)]
pub context_options: WalletContextOptions,

/// Return command outputs in json format
#[clap(long, default_value = "false")]
json: bool,

/// Msg command will sign
#[clap(long, default_value = "")]
msg: String,
}

#[async_trait]
impl CommandAction<Option<AccountSignView>> for SignCommand {
async fn execute(self) -> RoochResult<Option<AccountSignView>> {
impl CommandAction<Option<AuthPayload>> for SignCommand {
async fn execute(self) -> RoochResult<Option<AuthPayload>> {
let context = self.context_options.build_require_password()?;
let password = context.get_password();
let address_mapping = context.address_mapping();
let sender = context.resolve_address(self.tx_options.sender)?.into();
let kp = context.keystore.get_key_pair(&sender, password)?;
let bitcoin_address = kp.public().bitcoin_address()?;
let max_gas_amount = self.tx_options.max_gas_amount;

let mapping = context.address_mapping();
let address = self.address.into_rooch_address(&mapping).map_err(|e| {
RoochError::CommandArgumentError(format!("Invalid Rooch address String: {}", e))
})?;

let signature = context.keystore.sign_hashed(
&address,
&self.msg.clone().to_bytes(),
password.clone(),
)?;

let kp = context.keystore.get_key_pair(&address, password)?;
let function_id = self.function.into_function_id(&address_mapping)?;
let args = self
.args
.into_iter()
.map(|arg| arg.into_bytes(&address_mapping))
.collect::<Result<Vec<_>>>()?;
let type_args = self
.type_args
.into_iter()
.map(|tag| {
Ok(TypeTag::Struct(Box::new(
tag.into_struct_tag(&address_mapping)?,
)))
})
.collect::<Result<Vec<_>>>()?;
let action = MoveAction::new_function_call(function_id, type_args, args);

let auth_payload = AuthPayloadView::new(
BytesView::from(signature.as_ref().to_vec()),
BytesView::from_str("Bitcoin Signed Message:\n")?,
BytesView::from_str("Rooch Transaction:\n")?,
BytesView::from(kp.public().as_ref().to_vec()),
address.clone().to_bech32(),
);
let tx_data = context
.build_tx_data(sender, action, max_gas_amount)
.await?;
let sign_data = SignData::new_with_default(&tx_data);
let data_hash = sign_data.data_hash();
let signature = kp.sign(data_hash.as_bytes());
let auth_payload = AuthPayload::new(sign_data, signature, bitcoin_address.to_string());

if self.json {
Ok(Some(AccountSignView::new(self.msg.clone(), auth_payload)))
Ok(Some(auth_payload))
} else {
println!("Msg you input : {}", &self.msg);
println!("Signature : {}", signature.encode_hex::<String>());
println!("Auth Payload: {:?}", auth_payload);
Ok(None)
}
}
Expand Down
20 changes: 7 additions & 13 deletions crates/rooch/src/commands/account/commands/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ use rooch_key::keystore::account_keystore::AccountKeystore;
use rooch_rpc_api::jsonrpc_types::account_sign_view::AccountSignView;
use rooch_types::error::{RoochError, RoochResult};

/// Sign an msg with current account private key (sign_hashed)
/// Verify a signed message
///
/// This operation must be specified with -a or
/// --address to export only one address with a private key.
/// This operation must be specified with -m, or
/// --message to verify the signed message
#[derive(Debug, Parser)]
pub struct VerifyCommand {
/// signature that will be verified
#[clap(long, required = true)]
signature: String,
/// the message to be verified
#[clap(short = 'm', long, required = true)]
message: String,

#[clap(flatten)]
pub context_options: WalletContextOptions,
Expand All @@ -34,14 +34,8 @@ impl CommandAction<Option<AccountSignView>> for VerifyCommand {
let password = context.get_password();

let mapping = context.address_mapping();
let addrss = self.signature.into_rooch_address(&mapping).map_err(|e| {
RoochError::CommandArgumentError(format!("Invalid Rooch address String: {}", e))
})?;

let mut msg_body = Vec::<u8>::new();
msg_body.copy_from_slice(&auth_payload.message_prefix);
msg_body.copy_from_slice(&self.msg.clone().into_bytes());

self.message;
let signature = context.keystore.sign_hashed(&addrss, &msg_body, password)?;

if self.json {
Expand Down

0 comments on commit 4959be4

Please sign in to comment.