From f0619b1e2eba3b1596b52359dca241bd28099de7 Mon Sep 17 00:00:00 2001 From: Eval EXEC Date: Wed, 6 Mar 2024 17:17:32 +0800 Subject: [PATCH 1/3] sudt amount should be u128 --- src/transaction/builder/sudt.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/transaction/builder/sudt.rs b/src/transaction/builder/sudt.rs index b56c678e..a70be99d 100644 --- a/src/transaction/builder/sudt.rs +++ b/src/transaction/builder/sudt.rs @@ -67,7 +67,7 @@ impl SudtTransactionBuilder { } /// Add an output cell with the given lock script and sudt amount - pub fn add_output>(&mut self, output_lock_script: S, sudt_amount: u64) { + pub fn add_output>(&mut self, output_lock_script: S, sudt_amount: u128) { let type_script = build_sudt_type_script( self.configuration.network_info(), &self.sudt_owner_lock_script, @@ -122,10 +122,10 @@ impl CkbTransactionBuilder for SudtTransactionBuilder { let mut sudt_input_iter = input_iter.clone(); sudt_input_iter.set_type_script(Some(sudt_type_script)); - let outputs_sudt_amount: u64 = tx + let outputs_sudt_amount: u128 = tx .outputs_data .iter() - .map(|data| u64::from_le_bytes(data.raw_data().as_ref().try_into().unwrap())) + .map(|data| u128::from_le_bytes(data.raw_data().as_ref().try_into().unwrap())) .sum(); let mut inputs_sudt_amount = 0; @@ -133,7 +133,7 @@ impl CkbTransactionBuilder for SudtTransactionBuilder { for input in sudt_input_iter { let input = input?; let input_amount = - u64::from_le_bytes(input.live_cell.output_data.as_ref().try_into().unwrap()); + u128::from_le_bytes(input.live_cell.output_data.as_ref().try_into().unwrap()); inputs_sudt_amount += input_amount; input_iter.push_input(input); if inputs_sudt_amount >= outputs_sudt_amount { From a68117a6869339cd2f5c632a80c27bf3b1cca020 Mon Sep 17 00:00:00 2001 From: Eval EXEC Date: Wed, 6 Mar 2024 18:02:48 +0800 Subject: [PATCH 2/3] Check if sudt amount bytes length is less than u128 --- src/transaction/builder/sudt.rs | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/transaction/builder/sudt.rs b/src/transaction/builder/sudt.rs index a70be99d..6295da3b 100644 --- a/src/transaction/builder/sudt.rs +++ b/src/transaction/builder/sudt.rs @@ -8,6 +8,7 @@ use crate::{ tx_builder::{BalanceTxCapacityError, TxBuilderError}, NetworkInfo, NetworkType, TransactionWithScriptGroups, }; +use anyhow::anyhow; use ckb_types::{ core::{Capacity, ScriptHashType}, @@ -125,8 +126,25 @@ impl CkbTransactionBuilder for SudtTransactionBuilder { let outputs_sudt_amount: u128 = tx .outputs_data .iter() - .map(|data| u128::from_le_bytes(data.raw_data().as_ref().try_into().unwrap())) - .sum(); + .map(|data| { + if data.len() > std::mem::size_of::() { + return Err(TxBuilderError::Other(anyhow!( + "stdt_amount bytes length greater than 128" + ))); + } + if data.len() % std::mem::size_of::() != 0 { + return Err(TxBuilderError::Other(anyhow!( + "stdt_amount bytes length is not a multiple of u8 size" + ))); + } + + let mut data_bytes: Vec = + vec![0_u8; std::mem::size_of::() - data.len()]; + data_bytes.extend_from_slice(data.as_slice()); + Ok(u128::from_le_bytes(data_bytes.try_into().unwrap())) + }) + .collect::, TxBuilderError>>() + .map(|u128_vec| u128_vec.iter().sum())?; let mut inputs_sudt_amount = 0; From c8e34c59207b4c62ced380ee94507daa0ab64860 Mon Sep 17 00:00:00 2001 From: Eval EXEC Date: Wed, 6 Mar 2024 18:08:14 +0800 Subject: [PATCH 3/3] Extract parse_u128 Signed-off-by: Eval EXEC --- src/transaction/builder/sudt.rs | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/transaction/builder/sudt.rs b/src/transaction/builder/sudt.rs index 6295da3b..b137b5b6 100644 --- a/src/transaction/builder/sudt.rs +++ b/src/transaction/builder/sudt.rs @@ -90,6 +90,18 @@ impl SudtTransactionBuilder { } } +fn parse_u128(data: &[u8]) -> Result { + if data.len() > std::mem::size_of::() { + return Err(TxBuilderError::Other(anyhow!( + "stdt_amount bytes length greater than 128" + ))); + } + + let mut data_bytes: Vec = data.into(); + data_bytes.extend(std::iter::repeat(0_u8).take(std::mem::size_of::() - data.len())); + Ok(u128::from_le_bytes(data_bytes.try_into().unwrap())) +} + impl CkbTransactionBuilder for SudtTransactionBuilder { fn build( mut self, @@ -126,23 +138,7 @@ impl CkbTransactionBuilder for SudtTransactionBuilder { let outputs_sudt_amount: u128 = tx .outputs_data .iter() - .map(|data| { - if data.len() > std::mem::size_of::() { - return Err(TxBuilderError::Other(anyhow!( - "stdt_amount bytes length greater than 128" - ))); - } - if data.len() % std::mem::size_of::() != 0 { - return Err(TxBuilderError::Other(anyhow!( - "stdt_amount bytes length is not a multiple of u8 size" - ))); - } - - let mut data_bytes: Vec = - vec![0_u8; std::mem::size_of::() - data.len()]; - data_bytes.extend_from_slice(data.as_slice()); - Ok(u128::from_le_bytes(data_bytes.try_into().unwrap())) - }) + .map(|data| parse_u128(data.as_slice())) .collect::, TxBuilderError>>() .map(|u128_vec| u128_vec.iter().sum())?; @@ -150,8 +146,7 @@ impl CkbTransactionBuilder for SudtTransactionBuilder { for input in sudt_input_iter { let input = input?; - let input_amount = - u128::from_le_bytes(input.live_cell.output_data.as_ref().try_into().unwrap()); + let input_amount = parse_u128(input.live_cell.output_data.as_ref())?; inputs_sudt_amount += input_amount; input_iter.push_input(input); if inputs_sudt_amount >= outputs_sudt_amount {