Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to use automatically-generated asset tags #110

Merged
merged 4 commits into from
Nov 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

25 changes: 18 additions & 7 deletions src/interface/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ pub enum BuilderError {
/// state `{0}` provided to the builder has invalid name.
InvalidState(AssignmentType),

/// can't add asset of type `{0}`: you need to register the type with asset
/// type firtst using `add_asset_tag` method.
AssetTagUnknown(AssignmentType),
/// asset tag for the state `{0}` must be added before any fungible state of
/// the same type.
AssetTagSet(AssignmentType),

/// interface doesn't specifies default operation name, thus an explicit
/// operation type must be provided with `set_operation_type` method.
Expand Down Expand Up @@ -431,6 +431,10 @@ impl<Seal: ExposedSeal> OperationBuilder<Seal> {
.assignments_type(&name, ty)
.ok_or(BuilderError::AssignmentNotFound(name))?;

if self.fungible.contains_key(&type_id) {
return Err(BuilderError::AssetTagSet(type_id));
}

self.asset_tags.insert(type_id, asset_tag)?;
Ok(self)
}
Expand Down Expand Up @@ -481,10 +485,17 @@ impl<Seal: ExposedSeal> OperationBuilder<Seal> {
.assignments_type(&name, ty)
.ok_or(BuilderError::AssignmentNotFound(name))?;

let tag = *self
.asset_tags
.get(&type_id)
.ok_or(BuilderError::AssetTagUnknown(type_id))?;
let tag = match self.asset_tags.get(&type_id) {
Some(asset_tag) => *asset_tag,
None => {
let asset_tag = AssetTag::new_random(
format!("{}/{}", self.schema.schema_id(), self.iface.iface_id()),
type_id,
);
self.asset_tags.insert(type_id, asset_tag)?;
asset_tag
}
};

let state = RevealedValue::new_random_blinding(value, tag);

Expand Down
28 changes: 0 additions & 28 deletions src/interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ pub mod rgb21;
pub mod rgb25;
mod suppl;

pub use asset_tag_ext::AssetTagExt;
pub use builder::{BuilderError, ContractBuilder, TransitionBuilder};
pub use contract::{
AllocationWitness, ContractIface, FilterExclude, FilterIncludeAll, FungibleAllocation,
Expand Down Expand Up @@ -63,30 +62,3 @@ pub enum VerNo {
#[display("v1")]
V1 = 0,
}

// TODO: Move to RGB Core
mod asset_tag_ext {
use std::time::SystemTime;

use amplify::confinement::U8;
use bp::secp256k1::rand::{thread_rng, RngCore};
use commit_verify::{DigestExt, Sha256};
use rgb::{AssetTag, AssignmentType};

pub trait AssetTagExt: Sized {
fn new_random(contract_domain: impl AsRef<str>, assignment_type: AssignmentType) -> Self;
}

impl AssetTagExt for AssetTag {
fn new_random(contract_domain: impl AsRef<str>, assignment_type: AssignmentType) -> Self {
let rand = thread_rng().next_u64();
let timestamp = SystemTime::now().elapsed().expect("system time error");
let mut hasher = Sha256::default();
hasher.input_with_len::<U8>(contract_domain.as_ref().as_bytes());
hasher.input_raw(&assignment_type.to_le_bytes());
hasher.input_raw(&timestamp.as_nanos().to_le_bytes());
hasher.input_raw(&rand.to_le_bytes());
AssetTag::from(hasher.finish())
}
}
}
Loading