@@ -14,6 +14,7 @@ use crate::{
1414 high_level:: { QueryIter , load_cell_type_hash, load_input, load_script, load_script_hash} ,
1515 syscalls:: load_cell,
1616} ;
17+ use alloc:: vec:: Vec ;
1718use ckb_hash:: new_blake2b;
1819use ckb_types:: prelude:: Entity ;
1920
@@ -44,7 +45,7 @@ fn locate_index() -> Result<usize, SysError> {
4445///
4546/// # Arguments
4647///
47- /// * `type_id` - A 32-byte array representing the Type ID to validate.
48+ /// * `type_id` - A slice representing the Type ID to validate.
4849///
4950/// # Returns
5051///
@@ -62,9 +63,9 @@ fn locate_index() -> Result<usize, SysError> {
6263/// use ckb_std::type_id::validate_type_id;
6364///
6465/// let type_id = [0u8; 32];
65- /// validate_type_id(type_id)?;
66+ /// validate_type_id(& type_id)?;
6667/// ```
67- pub fn validate_type_id ( type_id : [ u8 ; 32 ] ) -> Result < ( ) , SysError > {
68+ pub fn validate_type_id ( type_id : & [ u8 ] ) -> Result < ( ) , SysError > {
6869 // after this checking, there are 3 cases:
6970 // 1. 0 input cell and 1 output cell, it's minting operation
7071 // 2. 1 input cell and 1 output cell, it's transfer operation
@@ -82,37 +83,38 @@ pub fn validate_type_id(type_id: [u8; 32]) -> Result<(), SysError> {
8283 blake2b. update ( & index. to_le_bytes ( ) ) ;
8384 let mut ret = [ 0 ; 32 ] ;
8485 blake2b. finalize ( & mut ret) ;
85-
86- if ret != type_id {
86+ if type_id. len ( ) > ret. len ( ) {
87+ return Err ( SysError :: TypeIDError ) ;
88+ }
89+ if & ret[ ..type_id. len ( ) ] != type_id {
8790 return Err ( SysError :: TypeIDError ) ;
8891 }
8992 }
9093 // case 2 & 3: for the `else` part, it's transfer operation or burning operation
9194 Ok ( ( ) )
9295}
9396
94- fn load_id_from_args ( offset : usize ) -> Result < [ u8 ; 32 ] , SysError > {
97+ fn load_id_from_args ( offset : usize , length : usize ) -> Result < Vec < u8 > , SysError > {
9598 let script = load_script ( ) ?;
9699 let args = script. as_reader ( ) . args ( ) ;
97100 let args_data = args. raw_data ( ) ;
98101
99- args_data
100- . get ( offset..offset + 32 )
102+ Ok ( args_data
103+ . get ( offset..offset + length )
101104 . ok_or ( SysError :: TypeIDError ) ?
102- . try_into ( )
103- . map_err ( |_| SysError :: TypeIDError )
105+ . to_vec ( ) )
104106}
105107
106108///
107109/// Validates that the script follows the Type ID rule.
108110///
109- /// This function checks if the Type ID (a 32-byte value ) stored in the script's `args`
111+ /// This function checks if the Type ID (variable length ) stored in the script's `args`
110112/// at the specified offset is valid according to the Type ID rules.
111113///
112114/// # Arguments
113115///
114116/// * `offset` - The byte offset in the script's `args` where the Type ID starts.
115- ///
117+ /// * `length` - The length of Type ID
116118/// # Returns
117119///
118120/// * `Ok(())` if the Type ID is valid.
@@ -125,7 +127,7 @@ fn load_id_from_args(offset: usize) -> Result<[u8; 32], SysError> {
125127///
126128/// fn main() -> Result<(), ckb_std::error::SysError> {
127129/// // Check the Type ID stored at the beginning of the script args
128- /// check_type_id(0)?;
130+ /// check_type_id(0, 32 )?;
129131/// Ok(())
130132/// }
131133/// ```
@@ -134,8 +136,8 @@ fn load_id_from_args(offset: usize) -> Result<[u8; 32], SysError> {
134136///
135137/// This function internally calls `load_id_from_args` to retrieve the Type ID
136138/// and then `validate_type_id` to perform the actual validation.
137- pub fn check_type_id ( offset : usize ) -> Result < ( ) , SysError > {
138- let type_id = load_id_from_args ( offset) ?;
139- validate_type_id ( type_id) ?;
139+ pub fn check_type_id ( offset : usize , length : usize ) -> Result < ( ) , SysError > {
140+ let type_id = load_id_from_args ( offset, length ) ?;
141+ validate_type_id ( & type_id) ?;
140142 Ok ( ( ) )
141143}
0 commit comments