Skip to content

Commit 98cf0ff

Browse files
committed
feat: add solidity::to_selector
1 parent d980531 commit 98cf0ff

File tree

2 files changed

+57
-6
lines changed

2 files changed

+57
-6
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Nodash is a utility library for [Noir](https://github.com/noir-lang/noir) langua
77
Put this into your Nargo.toml.
88

99
```toml
10-
nodash = { git = "https://github.com/olehmisar/nodash/", tag = "v0.41.0" }
10+
nodash = { git = "https://github.com/olehmisar/nodash/", tag = "v0.41.1" }
1111
```
1212

1313
## Docs

src/solidity.nr

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,44 @@
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+
/// ```
326
pub 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+
2458
mod 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

Comments
 (0)