4545#define LABEL_INPUT_CELL_SINCE 0x3
4646#define LABEL_INPUT_OUTPOINT 0x4
4747
48- #define MASK_CELL_CAPACITY 0x0
49- #define MASK_CELL_TYPE_CODE_HASH 0x1
50- #define MASK_CELL_TYPE_ARGS 0x2
51- #define MASK_CELL_TYPE_HASH_TYPE 0x3
52- #define MASK_CELL_LOCK_CODE_HASH 0x4
53- #define MASK_CELL_LOCK_ARGS 0x5
54- #define MASK_CELL_LOCK_HASH_TYPE 0x6
55- #define MASK_CELL_DATA 0x7
48+ #define MASK_CELL_CAPACITY 0x1
49+ #define MASK_CELL_TYPE_CODE_HASH 0x2
50+ #define MASK_CELL_TYPE_ARGS 0x4
51+ #define MASK_CELL_TYPE_HASH_TYPE 0x8
52+ #define MASK_CELL_ANY_TYPE \
53+ (MASK_CELL_TYPE_CODE_HASH | MASK_CELL_TYPE_ARGS | MASK_CELL_TYPE_HASH_TYPE)
54+ #define MASK_CELL_LOCK_CODE_HASH 0x10
55+ #define MASK_CELL_LOCK_ARGS 0x20
56+ #define MASK_CELL_LOCK_HASH_TYPE 0x40
57+ #define MASK_CELL_ANY_LOCK \
58+ (MASK_CELL_LOCK_CODE_HASH | MASK_CELL_LOCK_ARGS | MASK_CELL_LOCK_HASH_TYPE)
59+ #define MASK_CELL_DATA 0x80
5660#define MASK_CELL_ALL 0xFF
5761
58- #define MASK_OUTPOINT_TX_HASH 0x0
59- #define MASK_OUTPOINT_INDEX 0x1
60- #define MASK_OUTPOINT_SINCE 0x2
62+ #define MASK_OUTPOINT_TX_HASH 0x1
63+ #define MASK_OUTPOINT_INDEX 0x2
64+ #define MASK_OUTPOINT_SINCE 0x4
6165#define MASK_OUTPOINT_ALL 0xFF
6266
6367// Extract lock from WitnessArgs
@@ -117,6 +121,38 @@ int hash_input(blake2b_state *ctx, size_t index_code, size_t source) {
117121 return load_and_hash (ctx , index_code , source , ckb_load_input );
118122}
119123
124+ int hash_script_fields (blake2b_state * ctx , size_t index_code , size_t source ,
125+ size_t field , uint8_t lock_masks ) {
126+ unsigned char script [SCRIPT_SIZE ];
127+ uint64_t len = SCRIPT_SIZE ;
128+ int ret = ckb_checked_load_cell_by_field (script , & len , 0 , index_code , source ,
129+ field );
130+ if (ret != CKB_SUCCESS ) {
131+ return ret ;
132+ }
133+ mol_seg_t script_seg ;
134+ script_seg .ptr = (uint8_t * )script ;
135+ script_seg .size = len ;
136+ if (MolReader_Script_verify (& script_seg , false) != MOL_OK ) {
137+ return ERROR_ENCODING ;
138+ }
139+
140+ if ((lock_masks & MASK_CELL_LOCK_CODE_HASH ) != 0 ) {
141+ mol_seg_t item_seg = MolReader_Script_get_code_hash (& script_seg );
142+ blake2b_update (ctx , item_seg .ptr , item_seg .size );
143+ }
144+ if ((lock_masks & MASK_CELL_LOCK_ARGS ) != 0 ) {
145+ mol_seg_t item_seg = MolReader_Script_get_args (& script_seg );
146+ blake2b_update (ctx , item_seg .ptr , item_seg .size );
147+ }
148+ if ((lock_masks & MASK_CELL_LOCK_HASH_TYPE ) != 0 ) {
149+ mol_seg_t item_seg = MolReader_Script_get_hash_type (& script_seg );
150+ blake2b_update (ctx , item_seg .ptr , item_seg .size );
151+ }
152+
153+ return CKB_SUCCESS ;
154+ }
155+
120156int main () {
121157 unsigned char witness [WITNESS_SIZE ];
122158 // Load witness of first input
@@ -191,10 +227,17 @@ int main() {
191227 case LABEL_INPUT_CELL_SINCE : {
192228 size_t source =
193229 (label == LABEL_OUTPUT ) ? CKB_SOURCE_OUTPUT : CKB_SOURCE_INPUT ;
194- size_t field ;
195- uint8_t item ;
196- switch (mask ) {
197- case MASK_CELL_CAPACITY : {
230+ if (mask == MASK_CELL_ALL ) {
231+ ret = hash_cell (& blake2b_ctx , index_code , source );
232+ if (ret != CKB_SUCCESS ) {
233+ return ret ;
234+ }
235+ ret = hash_cell_data (& blake2b_ctx , index_code , source );
236+ if (ret != CKB_SUCCESS ) {
237+ return ret ;
238+ }
239+ } else {
240+ if ((mask & MASK_CELL_CAPACITY ) != 0 ) {
198241 uint64_t capacity = 0 ;
199242 uint64_t len = 8 ;
200243 int ret = ckb_load_cell_by_field ((uint8_t * )(& capacity ), & len , 0 ,
@@ -204,137 +247,93 @@ int main() {
204247 return ret ;
205248 }
206249 blake2b_update (& blake2b_ctx , (uint8_t * )(& capacity ), 8 );
207- } break ;
208- case MASK_CELL_LOCK_CODE_HASH :
209- case MASK_CELL_LOCK_ARGS :
210- case MASK_CELL_LOCK_HASH_TYPE :
211- field = CKB_CELL_FIELD_LOCK ;
212- item = mask ;
213- goto PROCESS_SCRIPT ;
214- case MASK_CELL_TYPE_CODE_HASH :
215- field = CKB_CELL_FIELD_TYPE ;
216- item = MASK_CELL_LOCK_CODE_HASH ;
217- goto PROCESS_SCRIPT ;
218- case MASK_CELL_TYPE_ARGS :
219- field = CKB_CELL_FIELD_TYPE ;
220- item = MASK_CELL_LOCK_ARGS ;
221- goto PROCESS_SCRIPT ;
222- case MASK_CELL_TYPE_HASH_TYPE :
223- field = CKB_CELL_FIELD_TYPE ;
224- item = MASK_CELL_LOCK_HASH_TYPE ;
225- PROCESS_SCRIPT : {
226- unsigned char script [SCRIPT_SIZE ];
227- uint64_t len = SCRIPT_SIZE ;
228- int ret = ckb_checked_load_cell_by_field (script , & len , 0 ,
229- index_code , source , field );
230- if (ret != CKB_SUCCESS ) {
231- return ret ;
250+ }
251+ if ((mask & MASK_CELL_ANY_TYPE ) != 0 ) {
252+ uint8_t lock_masks = 0 ;
253+ if ((mask & MASK_CELL_TYPE_CODE_HASH ) != 0 ) {
254+ lock_masks |= MASK_CELL_LOCK_CODE_HASH ;
232255 }
233-
234- mol_seg_t script_seg ;
235- script_seg .ptr = (uint8_t * )script ;
236- script_seg .size = len ;
237- if (MolReader_Script_verify (& script_seg , false) != MOL_OK ) {
238- return ERROR_ENCODING ;
256+ if ((mask & MASK_CELL_TYPE_ARGS ) != 0 ) {
257+ lock_masks |= MASK_CELL_LOCK_ARGS ;
239258 }
240-
241- mol_seg_t item_seg ;
242- switch (item ) {
243- case MASK_CELL_LOCK_CODE_HASH :
244- item_seg = MolReader_Script_get_code_hash (& script_seg );
245- blake2b_update (& blake2b_ctx , item_seg .ptr , item_seg .size );
246- break ;
247- case MASK_CELL_LOCK_ARGS :
248- item_seg = MolReader_Script_get_args (& script_seg );
249- blake2b_update (& blake2b_ctx , item_seg .ptr , item_seg .size );
250- break ;
251- case MASK_CELL_LOCK_HASH_TYPE :
252- item_seg = MolReader_Script_get_hash_type (& script_seg );
253- blake2b_update (& blake2b_ctx , item_seg .ptr , item_seg .size );
254- break ;
259+ if ((mask & MASK_CELL_TYPE_HASH_TYPE ) != 0 ) {
260+ lock_masks |= MASK_CELL_LOCK_HASH_TYPE ;
255261 }
256- } break ;
257- case MASK_CELL_DATA :
258- ret = hash_cell_data (& blake2b_ctx , index_code , source );
262+ ret = hash_script_fields (& blake2b_ctx , index_code , source ,
263+ CKB_CELL_FIELD_TYPE , lock_masks );
259264 if (ret != CKB_SUCCESS ) {
260265 return ret ;
261266 }
262- break ;
263- case MASK_CELL_ALL :
264- ret = hash_cell (& blake2b_ctx , index_code , source );
267+ }
268+ if ((mask & MASK_CELL_ANY_LOCK ) != 0 ) {
269+ ret = hash_script_fields (& blake2b_ctx , index_code , source ,
270+ CKB_CELL_FIELD_LOCK , mask );
265271 if (ret != CKB_SUCCESS ) {
266272 return ret ;
267273 }
274+ }
275+ if ((mask & MASK_CELL_DATA ) != 0 ) {
268276 ret = hash_cell_data (& blake2b_ctx , index_code , source );
269277 if (ret != CKB_SUCCESS ) {
270278 return ret ;
271279 }
272- break ;
273- default :
274- return ERROR_INVALID_MASK ;
280+ }
275281 }
276282 if (label == LABEL_INPUT_CELL_SINCE ) {
277283 uint8_t since [8 ];
278284 uint64_t len = 8 ;
279- int ret = ckb_load_input_by_field ( since , & len , 0 , index_code , source ,
280- CKB_INPUT_FIELD_SINCE );
285+ int ret = ckb_checked_load_input_by_field (
286+ since , & len , 0 , index_code , source , CKB_INPUT_FIELD_SINCE );
281287 if (ret != CKB_SUCCESS ) {
282288 return ret ;
283289 }
284290 blake2b_update (& blake2b_ctx , since , 8 );
285291 }
286292 } break ;
287293 case LABEL_INPUT_OUTPOINT : {
288- uint8_t buf [INPUT_SIZE ];
289- uint64_t len = INPUT_SIZE ;
290- int ret ;
291294 if (mask == MASK_OUTPOINT_ALL ) {
292- ret = ckb_checked_load_input (buf , & len , 0 , index_code ,
293- CKB_SOURCE_INPUT );
295+ ret = hash_input (& blake2b_ctx , index_code , CKB_SOURCE_INPUT );
296+ if (ret != CKB_SUCCESS ) {
297+ return ret ;
298+ }
294299 } else {
295- switch (mask ) {
296- case MASK_OUTPOINT_SINCE :
297- ret = ckb_checked_load_input_by_field (buf , & len , 0 , index_code ,
298- CKB_SOURCE_INPUT ,
299- CKB_INPUT_FIELD_SINCE );
300- break ;
301- case MASK_OUTPOINT_TX_HASH :
302- case MASK_OUTPOINT_INDEX : {
303- uint8_t temp [INPUT_SIZE ];
304- uint64_t temp_len = INPUT_SIZE ;
305- ret = ckb_checked_load_input_by_field (
306- temp , & temp_len , 0 , index_code , CKB_SOURCE_INPUT ,
307- CKB_INPUT_FIELD_OUT_POINT );
308- if (ret != CKB_SUCCESS ) {
309- return ret ;
310- }
311- mol_seg_t outpoint_seg ;
312- outpoint_seg .ptr = temp ;
313- outpoint_seg .size = temp_len ;
314- if (MolReader_OutPoint_verify (& outpoint_seg , false) != MOL_OK ) {
315- return ERROR_ENCODING ;
316- }
317- if (mask == MASK_OUTPOINT_TX_HASH ) {
318- mol_seg_t tx_hash_seg =
319- MolReader_OutPoint_get_tx_hash (& outpoint_seg );
320- memcpy (buf , tx_hash_seg .ptr , tx_hash_seg .size );
321- len = tx_hash_seg .size ;
322- } else {
323- mol_seg_t index_seg =
324- MolReader_OutPoint_get_tx_hash (& index_seg );
325- memcpy (buf , index_seg .ptr , index_seg .size );
326- len = index_seg .size ;
327- }
328- ret = CKB_SUCCESS ;
329- } break ;
330- default :
331- return ERROR_INVALID_MASK ;
300+ if ((mask & MASK_OUTPOINT_SINCE ) != 0 ) {
301+ uint8_t since [8 ];
302+ uint64_t len = 8 ;
303+ ret = ckb_checked_load_input_by_field (since , & len , 0 , index_code ,
304+ CKB_SOURCE_INPUT ,
305+ CKB_INPUT_FIELD_SINCE );
306+ if (ret != CKB_SUCCESS ) {
307+ return ret ;
308+ }
309+ blake2b_update (& blake2b_ctx , since , 8 );
310+ }
311+
312+ uint8_t input_buf [INPUT_SIZE ];
313+ uint64_t input_len = INPUT_SIZE ;
314+ ret = ckb_checked_load_input_by_field (input_buf , & input_len , 0 ,
315+ index_code , CKB_SOURCE_INPUT ,
316+ CKB_INPUT_FIELD_OUT_POINT );
317+ if (ret != CKB_SUCCESS ) {
318+ return ret ;
319+ }
320+ mol_seg_t outpoint_seg ;
321+ outpoint_seg .ptr = input_buf ;
322+ outpoint_seg .size = input_len ;
323+ if (MolReader_OutPoint_verify (& outpoint_seg , false) != MOL_OK ) {
324+ return ERROR_ENCODING ;
325+ }
326+
327+ if ((mask & MASK_OUTPOINT_TX_HASH ) != 0 ) {
328+ mol_seg_t tx_hash_seg =
329+ MolReader_OutPoint_get_tx_hash (& outpoint_seg );
330+ blake2b_update (& blake2b_ctx , tx_hash_seg .ptr , tx_hash_seg .size );
331+ }
332+ if ((mask & MASK_OUTPOINT_INDEX ) != 0 ) {
333+ mol_seg_t index_seg = MolReader_OutPoint_get_tx_hash (& index_seg );
334+ blake2b_update (& blake2b_ctx , index_seg .ptr , index_seg .size );
332335 }
333336 }
334- if (ret != CKB_SUCCESS ) {
335- return ret ;
336- }
337- blake2b_update (& blake2b_ctx , buf , len );
338337 } break ;
339338 case LABEL_END_OF_LIST :
340339 has_more = 0 ;
0 commit comments