token_id.rs 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839
  1. use group::ff::PrimeField;
  2. use super::types::DrkTokenId;
  3. use crate::{util::net_name::NetworkName, Error, Result};
  4. pub fn generate_id(network: &NetworkName, token_str: &str) -> Result<DrkTokenId> {
  5. let mut net_bytes: Vec<u8> = network.to_string().as_bytes().to_vec();
  6. // TODO: Check for fixed length token_str
  7. let mut token_bytes = match network {
  8. NetworkName::DarkFi => bs58::decode(token_str).into_vec()?,
  9. NetworkName::Bitcoin => bs58::decode(token_str).into_vec()?,
  10. NetworkName::Ethereum => hex::decode(token_str.strip_prefix("0x").unwrap())?,
  11. NetworkName::Solana => bs58::decode(token_str).into_vec()?,
  12. };
  13. net_bytes.append(&mut token_bytes);
  14. // Since our circuit is built to take a 2^64-1 range, we take the first 64
  15. // bits of the hash and make an unsigned integer from it, which we can then
  16. // cast into pallas::Base.
  17. let data: [u8; 8] = blake3::hash(&net_bytes).as_bytes()[0..8].try_into()?;
  18. Ok(DrkTokenId::from(u64::from_le_bytes(data)))
  19. }
  20. /// Parse a `DrkTokenId` from a base58-encoded string
  21. pub fn parse_b58(s: &str) -> Result<DrkTokenId> {
  22. let bytes = bs58::decode(s).into_vec()?;
  23. if bytes.len() != 32 {
  24. return Err(Error::ParseFailed("Failed parsing DrkTokenId from base58 string"))
  25. }
  26. let ret = DrkTokenId::from_repr(bytes.try_into().unwrap());
  27. if ret.is_some().unwrap_u8() == 1 {
  28. return Ok(ret.unwrap())
  29. }
  30. Err(Error::ParseFailed("Failed parsing DrkTokenId from base58 string"))
  31. }