Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(gw-tools): sudt transfer with eip712 message #744

Merged
merged 1 commit into from
Jun 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crates/generator/src/account_lock_manage/eip712/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ pub trait EIP712Encode {
hasher.finalize().into()
}

fn eip712_message(&self, domain_seperator: [u8; 32]) -> [u8; 32] {
fn eip712_message(&self, domain_separator: [u8; 32]) -> [u8; 32] {
let mut hasher = Keccak256::new();
hasher.update(b"\x19\x01");
hasher.update(&domain_seperator);
hasher.update(&domain_separator);
hasher.update(&self.hash_struct());
hasher.finalize().into()
}
Expand Down
6 changes: 3 additions & 3 deletions crates/generator/src/account_lock_manage/eip712/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,8 @@ mod tests {
}

#[test]
fn test_domain_seperator_encoding() {
let domain_seperator = EIP712Domain {
fn test_domain_separator_encoding() {
let domain_separator = EIP712Domain {
name: "Ether Mail".to_string(),
version: "1".to_string(),
chain_id: 1,
Expand All @@ -414,7 +414,7 @@ mod tests {
},
salt: None,
};
let domain_hash = domain_seperator.hash_struct();
let domain_hash = domain_separator.hash_struct();
assert_eq!(
hex::encode(domain_hash),
"f2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f"
Expand Down
4 changes: 2 additions & 2 deletions crates/generator/src/account_lock_manage/secp256k1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ impl LockAlgorithm for Secp256k1Eth {
to_script_hash,
)
.map_err(|err| {
LockAlgorithmError::InvalidSignature(format!("Invlid l2 transaction format {}", err))
LockAlgorithmError::InvalidSignature(format!("Invalid l2 transaction format {}", err))
})?;
let message = typed_tx.eip712_message(Self::domain_with_chain_id(chain_id).hash_struct());
self.verify_alone(
Expand All @@ -251,7 +251,7 @@ impl LockAlgorithm for Secp256k1Eth {
address,
)
.map_err(|err| {
LockAlgorithmError::InvalidSignature(format!("Invlid withdrawal format {}", err))
LockAlgorithmError::InvalidSignature(format!("Invalid withdrawal format {}", err))
})?;
let message = typed_message.eip712_message(
Self::domain_with_chain_id(withdrawal.raw().chain_id().unpack()).hash_struct(),
Expand Down
2 changes: 0 additions & 2 deletions crates/tools/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1126,7 +1126,6 @@ async fn main() -> Result<()> {
let privkey_path = Path::new(m.value_of("privkey-path").unwrap());
let amount = m.value_of("amount").unwrap();
let fee = m.value_of("fee").unwrap();
let registry_id = m.value_of("eth-registry-id").unwrap().parse().unwrap();
let scripts_deployment_path = Path::new(m.value_of("scripts-deployment-path").unwrap());
let config_path = Path::new(m.value_of("config-path").unwrap());
let godwoken_rpc_url = m.value_of("godwoken-rpc-url").unwrap();
Expand All @@ -1144,7 +1143,6 @@ async fn main() -> Result<()> {
sudt_id,
amount,
fee,
registry_id,
config_path,
scripts_deployment_path,
)
Expand Down
28 changes: 17 additions & 11 deletions crates/tools/src/sudt/transfer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::account::{eth_sign, privkey_to_l2_script_hash, read_privkey};
use crate::godwoken_rpc::GodwokenRpcClient;
use crate::types::ScriptsDeploymentResult;
use crate::utils::message::generate_transaction_message_to_sign;
use crate::utils::message::generate_eip712_message_to_sign;
use crate::utils::transaction::{read_config, wait_for_l2_tx};
use anyhow::Result;
use ckb_jsonrpc_types::JsonBytes;
Expand All @@ -22,7 +22,6 @@ pub async fn transfer(
sudt_id: u32,
amount: &str,
fee: &str,
registry_id: u32,
config_path: &Path,
scripts_deployment_path: &Path,
) -> Result<()> {
Expand All @@ -48,6 +47,8 @@ pub async fn transfer(
.await?;
let from_id = from_id.expect("from id not found!");

let chain_id: u64 = config.genesis.rollup_config.chain_id.into();

let nonce = godwoken_rpc_client.get_nonce(from_id).await?;

let to_addr = hex::decode(to.trim_start_matches("0x"))?;
Expand All @@ -59,7 +60,7 @@ pub async fn transfer(
.amount(GwPack::pack(&amount))
.fee(
Fee::new_builder()
.registry_id(GwPack::pack(&registry_id))
.registry_id(GwPack::pack(&ETH_REGISTRY_ACCOUNT_ID))
.amount(GwPack::pack(&fee))
.build(),
)
Expand All @@ -72,16 +73,22 @@ pub async fn transfer(
.to_id(GwPack::pack(&sudt_id))
.nonce(GwPack::pack(&nonce))
.args(GwPack::pack(&sudt_args.as_bytes()))
.chain_id(chain_id.pack())
.build();

let sender_script_hash = godwoken_rpc_client.get_script_hash(from_id).await?;
let sender_registry_address = godwoken_rpc_client
.get_registry_address_by_script_hash(&sender_script_hash)
.await?
.expect("registry address");
let receiver_script_hash = godwoken_rpc_client.get_script_hash(sudt_id).await?;

let message = generate_transaction_message_to_sign(
&raw_l2transaction,
rollup_type_hash,
&sender_script_hash,
&receiver_script_hash,
let mut to_script_hash: [u8; 32] = [0; 32];
to_script_hash.copy_from_slice(receiver_script_hash.pack().as_slice());
let message = generate_eip712_message_to_sign(
raw_l2transaction.to_owned(),
sender_registry_address,
gw_common::H256::from(to_script_hash),
chain_id,
);
let signature = eth_sign(&message, privkey)?;

Expand All @@ -93,8 +100,7 @@ pub async fn transfer(
log::info!("l2 transaction: {}", l2_transaction);

let bytes = JsonBytes::from_bytes(l2_transaction.as_bytes());
let tx_hash = tokio::runtime::Handle::current()
.block_on(godwoken_rpc_client.submit_l2transaction(bytes))?;
let tx_hash = godwoken_rpc_client.submit_l2transaction(bytes).await?;

log::info!("tx_hash: 0x{}", faster_hex::hex_string(tx_hash.as_bytes())?);

Expand Down
35 changes: 35 additions & 0 deletions crates/tools/src/utils/message.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
use anyhow::anyhow;
use ckb_fixed_hash::H256;
use gw_generator::account_lock_manage::eip712::{self, types::EIP712Domain};
use gw_types::{packed::RawL2Transaction, prelude::*};

use crate::hasher::{CkbHasher, EthHasher};

fn domain_with_chain_id(chain_id: u64) -> EIP712Domain {
EIP712Domain {
name: "Godwoken".to_string(),
chain_id,
version: "1".to_string(),
verifying_contract: None,
salt: None,
}
}

pub fn generate_transaction_message_to_sign(
raw_l2transaction: &RawL2Transaction,
rollup_type_hash: &H256,
Expand All @@ -26,3 +38,26 @@ pub fn generate_transaction_message_to_sign(

message
}

pub fn generate_eip712_message_to_sign(
raw_l2transaction: RawL2Transaction,
sender_address: gw_common::registry_address::RegistryAddress,
receiver_script_hash: gw_common::H256,
chain_id: u64,
) -> H256 {
let typed_tx = eip712::types::L2Transaction::from_raw(
raw_l2transaction,
sender_address,
receiver_script_hash,
)
.map_err(|err| {
anyhow!(format!("Invalid l2transaction format {}", err));
})
.expect("l2transaction");

eip712::traits::EIP712Encode::eip712_message(
&typed_tx,
eip712::traits::EIP712Encode::hash_struct(&domain_with_chain_id(chain_id)),
)
.into()
}