#[derive(LightHasher)]
{
// Attributes available to this derive:
#[skip]
#[hash]
}
Expand description
Makes the annotated struct hashable by implementing the following traits:
AsByteVec
, which makes the struct convertable to a 2D byte vector.DataHasher
, which makes the struct hashable with thehash()
method, based on the byte inputs fromAsByteVec
implementation.
This macro assumes that all the fields of the struct implement the
AsByteVec
trait. The trait is implemented by default for the most of
standard Rust types (primitives, String
, arrays and options carrying the
former). If there is a field of a type not implementing the trait, there
are two options:
- The most recommended one - annotating that type with the
light_hasher
macro as well. - Manually implementing the
AsByteVec
trait.
§Attributes
skip
- skips the given field, it doesn’t get included neither inAsByteVec
norDataHasher
implementation.hash
- makes sure that the byte value does not exceed the BN254 prime field modulus, by hashing it (with Keccak) and truncating it to 31 bytes. It’s generally a good idea to use it on any field which is expected to output more than 31 bytes.
§Examples
Compressed account with only primitive types as fields:
ⓘ
#[derive(LightHasher)]
pub struct MyCompressedAccount {
a: i64,
b: Option<u64>,
}
Compressed account with fields which might exceed the BN254 prime field:
ⓘ
#[derive(LightHasher)]
pub struct MyCompressedAccount {
a: i64
b: Option<u64>,
#[hash]
c: [u8; 32],
#[hash]
d: String,
}
Compressed account with fields we want to skip:
ⓘ
#[derive(LightHasher)]
pub struct MyCompressedAccount {
a: i64
b: Option<u64>,
#[skip]
c: [u8; 32],
}
Compressed account with a nested struct:
ⓘ
#[derive(LightHasher)]
pub struct MyCompressedAccount {
a: i64
b: Option<u64>,
c: MyStruct,
}
#[derive(LightHasher)]
pub struct MyStruct {
a: i32
b: u32,
}
Compressed account with a type with a custom AsByteVec
implementation:
ⓘ
#[derive(LightHasher)]
pub struct MyCompressedAccount {
a: i64
b: Option<u64>,
c: RData,
}
pub enum RData {
A(Ipv4Addr),
AAAA(Ipv6Addr),
CName(String),
}
impl AsByteVec for RData {
fn as_byte_vec(&self) -> Vec<Vec<u8>> {
match self {
Self::A(ipv4_addr) => vec![ipv4_addr.octets().to_vec()],
Self::AAAA(ipv6_addr) => vec![ipv6_addr.octets().to_vec()],
Self::CName(cname) => cname.as_byte_vec(),
}
}
}