1- global SELECTOR_LENGTH : u32 = 4 ;
1+ use crate::ArrayExtensions ;
22
3+ pub global SELECTOR_LENGTH : u32 = 4 ;
4+
5+ /// Encodes a function selector and its arguments into a byte array.
6+ ///
7+ /// ## Arguments
8+ ///
9+ /// * `selector` - The function selector to encode.
10+ /// * `args` - The arguments to encode.
11+ ///
12+ /// ## Returns
13+ ///
14+ /// A byte array containing the function selector and its arguments.
15+ ///
16+ /// ## Example
17+ ///
18+ /// ```noir
19+ /// let selector: u32 = 0xa9059cbb; // transfer(address,uint256)
20+ /// let args: [Field; 2] = [
21+ /// 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045, // address
22+ /// 123, // uint256
23+ /// ];
24+ /// let encoded = encode_with_selector(selector, args);
25+ /// ```
326pub fn encode_with_selector <let N : u32 >(
427 selector : u32 ,
528 args : [Field ; N ],
29+ ) -> [u8 ; SELECTOR_LENGTH + N * 32 ] {
30+ let selector_bytes : [u8 ; SELECTOR_LENGTH ] = (selector as Field ).to_be_bytes ();
31+ encode_with_selector_bytes (selector_bytes , args )
32+ }
33+
34+ pub fn encode_with_selector_bytes <let N : u32 >(
35+ selector : [u8 ; SELECTOR_LENGTH ],
36+ args : [Field ; N ],
637) -> [u8 ; SELECTOR_LENGTH + N * 32 ] {
738 let mut result = [0 ; SELECTOR_LENGTH + N * 32 ];
839
9- let selector_bytes : [u8 ; 4 ] = (selector as Field ).to_be_bytes ();
1040 for i in 0 ..SELECTOR_LENGTH {
11- result [i ] = selector_bytes [i ];
41+ result [i ] = selector [i ];
1242 }
1343
1444 for i in 0 ..N {
@@ -21,11 +51,15 @@ pub fn encode_with_selector<let N: u32>(
2151 result
2252}
2353
54+ pub fn to_selector <let N : u32 >(signature : str <N >) -> [u8 ; SELECTOR_LENGTH ] {
55+ crate ::keccak256 (signature .as_bytes ()).slice ::<SELECTOR_LENGTH >(0 )
56+ }
57+
2458mod tests {
25- use crate::solidity::encode_with_selector ;
59+ use crate::solidity:: { encode_with_selector , encode_with_selector_bytes , to_selector } ;
2660
2761 #[test]
28- fn test_simple () {
62+ fn test_simple_selector () {
2963 let selector : u32 = 0xa9059cbb ; // transfer(address,uint256)
3064 let args : [Field ; 2 ] = [
3165 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 , // address
@@ -40,6 +74,23 @@ mod tests {
4074 assert (encoded == expected );
4175 }
4276
77+ #[test]
78+ fn test_simple_signature () {
79+ let args : [Field ; 2 ] = [
80+ 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 , // address
81+ 123 , // uint256
82+ ];
83+
84+ let encoded =
85+ encode_with_selector_bytes (comptime { to_selector ("transfer(address,uint256)" ) }, args );
86+ let expected : [u8 ; 68 ] = [
87+ 169 , 5 , 156 , 187 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 216 , 218 , 107 , 242 , 105 , 100 , 175 ,
88+ 157 , 126 , 237 , 158 , 3 , 229 , 52 , 21 , 211 , 122 , 169 , 96 , 69 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ,
89+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 123 ,
90+ ];
91+ assert (encoded == expected );
92+ }
93+
4394 #[test]
4495 fn test_deposit () {
4596 let result = encode_with_selector (
0 commit comments