diff --git a/Cargo.lock b/Cargo.lock index 7fb52e90..1410f125 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -599,7 +599,7 @@ dependencies = [ [[package]] name = "rgb-core" version = "0.11.0-beta.1" -source = "git+https://github.com/RGB-WG/rgb-core?branch=v0.11#8abc864deb3d907afa2644aed11f9a739c79c565" +source = "git+https://github.com/RGB-WG/rgb-core?branch=v0.11#d80b3f516994d005578c010d22362d9a25783d23" dependencies = [ "aluvm", "amplify", diff --git a/src/interface/builder.rs b/src/interface/builder.rs index 5e42c587..72136af7 100644 --- a/src/interface/builder.rs +++ b/src/interface/builder.rs @@ -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. @@ -431,6 +431,10 @@ impl OperationBuilder { .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) } @@ -481,10 +485,17 @@ impl OperationBuilder { .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); diff --git a/src/interface/mod.rs b/src/interface/mod.rs index 2ac4afc5..8ec4554a 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -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, @@ -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, assignment_type: AssignmentType) -> Self; - } - - impl AssetTagExt for AssetTag { - fn new_random(contract_domain: impl AsRef, 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::(contract_domain.as_ref().as_bytes()); - hasher.input_raw(&assignment_type.to_le_bytes()); - hasher.input_raw(×tamp.as_nanos().to_le_bytes()); - hasher.input_raw(&rand.to_le_bytes()); - AssetTag::from(hasher.finish()) - } - } -}