diff --git a/Cargo.lock b/Cargo.lock index c201786d..2fe20d79 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,7 +33,6 @@ dependencies = [ "amplify_num", "amplify_syn", "ascii", - "rand", "serde", "stringly_conversions", "wasm-bindgen", @@ -171,12 +170,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "340e09e8399c7bd8912f495af6aa58bea0c9214773417ffaa8f6460f93aaee56" -[[package]] -name = "bitcoin-private" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73290177011694f38ec25e165d0387ab7ea749a4b81cd4c80dae5988229f7a57" - [[package]] name = "bitcoin_hashes" version = "0.14.0" @@ -223,7 +216,7 @@ dependencies = [ "amplify", "chrono", "commit_verify", - "secp256k1 0.30.0", + "secp256k1", "serde", "strict_encoding", "strict_types", @@ -256,7 +249,7 @@ dependencies = [ "base85", "bp-consensus", "commit_verify", - "secp256k1 0.30.0", + "secp256k1", "serde", "strict_encoding", ] @@ -529,12 +522,6 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" -[[package]] -name = "mime" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" - [[package]] name = "minicov" version = "0.3.5" @@ -640,9 +627,7 @@ dependencies = [ "chrono", "commit_verify", "getrandom", - "mime", "rand", - "secp256k1-zkp", "serde", "single_use_seals", "strict_encoding", @@ -681,17 +666,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" -[[package]] -name = "secp256k1" -version = "0.29.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" -dependencies = [ - "rand", - "secp256k1-sys", - "serde", -] - [[package]] name = "secp256k1" version = "0.30.0" @@ -713,29 +687,6 @@ dependencies = [ "cc", ] -[[package]] -name = "secp256k1-zkp" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52a44aed3002b5ae975f8624c5df3a949cfbf00479e18778b6058fcd213b76e3" -dependencies = [ - "bitcoin-private", - "rand", - "secp256k1 0.29.1", - "secp256k1-zkp-sys", - "serde", -] - -[[package]] -name = "secp256k1-zkp-sys" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6eea7919e0cab992510edfbf40bd9342c0a3c2bb910f2c51355c2cb2d69839" -dependencies = [ - "cc", - "secp256k1-sys", -] - [[package]] name = "serde" version = "1.0.210" diff --git a/Cargo.toml b/Cargo.toml index ce5303e5..45ea320c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,16 +22,14 @@ name = "rgbcore-stl" required-features = ["stl"] [dependencies] -amplify = { version = "~4.7.0", features = ["rand"] } +amplify = "~4.7.0" baid64 = "~0.2.2" strict_encoding = "~2.7.0" strict_types = { version = "~2.7.0", features = ["armor"] } aluvm = { version = "~0.11.0-beta.9", features = ["std", "ascii-armor"] } -commit_verify = { version = "~0.11.0-beta.9", features = ["rand", "derive"] } +commit_verify = { version = "~0.11.0-beta.9", features = ["derive"] } single_use_seals = "~0.11.0-beta.9" bp-core = { version = "~0.11.0-beta.9" } -secp256k1-zkp = { version = "0.11.0", features = ["rand", "rand-std", "global-context"] } # TODO: Update version before the release -mime = "~0.3.17" serde_crate = { package = "serde", version = "1", features = ["derive"], optional = true } chrono = "0.4.38" @@ -47,7 +45,6 @@ serde = [ "commit_verify/serde", "bp-core/serde", "aluvm/serde", - "secp256k1-zkp/serde" ] [target.'cfg(target_arch = "wasm32")'.dependencies] diff --git a/src/operation/assignments.rs b/src/operation/assignments.rs index 7e719423..4ef0aa3c 100644 --- a/src/operation/assignments.rs +++ b/src/operation/assignments.rs @@ -20,31 +20,25 @@ // See the License for the specific language governing permissions and // limitations under the License. -use core::cmp::Ordering; -use core::fmt::Debug; +use std::cmp::Ordering; use std::collections::{btree_map, BTreeSet}; +use std::fmt::Debug; use std::hash::Hash; +use std::ops::{Deref, DerefMut}; -use amplify::confinement::{Confined, SmallVec, TinyOrdMap}; +use amplify::confinement::{Confined, NonEmptyVec, TinyOrdMap, U16 as U16MAX}; use commit_verify::{Conceal, ReservedBytes}; use strict_encoding::{StrictDumb, StrictEncode}; -use super::ExposedState; -use crate::operation::seal::GenesisSeal; use crate::{ - AssignmentType, ExposedSeal, GraphSeal, RevealedAttach, RevealedData, RevealedValue, - SecretSeal, StateType, VoidState, XChain, LIB_NAME_RGB_COMMIT, + AssignmentType, ExposedSeal, GenesisSeal, GraphSeal, SecretSeal, State, XChain, + LIB_NAME_RGB_COMMIT, }; #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Display, Error)] #[display(doc_comments)] /// the requested data are not present. -pub struct UnknownDataError; - -pub type AssignRights = Assign; -pub type AssignFungible = Assign; -pub type AssignData = Assign; -pub type AssignAttach = Assign; +pub struct ItemAbsent; /// State data are assigned to a seal definition, which means that they are /// owned by a person controlling spending of the seal UTXO, unless the seal @@ -63,34 +57,20 @@ pub type AssignAttach = Assign; crate = "serde_crate", rename_all = "camelCase", untagged, - bound = "State::Confidential: serde::Serialize + serde::de::DeserializeOwned, State: \ - serde::Serialize + serde::de::DeserializeOwned, Seal: serde::Serialize + \ - serde::de::DeserializeOwned" + bound = "Seal: serde::Serialize + serde::de::DeserializeOwned" ) )] -pub enum Assign { +pub enum Assign { #[strict_type(tag = 0x00)] Confidential { - seal: XChain, - state: State::Confidential, - lock: ReservedBytes<2, 0>, - }, - #[strict_type(tag = 0x03)] - Revealed { - seal: XChain, - state: State, - lock: ReservedBytes<2, 0>, - }, - #[strict_type(tag = 0x02)] - ConfidentialSeal { seal: XChain, state: State, lock: ReservedBytes<2, 0>, }, #[strict_type(tag = 0x01)] - ConfidentialState { + Revealed { seal: XChain, - state: State::Confidential, + state: State, lock: ReservedBytes<2, 0>, }, } @@ -99,27 +79,27 @@ pub enum Assign { // Assignment indexes are part of the transition ancestor's commitment, so // here we use deterministic ordering based on hash values of the concealed // seal data contained within the assignment -impl PartialOrd for Assign { +impl PartialOrd for Assign { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for Assign { +impl Ord for Assign { fn cmp(&self, other: &Self) -> Ordering { self.to_confidential_seal() .cmp(&other.to_confidential_seal()) } } -impl PartialEq for Assign { +impl PartialEq for Assign { fn eq(&self, other: &Self) -> bool { self.to_confidential_seal() == other.to_confidential_seal() - && self.to_confidential_state() == other.to_confidential_state() + && self.as_state() == other.as_state() } } -impl Eq for Assign {} +impl Eq for Assign {} -impl Assign { +impl Assign { pub fn revealed(seal: XChain, state: State) -> Self { Assign::Revealed { seal, @@ -134,22 +114,12 @@ impl Assign { seal: _, state, lock, - } - | Assign::ConfidentialState { - seal: _, - state, - lock, - } => Assign::ConfidentialState { - seal, - state: *state, + } => Assign::Confidential { + seal: seal.conceal(), + state: state.clone(), lock: *lock, }, - Assign::ConfidentialSeal { - seal: _, - state, - lock, - } - | Assign::Revealed { + Assign::Revealed { seal: _, state, lock, @@ -161,75 +131,40 @@ impl Assign { } } - pub fn to_confidential_seal(&self) -> XChain { + pub fn as_state(&self) -> &State { match self { - Assign::Revealed { seal, .. } | Assign::ConfidentialState { seal, .. } => { - seal.conceal() - } - Assign::Confidential { seal, .. } | Assign::ConfidentialSeal { seal, .. } => *seal, + Assign::Confidential { state, .. } | Assign::Revealed { state, .. } => state, } } - pub fn revealed_seal(&self) -> Option> { + pub fn to_state(&self) -> State { match self { - Assign::Revealed { seal, .. } | Assign::ConfidentialState { seal, .. } => Some(*seal), - Assign::Confidential { .. } | Assign::ConfidentialSeal { .. } => None, + Assign::Confidential { state, .. } | Assign::Revealed { state, .. } => state.clone(), } } - pub fn to_confidential_state(&self) -> State::Confidential { + pub fn into_state(self) -> State { match self { - Assign::Revealed { state, .. } | Assign::ConfidentialSeal { state, .. } => { - state.conceal() - } - Assign::Confidential { state, .. } | Assign::ConfidentialState { state, .. } => *state, + Assign::Confidential { state, .. } | Assign::Revealed { state, .. } => state, } } - pub fn as_revealed_state(&self) -> Option<&State> { - match self { - Assign::Revealed { state, .. } | Assign::ConfidentialSeal { state, .. } => Some(state), - Assign::Confidential { .. } | Assign::ConfidentialState { .. } => None, - } - } - - pub fn as_revealed_state_mut(&mut self) -> Option<&mut State> { - match self { - Assign::Revealed { state, .. } | Assign::ConfidentialSeal { state, .. } => Some(state), - Assign::Confidential { .. } | Assign::ConfidentialState { .. } => None, - } - } - - pub fn into_revealed_state(self) -> Option { - match self { - Assign::Revealed { state, .. } | Assign::ConfidentialSeal { state, .. } => Some(state), - Assign::Confidential { .. } | Assign::ConfidentialState { .. } => None, - } - } - - pub fn as_revealed(&self) -> Option<(&XChain, &State)> { - match self { - Assign::Revealed { seal, state, .. } => Some((seal, state)), - _ => None, - } - } - - pub fn to_revealed(&self) -> Option<(XChain, State)> { + pub fn to_confidential_seal(&self) -> XChain { match self { - Assign::Revealed { seal, state, .. } => Some((*seal, state.clone())), - _ => None, + Assign::Revealed { seal, .. } => seal.conceal(), + Assign::Confidential { seal, .. } => *seal, } } - pub fn into_revealed(self) -> Option<(XChain, State)> { + pub fn revealed_seal(&self) -> Option> { match self { - Assign::Revealed { seal, state, .. } => Some((seal, state)), - _ => None, + Assign::Revealed { seal, .. } => Some(*seal), + Assign::Confidential { .. } => None, } } } -impl Conceal for Assign +impl Conceal for Assign where Self: Clone { type Concealed = Self; @@ -237,34 +172,19 @@ where Self: Clone fn conceal(&self) -> Self::Concealed { match self { Assign::Confidential { .. } => self.clone(), - Assign::ConfidentialState { seal, state, lock } => Self::Confidential { - seal: seal.conceal(), - state: *state, - lock: *lock, - }, Assign::Revealed { seal, state, lock } => Self::Confidential { seal: seal.conceal(), - state: state.conceal(), - lock: *lock, - }, - Assign::ConfidentialSeal { seal, state, lock } => Self::Confidential { - seal: *seal, - state: state.conceal(), + state: state.clone(), lock: *lock, }, } } } -impl Assign { - pub fn transmutate_seals(&self) -> Assign { +impl Assign { + pub fn transmute_seals(&self) -> Assign { match self { Assign::Confidential { seal, state, lock } => Assign::Confidential { - seal: *seal, - state: *state, - lock: *lock, - }, - Assign::ConfidentialSeal { seal, state, lock } => Assign::ConfidentialSeal { seal: *seal, state: state.clone(), lock: *lock, @@ -274,296 +194,79 @@ impl Assign { state: state.clone(), lock: *lock, }, - Assign::ConfidentialState { seal, state, lock } => Assign::ConfidentialState { - seal: seal.transmutate(), - state: *state, - lock: *lock, - }, } } } -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT, tags = custom, dumb = Self::Declarative(strict_dumb!()))] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Debug, From)] +#[derive(StrictType, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB_COMMIT)] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), - serde( - crate = "serde_crate", - rename_all = "camelCase", - tag = "type", - content = "items", - bound = "Seal: serde::Serialize + serde::de::DeserializeOwned" - ) + serde(crate = "serde_crate", bound = "Seal: serde::Serialize + serde::de::DeserializeOwned") )] -pub enum TypedAssigns { - // TODO: Consider using non-empty variants - #[strict_type(tag = 0x00)] - Declarative(SmallVec>), - #[strict_type(tag = 0x01)] - Fungible(SmallVec>), - #[strict_type(tag = 0x02)] - Structured(SmallVec>), - #[strict_type(tag = 0xFF)] - Attachment(SmallVec>), +pub struct TypedAssigns(NonEmptyVec, U16MAX>); + +impl Deref for TypedAssigns { + type Target = NonEmptyVec, U16MAX>; + + fn deref(&self) -> &Self::Target { &self.0 } +} + +impl DerefMut for TypedAssigns { + fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } +} + +impl StrictDumb for TypedAssigns { + fn strict_dumb() -> Self { Self(NonEmptyVec::with(strict_dumb!())) } } impl Conceal for TypedAssigns { type Concealed = Self; fn conceal(&self) -> Self::Concealed { - match self { - TypedAssigns::Declarative(s) => { - let concealed_iter = s.iter().map(AssignRights::::conceal); - let inner = SmallVec::try_from_iter(concealed_iter).expect("same size"); - TypedAssigns::Declarative(inner) - } - TypedAssigns::Fungible(s) => { - let concealed_iter = s.iter().map(AssignFungible::::conceal); - let inner = SmallVec::try_from_iter(concealed_iter).expect("same size"); - TypedAssigns::Fungible(inner) - } - TypedAssigns::Structured(s) => { - let concealed_iter = s.iter().map(AssignData::::conceal); - let inner = SmallVec::try_from_iter(concealed_iter).expect("same size"); - TypedAssigns::Structured(inner) - } - TypedAssigns::Attachment(s) => { - let concealed_iter = s.iter().map(AssignAttach::::conceal); - let inner = SmallVec::try_from_iter(concealed_iter).expect("same size"); - TypedAssigns::Attachment(inner) - } - } + let concealed_iter = self.0.iter().map(Assign::::conceal); + let inner = NonEmptyVec::from_iter_checked(concealed_iter); + TypedAssigns(inner) } } impl TypedAssigns { - pub fn is_empty(&self) -> bool { - match self { - TypedAssigns::Declarative(set) => set.is_empty(), - TypedAssigns::Fungible(set) => set.is_empty(), - TypedAssigns::Structured(set) => set.is_empty(), - TypedAssigns::Attachment(set) => set.is_empty(), - } - } - - pub fn len_u16(&self) -> u16 { - match self { - TypedAssigns::Declarative(set) => set.len_u16(), - TypedAssigns::Fungible(set) => set.len_u16(), - TypedAssigns::Structured(set) => set.len_u16(), - TypedAssigns::Attachment(set) => set.len_u16(), - } - } - - #[inline] - pub fn state_type(&self) -> StateType { - match self { - TypedAssigns::Declarative(_) => StateType::Void, - TypedAssigns::Fungible(_) => StateType::Fungible, - TypedAssigns::Structured(_) => StateType::Structured, - TypedAssigns::Attachment(_) => StateType::Attachment, - } - } - - #[inline] - pub fn is_declarative(&self) -> bool { matches!(self, TypedAssigns::Declarative(_)) } + pub fn with(item: Assign) -> Self { Self(NonEmptyVec::with(item)) } - #[inline] - pub fn is_fungible(&self) -> bool { matches!(self, TypedAssigns::Fungible(_)) } - - #[inline] - pub fn is_structured(&self) -> bool { matches!(self, TypedAssigns::Structured(_)) } - - #[inline] - pub fn is_attachment(&self) -> bool { matches!(self, TypedAssigns::Attachment(_)) } - - #[inline] - pub fn as_declarative(&self) -> &[AssignRights] { - match self { - TypedAssigns::Declarative(set) => set, - _ => Default::default(), - } - } - - #[inline] - pub fn as_fungible(&self) -> &[AssignFungible] { - match self { - TypedAssigns::Fungible(set) => set, - _ => Default::default(), - } - } - - #[inline] - pub fn as_structured(&self) -> &[AssignData] { - match self { - TypedAssigns::Structured(set) => set, - _ => Default::default(), - } - } - - #[inline] - pub fn as_attachment(&self) -> &[AssignAttach] { - match self { - TypedAssigns::Attachment(set) => set, - _ => Default::default(), - } - } - - #[inline] - pub fn as_declarative_mut(&mut self) -> Option<&mut SmallVec>> { - match self { - TypedAssigns::Declarative(set) => Some(set), - _ => None, - } - } - - #[inline] - pub fn as_fungible_mut(&mut self) -> Option<&mut SmallVec>> { - match self { - TypedAssigns::Fungible(set) => Some(set), - _ => None, - } - } - - #[inline] - pub fn as_structured_mut(&mut self) -> Option<&mut SmallVec>> { - match self { - TypedAssigns::Structured(set) => Some(set), - _ => None, - } - } - - #[inline] - pub fn as_attachment_mut(&mut self) -> Option<&mut SmallVec>> { - match self { - TypedAssigns::Attachment(set) => Some(set), - _ => None, - } - } - - /// If seal definition does not exist, returns [`UnknownDataError`]. If the + /// If seal definition does not exist, returns [`ItemAbsent`]. If the /// seal is confidential, returns `Ok(None)`; otherwise returns revealed /// seal data packed as `Ok(Some(`[`Seal`]`))` - pub fn revealed_seal_at(&self, index: u16) -> Result>, UnknownDataError> { - Ok(match self { - TypedAssigns::Declarative(vec) => vec - .get(index as usize) - .ok_or(UnknownDataError)? - .revealed_seal(), - TypedAssigns::Fungible(vec) => vec - .get(index as usize) - .ok_or(UnknownDataError)? - .revealed_seal(), - TypedAssigns::Structured(vec) => vec - .get(index as usize) - .ok_or(UnknownDataError)? - .revealed_seal(), - TypedAssigns::Attachment(vec) => vec - .get(index as usize) - .ok_or(UnknownDataError)? - .revealed_seal(), - }) - } - - pub fn to_confidential_seals(&self) -> Vec> { - match self { - TypedAssigns::Declarative(s) => s - .iter() - .map(AssignRights::::to_confidential_seal) - .collect(), - TypedAssigns::Fungible(s) => s - .iter() - .map(AssignFungible::::to_confidential_seal) - .collect(), - TypedAssigns::Structured(s) => s - .iter() - .map(AssignData::::to_confidential_seal) - .collect(), - TypedAssigns::Attachment(s) => s - .iter() - .map(AssignAttach::::to_confidential_seal) - .collect(), - } - } - - pub fn as_structured_state_at( - &self, - index: u16, - ) -> Result, UnknownDataError> { - match self { - TypedAssigns::Structured(vec) => Ok(vec - .get(index as usize) - .ok_or(UnknownDataError)? - .as_revealed_state()), - _ => Err(UnknownDataError), - } + pub fn revealed_seal_at(&self, index: u16) -> Result>, ItemAbsent> { + Ok(self + .0 + .get(index as usize) + .ok_or(ItemAbsent)? + .revealed_seal()) } - pub fn as_fungible_state_at( - &self, - index: u16, - ) -> Result, UnknownDataError> { - match self { - TypedAssigns::Fungible(vec) => Ok(vec - .get(index as usize) - .ok_or(UnknownDataError)? - .as_revealed_state()), - _ => Err(UnknownDataError), - } + pub fn as_state_at(&self, index: u16) -> Result<&State, ItemAbsent> { + Ok(self.0.get(index as usize).ok_or(ItemAbsent)?.as_state()) } - pub fn into_structured_state_at( - self, - index: u16, - ) -> Result, UnknownDataError> { - match self { - TypedAssigns::Structured(vec) => { - if index as usize >= vec.len() { - return Err(UnknownDataError); - } - Ok(vec.release().remove(index as usize).into_revealed_state()) - } - _ => Err(UnknownDataError), + pub fn into_state_at(self, index: u16) -> Result { + if index >= self.0.len_u16() { + return Err(ItemAbsent); } + Ok(self.0.release().remove(index as usize).into_state()) } - pub fn into_fungible_state_at( - self, - index: u16, - ) -> Result, UnknownDataError> { - match self { - TypedAssigns::Fungible(vec) => { - if index as usize >= vec.len() { - return Err(UnknownDataError); - } - Ok(vec.release().remove(index as usize).into_revealed_state()) - } - _ => Err(UnknownDataError), - } + pub fn confidential_seals(&self) -> Vec> { + self.0 + .iter() + .map(Assign::::to_confidential_seal) + .collect() } } impl TypedAssigns { - pub fn transmutate_seals(&self) -> TypedAssigns { - match self { - TypedAssigns::Declarative(a) => TypedAssigns::Declarative( - Confined::try_from_iter(a.iter().map(|a| a.transmutate_seals())) - .expect("same size"), - ), - TypedAssigns::Fungible(a) => TypedAssigns::Fungible( - Confined::try_from_iter(a.iter().map(|a| a.transmutate_seals())) - .expect("same size"), - ), - TypedAssigns::Structured(a) => TypedAssigns::Structured( - Confined::try_from_iter(a.iter().map(|a| a.transmutate_seals())) - .expect("same size"), - ), - TypedAssigns::Attachment(a) => TypedAssigns::Attachment( - Confined::try_from_iter(a.iter().map(|a| a.transmutate_seals())) - .expect("same size"), - ), - } + pub fn transmute_seals(&self) -> TypedAssigns { + TypedAssigns(NonEmptyVec::from_iter_checked(self.0.iter().map(Assign::transmute_seals))) } } @@ -589,9 +292,9 @@ impl Default for Assignments { } impl Assignments { - pub fn transmutate_seals(&self) -> Assignments { + pub fn transmute_seals(&self) -> Assignments { Assignments( - Confined::try_from_iter(self.iter().map(|(t, a)| (*t, a.transmutate_seals()))) + Confined::try_from_iter(self.iter().map(|(t, a)| (*t, a.transmute_seals()))) .expect("same size"), ) } @@ -623,9 +326,9 @@ impl AssignmentsRef<'_> { pub fn is_empty(&self) -> bool { self.len() == 0 } - pub fn flat(&self) -> Assignments { + pub fn to_graph_seals(&self) -> Assignments { match *self { - AssignmentsRef::Genesis(a) => a.transmutate_seals(), + AssignmentsRef::Genesis(a) => a.transmute_seals(), AssignmentsRef::Graph(a) => a.clone(), } } @@ -646,7 +349,7 @@ impl AssignmentsRef<'_> { pub fn get(&self, t: AssignmentType) -> Option> { match self { - AssignmentsRef::Genesis(a) => a.get(&t).map(TypedAssigns::transmutate_seals), + AssignmentsRef::Genesis(a) => a.get(&t).map(TypedAssigns::transmute_seals), AssignmentsRef::Graph(a) => a.get(&t).cloned(), } } diff --git a/src/operation/attachment.rs b/src/operation/attachment.rs deleted file mode 100644 index 43084a06..00000000 --- a/src/operation/attachment.rs +++ /dev/null @@ -1,210 +0,0 @@ -// RGB Core Library: consensus layer for RGB smart contracts. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Written in 2019-2024 by -// Dr Maxim Orlovsky -// -// Copyright (C) 2019-2024 LNP/BP Standards Association. All rights reserved. -// Copyright (C) 2019-2024 Dr Maxim Orlovsky. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::fmt; -use std::fmt::{Display, Formatter}; -use std::str::FromStr; - -use amplify::{ByteArray, Bytes32}; -use baid64::{Baid64ParseError, DisplayBaid64, FromBaid64Str}; -use bp::secp256k1::rand::{random, Rng, RngCore}; -use commit_verify::{CommitId, CommitmentId, Conceal, DigestExt, Sha256}; -use strict_encoding::{StrictEncode, StrictSerialize}; - -use super::{ConfidentialState, ExposedState}; -use crate::{ - impl_serde_baid64, ConcealedState, MediaType, RevealedState, StateType, LIB_NAME_RGB_COMMIT, -}; - -/// Unique data attachment identifier -#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)] -#[wrapper(Deref, BorrowSlice, Hex, Index, RangeOps)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -pub struct AttachId( - #[from] - #[from([u8; 32])] - Bytes32, -); - -impl DisplayBaid64 for AttachId { - const HRI: &'static str = "rgb:fs"; - const CHUNKING: bool = true; - const PREFIX: bool = true; - const EMBED_CHECKSUM: bool = false; - const MNEMONIC: bool = true; - fn to_baid64_payload(&self) -> [u8; 32] { self.to_byte_array() } -} -impl FromBaid64Str for AttachId {} -impl FromStr for AttachId { - type Err = Baid64ParseError; - fn from_str(s: &str) -> Result { Self::from_baid64_str(s) } -} -impl Display for AttachId { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { self.fmt_baid64(f) } -} - -impl_serde_baid64!(AttachId); - -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Display)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -#[display("{id}:{media_type}")] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub struct AttachState { - pub id: AttachId, - /// We do not enforce a MIME standard since non-standard types can be also - /// used - pub media_type: MediaType, -} -impl StrictSerialize for AttachState {} - -impl From for AttachState { - fn from(attach: RevealedAttach) -> Self { - AttachState { - id: attach.file.id, - media_type: attach.file.media_type, - } - } -} - -#[derive(Clone, PartialOrd, Ord, PartialEq, Eq, Hash, Debug)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -#[derive(CommitEncode)] -#[commit_encode(strategy = strict, id = ConcealedAttach)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub struct RevealedAttach { - pub file: AttachState, - pub salt: u64, -} - -impl RevealedAttach { - /// Constructs new state using the provided value using random blinding - /// factor. - pub fn new_random_salt(id: AttachId, media_type: impl Into) -> Self { - Self::with_salt(id, media_type, random()) - } - - /// Constructs new state using the provided value and random generator for - /// creating blinding factor. - pub fn with_rng( - id: AttachId, - media_type: impl Into, - rng: &mut R, - ) -> Self { - Self::with_salt(id, media_type, rng.next_u64()) - } - - /// Convenience constructor. - pub fn with_salt(id: AttachId, media_type: impl Into, salt: u64) -> Self { - Self { - file: AttachState { - id, - media_type: media_type.into(), - }, - salt, - } - } -} - -impl ExposedState for RevealedAttach { - type Confidential = ConcealedAttach; - fn state_type(&self) -> StateType { StateType::Attachment } - fn state_data(&self) -> RevealedState { RevealedState::Attachment(self.clone()) } -} - -impl Conceal for RevealedAttach { - type Concealed = ConcealedAttach; - - fn conceal(&self) -> Self::Concealed { self.commit_id() } -} - -/// Confidential version of an attachment information. -/// -/// See also revealed version [`RevealedAttach`]. -#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)] -#[wrapper(Deref, BorrowSlice, Hex, Index, RangeOps)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct ConcealedAttach( - #[from] - #[from([u8; 32])] - Bytes32, -); - -impl ConfidentialState for ConcealedAttach { - fn state_type(&self) -> StateType { StateType::Attachment } - fn state_commitment(&self) -> ConcealedState { ConcealedState::Attachment(*self) } -} - -impl From for ConcealedAttach { - fn from(hasher: Sha256) -> Self { hasher.finish().into() } -} - -impl CommitmentId for ConcealedAttach { - const TAG: &'static str = "urn:lnp-bp:rgb:state-attach#2024-02-12"; -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn attach_id_display() { - const ID: &str = - "rgb:fs:bGxsbGxs-bGxsbGx-sbGxsbG-xsbGxsb-GxsbGxs-bGxsbGw#invite-potato-oval"; - let id = AttachId::from_byte_array([0x6c; 32]); - assert_eq!(ID, id.to_string()); - assert_eq!(ID, id.to_baid64_string()); - assert_eq!("invite-potato-oval", id.to_baid64_mnemonic()); - } - - #[test] - fn attach_id_from_str() { - let id = AttachId::from_byte_array([0x6c; 32]); - assert_eq!( - id, - AttachId::from_str( - "rgb:fs:bGxsbGxs-bGxsbGx-sbGxsbG-xsbGxsb-GxsbGxs-bGxsbGw#invite-potato-oval" - ) - .unwrap() - ); - assert_eq!( - id, - AttachId::from_str("rgb:fs:bGxsbGxs-bGxsbGx-sbGxsbG-xsbGxsb-GxsbGxs-bGxsbGw").unwrap() - ); - } -} diff --git a/src/operation/commit.rs b/src/operation/commit.rs index 8af62f15..71327bed 100644 --- a/src/operation/commit.rs +++ b/src/operation/commit.rs @@ -25,7 +25,7 @@ use std::fmt::{Display, Formatter}; use std::str::FromStr; use std::{fmt, vec}; -use amplify::confinement::{Confined, MediumOrdMap, U16 as U16MAX}; +use amplify::confinement::{Confined, MediumOrdMap, SmallBlob, U16 as U16MAX}; use amplify::hex::{FromHex, ToHex}; use amplify::num::u256; use amplify::{hex, ByteArray, Bytes32, FromSliceError, Wrapper}; @@ -36,12 +36,11 @@ use commit_verify::{ }; use strict_encoding::StrictDumb; +use crate::operation::state::StateCommitment; use crate::{ - impl_serde_baid64, Assign, AssignmentType, Assignments, BundleId, ConcealedAttach, - ConcealedData, ConcealedState, ConfidentialState, DataState, ExposedSeal, ExposedState, - Extension, ExtensionType, Ffv, Genesis, GlobalState, GlobalStateType, Operation, - PedersenCommitment, Redeemed, SchemaId, SecretSeal, Transition, TransitionBundle, - TransitionType, TypedAssigns, XChain, LIB_NAME_RGB_COMMIT, + impl_serde_baid64, Assign, AssignmentType, Assignments, BundleId, ExposedSeal, Extension, + ExtensionType, Ffv, Genesis, GlobalState, GlobalStateType, Operation, Redeemed, SchemaId, + SecretSeal, Transition, TransitionBundle, TransitionType, XChain, LIB_NAME_RGB_COMMIT, }; /// Unique contract identifier equivalent to the contract genesis commitment @@ -189,9 +188,7 @@ impl AssignmentIndex { pub struct OpDisclose { pub id: OpId, pub seals: MediumOrdMap>, - pub fungible: MediumOrdMap, - pub data: MediumOrdMap, - pub attach: MediumOrdMap, + pub state: MediumOrdMap, } #[derive(Clone, Eq, PartialEq, Hash, Debug)] @@ -238,7 +235,6 @@ pub struct BaseCommitment { pub issuer: StrictHash, pub testnet: bool, pub alt_layers1: StrictHash, - pub asset_tags: StrictHash, } #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] @@ -283,7 +279,6 @@ impl Genesis { testnet: self.testnet, alt_layers1: self.alt_layers1.commit_id(), issuer: self.issuer.commit_id(), - asset_tags: self.asset_tags.commit_id(), }; OpCommitment { ffv: self.ffv, @@ -339,21 +334,10 @@ impl Extension { } } -impl ConcealedState { - fn commit_encode(&self, e: &mut CommitEngine) { - match self { - ConcealedState::Void => {} - ConcealedState::Fungible(val) => e.commit_to_serialized(&val.commitment()), - ConcealedState::Structured(dat) => e.commit_to_serialized(dat), - ConcealedState::Attachment(att) => e.commit_to_serialized(att), - } - } -} - #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub struct AssignmentCommitment { pub ty: AssignmentType, - pub state: ConcealedState, + pub state: StateCommitment, pub seal: XChain, pub lock: ReservedBytes<2, 0>, } @@ -363,21 +347,21 @@ impl CommitEncode for AssignmentCommitment { fn commit_encode(&self, e: &mut CommitEngine) { e.commit_to_serialized(&self.ty); - self.state.commit_encode(e); e.commit_to_serialized(&self.seal); + e.commit_to_serialized(&self.state); e.commit_to_serialized(&self.lock); e.set_finished(); } } -impl Assign { +impl Assign { pub fn commitment(&self, ty: AssignmentType) -> AssignmentCommitment { let Self::Confidential { seal, state, lock } = self.conceal() else { unreachable!(); }; AssignmentCommitment { ty, - state: state.state_commitment(), + state: state.commit_id(), seal, lock, } @@ -392,23 +376,7 @@ impl MerkleLeaves for Assignments { fn merkle_leaves(&self) -> Self::LeafIter<'_> { self.iter() - .flat_map(|(ty, a)| { - match a { - TypedAssigns::Declarative(list) => { - list.iter().map(|a| a.commitment(*ty)).collect::>() - } - TypedAssigns::Fungible(list) => { - list.iter().map(|a| a.commitment(*ty)).collect() - } - TypedAssigns::Structured(list) => { - list.iter().map(|a| a.commitment(*ty)).collect() - } - TypedAssigns::Attachment(list) => { - list.iter().map(|a| a.commitment(*ty)).collect() - } - } - .into_iter() - }) + .flat_map(|(ty, a)| a.iter().map(|a| a.commitment(*ty))) .collect::>() .into_iter() } @@ -417,7 +385,7 @@ impl MerkleLeaves for Assignments { #[derive(Clone, Eq, PartialEq, Hash, Debug)] pub struct GlobalCommitment { pub ty: GlobalStateType, - pub state: DataState, + pub state: SmallBlob, } impl CommitEncode for GlobalCommitment { diff --git a/src/operation/data.rs b/src/operation/data.rs deleted file mode 100644 index 1ad420b0..00000000 --- a/src/operation/data.rs +++ /dev/null @@ -1,192 +0,0 @@ -// RGB Core Library: consensus layer for RGB smart contracts. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Written in 2019-2024 by -// Dr Maxim Orlovsky -// -// Copyright (C) 2019-2024 LNP/BP Standards Association. All rights reserved. -// Copyright (C) 2019-2024 Dr Maxim Orlovsky. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use core::fmt::{self, Debug, Formatter}; -use std::cmp::Ordering; - -use amplify::confinement::SmallBlob; -use amplify::hex::ToHex; -use amplify::{Bytes32, Wrapper}; -use bp::secp256k1::rand::{random, Rng, RngCore}; -use commit_verify::{CommitId, CommitmentId, Conceal, DigestExt, Sha256}; -use strict_encoding::{StrictSerialize, StrictType}; - -use super::{ConfidentialState, ExposedState}; -use crate::{ConcealedState, RevealedState, StateType, LIB_NAME_RGB_COMMIT}; - -/// Struct using for storing Void (i.e. absent) state -#[derive(Copy, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash, Display, Default)] -#[display("void")] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -pub struct VoidState(()); - -impl ConfidentialState for VoidState { - fn state_type(&self) -> StateType { StateType::Void } - fn state_commitment(&self) -> ConcealedState { ConcealedState::Void } -} - -impl ExposedState for VoidState { - type Confidential = VoidState; - fn state_type(&self) -> StateType { StateType::Void } - fn state_data(&self) -> RevealedState { RevealedState::Void } -} - -impl Conceal for VoidState { - type Concealed = VoidState; - fn conceal(&self) -> Self::Concealed { *self } -} - -#[derive(Wrapper, Clone, Debug, PartialOrd, Ord, PartialEq, Eq, Hash, From, Display, Default)] -#[display(LowerHex)] -#[wrapper(Deref, AsSlice, BorrowSlice, Hex)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -pub struct DataState(SmallBlob); -impl StrictSerialize for DataState {} - -impl From for DataState { - fn from(data: RevealedData) -> Self { data.value } -} - -#[cfg(feature = "serde")] -mod _serde { - use amplify::hex::FromHex; - use serde_crate::de::Error; - use serde_crate::{Deserialize, Deserializer, Serialize, Serializer}; - - use super::*; - - impl Serialize for DataState { - fn serialize(&self, serializer: S) -> Result - where S: Serializer { - serializer.serialize_str(&self.to_string()) - } - } - - impl<'de> Deserialize<'de> for DataState { - fn deserialize(deserializer: D) -> Result - where D: Deserializer<'de> { - let s = String::deserialize(deserializer)?; - Self::from_hex(&s).map_err(D::Error::custom) - } - } -} - -#[derive(Clone, Eq, PartialEq, Hash)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -#[derive(CommitEncode)] -#[commit_encode(strategy = strict, id = ConcealedData)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -pub struct RevealedData { - pub value: DataState, - pub salt: u128, -} - -impl RevealedData { - /// Constructs new state using the provided value using random blinding - /// factor. - pub fn new_random_salt(value: impl Into) -> Self { Self::with_salt(value, random()) } - - /// Constructs new state using the provided value and random generator for - /// creating blinding factor. - pub fn with_rng(value: impl Into, rng: &mut R) -> Self { - Self::with_salt(value, rng.gen()) - } - - /// Convenience constructor. - pub fn with_salt(value: impl Into, salt: u128) -> Self { - Self { - value: value.into(), - salt, - } - } -} - -impl ExposedState for RevealedData { - type Confidential = ConcealedData; - fn state_type(&self) -> StateType { StateType::Structured } - fn state_data(&self) -> RevealedState { RevealedState::Structured(self.clone()) } -} - -impl Conceal for RevealedData { - type Concealed = ConcealedData; - - fn conceal(&self) -> Self::Concealed { self.commit_id() } -} - -impl PartialOrd for RevealedData { - fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } -} - -impl Ord for RevealedData { - fn cmp(&self, other: &Self) -> Ordering { - match self.value.cmp(&other.value) { - Ordering::Equal => self.salt.cmp(&other.salt), - other => other, - } - } -} - -impl Debug for RevealedData { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let val = String::from_utf8(self.value.to_vec()).unwrap_or_else(|_| self.value.to_hex()); - - f.debug_struct("RevealedData") - .field("value", &val) - .field("salt", &self.salt) - .finish() - } -} - -/// Confidential version of an structured state data. -/// -/// See also revealed version [`RevealedData`]. -#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)] -#[wrapper(Deref, BorrowSlice, Hex, Index, RangeOps)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT, rename = "ConcealedData")] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct ConcealedData( - #[from] - #[from([u8; 32])] - Bytes32, -); - -impl ConfidentialState for ConcealedData { - fn state_type(&self) -> StateType { StateType::Structured } - fn state_commitment(&self) -> ConcealedState { ConcealedState::Structured(*self) } -} - -impl From for ConcealedData { - fn from(hasher: Sha256) -> Self { hasher.finish().into() } -} - -impl CommitmentId for ConcealedData { - const TAG: &'static str = "urn:lnp-bp:rgb:state-data#2024-02-12"; -} diff --git a/src/operation/fungible.rs b/src/operation/fungible.rs deleted file mode 100644 index d6dc7319..00000000 --- a/src/operation/fungible.rs +++ /dev/null @@ -1,686 +0,0 @@ -// RGB Core Library: consensus layer for RGB smart contracts. -// -// SPDX-License-Identifier: Apache-2.0 -// -// Written in 2019-2024 by -// Dr Maxim Orlovsky -// -// Copyright (C) 2019-2024 LNP/BP Standards Association. All rights reserved. -// Copyright (C) 2019-2024 Dr Maxim Orlovsky. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! This mod represents **atomic rational values** (or, simply just **value**), -//! it a value representing a portion of something whole with a certain fixed -//! level of precision (atomicity). Such values are commonly used to represent -//! some coins of fungible tokens, where each coin or token consists of an -//! integer number of atomic subdivisions of the total supply (like satoshis in -//! bitcoin represent just a portion, i.e. fixed-precision rational number, of -//! the total possible bitcoin supply). Such numbers demonstrate constant -//! properties regarding their total sum and, thus, can be made confidential -//! using elliptic curve homomorphic cryptography such as Pedesen commitments. - -use core::fmt::Debug; -use core::num::ParseIntError; -use core::ops::Deref; -use core::str::FromStr; -use std::hash::Hash; -use std::io; - -use amplify::confinement::U8; -use amplify::hex::ToHex; -// We do not import particular modules to keep aware with namespace prefixes -// that we do not use the standard secp256k1zkp library -use amplify::{hex, Array, Bytes32, Wrapper}; -use bp::secp256k1::rand::thread_rng; -use chrono::{DateTime, Utc}; -use commit_verify::{CommitVerify, CommitmentProtocol, Conceal, DigestExt, Sha256}; -use secp256k1_zkp::rand::{Rng, RngCore}; -use secp256k1_zkp::SECP256K1; -use strict_encoding::{ - DecodeError, ReadTuple, StrictDecode, StrictDumb, StrictEncode, TypedRead, TypedWrite, - WriteTuple, -}; - -use super::{ConfidentialState, ExposedState}; -use crate::{ - AssignmentType, ConcealedState, FungibleType, RevealedState, StateType, LIB_NAME_RGB_COMMIT, -}; - -#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)] -#[wrapper(Deref, BorrowSlice, Hex, Index, RangeOps)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct AssetTag( - #[from] - #[from([u8; 32])] - Bytes32, -); - -impl AssetTag { - pub fn new_random(contract_domain: impl AsRef, assignment_type: AssignmentType) -> Self { - AssetTag::new_deterministic( - contract_domain, - assignment_type, - Utc::now(), - thread_rng().next_u64(), - ) - } - - pub fn new_deterministic( - contract_domain: impl AsRef, - assignment_type: AssignmentType, - timestamp: DateTime, - salt: u64, - ) -> Self { - let timestamp = timestamp.timestamp(); - 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.to_le_bytes()); - hasher.input_raw(&salt.to_le_bytes()); - AssetTag::from(hasher.finish()) - } -} - -/// An atom of an additive state, which thus can be monomorphically encrypted. -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Default, Debug, Display, From)] -#[display(inner)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase", transparent) -)] -pub struct FungibleState(u64); - -impl From for FungibleState { - #[inline] - fn from(revealed: RevealedValue) -> Self { revealed.value() } -} - -impl FromStr for FungibleState { - type Err = ParseIntError; - - #[inline] - fn from_str(s: &str) -> Result { s.parse().map(Self) } -} - -impl From for u64 { - #[inline] - fn from(value: FungibleState) -> Self { value.0 } -} - -impl FungibleState { - pub fn to_u64(&self) -> u64 { (*self).into() } -} - -/// value provided for a blinding factor overflows prime field order for -/// Secp256k1 curve. -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Display, Error, From)] -#[display(doc_comments)] -#[from(secp256k1_zkp::UpstreamError)] -pub struct InvalidFieldElement; - -/// Errors parsing string representation of a blinding factor. -#[derive(Copy, Clone, Eq, PartialEq, Debug, Display, Error, From)] -#[display(doc_comments)] -pub enum BlindingParseError { - /// invalid blinding factor hex representation - {0} - #[from] - Hex(hex::Error), - - /// blinding factor value is invalid and does not belong to the Secp256k1 - /// curve field. - #[from(InvalidFieldElement)] - InvalidFieldElement, -} - -/// Blinding factor used in creating Pedersen commitment to an [`AtomicValue`]. -/// -/// Knowledge of the blinding factor is important to reproduce the commitment -/// process if the original value is kept. -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)] -#[display(Self::to_hex)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", try_from = "secp256k1_zkp::SecretKey") -)] -pub struct BlindingFactor(Bytes32); - -impl BlindingFactor { - pub const EMPTY: Self = BlindingFactor(Bytes32::from_array([0x7E; 32])); -} - -impl Deref for BlindingFactor { - type Target = [u8; 32]; - fn deref(&self) -> &Self::Target { self.0.as_inner() } -} - -impl ToHex for BlindingFactor { - fn to_hex(&self) -> String { self.0.to_hex() } -} - -impl FromStr for BlindingFactor { - type Err = BlindingParseError; - fn from_str(s: &str) -> Result { - let bytes = Bytes32::from_str(s)?; - Self::try_from(bytes).map_err(BlindingParseError::from) - } -} - -impl From for BlindingFactor { - fn from(key: secp256k1_zkp::SecretKey) -> Self { Self(Bytes32::from_inner(*key.as_ref())) } -} - -impl From for secp256k1_zkp::SecretKey { - fn from(bf: BlindingFactor) -> Self { bf.to_secret_key() } -} - -impl BlindingFactor { - /// Creates a random blinding factor. - #[inline] - pub fn random() -> Self { Self::random_custom(&mut thread_rng()) } - - /// Generates a random blinding factor using custom random number generator. - #[inline] - pub fn random_custom(rng: &mut R) -> Self { - secp256k1_zkp::SecretKey::new(rng).into() - } - - /// Generates new blinding factor which balances a given set of negatives - /// and positives into zero. - /// - /// # Errors - /// - /// * if negatives are empty set; - /// * if any subset of the negatives or positives are inverses of other negatives or positives, - /// * if the balancing factor is zero (sum of negatives already equal to the sum of positives). - pub fn zero_balanced( - negative: impl IntoIterator, - positive: impl IntoIterator, - ) -> Result { - let mut blinding_neg_sum = secp256k1_zkp::Scalar::ZERO; - let mut blinding_pos_sum = secp256k1_zkp::Scalar::ZERO; - for neg in negative { - blinding_neg_sum = neg.to_secret_key().add_tweak(&blinding_neg_sum)?.into(); - } - let blinding_neg_sum = - secp256k1_zkp::SecretKey::from_slice(&blinding_neg_sum.to_be_bytes())?.negate(); - for pos in positive { - blinding_pos_sum = pos.to_secret_key().add_tweak(&blinding_pos_sum)?.into(); - } - let blinding_correction = blinding_neg_sum.add_tweak(&blinding_pos_sum)?.negate(); - Ok(blinding_correction.into()) - } - - fn to_secret_key(self) -> secp256k1_zkp::SecretKey { - secp256k1_zkp::SecretKey::from_slice(self.0.as_slice()) - .expect("blinding factor is an invalid secret key") - } -} - -impl TryFrom<[u8; 32]> for BlindingFactor { - type Error = InvalidFieldElement; - - fn try_from(array: [u8; 32]) -> Result { - secp256k1_zkp::SecretKey::from_slice(&array) - .map_err(|_| InvalidFieldElement) - .map(Self::from) - } -} - -impl TryFrom for BlindingFactor { - type Error = InvalidFieldElement; - - fn try_from(bytes: Bytes32) -> Result { - Self::try_from(bytes.to_byte_array()) - } -} - -/// State item for a homomorphically-encryptable state. -/// -/// Consists of the 64-bit value and -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT, rename = "RevealedFungible", tags = custom)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", untagged) -)] -pub enum RevealedValue { - #[strict_type(tag = 8)] - Asset { - /// Original value in smallest indivisible units - value: FungibleState, - - /// Blinding factor used in hashing - blinding: BlindingFactor, - }, - - #[strict_type(tag = 0xFF)] - ConfidentialAsset { - /// Original value in smallest indivisible units - value: FungibleState, - - /// Blinding factor used in Pedersen commitment - blinding: BlindingFactor, - - /// Asset-specific tag preventing mixing assets of different type. - tag: AssetTag, - }, -} - -impl StrictDumb for RevealedValue { - fn strict_dumb() -> Self { - Self::Asset { - value: strict_dumb!(), - blinding: strict_dumb!(), - } - } -} - -impl RevealedValue { - /// Constructs new state using the provided value using random blinding - /// factor. - pub fn confidential_random_blinding(value: impl Into, tag: AssetTag) -> Self { - Self::ConfidentialAsset { - value: value.into(), - blinding: BlindingFactor::random(), - tag, - } - } - - /// Constructs new confidential asset using the provided value and random generator for - /// creating blinding factor. - pub fn confidential_with_rng( - value: impl Into, - rng: &mut R, - tag: AssetTag, - ) -> Self { - Self::ConfidentialAsset { - value: value.into(), - blinding: BlindingFactor::random_custom(rng), - tag, - } - } - - /// Constructs new non-confidential asset using the provided value using random blinding - /// factor. - pub fn asset_random_blinding(value: impl Into) -> Self { - Self::Asset { - value: value.into(), - blinding: BlindingFactor::random(), - } - } - - /// Constructs new non-confidential asset using the provided value and random generator for - /// creating blinding factor. - pub fn asset_with_rng(value: impl Into, rng: &mut R) -> Self { - Self::Asset { - value: value.into(), - blinding: BlindingFactor::random_custom(rng), - } - } - - pub fn fungible_type(&self) -> FungibleType { - match self { - RevealedValue::Asset { .. } => FungibleType::U64, - RevealedValue::ConfidentialAsset { .. } => FungibleType::ConfidentialAsset, - } - } - - pub fn value(&self) -> FungibleState { - match self { - RevealedValue::Asset { value, .. } => *value, - RevealedValue::ConfidentialAsset { value, .. } => *value, - } - } -} - -impl ExposedState for RevealedValue { - type Confidential = ConcealedValue; - fn state_type(&self) -> StateType { StateType::Fungible } - fn state_data(&self) -> RevealedState { RevealedState::Fungible(*self) } -} - -impl Conceal for RevealedValue { - type Concealed = ConcealedValue; - - fn conceal(&self) -> Self::Concealed { ConcealedValue::commit(self) } -} - -/// Opaque type holding pedersen commitment for an [`FungibleState`]. -#[derive(Wrapper, Copy, Clone, Eq, PartialEq, Hash, Debug, From)] -#[wrapper(Deref, FromStr, Display, LowerHex)] -#[derive(StrictType)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct PedersenCommitment(secp256k1_zkp::PedersenCommitment); - -impl StrictDumb for PedersenCommitment { - fn strict_dumb() -> Self { - secp256k1_zkp::PedersenCommitment::from_slice(&[0x08; 33]) - .expect("hardcoded pedersen commitment value") - .into() - } -} - -impl StrictEncode for PedersenCommitment { - fn strict_encode(&self, writer: W) -> io::Result { - writer.write_tuple::(|w| Ok(w.write_field(&self.0.serialize())?.complete())) - } -} - -impl StrictDecode for PedersenCommitment { - fn strict_decode(reader: &mut impl TypedRead) -> Result { - reader.read_tuple(|r| { - let commitment = r.read_field::<[u8; 33]>()?; - secp256k1_zkp::PedersenCommitment::from_slice(&commitment) - .map_err(|_| { - DecodeError::DataIntegrityError(s!("invalid pedersen commitment data")) - }) - .map(PedersenCommitment::from_inner) - }) - } -} - -/// A dumb placeholder for a future bulletproofs. -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct NoiseDumb(Array); - -impl Default for NoiseDumb { - fn default() -> Self { - let mut dumb = [0u8; 512]; - thread_rng().fill(&mut dumb); - NoiseDumb(dumb.into()) - } -} - -/// Range proof value. -/// -/// Range proofs must be used alongside [`PedersenCommitment`]s to ensure that -/// the value do not overflow on arithmetic operations with the commitments. -#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] -#[derive(StrictType)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT, tags = custom)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase", untagged) -)] -pub enum RangeProof { - /// Value used when bulletproofs library is not available. - /// - /// Always fails validation if no source value is given. - #[strict_type(tag = 0xFF)] - Placeholder(NoiseDumb), -} - -impl Default for RangeProof { - fn default() -> Self { RangeProof::Placeholder(default!()) } -} - -impl StrictEncode for RangeProof { - fn strict_encode(&self, writer: W) -> io::Result { - eprintln!("bulletproof dummies must never be stored"); - Ok(writer) - } -} - -impl StrictDecode for RangeProof { - fn strict_decode(_: &mut impl TypedRead) -> Result { - panic!("bulletproofs dummies must never be read") - } -} - -pub struct PedersenProtocol; - -impl CommitmentProtocol for PedersenProtocol {} - -/// Confidential version of the fungible state. -/// -/// See also revealed version [`RevealedValue`]. -#[derive(Clone, Copy, Eq, Debug)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT, rename = "ConcealedFungible", tags = custom, dumb = Self::HashedValue(strict_dumb!()))] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase", untagged) -)] -pub enum ConcealedValue { - #[strict_type(tag = 0x00)] - HashedValue(Bytes32), - - #[strict_type(tag = 0xFF)] - ConfidentialAsset { - /// Pedersen commitment to the original [`FungibleState`]. - commitment: PedersenCommitment, - /// Range proof for the [`FungibleState`] not exceeding type boundaries. - range_proof: RangeProof, - }, -} - -impl PartialEq for ConcealedValue { - fn eq(&self, other: &Self) -> bool { - match (self, other) { - (Self::HashedValue(h1), Self::HashedValue(h2)) => h1 == h2, - ( - Self::ConfidentialAsset { commitment: c1, .. }, - Self::ConfidentialAsset { commitment: c2, .. }, - ) => c1 == c2, - (Self::HashedValue(_), Self::ConfidentialAsset { .. }) - | (Self::ConfidentialAsset { .. }, Self::HashedValue(_)) => false, - } - } -} - -impl ConfidentialState for ConcealedValue { - fn state_type(&self) -> StateType { StateType::Fungible } - fn state_commitment(&self) -> ConcealedState { ConcealedState::Fungible(*self) } -} - -impl CommitVerify for ConcealedValue { - fn commit(revealed: &RevealedValue) -> Self { - match revealed { - RevealedValue::Asset { value, blinding } => {} - - RevealedValue::ConfidentialAsset { - value, - blinding, - tag, - } => { - use secp256k1_zkp::{Generator, Tag, Tweak}; - - let blinding = Tweak::from_inner(blinding.0.into_inner()) - .expect("type guarantees of BlindingFactor are broken"); - - let tag = Tag::from(tag.to_byte_array()); - let generator = Generator::new_unblinded(SECP256K1, tag); - - let commitment = secp256k1_zkp::PedersenCommitment::new( - SECP256K1, - value.to_u64(), - blinding, - generator, - ) - .into(); - - // TODO: Do actual conceal upon integration of bulletproofs library - let range_proof = RangeProof::default(); - ConcealedValue::ConfidentialAsset { - commitment, - range_proof, - } - } - } - } -} - -/// Errors verifying range proofs. -#[derive(Copy, Clone, PartialEq, Eq, Debug, Display, Error)] -#[display(doc_comments)] -pub enum RangeProofError { - /// invalid blinding factor {0}. - InvalidBlinding(BlindingFactor), - - /// bulletproofs verification is not implemented in RGB Core v0.10. Please - /// update your software and try again, or ask your software producer to use - /// latest RGB release. - BulletproofsAbsent, -} - -impl ConcealedValue { - /// Verifies validity of the range proof. - pub fn verify_range_proof(&self) -> Result { - // We always fail here - Err(RangeProofError::BulletproofsAbsent) - } -} - -#[cfg(test)] -mod test { - use amplify::ByteArray; - - use super::*; - - #[test] - fn pedersen_blinding_mismatch() { - let mut r = thread_rng(); - let tag = AssetTag::from_byte_array([1u8; 32]); - - let a = PedersenCommitment::commit(&RevealedValue::confidential_rng(15, &mut r, tag)) - .into_inner(); - let b = PedersenCommitment::commit(&RevealedValue::confidential_rng(7, &mut r, tag)) - .into_inner(); - - let c = PedersenCommitment::commit(&RevealedValue::confidential_rng(13, &mut r, tag)) - .into_inner(); - let d = PedersenCommitment::commit(&RevealedValue::confidential_rng(9, &mut r, tag)) - .into_inner(); - - assert!(!secp256k1_zkp::verify_commitments_sum_to_equal(SECP256K1, &[a, b], &[c, d])) - } - - #[test] - fn pedersen_blinding_same() { - let blinding = - BlindingFactor::from(secp256k1_zkp::SecretKey::from_slice(&[1u8; 32]).unwrap()); - let tag = AssetTag::from_byte_array([1u8; 32]); - - let a = PedersenCommitment::commit(&RevealedValue::with_blinding(15, blinding, tag)) - .into_inner(); - let b = PedersenCommitment::commit(&RevealedValue::with_blinding(7, blinding, tag)) - .into_inner(); - - let c = PedersenCommitment::commit(&RevealedValue::with_blinding(13, blinding, tag)) - .into_inner(); - let d = PedersenCommitment::commit(&RevealedValue::with_blinding(9, blinding, tag)) - .into_inner(); - - assert!(secp256k1_zkp::verify_commitments_sum_to_equal(SECP256K1, &[a, b], &[c, d])) - } - - #[test] - fn pedersen_blinding_same_tag_differ() { - let blinding = - BlindingFactor::from(secp256k1_zkp::SecretKey::from_slice(&[1u8; 32]).unwrap()); - let tag = AssetTag::from_byte_array([1u8; 32]); - let tag2 = AssetTag::from_byte_array([2u8; 32]); - - let a = PedersenCommitment::commit(&RevealedValue::with_blinding(15, blinding, tag2)) - .into_inner(); - let b = PedersenCommitment::commit(&RevealedValue::with_blinding(7, blinding, tag)) - .into_inner(); - - let c = PedersenCommitment::commit(&RevealedValue::with_blinding(13, blinding, tag2)) - .into_inner(); - let d = PedersenCommitment::commit(&RevealedValue::with_blinding(9, blinding, tag)) - .into_inner(); - - assert!(!secp256k1_zkp::verify_commitments_sum_to_equal(SECP256K1, &[a, b], &[c, d])) - } - - #[test] - fn pedersen_two_tags() { - let blinding = - BlindingFactor::from(secp256k1_zkp::SecretKey::from_slice(&[1u8; 32]).unwrap()); - let tag = AssetTag::from_byte_array([1u8; 32]); - let tag2 = AssetTag::from_byte_array([2u8; 32]); - - let a = PedersenCommitment::commit(&RevealedValue::with_blinding(15, blinding, tag2)) - .into_inner(); - let b = PedersenCommitment::commit(&RevealedValue::with_blinding(7, blinding, tag2)) - .into_inner(); - let c = PedersenCommitment::commit(&RevealedValue::with_blinding(2, blinding, tag)) - .into_inner(); - let d = PedersenCommitment::commit(&RevealedValue::with_blinding(4, blinding, tag)) - .into_inner(); - - let e = PedersenCommitment::commit(&RevealedValue::with_blinding(13, blinding, tag2)) - .into_inner(); - let f = PedersenCommitment::commit(&RevealedValue::with_blinding(9, blinding, tag2)) - .into_inner(); - let g = PedersenCommitment::commit(&RevealedValue::with_blinding(1, blinding, tag)) - .into_inner(); - let h = PedersenCommitment::commit(&RevealedValue::with_blinding(5, blinding, tag)) - .into_inner(); - - assert!(secp256k1_zkp::verify_commitments_sum_to_equal(SECP256K1, &[a, b, c, d], &[ - e, f, g, h - ])) - } - - #[test] - fn pedersen_blinding_balance() { - let blinding1 = BlindingFactor::random(); - let blinding2 = BlindingFactor::random(); - let blinding3 = BlindingFactor::random(); - let blinding4 = BlindingFactor::zero_balanced([blinding1, blinding2], [blinding3]).unwrap(); - let tag = AssetTag::from_byte_array([1u8; 32]); - - let a = PedersenCommitment::commit(&RevealedValue::with_blinding(15, blinding1, tag)) - .into_inner(); - let b = PedersenCommitment::commit(&RevealedValue::with_blinding(7, blinding2, tag)) - .into_inner(); - - let c = PedersenCommitment::commit(&RevealedValue::with_blinding(13, blinding3, tag)) - .into_inner(); - let d = PedersenCommitment::commit(&RevealedValue::with_blinding(9, blinding4, tag)) - .into_inner(); - - assert!(secp256k1_zkp::verify_commitments_sum_to_equal(SECP256K1, &[a, b], &[c, d])) - } -} diff --git a/src/operation/global.rs b/src/operation/global.rs index 25dadc12..647fb399 100644 --- a/src/operation/global.rs +++ b/src/operation/global.rs @@ -23,11 +23,11 @@ use std::collections::btree_map; use std::vec; -use amplify::confinement::{Confined, TinyOrdMap, U16}; +use amplify::confinement::{Confined, NonEmptyVec, SmallBlob, TinyOrdMap, U16 as U16MAX}; use amplify::{confinement, Wrapper}; use strict_encoding::StrictDumb; -use crate::{schema, DataState, LIB_NAME_RGB_COMMIT}; +use crate::{schema, LIB_NAME_RGB_COMMIT}; #[derive(Wrapper, WrapperMut, Clone, PartialEq, Eq, Hash, Debug, From)] #[wrapper(Deref)] @@ -39,19 +39,19 @@ use crate::{schema, DataState, LIB_NAME_RGB_COMMIT}; derive(Serialize, Deserialize), serde(crate = "serde_crate", transparent) )] -pub struct GlobalValues(Confined, 1, U16>); +pub struct GlobalValues(NonEmptyVec); impl StrictDumb for GlobalValues { - fn strict_dumb() -> Self { Self(Confined::with(DataState::strict_dumb())) } + fn strict_dumb() -> Self { Self(NonEmptyVec::with(SmallBlob::strict_dumb())) } } impl GlobalValues { - pub fn with(state: DataState) -> Self { GlobalValues(Confined::with(state)) } + pub fn with(state: SmallBlob) -> Self { GlobalValues(Confined::with(state)) } } impl IntoIterator for GlobalValues { - type Item = DataState; - type IntoIter = vec::IntoIter; + type Item = SmallBlob; + type IntoIter = vec::IntoIter; fn into_iter(self) -> Self::IntoIter { self.0.into_iter() } } @@ -72,7 +72,7 @@ impl GlobalState { pub fn add_state( &mut self, ty: schema::GlobalStateType, - state: DataState, + state: SmallBlob, ) -> Result<(), confinement::Error> { match self.0.get_mut(&ty) { Some(vec) => vec.push(state), @@ -83,7 +83,7 @@ impl GlobalState { pub fn extend_state( &mut self, ty: schema::GlobalStateType, - iter: impl IntoIterator, + iter: impl IntoIterator, ) -> Result<(), confinement::Error> { match self.0.get_mut(&ty) { Some(vec) => vec.extend(iter), diff --git a/src/operation/mod.rs b/src/operation/mod.rs index c13450be..3ffb43ce 100644 --- a/src/operation/mod.rs +++ b/src/operation/mod.rs @@ -22,9 +22,6 @@ mod meta; mod global; -mod data; -mod fungible; -mod attachment; mod state; pub mod seal; pub mod assignments; @@ -33,32 +30,23 @@ mod bundle; mod xchain; mod commit; -pub use assignments::{ - Assign, AssignAttach, AssignData, AssignFungible, AssignRights, Assignments, AssignmentsRef, - TypedAssigns, -}; -pub use attachment::{AttachId, AttachState, ConcealedAttach, RevealedAttach}; +pub use assignments::{Assign, Assignments, AssignmentsRef, ItemAbsent, TypedAssigns}; pub use bundle::{BundleId, InputMap, TransitionBundle, Vin}; pub use commit::{ AssignmentCommitment, AssignmentIndex, BaseCommitment, BundleDisclosure, ContractId, DiscloseHash, GlobalCommitment, OpCommitment, OpDisclose, OpId, TypeCommitment, }; -pub use data::{ConcealedData, DataState, RevealedData, VoidState}; -pub use fungible::{ - AssetTag, BlindingFactor, BlindingParseError, ConcealedValue, FungibleState, - InvalidFieldElement, NoiseDumb, PedersenCommitment, RangeProof, RangeProofError, RevealedValue, -}; pub use global::{GlobalState, GlobalValues}; pub use meta::{MetaValue, Metadata, MetadataError}; pub use operations::{ - AssetTags, Extension, Genesis, Identity, Input, Inputs, Operation, Opout, OpoutParseError, - Redeemed, Transition, Valencies, + Extension, Genesis, Identity, Input, Inputs, Operation, Opout, OpoutParseError, Redeemed, + Transition, Valencies, }; pub use seal::{ ExposedSeal, GenesisSeal, GraphSeal, OutputSeal, SecretSeal, TxoSeal, XGenesisSeal, XGraphSeal, XOutputSeal, }; -pub use state::{ConcealedState, ConfidentialState, ExposedState, RevealedState, StateType}; +pub use state::{AttachId, State, StateCommitment}; pub use xchain::{ AltLayer1, AltLayer1Set, Impossible, Layer1, XChain, XChainParseError, XOutpoint, XCHAIN_BITCOIN_PREFIX, XCHAIN_LIQUID_PREFIX, diff --git a/src/operation/operations.rs b/src/operation/operations.rs index eaf7a96c..f345a2c4 100644 --- a/src/operation/operations.rs +++ b/src/operation/operations.rs @@ -37,10 +37,9 @@ use strict_encoding::{RString, StrictDeserialize, StrictEncode, StrictSerialize} use crate::schema::{self, ExtensionType, OpFullType, OpType, SchemaId, TransitionType}; use crate::{ - AltLayer1Set, AssetTag, Assign, AssignmentIndex, AssignmentType, Assignments, AssignmentsRef, - ConcealedAttach, ConcealedData, ConcealedValue, ContractId, DiscloseHash, ExposedState, Ffv, - GenesisSeal, GlobalState, GraphSeal, Metadata, OpDisclose, OpId, SecretSeal, TypedAssigns, - VoidState, XChain, LIB_NAME_RGB_COMMIT, + AltLayer1Set, AssignmentIndex, AssignmentType, Assignments, AssignmentsRef, ContractId, + DiscloseHash, Ffv, GenesisSeal, GlobalState, GraphSeal, Metadata, OpDisclose, OpId, SecretSeal, + StateCommitment, TypedAssigns, XChain, LIB_NAME_RGB_COMMIT, }; #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)] @@ -95,20 +94,6 @@ impl FromStr for Opout { } } -#[derive(Wrapper, WrapperMut, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default, From)] -#[wrapper(Deref)] -#[wrapper_mut(DerefMut)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT)] -#[derive(CommitEncode)] -#[commit_encode(strategy = strict, id = StrictHash)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct AssetTags(TinyOrdMap); - #[derive(Wrapper, WrapperMut, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default, From)] #[wrapper(Deref)] #[wrapper_mut(DerefMut)] @@ -258,52 +243,24 @@ pub trait Operation { /// Provides summary about parts of the operation which are revealed. fn disclose(&self) -> OpDisclose { - fn proc_seals( - ty: AssignmentType, - a: &[Assign], - seals: &mut BTreeMap>, - state: &mut BTreeMap, - ) { - for (index, assignment) in a.iter().enumerate() { + let mut seals: BTreeMap> = bmap!(); + let mut state: BTreeMap = bmap!(); + for (ty, assigns) in self.assignments().to_graph_seals() { + for (index, assignment) in assigns.iter().enumerate() { if let Some(seal) = assignment.revealed_seal() { seals.insert(AssignmentIndex::new(ty, index as u16), seal.to_secret_seal()); } - if let Some(revealed) = assignment.as_revealed_state() { - state.insert(AssignmentIndex::new(ty, index as u16), revealed.conceal()); - } - } - } - - let mut seals: BTreeMap> = bmap!(); - let mut void: BTreeMap = bmap!(); - let mut fungible: BTreeMap = bmap!(); - let mut data: BTreeMap = bmap!(); - let mut attach: BTreeMap = bmap!(); - for (ty, assigns) in self.assignments().flat() { - match assigns { - TypedAssigns::Declarative(a) => { - proc_seals(ty, &a, &mut seals, &mut void); - } - TypedAssigns::Fungible(a) => { - proc_seals(ty, &a, &mut seals, &mut fungible); - } - TypedAssigns::Structured(a) => { - proc_seals(ty, &a, &mut seals, &mut data); - } - TypedAssigns::Attachment(a) => { - proc_seals(ty, &a, &mut seals, &mut attach); - } + state.insert( + AssignmentIndex::new(ty, index as u16), + assignment.as_state().commit_id(), + ); } } OpDisclose { id: self.id(), seals: Confined::from_checked(seals), - fungible: Confined::from_iter_checked( - fungible.into_iter().map(|(k, s)| (k, s.commitment())), - ), - data: Confined::from_checked(data), - attach: Confined::from_checked(attach), + state: Confined::from_checked(state), } } @@ -361,7 +318,6 @@ pub struct Genesis { pub issuer: Identity, pub testnet: bool, pub alt_layers1: AltLayer1Set, - pub asset_tags: AssetTags, pub metadata: Metadata, pub globals: GlobalState, pub assignments: Assignments, @@ -541,9 +497,7 @@ impl Operation for Genesis { #[inline] fn assignments_by_type(&self, t: AssignmentType) -> Option> { - self.assignments - .get(&t) - .map(TypedAssigns::transmutate_seals) + self.assignments.get(&t).map(TypedAssigns::transmute_seals) } #[inline] @@ -586,9 +540,7 @@ impl Operation for Extension { #[inline] fn assignments_by_type(&self, t: AssignmentType) -> Option> { - self.assignments - .get(&t) - .map(TypedAssigns::transmutate_seals) + self.assignments.get(&t).map(TypedAssigns::transmute_seals) } #[inline] diff --git a/src/operation/state.rs b/src/operation/state.rs index 2eaa0155..91ab9b77 100644 --- a/src/operation/state.rs +++ b/src/operation/state.rs @@ -21,107 +21,110 @@ // limitations under the License. use core::fmt::Debug; -use core::hash::Hash; +use std::fmt; +use std::fmt::{Display, Formatter}; +use std::str::FromStr; -use commit_verify::Conceal; -use strict_encoding::{StrictDecode, StrictDumb, StrictEncode}; +use amplify::confinement::{SmallBlob, U16 as U16MAX}; +use amplify::{Bytes32, Wrapper}; +use baid64::{Baid64ParseError, DisplayBaid64, FromBaid64Str}; +use commit_verify::{CommitmentId, DigestExt, ReservedBytes, Sha256}; +use strict_encoding::{StrictSerialize, StrictType}; -use crate::{ - ConcealedAttach, ConcealedData, ConcealedValue, RevealedAttach, RevealedData, RevealedValue, -}; +use crate::{impl_serde_baid64, LIB_NAME_RGB_COMMIT}; -/// Marker trait for types of state which are just a commitment to the actual -/// state data. -pub trait ConfidentialState: Debug + Eq + Copy { - fn state_type(&self) -> StateType; - fn state_commitment(&self) -> ConcealedState; -} +/// Unique data attachment identifier +#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)] +#[wrapper(Deref, BorrowSlice, Hex, Index, RangeOps)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB_COMMIT)] +pub struct AttachId( + #[from] + #[from([u8; 32])] + Bytes32, +); -/// Marker trait for types of state holding explicit state data. -pub trait ExposedState: - Debug - + StrictDumb - + StrictEncode - + StrictDecode - + Conceal - + Eq - + Clone -{ - type Confidential: ConfidentialState + StrictEncode + StrictDecode + StrictDumb; - fn state_type(&self) -> StateType; - fn state_data(&self) -> RevealedState; +impl DisplayBaid64 for AttachId { + const HRI: &'static str = "rgb:fs"; + const CHUNKING: bool = true; + const PREFIX: bool = true; + const EMBED_CHECKSUM: bool = false; + const MNEMONIC: bool = true; + fn to_baid64_payload(&self) -> [u8; 32] { self.to_byte_array() } +} +impl FromBaid64Str for AttachId {} +impl FromStr for AttachId { + type Err = Baid64ParseError; + fn from_str(s: &str) -> Result { Self::from_baid64_str(s) } +} +impl Display for AttachId { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { self.fmt_baid64(f) } } -/// Categories of the state -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -#[display(lowercase)] -pub enum StateType { - /// No state data - Void, - - /// Value-based state, i.e. which can be committed to with a Pedersen - /// commitment - Fungible, - - /// State defined with custom data - Structured, +impl_serde_baid64!(AttachId); - /// Attached data container - Attachment, +#[derive(Clone, PartialOrd, Ord, Eq, PartialEq, Hash, Debug)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB_COMMIT)] +#[derive(CommitEncode)] +#[commit_encode(strategy = strict, id = StateCommitment)] +#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] +pub struct State { + pub reserved: ReservedBytes<1>, + pub value: SmallBlob, + pub attach: Option, } -/// Categories of the state -#[derive(Clone, Eq, PartialEq, Hash, Debug)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase", tag = "type") -)] -pub enum RevealedState { - Void, - Fungible(RevealedValue), - Structured(RevealedData), - Attachment(RevealedAttach), -} +impl State { + /// # Panics + /// + /// If the size of the serialized value exceeds 0xFFFF bytes. + pub fn new(value: impl StrictSerialize) -> Self { + State { + reserved: default!(), + value: value + .to_strict_serialized::() + .expect("unable to fit in the data"), + attach: None, + } + } -impl RevealedState { - pub fn state_type(&self) -> StateType { - match self { - RevealedState::Void => StateType::Void, - RevealedState::Fungible(_) => StateType::Fungible, - RevealedState::Structured(_) => StateType::Structured, - RevealedState::Attachment(_) => StateType::Attachment, + /// # Panics + /// + /// If the size of the serialized value exceeds 0xFFFF bytes. + pub fn with(value: impl StrictSerialize, attach: AttachId) -> Self { + State { + reserved: default!(), + value: value + .to_strict_serialized::() + .expect("unable to fit in the data"), + attach: Some(attach), } } } -#[derive(Copy, Clone, Eq, PartialEq, Debug)] +/// Confidential version of a structured state data. +/// +/// See also revealed version [`State`]. +#[derive(Wrapper, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)] +#[wrapper(Deref, BorrowSlice, Hex, Index, RangeOps)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB_COMMIT, rename = "ConcealedData")] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase", tag = "type") + serde(crate = "serde_crate", transparent) )] -#[allow(clippy::large_enum_variant)] -pub enum ConcealedState { - Void, - Fungible(ConcealedValue), - Structured(ConcealedData), - Attachment(ConcealedAttach), +pub struct StateCommitment( + #[from] + #[from([u8; 32])] + Bytes32, +); + +impl From for StateCommitment { + fn from(hasher: Sha256) -> Self { hasher.finish().into() } } -impl ConfidentialState for ConcealedState { - fn state_type(&self) -> StateType { - match self { - ConcealedState::Void => StateType::Void, - ConcealedState::Fungible(_) => StateType::Fungible, - ConcealedState::Structured(_) => StateType::Structured, - ConcealedState::Attachment(_) => StateType::Attachment, - } - } - fn state_commitment(&self) -> ConcealedState { *self } +impl CommitmentId for StateCommitment { + const TAG: &'static str = "urn:lnp-bp:rgb:state-data#2024-10-13"; } diff --git a/src/schema/mod.rs b/src/schema/mod.rs index 54073447..3e26fb7f 100644 --- a/src/schema/mod.rs +++ b/src/schema/mod.rs @@ -32,4 +32,4 @@ pub use operations::{ OpFullType, OpSchema, OpType, TransitionSchema, ValencySchema, ValencyType, }; pub use schema::{ExtensionType, GlobalStateType, MetaType, Schema, SchemaId, TransitionType}; -pub use state::{FungibleType, GlobalStateSchema, MediaType, OwnedStateSchema}; +pub use state::{GlobalStateSchema, OwnedStateSchema}; diff --git a/src/schema/schema.rs b/src/schema/schema.rs index 5f70800f..974f5007 100644 --- a/src/schema/schema.rs +++ b/src/schema/schema.rs @@ -21,6 +21,7 @@ // limitations under the License. use std::cmp::Ordering; +use std::collections::BTreeSet; use std::fmt::{self, Display, Formatter}; use std::str::FromStr; @@ -227,19 +228,16 @@ impl Schema { schema } - pub fn types(&self) -> impl Iterator + '_ { + pub fn types(&self) -> BTreeSet { self.meta_types .values() .copied() .chain(self.global_types.values().map(|i| i.sem_id)) - .chain( - self.owned_types - .values() - .filter_map(OwnedStateSchema::sem_id), - ) + .chain(self.owned_types.values().map(|s| s.sem_id)) + .collect() } - pub fn libs(&self) -> impl Iterator + '_ { + pub fn libs(&self) -> BTreeSet { self.genesis .validator .iter() @@ -247,6 +245,7 @@ impl Schema { .chain(self.transitions.values().filter_map(|i| i.validator)) .chain(self.extensions.values().filter_map(|i| i.validator)) .map(|site| site.lib) + .collect() } } diff --git a/src/schema/state.rs b/src/schema/state.rs index e4435c69..839d886f 100644 --- a/src/schema/state.rs +++ b/src/schema/state.rs @@ -22,90 +22,32 @@ use amplify::num::u24; use commit_verify::ReservedBytes; -use strict_encoding::Primitive; use strict_types::SemId; -use crate::{StateType, LIB_NAME_RGB_COMMIT}; - -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT, tags = repr, into_u8, try_from_u8)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase", tag = "type") -)] -#[non_exhaustive] -#[repr(u8)] -pub enum MediaType { - #[display("*/*")] - #[strict_type(dumb)] - Any = 0xFF, - // TODO: Complete MIME type implementation -} - -impl MediaType { - pub fn conforms(&self, other: &MediaType) -> bool { - match (self, other) { - (MediaType::Any, MediaType::Any) => true, - } - } -} +use crate::LIB_NAME_RGB_COMMIT; #[derive(Copy, Clone, PartialEq, Eq, Debug)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT, tags = order)] +#[strict_type(lib = LIB_NAME_RGB_COMMIT)] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "camelCase") )] -pub enum OwnedStateSchema { - #[strict_type(dumb)] - Declarative, - Fungible(FungibleType), - Structured(SemId), - Attachment(MediaType), - // TODO: Computed state (RCP240327A) will be added here +pub struct OwnedStateSchema { + pub reserved: ReservedBytes<1>, + pub sem_id: SemId, } -impl OwnedStateSchema { - pub fn state_type(&self) -> StateType { - match self { - OwnedStateSchema::Declarative => StateType::Void, - OwnedStateSchema::Fungible(_) => StateType::Fungible, - OwnedStateSchema::Structured(_) => StateType::Structured, - OwnedStateSchema::Attachment(_) => StateType::Attachment, - } - } - - pub fn sem_id(&self) -> Option { - if let Self::Structured(id) = self { - Some(*id) - } else { - None +impl From for OwnedStateSchema { + fn from(sem_id: SemId) -> Self { + Self { + reserved: none!(), + sem_id, } } } -#[derive(Copy, Clone, PartialEq, Eq, Debug, Default, Display)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_COMMIT, tags = repr, into_u8, try_from_u8)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -#[repr(u8)] -pub enum FungibleType { - #[default] - #[display("U64")] - U64 = Primitive::U64.into_code(), - - #[display("ConfidentialAsset")] - ConfidentialAsset = 0xFF, -} - #[derive(Clone, PartialEq, Eq, Hash, Debug)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_COMMIT)] @@ -115,8 +57,6 @@ pub enum FungibleType { serde(crate = "serde_crate", rename_all = "camelCase") )] pub struct GlobalStateSchema { - // TODO: Reserved for computed state (RCP240327A): will be used as an enum tag with computed - // state having value 1. pub reserved: ReservedBytes<1>, pub sem_id: SemId, pub max_items: u24, diff --git a/src/stl.rs b/src/stl.rs index bbc97c6f..715ce926 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -37,10 +37,10 @@ use crate::{ /// Strict types id for the library providing data types for RGB consensus. pub const LIB_ID_RGB_COMMIT: &str = - "stl:IFcnrPeI-TANxLfZ-feJax6Q-1TUM4Hq-AjI161s-3tbmxak#harvest-person-orion"; + "stl:JepgtiGZ-TYqkSmV-vo6ysWP-gZZEU03-pVoHbyj-nR02608#aspect-shoe-garcia"; /// Strict types id for the library providing data types for RGB consensus. pub const LIB_ID_RGB_LOGIC: &str = - "stl:mqltqlPk-O9$pYOd-BACRI70-DOMJ6cp-TFvhcK1-ibrOI9U#import-boxer-seminar"; + "stl:nKQEKac1-dDxkN3M-dXhgnba-CkprxwT-So5aC5D-meYuULE#charm-chief-invite"; fn _rgb_commit_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_RGB_COMMIT), tiny_bset! { diff --git a/src/validation/logic.rs b/src/validation/logic.rs index b579f7a1..b28b603a 100644 --- a/src/validation/logic.rs +++ b/src/validation/logic.rs @@ -21,7 +21,7 @@ // limitations under the License. use std::cell::RefCell; -use std::collections::BTreeSet; +use std::collections::{BTreeMap, BTreeSet}; use std::rc::Rc; use aluvm::data::Number; @@ -36,10 +36,9 @@ use crate::schema::{AssignmentsSchema, GlobalSchema, ValencySchema}; use crate::validation::{CheckedConsignment, ConsignmentApi}; use crate::vm::{ContractStateAccess, ContractStateEvolve, OpInfo, OrdOpRef, RgbIsa, VmContext}; use crate::{ - validation, Assign, AssignmentType, Assignments, AssignmentsRef, ConcealedState, - ConfidentialState, ExposedSeal, ExposedState, Extension, GlobalState, GlobalStateSchema, - GlobalValues, GraphSeal, Inputs, MetaSchema, Metadata, OpId, Operation, Opout, - OwnedStateSchema, RevealedState, Schema, StateType, Transition, TypedAssigns, Valencies, + validation, Assign, AssignmentType, Assignments, AssignmentsRef, ExposedSeal, Extension, + GlobalState, GlobalStateSchema, GlobalValues, GraphSeal, Inputs, MetaSchema, Metadata, OpId, + Operation, Opout, OwnedStateSchema, Schema, Transition, TypedAssigns, Valencies, }; impl Schema { @@ -69,31 +68,16 @@ impl Schema { validator, ty, ) = match op { - OrdOpRef::Genesis(genesis) => { - for id in genesis.asset_tags.keys() { - if !matches!(self.owned_types.get(id), Some(OwnedStateSchema::Fungible(_))) { - status.add_failure(validation::Failure::AssetTagNoState(*id)); - } - } - for (id, ss) in &self.owned_types { - if ss.state_type() == StateType::Fungible - && !genesis.asset_tags.contains_key(id) - { - status.add_failure(validation::Failure::FungibleStateNoTag(*id)); - } - } - - ( - &self.genesis.metadata, - &self.genesis.globals, - &empty_assign_schema, - &empty_valency_schema, - &self.genesis.assignments, - &self.genesis.valencies, - self.genesis.validator, - None::, - ) - } + OrdOpRef::Genesis(_) => ( + &self.genesis.metadata, + &self.genesis.globals, + &empty_assign_schema, + &empty_valency_schema, + &self.genesis.assignments, + &self.genesis.valencies, + self.genesis.validator, + None::, + ), OrdOpRef::Transition( Transition { transition_type, .. @@ -199,7 +183,6 @@ impl Schema { let op_info = OpInfo::with(opid, &op, &prev_state, &redeemed); let context = VmContext { contract_id: genesis.contract_id(), - asset_tags: &genesis.asset_tags, op_info, contract_state, }; @@ -372,7 +355,7 @@ impl Schema { for (owned_type_id, occ) in assign_schema { let len = owned_state .get(owned_type_id) - .map(TypedAssigns::len_u16) + .map(|ta| ta.len_u16()) .unwrap_or(0); // Checking number of ancestor's assignment occurrences @@ -431,7 +414,7 @@ impl Schema { for (state_id, occ) in assign_schema { let len = owned_state .get(state_id) - .map(TypedAssigns::len_u16) + .map(|ta| ta.len_u16()) .unwrap_or(0); // Checking number of assignment occurrences @@ -446,21 +429,11 @@ impl Schema { validation and we would not reach this point", ); - match owned_state.get(state_id) { - None => {} - Some(TypedAssigns::Declarative(set)) => set - .iter() - .for_each(|data| status += assignment.validate(id, *state_id, data, types)), - Some(TypedAssigns::Fungible(set)) => set + if let Some(assignments) = owned_state.get(state_id) { + assignments .iter() - .for_each(|data| status += assignment.validate(id, *state_id, data, types)), - Some(TypedAssigns::Structured(set)) => set - .iter() - .for_each(|data| status += assignment.validate(id, *state_id, data, types)), - Some(TypedAssigns::Attachment(set)) => set - .iter() - .for_each(|data| status += assignment.validate(id, *state_id, data, types)), - }; + .for_each(|data| status += assignment.validate(id, *state_id, data, types)) + } } status @@ -493,7 +466,7 @@ fn extract_prev_state( inputs: &Inputs, status: &mut validation::Status, ) -> Assignments { - let mut assignments = bmap! {}; + let mut assignments = BTreeMap::>::new(); for input in inputs { let Opout { op, ty, no } = input.prev_out; @@ -506,64 +479,22 @@ fn extract_prev_state( }; let no = no as usize; - match prev_op.assignments_by_type(ty) { - Some(TypedAssigns::Declarative(prev_assignments)) => { - if let Some(prev_assign) = prev_assignments.get(no) { - if let Some(typed_assigns) = assignments - .entry(ty) - .or_insert_with(|| TypedAssigns::Declarative(Default::default())) - .as_declarative_mut() - { - typed_assigns.push(prev_assign.clone()).expect("same size"); - } - } else { - status.add_failure(validation::Failure::NoPrevOut(opid, input.prev_out)); - } - } - Some(TypedAssigns::Fungible(prev_assignments)) => { - if let Some(prev_assign) = prev_assignments.get(no) { - if let Some(typed_assigns) = assignments - .entry(ty) - .or_insert_with(|| TypedAssigns::Fungible(Default::default())) - .as_fungible_mut() - { - typed_assigns.push(prev_assign.clone()).expect("same size"); - } - } else { - status.add_failure(validation::Failure::NoPrevOut(opid, input.prev_out)); - } - } - Some(TypedAssigns::Structured(prev_assignments)) => { - if let Some(prev_assign) = prev_assignments.get(no) { - if let Some(typed_assigns) = assignments - .entry(ty) - .or_insert_with(|| TypedAssigns::Structured(Default::default())) - .as_structured_mut() - { - typed_assigns.push(prev_assign.clone()).expect("same size"); - } - } else { - status.add_failure(validation::Failure::NoPrevOut(opid, input.prev_out)); - } - } - Some(TypedAssigns::Attachment(prev_assignments)) => { - if let Some(prev_assign) = prev_assignments.get(no) { - if let Some(typed_assigns) = assignments - .entry(ty) - .or_insert_with(|| TypedAssigns::Attachment(Default::default())) - .as_attachment_mut() - { - typed_assigns.push(prev_assign.clone()).expect("same size"); - } + if let Some(prev_assignments) = prev_op.assignments_by_type(ty) { + if let Some(prev_assign) = prev_assignments.get(no).cloned() { + if let Some(typed_assigns) = assignments.get_mut(&ty) { + typed_assigns.push(prev_assign).expect("same size"); } else { - status.add_failure(validation::Failure::NoPrevOut(opid, input.prev_out)); + assignments + .insert(ty, TypedAssigns::with(prev_assign)) + .expect("same size"); } + } else { + status.add_failure(validation::Failure::NoPrevOut(opid, input.prev_out)); } - None => { - // Presence of the required owned rights type in the - // parent operation was already validated; we have nothing - // to report here - } + } else { + // Presence of the required owned rights type in the + // parent operation was already validated; we have nothing + // to report here } } Confined::try_from(assignments) @@ -572,95 +503,23 @@ fn extract_prev_state( } impl OwnedStateSchema { - pub fn validate( + pub fn validate( &self, opid: OpId, state_type: AssignmentType, - data: &Assign, + assign: &Assign, type_system: &TypeSystem, ) -> validation::Status { let mut status = validation::Status::new(); - match data { - Assign::Confidential { state, .. } | Assign::ConfidentialState { state, .. } => { - match (self, state.state_commitment()) { - (OwnedStateSchema::Declarative, ConcealedState::Void) => {} - (OwnedStateSchema::Fungible(_), ConcealedState::Fungible(value)) => { - // [SECURITY-CRITICAL]: Bulletproofs validation - if let Err(err) = value.verify_range_proof() { - status.add_failure(validation::Failure::BulletproofsInvalid( - opid, - state_type, - err.to_string(), - )); - } - } - (OwnedStateSchema::Structured(_), ConcealedState::Structured(_)) => { - status.add_warning(validation::Warning::UncheckableConfidentialState( - opid, state_type, - )); - } - (OwnedStateSchema::Attachment(_), ConcealedState::Attachment(_)) => { - status.add_warning(validation::Warning::UncheckableConfidentialState( - opid, state_type, - )); - } - // all other options are mismatches - (state_schema, found) => { - status.add_failure(validation::Failure::StateTypeMismatch { - opid, - state_type, - expected: state_schema.state_type(), - found: found.state_type(), - }); - } - } - } - Assign::Revealed { state, .. } | Assign::ConfidentialSeal { state, .. } => { - match (self, state.state_data()) { - (OwnedStateSchema::Declarative, RevealedState::Void) => {} - ( - OwnedStateSchema::Attachment(media_type), - RevealedState::Attachment(attach), - ) if !attach.file.media_type.conforms(media_type) => { - status.add_failure(validation::Failure::MediaTypeMismatch { - opid, - state_type, - expected: *media_type, - found: attach.file.media_type, - }); - } - (OwnedStateSchema::Fungible(schema), RevealedState::Fungible(v)) - if v.fungible_type() != *schema => - { - status.add_failure(validation::Failure::FungibleTypeMismatch { - opid, - state_type, - expected: *schema, - found: v.fungible_type(), - }); - } - (OwnedStateSchema::Fungible(_), RevealedState::Fungible(_)) => {} - (OwnedStateSchema::Structured(sem_id), RevealedState::Structured(data)) => { - if type_system - .strict_deserialize_type(*sem_id, data.value.as_ref()) - .is_err() - { - status.add_failure(validation::Failure::SchemaInvalidOwnedValue( - opid, state_type, *sem_id, - )); - }; - } - // all other options are mismatches - (state_schema, found) => { - status.add_failure(validation::Failure::StateTypeMismatch { - opid, - state_type, - expected: state_schema.state_type(), - found: found.state_type(), - }); - } - } - } + if type_system + .strict_deserialize_type(self.sem_id, assign.as_state().value.as_ref()) + .is_err() + { + status.add_failure(validation::Failure::SchemaInvalidOwnedValue( + opid, + state_type, + self.sem_id, + )); } status } diff --git a/src/validation/schema.rs b/src/validation/schema.rs index 4e8dafc2..4c9dbbe2 100644 --- a/src/validation/schema.rs +++ b/src/validation/schema.rs @@ -22,7 +22,7 @@ use strict_types::TypeSystem; -use crate::{validation, OpFullType, OpSchema, OwnedStateSchema, Schema, TransitionType}; +use crate::{validation, OpFullType, OpSchema, Schema, TransitionType}; impl Schema { pub fn verify(&self, types: &TypeSystem) -> validation::Status { @@ -56,12 +56,11 @@ impl Schema { } for (type_id, schema) in &self.owned_types { - if let OwnedStateSchema::Structured(sem_id) = schema { - if !types.contains_key(sem_id) { - status.add_failure(validation::Failure::SchemaOwnedSemIdUnknown( - *type_id, *sem_id, - )); - } + if !types.contains_key(&schema.sem_id) { + status.add_failure(validation::Failure::SchemaOwnedSemIdUnknown( + *type_id, + schema.sem_id, + )); } } diff --git a/src/validation/status.rs b/src/validation/status.rs index f77c6a0a..c19ae8c4 100644 --- a/src/validation/status.rs +++ b/src/validation/status.rs @@ -31,8 +31,8 @@ use crate::schema::{self, SchemaId}; use crate::validation::WitnessResolverError; use crate::vm::XWitnessId; use crate::{ - BundleId, ContractId, Layer1, OccurrencesMismatch, OpFullType, OpId, Opout, StateType, Vin, - XGraphSeal, XOutputSeal, + BundleId, ContractId, Layer1, OccurrencesMismatch, OpFullType, OpId, Opout, Vin, XGraphSeal, + XOutputSeal, }; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Display)] @@ -263,13 +263,6 @@ pub enum Failure { /// which is an input of the state transition {3}. BundleInvalidCommitment(BundleId, Vin, XWitnessId, OpId), - // Errors checking asset tags - /// asset type provided in genesis references unknown fungible state of type - /// {0}. - AssetTagNoState(schema::AssignmentType), - /// fungible state {0} has no asset tag defined. - FungibleStateNoTag(schema::AssignmentType), - // Errors checking seal closing /// transition {opid} references state type {state_type} absent in the /// outputs of previous state transition {prev_id}. @@ -322,33 +315,6 @@ pub enum Failure { valency: schema::ValencyType, }, - // State check errors - /// state in {opid}/{state_type} is of {found} type, while schema requires - /// it to be {expected}. - StateTypeMismatch { - opid: OpId, - state_type: schema::AssignmentType, - expected: StateType, - found: StateType, - }, - /// state in {opid}/{state_type} is of {found} type, while schema requires - /// it to be {expected}. - MediaTypeMismatch { - opid: OpId, - state_type: schema::AssignmentType, - expected: schema::MediaType, - found: schema::MediaType, - }, - /// state in {opid}/{state_type} is of {found} type, while schema requires - /// it to be {expected}. - FungibleTypeMismatch { - opid: OpId, - state_type: schema::AssignmentType, - expected: schema::FungibleType, - found: schema::FungibleType, - }, - /// invalid bulletproofs in {0}:{1}: {2} - BulletproofsInvalid(OpId, schema::AssignmentType, String), /// evaluation of AluVM script for operation {0} has failed with the code /// {1:?} and message {2:?}. ScriptFailure(OpId, Option, Option), @@ -368,10 +334,6 @@ pub enum Failure { )] #[display(doc_comments)] pub enum Warning { - /// operation {0} contains state in assignment {1} which is confidential and - /// thus was not validated. - UncheckableConfidentialState(OpId, schema::AssignmentType), - /// Custom warning by external services on top of RGB Core. #[display(inner)] Custom(String), diff --git a/src/vm/contract.rs b/src/vm/contract.rs index 633c3492..cfe69509 100644 --- a/src/vm/contract.rs +++ b/src/vm/contract.rs @@ -37,11 +37,10 @@ use single_use_seals::SealWitness; use strict_encoding::{StrictDecode, StrictDumb, StrictEncode}; use crate::{ - AssetTags, AssignmentType, Assignments, AssignmentsRef, AttachState, ContractId, DataState, - ExposedSeal, Extension, ExtensionType, FungibleState, Genesis, GlobalState, GlobalStateType, - GraphSeal, Impossible, Inputs, Layer1, Metadata, OpFullType, OpId, OpType, Operation, - Transition, TransitionType, TxoSeal, TypedAssigns, Valencies, XChain, XOutpoint, XOutputSeal, - LIB_NAME_RGB_LOGIC, + AssignmentType, Assignments, AssignmentsRef, ContractId, ExposedSeal, Extension, ExtensionType, + Genesis, GlobalState, GlobalStateType, GraphSeal, Impossible, Inputs, Layer1, Metadata, + OpFullType, OpId, OpType, Operation, State, Transition, TransitionType, TxoSeal, TypedAssigns, + Valencies, XChain, XOutpoint, XOutputSeal, LIB_NAME_RGB_LOGIC, }; pub type XWitnessId = XChain; @@ -572,7 +571,7 @@ impl GlobalOrd { } pub trait GlobalStateIter { - type Data: Borrow; + type Data: Borrow; fn size(&mut self) -> u24; fn prev(&mut self) -> Option<(GlobalOrd, Self::Data)>; fn last(&mut self) -> Option<(GlobalOrd, Self::Data)>; @@ -633,7 +632,7 @@ impl GlobalContractState { /// Retrieves global state data located `depth` items back from the most /// recent global state value. Ensures that the global state ordering is /// consensus-based. - pub fn nth(&mut self, depth: u24) -> Option + '_> { + pub fn nth(&mut self, depth: u24) -> Option + '_> { if depth >= self.iter.size() { return None; } @@ -674,25 +673,11 @@ pub trait ContractStateAccess: Debug { ty: GlobalStateType, ) -> Result, UnknownGlobalStateType>; - fn rights(&self, outpoint: XOutpoint, ty: AssignmentType) -> u32; - - fn fungible( - &self, - outpoint: XOutpoint, - ty: AssignmentType, - ) -> impl DoubleEndedIterator; - - fn data( - &self, - outpoint: XOutpoint, - ty: AssignmentType, - ) -> impl DoubleEndedIterator>; - - fn attach( + fn state( &self, outpoint: XOutpoint, ty: AssignmentType, - ) -> impl DoubleEndedIterator>; + ) -> impl DoubleEndedIterator>; } pub trait ContractStateEvolve { @@ -705,7 +690,6 @@ pub trait ContractStateEvolve { pub struct VmContext<'op, S: ContractStateAccess> { pub contract_id: ContractId, - pub asset_tags: &'op AssetTags, pub op_info: OpInfo<'op>, pub contract_state: Rc>, } diff --git a/src/vm/op_contract.rs b/src/vm/op_contract.rs index 8078be27..47d19891 100644 --- a/src/vm/op_contract.rs +++ b/src/vm/op_contract.rs @@ -33,151 +33,92 @@ use aluvm::library::{CodeEofError, IsaSeg, LibSite, Read, Write}; use aluvm::reg::{CoreRegs, Reg, Reg16, Reg32, RegA, RegS}; use amplify::num::{u24, u3, u4}; use amplify::Wrapper; -use commit_verify::CommitVerify; use super::opcodes::*; use super::{ContractStateAccess, VmContext}; -use crate::{ - Assign, AssignmentType, BlindingFactor, GlobalStateType, MetaType, PedersenCommitment, - RevealedValue, TypedAssigns, -}; +use crate::{AssignmentType, GlobalStateType, MetaType}; #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)] pub enum ContractOp { - /// Counts number of inputs (previous state entries) of the provided type - /// and puts the number to the destination `a16` register. + /// Counts number of inputs (previous state entries) of the provided type and puts the number + /// to the destination `a16` register. /// - /// If the operation doesn't contain inputs with a given assignment type, - /// sets destination index to zero. Does not change `st0` register. + /// If the operation doesn't contain inputs with a given assignment type, sets destination + /// index to zero. Does not change `st0` register. #[display("cnp {0},a16{1}")] CnP(AssignmentType, Reg32), - /// Counts number of outputs (owned state entries) of the provided type - /// and puts the number to the destination `a16` register. + /// Counts number of outputs (owned state entries) of the provided type and puts the number to + /// the destination `a16` register. /// - /// If the operation doesn't contain inputs with a given assignment type, - /// sets destination index to zero. Does not change `st0` register. + /// If the operation doesn't contain inputs with a given assignment type, sets destination + /// index to zero. Does not change `st0` register. #[display("cns {0},a16{1}")] CnS(AssignmentType, Reg32), - /// Counts number of global state items of the provided type affected by the - /// current operation and puts the number to the destination `a8` register. + /// Counts number of global state items of the provided type affected by the current operation + /// and puts the number to the destination `a8` register. /// - /// If the operation doesn't contain inputs with a given assignment type, - /// sets destination index to zero. Does not change `st0` register. + /// If the operation doesn't contain inputs with a given assignment type, sets destination + /// index to zero. Does not change `st0` register. #[display("cng {0},a8{1}")] CnG(GlobalStateType, Reg32), - /// Counts number of global state items of the provided type in the contract - /// state and puts the number to the destination `a32` register. + /// Counts number of global state items of the provided type in the contract state and puts the + /// number to the destination `a32` register. /// - /// If the operation doesn't contain inputs with a given assignment type, - /// sets destination index to zero. Does not change `st0` register. + /// If the operation doesn't contain inputs with a given assignment type, sets destination + /// index to zero. Does not change `st0` register. #[display("cnc {0},a32{1}")] CnC(GlobalStateType, Reg32), - /// Loads input (previous) structured state with type id from the first - /// argument and index from the second argument `a16` register into a - /// register provided in the third argument. + /// Loads input (previous) state with type id from the first argument and index from the second + /// argument `a16` register into a register provided in the third argument. /// - /// If the state is absent or is not a structured state sets `st0` to - /// `false` and terminates the program. + /// If the state is absent or is not a structured state sets `st0` to `false` and terminates + /// the program. /// /// If the state at the index is concealed, sets destination to `None`. #[display("ldp {0},a16{1},{2}")] LdP(AssignmentType, Reg16, RegS), - /// Loads owned structured state with type id from the first argument and - /// index from the second argument `a16` register into a register provided - /// in the third argument. + /// Loads owned state with type id from the first argument and index from the second argument + /// `a16` register into a register provided in the third argument. /// - /// If the state is absent or is not a structured state sets `st0` to - /// `false` and terminates the program. + /// If the state is absent or is not a structured state sets `st0` to `false` and terminates + /// the program. /// /// If the state at the index is concealed, sets destination to `None`. #[display("lds {0},a16{1},{2}")] LdS(AssignmentType, Reg16, RegS), - /// Loads owned fungible state with type id from the first argument and - /// index from the second argument `a16` register into `a64` register - /// provided in the third argument. - /// - /// If the state is absent or is not a fungible state sets `st0` to - /// `false` and terminates the program. - /// - /// If the state at the index is concealed, sets destination to `None`. - #[display("ldf {0},a16{1},a64{2}")] - LdF(AssignmentType, Reg16, Reg16), - - /// Loads global state from the current operation with type id from the - /// first argument and index from the second argument `a8` register into a - /// register provided in the third argument. + /// Loads global state from the current operation with type id from the first argument and + /// index from the second argument `a8` register into a register provided in the third + /// argument. /// /// If the state is absent sets `st0` to `false` and terminates the program. #[display("ldg {0},a8{1},{2}")] LdG(GlobalStateType, Reg16, RegS), - /// Loads part of the contract global state with type id from the first - /// argument at the depth from the second argument `a32` register into a - /// register provided in the third argument. + /// Loads part of the contract global state with type id from the first argument at the depth + /// from the second argument `a32` register into a register provided in the third argument. /// - /// If the contract doesn't have the provided global state type, or it - /// doesn't contain a value at the requested index, sets `st0` - /// to fail state and terminates the program. The value of the - /// destination register is not changed. + /// If the contract doesn't have the provided global state type, or it doesn't contain a value + /// at the requested index, sets `st0` to fail state and terminates the program. The value + /// of the destination register is not changed. #[display("ldc {0},a32{1},{2}")] LdC(GlobalStateType, Reg16, RegS), - /// Loads operation metadata with a type id from the first argument into a - /// register provided in the second argument. + /// Loads operation metadata with a type id from the first argument into a register provided in + /// the second argument. /// - /// If the operation doesn't have metadata, sets `st0` to fail state and - /// terminates the program. The value of the destination register is not - /// changed. + /// If the operation doesn't have metadata, sets `st0` to fail state and terminates the + /// program. The value of the destination register is not changed. #[display("ldm {0},{1}")] LdM(MetaType, RegS), - /// Verify sum of pedersen commitments from inputs and outputs. - /// - /// The only argument specifies owned state type for the sum operation. If - /// this state does not exist, or either inputs or outputs does not have - /// any data for the state, the verification fails. - /// - /// If verification succeeds, doesn't change `st0` value; otherwise sets it - /// to `false` and stops execution. - #[display("pcvs {0}")] - Pcvs(AssignmentType), - - /// Verifies equivalence of a sum of pedersen commitments for the list of - /// assignment outputs to a value from `a64[0]` register. - /// - /// The first argument specifies owned state type for the sum operation. If - /// this state does not exist, or either inputs or outputs does not have - /// any data for the state, the verification fails. - /// - /// If `a64[0]` register does not contain value, the verification fails. - /// - /// If verification succeeds, doesn't change `st0` value; otherwise sets it - /// to `false` and stops execution. - #[display("pcas {0}")] - Pcas(/** owned state type */ AssignmentType), - - /// Verifies equivalence of a sum of pedersen commitments for the list of - /// inputs to a value from `a64[0]` register. - /// - /// The first argument specifies owned state type for the sum operation. If - /// this state does not exist, or either inputs or outputs does not have - /// any data for the state, the verification fails. - /// - /// If `a64[0]` register does not contain value, the verification fails. - /// - /// If verification succeeds, doesn't change `st0` value; otherwise sets it - /// to `false` and stops execution. - #[display("pcps {0}")] - Pcps(/** owned state type */ AssignmentType), - - /// All other future unsupported operations, which must set `st0` to - /// `false` and stop the execution. + /// All other future unsupported operations, which must set `st0` to `false` and stop the + /// execution. #[display("fail {0}")] Fail(u8, PhantomData), } @@ -189,9 +130,9 @@ impl InstructionSet for ContractOp { fn src_regs(&self) -> BTreeSet { match self { - ContractOp::LdP(_, reg, _) - | ContractOp::LdF(_, reg, _) - | ContractOp::LdS(_, reg, _) => bset![Reg::A(RegA::A16, (*reg).into())], + ContractOp::LdP(_, reg, _) | ContractOp::LdS(_, reg, _) => { + bset![Reg::A(RegA::A16, (*reg).into())] + } ContractOp::LdG(_, reg, _) => bset![Reg::A(RegA::A8, (*reg).into())], ContractOp::LdC(_, reg, _) => bset![Reg::A(RegA::A32, (*reg).into())], @@ -200,8 +141,6 @@ impl InstructionSet for ContractOp { | ContractOp::CnG(_, _) | ContractOp::CnC(_, _) | ContractOp::LdM(_, _) => bset![], - ContractOp::Pcvs(_) => bset![], - ContractOp::Pcas(_) | ContractOp::Pcps(_) => bset![Reg::A(RegA::A64, Reg32::Reg0)], ContractOp::Fail(_, _) => bset![], } } @@ -214,9 +153,6 @@ impl InstructionSet for ContractOp { ContractOp::CnP(_, reg) | ContractOp::CnS(_, reg) | ContractOp::CnC(_, reg) => { bset![Reg::A(RegA::A16, *reg)] } - ContractOp::LdF(_, _, reg) => { - bset![Reg::A(RegA::A64, (*reg).into())] - } ContractOp::LdG(_, _, reg) | ContractOp::LdS(_, _, reg) | ContractOp::LdP(_, _, reg) @@ -224,9 +160,6 @@ impl InstructionSet for ContractOp { | ContractOp::LdM(_, reg) => { bset![Reg::S(*reg)] } - ContractOp::Pcvs(_) | ContractOp::Pcas(_) | ContractOp::Pcps(_) => { - bset![] - } ContractOp::Fail(_, _) => bset![], } } @@ -239,12 +172,9 @@ impl InstructionSet for ContractOp { | ContractOp::CnC(_, _) => 2, ContractOp::LdP(_, _, _) | ContractOp::LdS(_, _, _) - | ContractOp::LdF(_, _, _) | ContractOp::LdG(_, _, _) | ContractOp::LdC(_, _, _) => 8, ContractOp::LdM(_, _) => 6, - ContractOp::Pcvs(_) => 1024, - ContractOp::Pcas(_) | ContractOp::Pcps(_) => 512, ContractOp::Fail(_, _) => u64::MAX, } } @@ -256,36 +186,6 @@ impl InstructionSet for ContractOp { return ExecStep::Stop; }}; } - macro_rules! load_inputs { - ($state_type:ident) => {{ - let Some(prev_state) = context.op_info.prev_state.get($state_type) else { - fail!() - }; - match prev_state { - TypedAssigns::Fungible(state) => state - .iter() - .map(Assign::to_confidential_state) - .map(|s| s.commitment.into_inner()) - .collect::>(), - _ => fail!(), - } - }}; - } - macro_rules! load_outputs { - ($state_type:ident) => {{ - let Some(new_state) = context.op_info.owned_state.get(*$state_type) else { - fail!() - }; - match new_state { - TypedAssigns::Fungible(state) => state - .iter() - .map(Assign::to_confidential_state) - .map(|s| s.commitment.into_inner()) - .collect::>(), - _ => fail!(), - } - }}; - } match self { ContractOp::CnP(state_type, reg) => { @@ -331,16 +231,15 @@ impl InstructionSet for ContractOp { }; let index: u16 = reg_32.into(); - let Some(Ok(state)) = context + let Some(state) = context .op_info .prev_state .get(state_type) - .map(|a| a.as_structured_state_at(index)) + .and_then(|a| a.as_state_at(index).ok()) else { fail!() }; - let state = state.map(|s| s.value.as_inner()); - regs.set_s(*reg, state); + regs.set_s(*reg, Some(&state.value)); } ContractOp::LdS(state_type, reg_32, reg) => { let Some(reg_32) = *regs.get_n(RegA::A16, *reg_32) else { @@ -348,32 +247,15 @@ impl InstructionSet for ContractOp { }; let index: u16 = reg_32.into(); - let Some(Ok(state)) = context - .op_info - .owned_state - .get(*state_type) - .map(|a| a.into_structured_state_at(index)) - else { - fail!() - }; - let state = state.map(|s| s.value.into_inner()); - regs.set_s(*reg, state); - } - ContractOp::LdF(state_type, reg_32, reg) => { - let Some(reg_32) = *regs.get_n(RegA::A16, *reg_32) else { - fail!() - }; - let index: u16 = reg_32.into(); - - let Some(Ok(state)) = context + let Some(state) = context .op_info .owned_state .get(*state_type) - .map(|a| a.into_fungible_state_at(index)) + .and_then(|a| a.into_state_at(index).ok()) else { fail!() }; - regs.set_n(RegA::A64, *reg, state.map(|s| s.value().to_u64())); + regs.set_s(*reg, Some(state.value)); } ContractOp::LdG(state_type, reg_8, reg_s) => { let Some(reg_32) = *regs.get_n(RegA::A8, *reg_8) else { @@ -389,7 +271,7 @@ impl InstructionSet for ContractOp { else { fail!() }; - regs.set_s(*reg_s, Some(state.as_inner())); + regs.set_s(*reg_s, Some(state)); } ContractOp::LdC(state_type, reg_32, reg_s) => { @@ -407,7 +289,7 @@ impl InstructionSet for ContractOp { let Some(state) = global.nth(index) else { fail!() }; - regs.set_s(*reg_s, Some(state.borrow().as_inner())); + regs.set_s(*reg_s, Some(&state.borrow().value)); } ContractOp::LdM(type_id, reg) => { let Some(meta) = context.op_info.metadata.get(type_id) else { @@ -416,63 +298,6 @@ impl InstructionSet for ContractOp { regs.set_s(*reg, Some(meta.to_inner())); } - ContractOp::Pcvs(state_type) => { - let inputs = load_inputs!(state_type); - let outputs = load_outputs!(state_type); - if !secp256k1_zkp::verify_commitments_sum_to_equal( - secp256k1_zkp::SECP256K1, - &inputs, - &outputs, - ) { - fail!() - } - } - - ContractOp::Pcas(owned_state) => { - let Some(sum) = *regs.get_n(RegA::A64, Reg32::Reg0) else { - fail!() - }; - let sum = u64::from(sum); - - let Some(tag) = context.asset_tags.get(owned_state) else { - fail!() - }; - let sum = RevealedValue::with_blinding(sum, BlindingFactor::EMPTY, *tag); - - let inputs = [PedersenCommitment::commit(&sum).into_inner()]; - let outputs = load_outputs!(owned_state); - - if !secp256k1_zkp::verify_commitments_sum_to_equal( - secp256k1_zkp::SECP256K1, - &inputs, - &outputs, - ) { - fail!() - } - } - - ContractOp::Pcps(owned_state) => { - let Some(sum) = *regs.get_n(RegA::A64, Reg32::Reg0) else { - fail!() - }; - let sum = u64::from(sum); - - let Some(tag) = context.asset_tags.get(owned_state) else { - fail!() - }; - let sum = RevealedValue::with_blinding(sum, BlindingFactor::EMPTY, *tag); - - let inputs = [PedersenCommitment::commit(&sum).into_inner()]; - let outputs = load_inputs!(owned_state); - - if !secp256k1_zkp::verify_commitments_sum_to_equal( - secp256k1_zkp::SECP256K1, - &inputs, - &outputs, - ) { - fail!() - } - } // All other future unsupported operations, which must set `st0` to `false`. _ => fail!(), } @@ -493,14 +318,9 @@ impl Bytecode for ContractOp { ContractOp::LdG(_, _, _) => INSTR_LDG, ContractOp::LdS(_, _, _) => INSTR_LDS, ContractOp::LdP(_, _, _) => INSTR_LDP, - ContractOp::LdF(_, _, _) => INSTR_LDF, ContractOp::LdC(_, _, _) => INSTR_LDC, ContractOp::LdM(_, _) => INSTR_LDM, - ContractOp::Pcvs(_) => INSTR_PCVS, - ContractOp::Pcas(_) => INSTR_PCAS, - ContractOp::Pcps(_) => INSTR_PCPS, - ContractOp::Fail(other, _) => *other, } } @@ -538,11 +358,6 @@ impl Bytecode for ContractOp { writer.write_u4(reg_a)?; writer.write_u4(reg_s)?; } - ContractOp::LdF(state_type, reg_a, reg_dst) => { - writer.write_u16(*state_type)?; - writer.write_u4(reg_a)?; - writer.write_u4(reg_dst)?; - } ContractOp::LdG(state_type, reg_a, reg_s) => { writer.write_u16(*state_type)?; writer.write_u4(reg_a)?; @@ -559,10 +374,6 @@ impl Bytecode for ContractOp { writer.write_u4(u4::ZERO)?; } - ContractOp::Pcvs(state_type) => writer.write_u16(*state_type)?, - ContractOp::Pcas(owned_type) => writer.write_u16(*owned_type)?, - ContractOp::Pcps(owned_type) => writer.write_u16(*owned_type)?, - ContractOp::Fail(_, _) => {} } Ok(()) @@ -600,11 +411,6 @@ impl Bytecode for ContractOp { reader.read_u4()?.into(), reader.read_u4()?.into(), ), - INSTR_LDF => Self::LdF( - reader.read_u16()?.into(), - reader.read_u4()?.into(), - reader.read_u4()?.into(), - ), INSTR_LDG => Self::LdG( reader.read_u16()?.into(), reader.read_u4()?.into(), @@ -626,10 +432,6 @@ impl Bytecode for ContractOp { i } - INSTR_PCVS => Self::Pcvs(reader.read_u16()?.into()), - INSTR_PCAS => Self::Pcas(reader.read_u16()?.into()), - INSTR_PCPS => Self::Pcps(reader.read_u16()?.into()), - x => Self::Fail(x, PhantomData), }) } diff --git a/src/vm/opcodes.rs b/src/vm/opcodes.rs index b1db3ea4..32ce1e04 100644 --- a/src/vm/opcodes.rs +++ b/src/vm/opcodes.rs @@ -35,7 +35,6 @@ pub const INSTR_CNC: u8 = 0b11_000_011; pub const INSTR_LDP: u8 = 0b11_000_100; pub const INSTR_LDS: u8 = 0b11_000_101; -pub const INSTR_LDF: u8 = 0b11_000_110; // Reserved 0b11_000_111 pub const INSTR_LDG: u8 = 0b11_001_000; @@ -43,12 +42,9 @@ pub const INSTR_LDC: u8 = 0b11_001_001; pub const INSTR_LDM: u8 = 0b11_001_010; // Reserved 0b11_001_111 -pub const INSTR_PCVS: u8 = 0b11_010_000; -pub const INSTR_PCAS: u8 = 0b11_010_001; -pub const INSTR_PCPS: u8 = 0b11_010_010; // Reserved 0b11_010_011 pub const INSTR_CONTRACT_FROM: u8 = 0b11_000_000; -pub const INSTR_CONTRACT_TO: u8 = 0b11_010_011; +pub const INSTR_CONTRACT_TO: u8 = 0b11_001_111; // TIMECHAIN: pub const INSTR_TIMECHAIN_FROM: u8 = 0b11_011_100; diff --git a/stl/AnchoredBundle.vesper b/stl/AnchoredBundle.vesper index 70188880..dd10357e 100644 --- a/stl/AnchoredBundle.vesper +++ b/stl/AnchoredBundle.vesper @@ -37,7 +37,7 @@ TransitionBundle rec globals map len=0..MAX8 aka=GlobalState key is U16 aka=GlobalStateType value list len=1..MAX16 aka=GlobalValues - element bytes len=0..MAX16 aka=DataState + element bytes len=0..MAX16 inputs set len=0..MAX16 aka=Inputs Input rec prevOut rec Opout @@ -47,231 +47,38 @@ TransitionBundle rec reserved bytes len=2 aka=ReservedBytes2 assignments map len=0..MAX8 aka=AssignmentsBlindSealTxPtr key is U16 aka=AssignmentType - value union TypedAssignsBlindSealTxPtr - declarative list len=0..MAX16 wrapped tag=0 - AssignVoidStateBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - fungible list len=0..MAX16 wrapped tag=1 - AssignRevealedValueBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec RevealedFungible - value union FungibleState - bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec RevealedFungible - value union FungibleState - bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag - lock bytes len=2 aka=ReservedBytes2 - structured list len=0..MAX16 wrapped tag=2 - AssignRevealedDataBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state bytes len=32 aka=ConcealedData - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state bytes len=32 aka=ConcealedData - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec RevealedData - value bytes len=0..MAX16 aka=DataState - salt is U128 - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec RevealedData - value bytes len=0..MAX16 aka=DataState - salt is U128 - lock bytes len=2 aka=ReservedBytes2 - attachment list len=0..MAX16 wrapped tag=3 - AssignRevealedAttachBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state bytes len=32 aka=ConcealedAttach - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state bytes len=32 aka=ConcealedAttach - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec RevealedAttach - file rec AttachState - id bytes len=32 aka=AttachId - mediaType enum MediaType any=255 - salt is U64 - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec RevealedAttach - file rec AttachState - id bytes len=32 aka=AttachId - mediaType enum MediaType any=255 - salt is U64 - lock bytes len=2 aka=ReservedBytes2 + value list len=1..MAX16 aka=TypedAssignsBlindSealTxPtr + AssignBlindSealTxPtr union + confidential rec tag=0 + seal union XChainSecretSeal + bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 + liquid bytes len=32 wrapped aka=SecretSeal tag=1 + state rec State + reserved bytes len=1 aka=ReservedBytes1 + value bytes len=0..MAX16 + some bytes len=32 option wrapped aka=AttachId tag=1 + lock bytes len=2 aka=ReservedBytes2 + revealed rec tag=1 + seal union XChainBlindSealTxPtr + bitcoin rec BlindSealTxPtr wrapped tag=0 + method enum Method opretFirst=0 tapretFirst=1 + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 + liquid rec BlindSealTxPtr wrapped tag=1 + method enum Method opretFirst=0 tapretFirst=1 + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 + state rec State + reserved bytes len=1 aka=ReservedBytes1 + value bytes len=0..MAX16 + some bytes len=32 option wrapped aka=AttachId tag=1 + lock bytes len=2 aka=ReservedBytes2 valencies set len=0..MAX8 aka=Valencies element is U16 aka=ValencyType validator bytes len=1 aka=ReservedBytes1 diff --git a/stl/RGBCommit@0.1.0.sta b/stl/RGBCommit@0.1.0.sta index 67979284..345df8d2 100644 --- a/stl/RGBCommit@0.1.0.sta +++ b/stl/RGBCommit@0.1.0.sta @@ -1,5 +1,5 @@ -----BEGIN STRICT TYPE LIB----- -Id: stl:IFcnrPeI-TANxLfZ-feJax6Q-1TUM4Hq-AjI161s-3tbmxak#harvest-person-orion +Id: stl:JepgtiGZ-TYqkSmV-vo6ysWP-gZZEU03-pVoHbyj-nR02608#aspect-shoe-garcia Name: RGBCommit Dependencies: StrictTypes#century-comrade-chess, @@ -8,7 +8,7 @@ Dependencies: CommitVerify#miller-pancake-elastic, Std#ralph-blue-lucky, Bitcoin#signal-color-cipher -Check-SHA256: 1d68b2a0bcfecf99effcecd7c9c35f870a1300e71a3ce3da8144587537895235 +Check-SHA256: 3eace4fa98ea2690b3f4e4e4e83ab1fe9e594e56fe3f5dd56985cd046009e306 2~tNwLvL+uX>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI)Q*?4^V{}w`aAk8=6V}(%hjW>8 uUwNXi!t*yd7K}=K!`A`1OPgv%fUznLQq3*a%Ez0HGd)Hmb;*F>vukd; =m`ygb@x#_>`RmOO$0)3Z)}yry~#}iVEJ)s5j^%uEnQ9{n2s|9Fa^ps+HG#`XS5DMY;b5{PIYZeZ)9O} Xt{%a=RmHK6WZ%EWRm@*ULd%lgGoFTxUTU 76^nC$%1sKzB<;EQA|)S-x88IWKN#S$#@T&w`gPtRC#b^PGN0jYXqYdo~D%m7H6OD0<^0n_2##VWXRdj -y=DB@qgYOj1yf~hNn}O<2|;XhOksItaxnt|25f0@b!lV)3_)ykOksItaxqh7bOiwb2?5A!f_n>Eea4Xl -By!~v3=AX`3Ri0000000000{{R3000000B0+O=X=iRyWp-s@Y-MCYbaY{3XhLjhZe&wsVQf@*P;_zx1ONKtpQ8M_qJyiO1VIUJ=H=)@ii_1#@&^bY%hjG)3KC -&kYOztQDksx&yAAHY;R+00(t`--)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@O -Cd;@jJLYKfb7gWS-+`&{Sr=ykNJ#YFTr_BQwWqKF0Ra(XZ*FF3WMyu2X<=+rbYXO500sjDb7f&{0gt=F -=tr7PJW4?*h+3X!X@fjr@d0IimUQ-Q1Z;0(YXW)$9p7nv%krpqNJW4?*h+3X! -X@fjr@d0IimUQ-Q1Z;0(YXW)$9p7nv%krpqNc;WdH^P1aoC!YypA{4XEgn0epQk*PX+nL>xOm%pK>soMo}bYXO50sJ&Y-CxfQ3;(PYq10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUFsxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)y -umJ%A5Mys{W@%()Zggp3Y*S@nYybuW1aoC!YysPfS{i~B5OpZ>_>4e9YQ#rfba;u!+d5tm#=h2RwFCuo -bYXO50p}%){+CCYqok=CI6O*0D2Q5~XK8~xVetWFewK9hZ3Jv@V`~C>10COKearHwcS=7M7YzYaI8*bv -hMOc?)(rkC#nUFsxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)yumJ%B2y$h1WnpY(WB>*O1aoC!YypA{ -4XEgn0epQk*PX+nL>xOm%pK>soMo}bYXO50p}%){+CCYqok=CI6O*0D2Q5~XK8~xVetWF -ewK9hZ3Jv@V`~C>10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUFsxGg*8X!CPrawgw_sqk4BX8}k^ -^xj-FXm+)yumJ%eL349yXKqquc4c8~Wn@HQbYVhlX>MdwWnpYocu;h51OxyKV{dL|X=G(?bZKF100sjD -b7f&{0o#gN8iEuMbtv-qj6g$b#7A9pc!|f`I$jaRzSe2A1O;<+VRU5ya1CV;vVwtcAGbZ_5@VACR|ut2 -VXXq-)V^B9&!_4M1Z;0(YXW)$9p7nv%krpqNc;WdH^P1aoC!YypqE!sthuPUKDEU2%WC`V+X+ -(UG)mk--2W1{>juaWw^VbYXO50dNgv5VC@SZy&ck10COK -earHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUFsxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)yumJ%A5Mys{ -W@%()Zggp3Y*S@nYybuW1aoC!YysPfS{i~B5OpZ>_>4e9YQ#rfba;u!+d5tm#=h2RwFCuobYXO50sm-Y -z<5%CY59k^g5#W{6D&GDo53%OaP0&iRq10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC -#nUFsxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)yumJ%B2y$h1WnpY(WB>*O1aoC!YypqE!sthuPUKDE -U2%WC`V+X+(UG)mk--2W1{>juaWw^VbYXO50sm-Yz<5%CY59k^g5#W{6D&GDo53%OaP0&iRq10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUFsxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)y -umJ%dL349yXKqquc4c8~Wn@HQbYVhlX>MdwWnpYocxhw=1ONKtpQ8M_qJyiO1VIUJ=H=)@ii_1#@&^bY%f>4P_9rf`M-zw>{+&W0M0{2&GbCtpecGzFNi4 -r|Jm=Y;R+00(t`--)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OCd;@jJLYKfb7gWS-+`&{Sr=ykNJ#YF -Tr_BQwWqKF0Ra(XZ*FF3WMyu2X<=+rbYXO500sjDb7f&{0fGz-uWS7@0e2{fI -fIMdwWnpYocu;h51OxyKV{dL|X=G(?bZKF100sjDb7f&{0o#gN8iEuMbtv-q -j6g$b#7A9pc!|f`I$jaRzSe2A1O;<+VRU5yN@#iqkT|?l*=bx{^0c**fmF&H)l(b`S3$sb4!MK-1Z;0( -YXW)$9p7nv%krpqNc;WdH^P1aoC!YypqE!sthuPUKDEU2%WC`V+X+(UG)mk--2W1{>juaWw^V -bYXO50ZM3k2aq_tRM}}10COKearHwcS=7M7YzYaI8*bv -hMOc?)(rkC#nUFsxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)yumJ%A5Mys{W@%()Zggp3Y*S@nYybuW -1aoC!YysPfS{i~B5OpZ>_>4e9YQ#rfba;u!+d5tm#=h2RwFCuobYXO50c}La^e<`!Iztr?rsl#d#OQkE -ER^^L)C{HEhxT=ipag7hV`~C>10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUFsxGg*8X!CPrawgw_ -sqk4BX8}k^^xj-FXm+)yumJ%B2y$h1WnpY(WB>*O1aoC!YypqE!sthuPUKDEU2%WC`V+X+(UG)mk--2W -1{>juaWw^VbYXO50c}La^e<`!Iztr?rsl#d#OQkEER^^L)C{HEhxT=ipag7hV`~C>10COKearHwcS=7M -7YzYaI8*bvhMOc?)(rkC#nUFsxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)yumJ%eL349yXKqquc4c8~ -Wn@-iY;|QqY-w&}Q)OXnRCsA*1OxyKV{dL|X=G(?bZKF100sjDb7f&{0o#gN8iEuMbtv-qj6g$b#7A9p -c!|f`I$jaRzSe2A1O;<+VRU5yN@#iqkT|?l*=bx{^0c**fmF&H)l(b`S3$sb4!MK-1Z;0(YXW)$9p7nv -%krpqNc;WdH^P1aoC!YypA{4XEgn0epQk*PX+nL>xOm%pK>soMo}bYXO50ZM3k -2aq_tRM}}10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC -#nUFsxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)yumJ%A5Mys{W@%()Zggp3Y*S@nYybuW1aoC!YysPf -S{i~B5OpZ>_>4e9YQ#rfba;u!+d5tm#=h2RwFCuobYXO50c}La^e<`!Iztr?rsl#d#OQkEER^^L)C{HE -hxT=ipag7hV`~C>10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUFsxGg*8X!CPrawgw_sqk4BX8}k^ -^xj-FXm+)yumJ%B2y$h1WnpY(WB>*O1aoC!YypA{4XEgn0epQk*PX+nL>xOm%pK>soMo} -bYXO50c}La^e<`!Iztr?rsl#d#OQkEER^^L)C{HEhxT=ipag7hV`~C>10COKearHwcS=7M7YzYaI8*bv -hMOc?)(rkC#nUFsxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)yumJ%bL349yXKq$+X=GD$VRU6eY-w&} -Q)OXnRCrKyas&hb3}bI@W@%()Zggp3YybuW1aoC!YysPfS{i~B5OpZ>_>4e9YQ#rfba;u!+d5tm#=h2R -wFCuobYXO50WPwo{ujV7L@=1(T$>wOY}Ov_b`4?P%YY`+Wb+o`y98`+V`~C>10COKearHwcS=7M7YzYa -I8*bvhMOc?)(rkC#nUFsxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)yumJ%95o2#|W@%()Zggp3Y*Tb$ -bY%br0|awrVQc}9yTa&4noi_R;$3lnz4{Zl)X|Z&ZIQtMA_g1big7gsb97;JWdSa-rT!PdFhnqz;9Q#< -T5Q%H?RE`e-pha{(`54&;kyKEZ)0l$dIKHbX?@G`sCP;~6&DQwR5(-fxrUo0Th_>4e9YQ#rfba;u!+d5tm#=h2RwFCuobYXO50WPwo -{ujV7L@=1(T$>wOY}Ov_b`4?P%YY`+Wb+o`y98`+V`~C>10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC -#nUFsxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)yumJ%95o2#|W@%()Zggp3Y*Tb$bY%br0|awrVQc|{ -3=OYq{WJl0D5$WZob97;JWdSa-rT!PdFhnqz;9Q#WZob97;JWdSa-rT!PdFhnqz;9Q#<~nFGwl#> -J&iiT&+eT*0000000000{{R30000007(sJ$X=iS2Wo~qHLTqVnWK(5fY*ct@WCZ~L3IT`y;$>KfZ0H=m -hJ>?uVc;Wd;HQX=DL}aSf9!PV~dK2uo>;u!nFdemP_$ -e?^hl+JkM;eY!XaZDnL>VN`i=WdTAkVTFju)T~Wpi|4 -ZEyepNCs(hb9H5M0(t`--)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OCT*{+#r3Bk2FRnL+RBXEn8vr= -x`Tq%|A_kfK&ST81_yLyb98QHbOOpO9&dx0-7pM3Z=O*v*GCA9fL-<|HrZsA`NnJlR3~AEBGG%U@MZ$v -=XJ?|;InIPy66cFfOYp#JM2r7_Du?5Y;;Uvd1Z2QF#>u69p7nv%krpqNMd`Zf8beV{~tF1pxpD -002NB01rcNZewL(Y-MCYbaY{3XaxZP2LJ#-AOHD -0Z6?XZWsH8I~II?C0;dW+k!*yDqgzlqQwf$39g<|8VW;iZgg^CV{}Pm1pxpD002NB00~54bYW9;VRU5$ -0RRX906+i$000000096000000000R^cywiMb7^mG1`7jbW_AJEn^6;37FKqUhx?i3R+Mr!fY&(;2BFL( -m@EZk_srD_V{dMBa$#e1Nn`<^2rNlD$O59e#ogQsB77jPl+h5j^*S;IZf|a5WdHyO4P|(A -Wo~n6Z*Ek1aAg5xbsj>g6`?#s5rWnKhSeO?L~x^!;Y#eFP|P}0Z%EzBpbEf7FA*KKfDWJ -b8~5DZf#|5baMe=>KFFSbgda38zdDXQ0-0pHK5k@bh=O+>c= -6oKLk -F4~iax8KK|47hp+cWHEPWpi@^dIKHbX?@G`sCP;~6&DQwR5(-fxrUo0Thxis%Ku=2wF+7z(Wqt=tdZk`V^s(Ana000000093000000000Ma -Wn^V#ZF2w#0Y>fS!w4MxxaL=+DqP^k2!wz9AHH68xp8!<%Jqp^&Hw-a000000RI300000001IJrb7^O8 -ZDnqBa{vkfhyLPaScq)s9KMExvw34D6J>+NwrBxfixd_%u|$Wt0XD%jq57bK6Q|uUfIMEX^1}Vv6tLB! -)|10-o)0prc>n+a000000RI3000000010+sY-Mg^X=QT&2?0j!=EDda{kY~=q$*tC#t4Le{2#tvcDZqM -smk?aU=OZ$bvG|>z)+>9PT;Au-7)~D;-++htxcywiMb7^mG -RC#b^1pxp60s}^7b_D?d00Iq0b#7;AVr*qobYXO51OW&JVrg`9HZ%YQ0RR993`TWsXK7+=WmI`^Wdi{X -b#8NMXKrO=HZ($MbO;AWWo~72X>$e*17>D+0ot2U6Id2jc94hrndMfLayEe1ISdA&%p{mB1!VWk)d+KA -Xk~3-Nn`<(Qq$W5tE;F{pQrXd&=l*`O?@#x{Qdy?T_k!`1dtE~W^7?+a{_t;9p7nv%krpqNDb5bYX39002k^X>)UR -WpV+w=zxYCD0L!x4tB5Hm3vFbl?lapNXe%XU~*fKJ0+Y4bY*jNZe?@=$}AplgPGkh3_fq3Q7_j=2#kPT -_9!;lWR>~GYywm#VTK~nd#>BpbEf7FA*KKfDWJb8~5DZf#|5baMe=>KFFSbgda38zdDXQa{=9jW&m$tWDykZj`7#3_zANbB(SO{shhGe=&H{tM@n+a000000RI300000001IJrb7^O8ZDnqBa{vkfhyLPaScq)s9KMExvw34D -6J>+NwrBxfixd_%u|$Wt0XD%jq57bK6Q|uUfIMEX^1}Vv6tLB!)|10-o)0prc>n+a000000RI3000000 -010+sY-Mg^X=QT&2?0j!=EDda{kY~=q$*tC#t4Le{2#tvcDZqMsmk?aU=OZ$bvG|>z)+>9PT;Au-7)~D;-++hnxY;R&=Y*Tb$bY%qr015%s?vf5kh_h+&YE#h%O8d1V -_{UOl9{V;uR#^q%$8ES^HwOl>wiJc;WmI`^ -Wd#8M00In0Y;R&=Y*t}xb!Bq}0RRXAGM-jZ2Kh}DE2o;HYydTtf}Q!WH{}bI!u)W*#(e~Z0RR9100000 -|Nj60000002uWmRZggpMc?AIg1p)%fEFN!zncXl9K5w2;FV{y1jDTJCC^p$-mHEbO0#qkRz9SbZ=!8X@ -=Yuq$20sb<4l#S`iz7Vef}@Ca=a#qt2m;D19&dx0-7pM3Z=O*v*GCA9fL-<|HrZsA`NnJlR3}KjBNr;@ -ghiU?gEXK9KMDE{F?;HZBRuDVqlk6qmbd@_000000093F00000000F^Zg6#U1_B3ga%FZ;b#wuf5WIk~ -G+K)5%bR49t5yk`^qQ9la%FR6a&~280(t`--)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D -{wl@OCd;@jJLYKfb7gWS-+`&{Sr=ykNJ#YFTr_BQwWqKF0SHNMaCLM|VQ>Wj015*2Y!hN5_Bp3Y36tDM -M#=e#tGI($UA5U3KNx<*C>jbO<32;hs$B9ZCsU(1!DsC|W1LOd&b_IRG-(&Q$wPGkmB{9L9(7`0)Rt93 -YLV-HLXe?vTA1;^Q1`ZqBog<<0RR9100000|Nj600000021#ykb#!wD0RRaB)s0^W44ZlVPs)+VFdvI3ITQGP59r=ivkR6Lh9EroO>_;0000000030000000000B -Ph(?sa&l#EV`Xy&0t0PnZU6uR18re=0006EPjEwTZEb0EZDnqB1`7jbW_AJEn^6;37FKqUhx?i3R+Mr! -fY&(;2BFL(m@EZk_srD=Zf|a5WdHyO25)dwd2nR`=kby$tK%HuPpRtMKe5+wDRP}k(QuARKUbDjTz^bE -2yJC_VPs)+VFG#s9p7nv%krpqNM?JbaMiF10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUD@oClv)aMjKgwAH@`bu1x<7g|G$};xvA~n-$_S2y$g)Wo2z;WCD5v9p7nv%krpqNv2!%ioJ -pYH;+t0eX2w~A!Q+0eaZ{MVycPK^T!VRUq1V`yzR000000RI3000000 -01i@Rc4c8~Wn@8gbYWv?1_A_TX>4Ty3ATR{-|K6Y3I$*BbiAvUS*tg{!Gb}P!O*^_P#qhP1ao0*bN~Pd -3{quwWnpY(WJFD+0ot2U6Id2jc94hrndMfLayEe1ISdA&%p{mB1!VWk)dgm3VP|s!dIKHb -X?@G`sCP;~6&DQwR5(-fxrUo0ThOi(W05|TJ%PM*ricn_Pm -Xk-a=X>Db5bYX39002k{WMy_`Y;SO7asjsJfQB3>bs~EXcCXx(drQcb3B`Fx$)^%va$Ar)C7cOuWprUw -d2nTO015$hC`}q*rYXqYdo~D%m7H6OD0<^0n_2##VWXRdjy=DB@qgYOj0000000000{{R30000003ukO^Vqt7l -d2nTO015%s?vf5kh_h+&YE#h%O8d1V_{UOl9{V;uR#^q%KfZ0H=mhJ>?uV9R0ZFSEMRj;Km4qfBYZ5UUs>0bg9bqiCNA700000000300000000007XJu|>b7^w{ -7)aIA#9XnshcC})U)TI#r3b0kyqD7}ejM+$yUGm(3T1e7Wo~n6Z*Fq{3ISww9zv-Vp*%wog4O?q)g04A -aHEjnO6;Ie%sNwVNZtVhXadZr-SPY!h`6Z9%SYt5l1;p3@00000000300000000008a%FR6a&~280(t`--)Viz@~C%8KNS}Z0aQ3s^SOqb -BwN-D{wl@OCjNpJN#A(BKKz&v`r;e6DUv<<*U}cD+0ot2U6Id2jc94hrndMfLayEe1ISdA&%p{mB1!VWk)e2*8Zgg^CV{}Pm0iOsgNjk^^ -qPoT1+zTRnAg`3vXv9d*8d@RXy~6c6G6imLZewKt00<6ra$#@6CZd7@2WdSr&53UoI8eY9A{1GER -g--GiI0S#x1is&)M%fmnGH3{GWprU=VRT^u^?FS>S$_F2)vN@Mb6UJ-F(lri_dqerx4lR4>iBsz2WM<= -Vqt7^0p25#Yo@G%*b#-tU^&3KX?w7l?~*Sh8@1jRRblZzyas7*aCLNZ0jZ*TSChz_$|Xx}eRkFNAr%^e -Ll(1e@}~9=0-ijXfD2)Bb7^O8ZDnqBa{)s3lIz?v1U>x&T2C;PAKlCCveQ{N4udSh#@3Dqj&%ukVQgh? -V`*h`0o{dW0B>Pr5ftu@@z<*O39}j`u&O7io3b$Is?RA$O$l~kY-wa+bZ>G3dIKHbX?@G`sCP;~6&DQw -R5(-fxrUo0Th$AHP6|FsuXsI;G3ONG`V!CAn^8 -7TS9h9ibhaZ&^Bcn*B*;w|~I;-PD|t>j-IXaCLM|VQ>KznP+6nwW~k}RP!NmuV?G015$>$mV(;bz)!CmQ_M(k?Vd!kfCo{nDM?)_qK{868FUc))-~W22H5+ -SDrhMohTRsfLT>C1dS{r3#^{o?N>fE0RR9100000|Nj60000005L9wuZgXjLX>V>*V`ybM?JbaMa-0f+wLWmt%8=p4R=gtK{LClh6Z#kObxUW*hKHnBv9xdAr8 -G@<&SffJ|QFn~N>u=2wF+7z(Wqt=tdZk`V^s(Ana000000093000000000YNb8~5DZf#|5baMa-0f+wL -Wmt%8=p4R=gtK{LClh6Z#kObxUW*hKHnBv9xdAr8G@<&SffJ|QFn~N>u=2wF+7z(Wqt=tdZk`V^s(Ana -000000093000000000SgVQgh?V`*h`00{v`?dHP>9R0ZFSEMRj;Km4qfBYZ5UUs>0bg9bqiCNA700000 -000300000000009c42I3WMOn~asUJZ00eGtZe;)f009JZZ*64&1pxwLa5aA+<>R2XhQO_4{AcS-HH^7A -VzASV8M4NYxyCka@1Z8)ymjIKNK5;L!8FkfGTe+FK;UUh9M-4n+}vRfRB~Z%b7^#GZ*Ek1aAgGn0006G -RC#b^LvL+uX>@I6Zgd0#00(DfZe??6a{vVa0W)M-Q2pM493%15wcJ8Z{z5k9VD)f0JnAj^7J5MZ9{~z< -a$#@6CZU6-W0iOsgNjk^^qPoT1+zTRnAg`3vXv9d*8d@RXy~6c6G66JF53UoI8eY9A{1GERg--Gi -I0S#x1is&)M%fmnGH3z`Wq5RDZgXjGZU6-W0iOsgNjk^^qPoT1+zTRnAg`3vXv9d*8d@RXy~6c6G67_D -9zv-Vp*%wog4O?q)g04AaHEjnO6;Ie%sNwVNZuM$d2nT9L349yXKr&sY-w&}Q)OXnRCrKyas&hb3uI+u -Y+-U?bZK^F00jX62mv`K^WREqS2tt~EBII@xVqZNcP`ond^UU-JbUWd$~FK100000009600000000039 -W_507X<}?;00jX62m#u~=^e=I{=p`1zMng|0+NmwUpUW`Z@54^_oW>WVpRYD0000000960000000006C -b98cbV{~&L00;qEk8=qnO(R<<%JIK< -1B78x*e6}1oxDzJ3ElvocGBqp0000000030{{R30000303So3~VPj}*Wo~o;1pxpE0aMUzRzj^*Tk1C) -pGbjYG7000000RR600000000~xMY-Mg^X=QT-0RRaBM(yUq2ps*m=2xUD -T;RqCgn#@WzFu~@adfH5^@&-|0000000000{{R30000003szxlWo~16RC#b^1pxp60tr@cX=GD$VRU5$ -0RR916j(!OVQFqcY-w&}Q)OXnRCrKyas&bZ2V!Y-V{d7000jX8Ruk6O)Q5AKbFW;JEQ>MoHhG*Mzd(pE -tONi$rOUxcMklB)P_)|`Y=H7dO_e!^G2i>0SdC0NppV!6v|_i_0S0Voadl~A00jX8Ruk6O)Q5AKbFW;J -EQ>MoHhG*Mzd(pEtONi$rOUxcMklB)P_)|`Y=H7dO_e!^G2i>0SdC0NppV!6v|_i_6IerNVQFqcY-w&} -Q)OXnRCsA*1OfmDVrg_^Z)t7-1pxw96V}(%hjW>8uUwNXi!t*yd7K}=K!`A`1OPgv%fU#n#&NEOd)wn+ -n#11fGQ~$X901P7x>0daZB@{PThHqO25f0@b!lV(1pxw96V}(%hjW>8uUwNXi!t*yd7K}=K!`A`1OPgv -%fU#n#&NEOd)wn+n#11fGQ~$X901P7x>0daZB@{PThHqdSVL%GX>L8uUwNXi!t*yd7K}=K!`A`1OPgv%fU!!8SA{&vly$FvzVnzHf7z~rv`86=_Ka^V5yX| -y#`JJ25f0@b!lV(1pxw96V}(%hjW>8uUwNXi!t*yd7K}=K!`A`1OPgv%fU!!8SA{&vly$FvzVnzHf7z~ -rv`86=_Ka^V5yX|y#`JSSVL%GX>L?_X=DTf00&}ebYpL6ZU6-V0`+VYVk7oBr%DNv+($;q`HHK!gIHa) -*%m(-e#9sm3ZsHT^UK%K(4i9Ajp1M~R@C@!4#dQE#lUD;OiKi1RsjZVX>oOFWB>&L0`+VYVk7oBr%DNv -+($;q`HHK!gIHa)*%m(-e#9sm3ZsHT^UK%K(4i9Ajp1M~R@C@!4#dQE#lUD;OiKi1Rs +y=DB@qgYOj1yf~hNn|kq2|;XhOksItaxnt|25f0@b!lV)3_)ykOksItaxqh7bOiwb2?5A!f_n>Eea4Xl +By!~KtpQ8M_qJyiO1VIUJ=H=)@ii_1#@&^bY%g~3BrR~ +dP~K#bR53&CVQNOgk^Sj)R>~DbkbeMR#2D(Y;R+00(t`--)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@O +Cd;@jJLYKfb7gWS-+`&{Sr=ykNJ#YFTr_BQwWqKF0RaedWp-s@Y-MBs1_K0hWnpXqkGsO?N19ILP2yc~ +f4%w>xYW^+v~7{W03rq(;firJ1#@&^bY%g~3BrR~dP~K#bR53&CVQNOgk^Sj)R>~DbkbeMR#2D(Y;R+0 +0(t`--)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OCd;@jJLYKfb7gWS-+`&{Sr=ykNJ#YFTr_BQwWqKF +0TV%Ub7^O8LTqVnWK(5fY*ct@WCQ{L3}bI@W@%()Zggp3YybuW1aoC!YysPfS{i~B5OpZ>_>4e9YQ#rf +ba;u!+d5tm#=h2RwFCuobYXO50nQ1+gIan^#j|uAzVaq}oP>mBc6Zd6qNjAyUB*^Wm;`KZV`~C>10COK +earHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUFsxGg*8X!CPrawgw_sqk4BX8}k^^xj-FXm+)yumJ%92y$h1 +WnpY(WB>*O1aoC!YypA{4XEgn0epQk*PX+nL>xOm%pK>soMo}bYXO50nQ1+gIan^#j|uA +zVaq}oP>mBc6Zd6qNjAyUB*^Wm;`KZV`~C>10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUFsxGg*8 +X!CPrawgw_sqk4BX8}k^^xj-FXm+)yumJ%ML349yXKrm}Zgf<6aAgGn0006RL349yXKrm}Zgg`(Y-w&} +Q)OXnRCrKyas>eZ3IT`y;$>KfZ0H=mhJ>?uV?R*<~YN(+)WXPrU6NVcJ +Re9K)?f*I|1rIW1&*8w7q6LB=zWLDb5bYX39002k^X>)URWpV;~10COKearHw +cS=7M7YzYaI8*bvhMOc?)(rkC#nUEjudT)PryvH%qoUf%jN6#Tx81sfg4O?s`uaep_R|IjbY*jNZe?@= +$}AplgPGkh3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#VTK~nd#>D+0ot2U6Id2jc94hrndMfL +ayEe1ISdA&%p{mB1!VWk)e2*8Zgg^CV{}Pm0iOsgNjk^^qPoT1+zTRnAg`3vXv9d*8d@RXy~6c6G6imL +ZewKt00<3bcywiMb7^mGRC#b^0c3R^La7y@JVOzJ)&GXo9MeQ_qmbcB?4VH0I#X{*-Uw}FbYWy+bYTJY +dQCW4e)%xftOSp9TD)g5B;KO;Krzd=y+`rt_<1!4XKZg`VQg~&6}XL#aWHw+iM6uthuRGMK#pr*4B`SU +165T3F&!H#3t@9}X=iS2Wo~qH0j?GxoKezxloIF_owDud_=c42H~ZewX>a{=9jW&m$tWDykZj`7#3_zANbB(SO{ +shhGe=&H{tM@vO> +-_DBy8`Vb0jGrW9$=2qSMXvL3HGEG0000000000 +{{R30000002XbX(Wo2!100{v`?dHP>9R0ZFSEMRj;Km4qfBYZ5UUs>0bg9bqiCNA7000000003000000 +0000BVRLh7XKrm}Zgg`13IT`y;$>KfZ0H=mhJ>?uVa{vheM(yUq2ps*m=2xUDT;RqC +gn#@WzFu~@adfH5^@&-|0000000000{{R300000033g#@X=Gt^Z*l+x0ssVVZ*FA(00035b8l^B00jX8 +VsJHoA?4$swuZp1Wc+9AOf`(TIbyKWjTy4WkGaM+ZSSEb;k|42*wg~2q@3^Lq|9zft}OB~jx>)hO7 +4Mli#Wo~n6Z*Ek1aAgGn00065MrL*e0RR932S;UYWpinB1`GpcW_AJEn^6;37FKqUhx?i3R+Mr!fY&(; +2BFL(m@EZk_srD@b7N>_ZDC1d0hChH+XJhss8OG%_CC-Q>(otsF+cqN0Qy}ddQ=3E5CvvzVP|s!dIKHb +X?@G`sCP;~6&DQwR5(-fxrUo0Th~ +Wpi|4ZEyepNCs(hb9H5M0k-IXh8!q$B6|*YuiTY;OURW8#d%1{rxIXtTaY^?oCkDeb98QHbOOpO9&dx0 +-7pM3Z=O*v*GCA9fL-<|HrZsA`NnJlR3~AEBGG%U@MZ$v=XJ?|;InIPy66cFfOYp#JM2r7_Du?5Y;;Uv +d1Z2QF##l3QrKmH@SMtOBR5nML?B>%qbz^!%<&Wu0B;HjDvStiWprU=VRT^u^?FS>S$_F2)vN@Mb6UJ- +F(lri_dqerx4lR4>iBsz2WM<=Vqt7^0TsB7j&U$~)rqyT?}yq9{6LOtU<~2{Edy0m05KgKD+^(Bb7^O8 +ZDnqBa{;avAe>RsdgK|H>1&pp1|3-AXsbFp4x6E*tRilWSI!A`VQgh?V`*h`0o{dW0B>Pr5ftu@@z<*O +39}j`u&O7io3b$Is?RA$O$l~kY-wa+bZ>G3dIKHbX?@G`sCP;~6&DQwR5(-fxrUo0ThvO>-_DBy +8`Vb0jGrW9$=2qSMXvL3HGEG0000000000{{R30 +000003t@9}X=iS2Wo~qH015$z{^Dg=h-~N_zJ`Red1EINWrM}GXaQb}6c#qIM2EQnHo-KZ`k;Xmr`<4s +JYKN!!u{G5u+^j1lf!PF4>GEG0000000000{{R300000033g#@Wo~0>Wpe-t0Y>fS!w4MxxaL=+DqP^k +2!wz9AHH68xp8!<%Jqp^&Hw-a000000RI3000000010+sY-wa+bZ>G11OfmAZf|a7000011aog~WdH>M +0%CAAe<9`Lptgpr6F_xjAC6(~TLj#*ewiHf`^rCgHqw;r~cW`-Qc;Wd#8M3IWybk`76TvuW{aQ_%-X`?VwZ$5L?~`!+pRSq0(b70UsmT3TT2OXeO1S(z|% +$w*kbE|<-?c3W<^i5g8qjccm_0000000030000000000HM{I9mVQf=$VRU6vV`ybC`}q*rYXqYdo~D%m7H6OD0<^0n_2##VWXRdj +y=DB@qgYOj2yJ0_Npxjxa{vGX4@YcoVqt7kbYXO5RC#b^1pxp60t`oNZ(?C=R$**)Wpf1q00;mG002M$ +0000000030{{R30000010000000030{{R3000008Nn~YibZK;X1pxpB0s_h`9&dx0-7pM3Z=O*v*GCA9 +fL-<|HrZsA`NnJlR3}KjBNr;@ghiU?gEXK9KMDE{F?;HZBRuDVqlk6qmbd^20?I5NZ-bfLFbqC#o>4E? +M+l67UG^w8*<_XZ#%uyqCrG{{7b@t4MVjY>G@u4Q3HlB(d+LiLJm-R=h;`?dxBvhE000000RImF00000 +00l{IaCLMB0taw%Wp+<>bODnPynwMZT8l5kSW@l}O=!>^xB4~9n`Dx!RtcK)nwJQ2Wpib6c4cG&dIKHb +X?@G`sCP;~6&DQwR5(-fxrUo0ThRw7=FYk8VVufK10Q-T=FR=Q=>S+XYD&vO>-_DBy8`Vb0 +jGrW9$=2qSMXvL3Hj|@I6Zgd6<17>D+0ot2U6Id2jc94hr +ndMfLayEe1ISdA&%p{mB1!VWk)dg;EZewKt00;(ea8!A4WdT9RTeTEeEoEcZkq99%9y`(Ly)L1)ktPMR +FX-d`h(QQ#WprU=VRT^vdIKHbX?@G`sCP;~6&DQwR5(-fxrUo0ThsZfv!yd427@;7veO2zMB=|GX`mHaCLNZ0(t`--)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@O +CODo$h9?yTI7S;;e;>sZfv!yd427@;7veO2zMB=|GYesJb7^O8ZDnqBa{_t;9p7nv%krpqN +Wpe_010COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUEjudT)PryvH%qoUf%jN6#Tx81sfg4O?s`uaep +_R|IjcWHEPWpi@^dIKHbX?@G`sCP;~6&DQwR5(-fxrUo0ThClv)aMjKgwAH@`bu1x<7 +g|G$};xvA~n-$_S33g#@X=Gt^Z*l^910COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUEjudT)PryvH% +qoUf%jN6#Tx81sfg4O?s`uaep_R|IgPjE?O1pxpD002NB00mEQZ*_DA0|IYw0hP$+dLDIRU(}XWLTZug +enOC;Z(5k~zEJnJiX;;E#R7DB0f+wLWmt%8=p4R=gtK{LClh6Z#kObxUW*hKHnBv9xdLu)0006IPj_x* +WK(oubY)XxXk~3-1_B6jWpib6c4cG&dIKHbX?@G`sCP;~6&DQwR5(-fxrUo0ThNn`>=>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HJ_ +1fvw5rj-B|XP@r^w5ufb=C_Ju$l1`nW&GEpSWb-yQe|XiWo>0-1pxpG0Y>fS!w4MxxaL=+DqP^k2!wz9 +AHH68xp8!<%Jqp^&HwZFzp>JB4@xD;^wu&SY_r(AJ000000093000000000J4 +V`yboKLkF4~iax8KK|47hp(ZeeX@0!8YhU)%QM +kO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*;5t>gcQkwbf~^M){{|8P%hsRk~m~ep32F151Y4WWC?U>ZDn(G +VQp{#07waBWp-t3Z*XOD0k-IXh8!q$B6|*YuiTY;OURW8#d%1{rxIXtTaY^?oC$4ZbYWC^aAk7<3ITQG +P59r=ivkZ4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HJ_ +1fvw5rj-B|XP@r^w5ufb=C_Ju$l1`nW&GEpSWb-q0000000030000000000BXKZg`VQf@+aAk7<3IWyb +k`76TvuW{aQ_%-X`?VwZ$5L?~`!+pRSq0(b70Urr5zRxYEK#t?kH-RPfvS1oe0PQO`VOrdl$-fvv-}wV +0000000030000000000AZ+C8GWK?-@Wpe-u0f+wLWmt%8=p4R=gtK{LClh6Z#kObxUW*hKHnBv9xdBsz ++X>O7j~NF%g#J+iq45unJ`5_e64+kv93|H3u2=v7000000093000000000bjVQgh?V|i40aAk7<2?0j! +=EDda{kY~=q$*tC#t4Le{2#tvcDZqMsmk?$P>NY&HCT(P)^ +FVARS*Zg3m2dUS*m(weL9PhQe$_)hyWq5RDZgXjGZgT(%0c3R^La7y@JVOzJ)&GXo9MeQ_qmbcB?4VH0 +I#X{*-T?z>0?er0_e!9%6%WL6o5Q7yVM7GXa@w44CHDB`4cq_#000000093000000000Yga$#@6C +ZgT(%0W?w%t`n9TUcD*&5hFi^PVx{q1b@^7zTcrn*%qZTXaRP$8)%E7`<-;ovk@YSJ+V~kNcmIwC6DJ= +V=(On#Ml4;000000093000000000PbWpib6c4cG&dIKHbX?@G`sCP;~6&DQwR5(-fxrUo0Th;v2Uql0Ev@(iYu*+LHGLwE58<2vcKdWo=V=@3j=0mb^+R(Q4?4eR(6nw`65I6*X)C9iYp+?yjr7~y;ZDn*}WMOn+0rh%K +I9Y!AFx9LCk8@hQXE7w+qW3^C%eTEp@#^?_H3w&GZ(?C=a{(2&jgE0JdDV%vvhRo54E#WjYhVoG0xbho +RRA#^8!HBBZg6#Ua{;NMdRLRko603iZGCpt_aPM;fa{=9jW&m$tWDykZj`7#3_zANbB(SO{shhGe +=&H{tM@@6CZbEf#WNc*y0}EqpZ*yf$Wprq7WCB(b*4NaB +bD49mT$3z|G4nQgoFBhHh%l@K06L}1!ALH*5GA>8Wft0d6dj=*oo`t>c$)o5X19O9`rXu=lIsX*Zg6#U +O<`~W6`5yb%eAXO2UPPRaj@((`=>9Tsh)f38uw_!yYu^q5NmF4cWzX2VQzD2bZKvHa{vkfmB{9L9(7`0 +)Rt93YLV-HLXe?vTA1;^Q1`ZqBog<<0YE4pH%=ZM{+~fOw`1HtssYBvtOA`y;Ol}bNXetSa{&MV00000 +0RR600000001#AiVQzD2bZKvHQ)6glZD9rm2yJC_VPs)+VE_pMb>vO>-_DBy8`Vb0jGrW9$=2qSMXvL3 +HGEG0000000000{{R300000025D|^b#!w83IT`y +;$>KfZ0H=mhJ>?uVKfZ0H=mhJ>?uVa{vheM(yUq +2ps*m=2xUDT;RqCgn#@WzFu~@adfH5^@&-|0000000000{{R300000033g#@X=Gt^Z*l+x0ssVVZ*FA( +00035b8l^B00jX8VsJHoA?4$swuZp1Wc+9AOf`(TIbyKWjTy4WkGaM+ZSSEb;k|42*wg~2q@3^Lq| +9zft}OB~jx>)hO74peesZgXjLX>V>+d2nR~0RR934pez?WkYXmZE19EWo~o?0{{nSWo~72X>$Mt0ReiL +b7n-LQ-}t{Ge65I6*X)C9iYp+?yjr7~y&31xV6Wo~n6Z*Bku0s)^0 +EJ-@Z0;0Ob-P{Wzd?2rs)M&&=&l*}G;Jw22Ix+!dbsj>g6`?#s5rWnKhSeO?L~x^!;Y#eFP|P}0Z%E!6 +RC#b^WI=OtX=iS8LTqVnWK(5fY*ctqbaDj&00;s6_Dlm_Y~mX!E?C%1`$%3JP7urm`gAY2$MK_n@1WfQ +0000000030{{R300000PRC#b^WI=OtX=iS8LTqVnWK(5fY*ct@WCZ~L2m!wXJ#hh#&h?=hpm+@5FeQK| +-%aa06$;5$O3_sKRObNz000000096000000000SAVQgh?V`*h`1pxpF0Y>fS!w4MxxaL=+DqP^k2!wz9 +AHH68xp8!<%Jqp^&Hw-a000000RI300000001H-OY-Mg^c~p6DWd#8M00I?<6X>I@o0RmPN*4NaBbD49mT$3z|G4nQgoFBhHh%l@K06L}1!AM3Ys4h^n+Zt?u@<&aT +IfpUd`<+;gOgf;C*Zs6&x77g#Y-w?IX=DHe0RmPN*4NaBbD49mT$3z|G4nQgoFBhHh%l@K06L}1!AM3Y +s4h^n+Zt?u@<&aTIfpUd`<+;gOgf;C*Zs6&x78C^Lug@XZbEEnZe&wsVQf@*X=DTf00&}ebYpL6ZU6-V +0#*~&*VKn|nRBmPlPrrd^EP>$AHP6|FsuXsI;G3ONU+9nu7-Qt<6xS@-s>{OM>iY*&c?b?aZznm(1lyi +>j4IAX>oOFWB>&L0#*~&*VKn|nRBmPlPrrd^EP>$AHP6|FsuXsI;G3ONU+9nu7-Qt<6xS@-s>{OM>iY* +&c?b?aZznm(1lyi>kwE&Xklq?Q)OdvWpq$ +AHP6|FsuXsI;G3ONN5@Byw$T9tCzEwrAszt-P)%HZ|LbH=L2A=l(W4CP5}mNX>oOFWB>&L0#*~&*VKn| +nRBmPlPrrd^EP>$AHP6|FsuXsI;G3ONN5@Byw$T9tCzEwrAszt-P)%HZ|LbH=L2A=l(W4CP6}8jc*fjc* +f ^ ..0xff AssetTag} - -@mnemonic(airport-ladder-joseph) -data AssignRevealedAttachBlindSealTxPtr : confidential (seal XChainSecretSeal - , state ConcealedAttach - , lock CommitVerify.ReservedBytes2) - | confidentialState (seal XChainBlindSealTxPtr - , state ConcealedAttach - , lock CommitVerify.ReservedBytes2) - | confidentialSeal (seal XChainSecretSeal - , state RevealedAttach - , lock CommitVerify.ReservedBytes2) - | revealed (seal XChainBlindSealTxPtr - , state RevealedAttach - , lock CommitVerify.ReservedBytes2) - -@mnemonic(member-camera-parking) -data AssignRevealedAttachBlindSealTxid : confidential (seal XChainSecretSeal - , state ConcealedAttach - , lock CommitVerify.ReservedBytes2) - | confidentialState (seal XChainBlindSealTxid - , state ConcealedAttach - , lock CommitVerify.ReservedBytes2) - | confidentialSeal (seal XChainSecretSeal - , state RevealedAttach - , lock CommitVerify.ReservedBytes2) - | revealed (seal XChainBlindSealTxid - , state RevealedAttach - , lock CommitVerify.ReservedBytes2) - -@mnemonic(genius-editor-formula) -data AssignRevealedDataBlindSealTxPtr : confidential (seal XChainSecretSeal - , state ConcealedData - , lock CommitVerify.ReservedBytes2) - | confidentialState (seal XChainBlindSealTxPtr - , state ConcealedData - , lock CommitVerify.ReservedBytes2) - | confidentialSeal (seal XChainSecretSeal - , state RevealedData +@mnemonic(medical-wizard-career) +data AssignBlindSealTxPtr : confidential (seal XChainSecretSeal + , state State , lock CommitVerify.ReservedBytes2) | revealed (seal XChainBlindSealTxPtr - , state RevealedData - , lock CommitVerify.ReservedBytes2) - -@mnemonic(soda-edison-music) -data AssignRevealedDataBlindSealTxid : confidential (seal XChainSecretSeal - , state ConcealedData - , lock CommitVerify.ReservedBytes2) - | confidentialState (seal XChainBlindSealTxid - , state ConcealedData - , lock CommitVerify.ReservedBytes2) - | confidentialSeal (seal XChainSecretSeal - , state RevealedData - , lock CommitVerify.ReservedBytes2) - | revealed (seal XChainBlindSealTxid - , state RevealedData + , state State , lock CommitVerify.ReservedBytes2) -@mnemonic(rachel-unique-logic) -data AssignRevealedValueBlindSealTxPtr : confidential (seal XChainSecretSeal - , state ConcealedFungible - , lock CommitVerify.ReservedBytes2) - | confidentialState (seal XChainBlindSealTxPtr - , state ConcealedFungible - , lock CommitVerify.ReservedBytes2) - | confidentialSeal (seal XChainSecretSeal - , state RevealedFungible - , lock CommitVerify.ReservedBytes2) - | revealed (seal XChainBlindSealTxPtr - , state RevealedFungible - , lock CommitVerify.ReservedBytes2) - -@mnemonic(cadet-book-pablo) -data AssignRevealedValueBlindSealTxid : confidential (seal XChainSecretSeal - , state ConcealedFungible - , lock CommitVerify.ReservedBytes2) - | confidentialState (seal XChainBlindSealTxid - , state ConcealedFungible - , lock CommitVerify.ReservedBytes2) - | confidentialSeal (seal XChainSecretSeal - , state RevealedFungible +@mnemonic(fractal-dinner-forbid) +data AssignBlindSealTxid : confidential (seal XChainSecretSeal + , state State , lock CommitVerify.ReservedBytes2) | revealed (seal XChainBlindSealTxid - , state RevealedFungible - , lock CommitVerify.ReservedBytes2) - -@mnemonic(cycle-panther-cave) -data AssignVoidStateBlindSealTxPtr : confidential (seal XChainSecretSeal - , state VoidState - , lock CommitVerify.ReservedBytes2) - | confidentialState (seal XChainBlindSealTxPtr - , state VoidState - , lock CommitVerify.ReservedBytes2) - | confidentialSeal (seal XChainSecretSeal - , state VoidState - , lock CommitVerify.ReservedBytes2) - | revealed (seal XChainBlindSealTxPtr - , state VoidState - , lock CommitVerify.ReservedBytes2) - -@mnemonic(dynasty-iron-athena) -data AssignVoidStateBlindSealTxid : confidential (seal XChainSecretSeal - , state VoidState - , lock CommitVerify.ReservedBytes2) - | confidentialState (seal XChainBlindSealTxid - , state VoidState - , lock CommitVerify.ReservedBytes2) - | confidentialSeal (seal XChainSecretSeal - , state VoidState - , lock CommitVerify.ReservedBytes2) - | revealed (seal XChainBlindSealTxid - , state VoidState + , state State , lock CommitVerify.ReservedBytes2) @mnemonic(secret-penguin-limit) @@ -181,36 +79,17 @@ data AssignmentsBlindSealTxid : {AssignmentType -> ^ ..0xff TypedAssignsBlindSea @mnemonic(factor-hair-everest) data AttachId : [Byte ^ 32] -@mnemonic(harvard-burma-bicycle) -data AttachState : id AttachId, mediaType MediaType - -@mnemonic(amadeus-sunday-casino) +@mnemonic(tennis-mambo-change) data BaseCommitment : flags CommitVerify.ReservedBytes1 , schemaId SchemaId , timestamp I64 , issuer CommitVerify.StrictHash , testnet Std.Bool , altLayers1 CommitVerify.StrictHash - , assetTags CommitVerify.StrictHash - -@mnemonic(animal-plume-minus) -data BlindingFactor : [Byte ^ 32] - -@mnemonic(meter-arizona-albino) -data ConcealedAttach : [Byte ^ 32] - -@mnemonic(ivan-tripod-young) -data ConcealedData : [Byte ^ 32] - -@mnemonic(arizona-basic-moment) -data ConcealedFungible : commitment PedersenCommitment, rangeProof PedersenCommitment @mnemonic(uniform-welcome-papa) data ContractId : [Byte ^ 32] -@mnemonic(short-noise-postal) -data DataState : [Byte] - @mnemonic(reform-garden-ballet) data Extension : ffv Ffv , contractId ContractId @@ -238,14 +117,7 @@ data ExtensionType : U16 @mnemonic(pigment-career-hippie) data Ffv : U16 -@mnemonic(guide-poker-coconut) -data FungibleState : bits64#8 U64 - -@mnemonic(matrix-optimal-sinatra) -data FungibleType : unsigned64Bit#8 - - -@mnemonic(fashion-delta-polka) +@mnemonic(reptile-life-sunday) data Genesis : ffv Ffv , schemaId SchemaId , flags CommitVerify.ReservedBytes1 @@ -253,7 +125,6 @@ data Genesis : ffv Ffv , issuer Identity , testnet Std.Bool , altLayers1 AltLayer1Set - , assetTags AssetTags , metadata Metadata , globals GlobalState , assignments AssignmentsBlindSealTxid @@ -278,8 +149,8 @@ data GlobalStateSchema : reserved CommitVerify.ReservedBytes1 @mnemonic(yoga-quick-jasmine) data GlobalStateType : U16 -@mnemonic(charter-fractal-maze) -data GlobalValues : [DataState ^ 1..] +@mnemonic(nerve-jackson-fashion) +data GlobalValues : [[Byte] ^ 1..] @mnemonic(smart-pioneer-nominal) data Identity : Std.AsciiPrintable, [Std.AsciiPrintable ^ ..0xfff] @@ -293,10 +164,6 @@ data InputMap : {Bitcoin.Vout -> ^ 1.. OpId} @mnemonic(sector-charlie-diagram) data Inputs : {Input} -@mnemonic(isabel-heaven-north) -data MediaType : any#255 - - @mnemonic(quebec-mission-quota) data MetaType : U16 @@ -330,29 +197,12 @@ data Opout : op OpId , ty AssignmentType , no U16 -@mnemonic(neutral-mixer-visual) -data OwnedStateSchema : declarative () - | fungible FungibleType - | structured StrictTypes.SemId - | attachment MediaType - -@mnemonic(pupil-scale-jerome) -data PedersenCommitment : [Byte ^ 33] +@mnemonic(cover-shampoo-weather) +data OwnedStateSchema : reserved CommitVerify.ReservedBytes1, semId StrictTypes.SemId @mnemonic(anita-vega-pirate) data Redeemed : {ValencyType -> ^ ..0xff OpId} -@mnemonic(simple-bombay-salute) -data RevealedAttach : file AttachState, salt U64 - -@mnemonic(sleep-source-figure) -data RevealedData : value DataState, salt U128 - -@mnemonic(source-contact-member) -data RevealedFungible : value FungibleState - , blinding BlindingFactor - , tag AssetTag - @mnemonic(corona-igloo-sierra) data Schema : ffv Ffv , flags CommitVerify.ReservedBytes1 @@ -371,6 +221,11 @@ data Schema : ffv Ffv @mnemonic(ramirez-patron-simon) data SchemaId : [Byte ^ 32] +@mnemonic(teacher-bridge-vienna) +data State : reserved CommitVerify.ReservedBytes1 + , value [Byte] + , attach AttachId? + @mnemonic(michael-exact-eric) data Transition : ffv Ffv , contractId ContractId @@ -405,17 +260,11 @@ data TypeCommitment : genesis BaseCommitment | transition (ContractId, TransitionType) | extension (ContractId, ExtensionType) -@mnemonic(giant-trinity-lagoon) -data TypedAssignsBlindSealTxPtr : declarative [AssignVoidStateBlindSealTxPtr] - | fungible [AssignRevealedValueBlindSealTxPtr] - | structured [AssignRevealedDataBlindSealTxPtr] - | attachment#255 [AssignRevealedAttachBlindSealTxPtr] +@mnemonic(donald-mirage-sherman) +data TypedAssignsBlindSealTxPtr : [AssignBlindSealTxPtr ^ 1..] -@mnemonic(penguin-raja-machine) -data TypedAssignsBlindSealTxid : declarative [AssignVoidStateBlindSealTxid] - | fungible [AssignRevealedValueBlindSealTxid] - | structured [AssignRevealedDataBlindSealTxid] - | attachment#255 [AssignRevealedAttachBlindSealTxid] +@mnemonic(anita-galaxy-orca) +data TypedAssignsBlindSealTxid : [AssignBlindSealTxid ^ 1..] @mnemonic(shock-jester-orion) data Valencies : {ValencyType ^ ..0xff} @@ -423,9 +272,6 @@ data Valencies : {ValencyType ^ ..0xff} @mnemonic(aloha-dublin-brush) data ValencyType : U16 -@mnemonic(email-snow-safari) -data VoidState : () - @mnemonic(senator-limbo-raymond) data XChainBlindSealTxPtr : bitcoin BPCore.BlindSealTxPtr | liquid BPCore.BlindSealTxPtr diff --git a/stl/RGBLogic@0.1.0.sta b/stl/RGBLogic@0.1.0.sta index b84bc9fd..1624e1ac 100644 --- a/stl/RGBLogic@0.1.0.sta +++ b/stl/RGBLogic@0.1.0.sta @@ -1,13 +1,13 @@ -----BEGIN STRICT TYPE LIB----- -Id: stl:mqltqlPk-O9$pYOd-BACRI70-DOMJ6cp-TFvhcK1-ibrOI9U#import-boxer-seminar +Id: stl:nKQEKac1-dDxkN3M-dXhgnba-CkprxwT-So5aC5D-meYuULE#charm-chief-invite Name: RGBLogic Dependencies: - RGBCommit#harvest-person-orion, + RGBCommit#aspect-shoe-garcia, BPCore#austin-story-retro, Bitcoin#signal-color-cipher -Check-SHA256: 1c7df052c1790167b3a2f4748d4a8d602f3c8473195826c02efa6efc43b7f396 +Check-SHA256: 6f291126bf750b4f0351e02de217fac9d2dfa34c61a4201c4a624c79cd43a05e -2vSEvOmAmtV*?;pC#?5~OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#irV+%M?ynyZEb0ERuk6O)Q5AKbFW;J EQ>MoHhG*Mzd(pEtONi$rOUxc20~CnZ*pbzY!hN5_Bp3Y36tDMM#=e#tGI($UA5U3KNx<*C>ja}LTPkk Z)t7=20~CnZ*pY?00DdlT>wB!7L}MA7sFvK#<=RP4S#T1Vv-hhTICs&5fM~jaB^jIPH$voP+@X(Ze?;0 wjY>38tto&d&=eD n*!v8^Ea7rh?dzC2n+%RZ*X#DbN~eb0#*~&*VKn|nRBmPlPrrd^EP>$AHP6|FsuXsI;G3ONJmc3T+rxD K6vW;JU&?LxLM72H?wDC1Zo}=N}D)4mkCE~Z(?C=PjX}i0tIhyPjX}d{&9|4h)I8ST&b@+9Xb*9;C#?5~OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9 -#i?X<9zv-Vp*%wog4O?q)g04AaHEjnO6;Ie%sNwVNZti*Z*F5{000OCZ*Xa30w7l>toMja192_(UwD?W -=?zm*&IhOn$k(lG-qz;Dsg=m)dLDIRU(}XWLTZugenOC;Z(5k~zEJnJiX;;E#s3O)a$#@6CZU6=Z -2X|?7Ze??G0dl)S$QV;yG0%+u`Lqfm#|FpRuujhTP8r)T_J?np;R1Ad0w7l>toMja192_(UwD?W=?zm* -&IhOn$k(lG-qz;DsWeg#t`n9TUcD*&5hFi^PVx{q1b@^7zTcrn*%qZTXa#O>ZewKt00;zcaA{-$AXg`> -_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jmB{9L9(7`0)Rt93YLV-HLXe?vTA1;^Q1`ZqBog<<3Rh`# +LdY0XT`|v$|M|2EBF6^D+OST}`A!+zFZPFTn&AR;c>*QsV74KdO^T#SWpAUbtXTLNWJNUIm1rHjqn#Z# +>rZ5L9zv-Vp*%wog4O?q)g04AaHEjnO6;Ie%sNwVNZti*Z*F5{000OCZ*Xa30wwBTwjr5Kilj@6CZU6=Z +2X|?7Ze??G0dl)S$QV;yG0%+u`Lqfm#|FpRuujhTP8r)T_J?np;R1Ad0wwBTwjr5KiljZewKt00;zcaA{-$CF)?d +A(>5zq)KIPqpYl0_!(qHG~ShH9lWER9X9JvmB{9L9(7`0)Rt93YLV-HLXe?vTA1;^Q1`ZqBog<<3Rh`# Ze??GPjX}g0{{qNa${&|c4cG$00036ZE0?0WB>&L0bJY;BNZ=sBHM?<`J6+Fr=A_lQgbaV_>=c$Ts04O39g2dD_h*R5>c -*5<{jdBoUB2y8Zom7+;NN8Xgkb3WeV)QDb*=NiflQ)(Iz254nzXJ~W)00aqiX>Db5bYX39002k +5&{WyWo~p~bZK^F0000AS7~%^Wpi^-Z*v9%25ez@WpXhBCF)?dA(>5zq)KIPqpYl0_!(qHG~ShH9lWER +9X9JvdBoUB2y8Zom7+;NN8Xgkb3WeV)QDb*=NiflQ)(Iz254nzXJ~W)00aqiX>Db5bYX39002k -----END STRICT TYPE LIB----- diff --git a/stl/RGBLogic@0.1.0.stl b/stl/RGBLogic@0.1.0.stl index 24ed32dc..4e402efe 100644 Binary files a/stl/RGBLogic@0.1.0.stl and b/stl/RGBLogic@0.1.0.stl differ diff --git a/stl/RGBLogic@0.1.0.sty b/stl/RGBLogic@0.1.0.sty index 9d370b08..6c1b9c1f 100644 --- a/stl/RGBLogic@0.1.0.sty +++ b/stl/RGBLogic@0.1.0.sty @@ -1,5 +1,5 @@ {- - Id: stl:mqltqlPk-O9$pYOd-BACRI70-DOMJ6cp-TFvhcK1-ibrOI9U#import-boxer-seminar + Id: stl:nKQEKac1-dDxkN3M-dXhgnba-CkprxwT-So5aC5D-meYuULE#charm-chief-invite Name: RGBLogic Version: 0.1.0 Description: Consensus logic layer for RGB smart contracts @@ -11,7 +11,7 @@ @context typelib RGBLogic -import RGBCommit#harvest-person-orion +import RGBCommit#aspect-shoe-garcia use TransitionType#picture-reflex-brigade use ExtensionType#apropos-scoop-viva use Layer1#camilla-basket-justin diff --git a/stl/Schema.vesper b/stl/Schema.vesper index 21aae701..de44582c 100644 --- a/stl/Schema.vesper +++ b/stl/Schema.vesper @@ -50,11 +50,9 @@ Schema rec maxItems is U24 ownedTypes map len=0..MAX8 key is U16 aka=AssignmentType - value union OwnedStateSchema - declarative is Unit tag=0 - fungible enum FungibleType wrapped unsigned64Bit=8 tag=1 - structured bytes len=32 wrapped aka=SemId tag=2 - attachment enum MediaType wrapped any=255 tag=3 + value rec OwnedStateSchema + reserved bytes len=1 aka=ReservedBytes1 + semId bytes len=32 aka=SemId valencyTypes set len=0..MAX8 element is U16 aka=ValencyType genesis rec GenesisSchema diff --git a/stl/Transition.vesper b/stl/Transition.vesper index a612053c..3e6a4770 100644 --- a/stl/Transition.vesper +++ b/stl/Transition.vesper @@ -21,7 +21,6 @@ OpCommitment rec issuer bytes len=32 aka=StrictHash testnet enum Bool false=0 true=1 altLayers1 bytes len=32 aka=StrictHash - assetTags bytes len=32 aka=StrictHash transition tuple tag=1 _ bytes len=32 aka=ContractId _ is U16 aka=TransitionType @@ -48,7 +47,7 @@ Transition rec globals map len=0..MAX8 aka=GlobalState key is U16 aka=GlobalStateType value list len=1..MAX16 aka=GlobalValues - element bytes len=0..MAX16 aka=DataState + element bytes len=0..MAX16 inputs set len=0..MAX16 aka=Inputs Input rec prevOut rec Opout @@ -58,231 +57,38 @@ Transition rec reserved bytes len=2 aka=ReservedBytes2 assignments map len=0..MAX8 aka=AssignmentsBlindSealTxPtr key is U16 aka=AssignmentType - value union TypedAssignsBlindSealTxPtr - declarative list len=0..MAX16 wrapped tag=0 - AssignVoidStateBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state is Unit aka=VoidState - lock bytes len=2 aka=ReservedBytes2 - fungible list len=0..MAX16 wrapped tag=1 - AssignRevealedValueBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec ConcealedFungible - commitment bytes len=33 aka=PedersenCommitment - rangeProof bytes len=33 aka=PedersenCommitment - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec RevealedFungible - value union FungibleState - bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec RevealedFungible - value union FungibleState - bits64 is U64 wrapped tag=0 - blinding bytes len=32 aka=BlindingFactor - tag bytes len=32 aka=AssetTag - lock bytes len=2 aka=ReservedBytes2 - structured list len=0..MAX16 wrapped tag=2 - AssignRevealedDataBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state bytes len=32 aka=ConcealedData - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state bytes len=32 aka=ConcealedData - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec RevealedData - value bytes len=0..MAX16 aka=DataState - salt is U128 - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec RevealedData - value bytes len=0..MAX16 aka=DataState - salt is U128 - lock bytes len=2 aka=ReservedBytes2 - attachment list len=0..MAX16 wrapped tag=3 - AssignRevealedAttachBlindSealTxPtr union - confidential rec tag=0 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state bytes len=32 aka=ConcealedAttach - lock bytes len=2 aka=ReservedBytes2 - confidentialState rec tag=1 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state bytes len=32 aka=ConcealedAttach - lock bytes len=2 aka=ReservedBytes2 - confidentialSeal rec tag=2 - seal union XChainSecretSeal - bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 - liquid bytes len=32 wrapped aka=SecretSeal tag=1 - state rec RevealedAttach - file rec AttachState - id bytes len=32 aka=AttachId - mediaType enum MediaType any=255 - salt is U64 - lock bytes len=2 aka=ReservedBytes2 - revealed rec tag=3 - seal union XChainBlindSealTxPtr - bitcoin rec BlindSealTxPtr wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxPtr wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid union TxPtr - witnessTx is Unit tag=0 - txid bytes len=32 wrapped aka=Txid tag=1 - vout is U32 aka=Vout - blinding is U64 - state rec RevealedAttach - file rec AttachState - id bytes len=32 aka=AttachId - mediaType enum MediaType any=255 - salt is U64 - lock bytes len=2 aka=ReservedBytes2 + value list len=1..MAX16 aka=TypedAssignsBlindSealTxPtr + AssignBlindSealTxPtr union + confidential rec tag=0 + seal union XChainSecretSeal + bitcoin bytes len=32 wrapped aka=SecretSeal tag=0 + liquid bytes len=32 wrapped aka=SecretSeal tag=1 + state rec State + reserved bytes len=1 aka=ReservedBytes1 + value bytes len=0..MAX16 + some bytes len=32 option wrapped aka=AttachId tag=1 + lock bytes len=2 aka=ReservedBytes2 + revealed rec tag=1 + seal union XChainBlindSealTxPtr + bitcoin rec BlindSealTxPtr wrapped tag=0 + method enum Method opretFirst=0 tapretFirst=1 + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 + liquid rec BlindSealTxPtr wrapped tag=1 + method enum Method opretFirst=0 tapretFirst=1 + txid union TxPtr + witnessTx is Unit tag=0 + txid bytes len=32 wrapped aka=Txid tag=1 + vout is U32 aka=Vout + blinding is U64 + state rec State + reserved bytes len=1 aka=ReservedBytes1 + value bytes len=0..MAX16 + some bytes len=32 option wrapped aka=AttachId tag=1 + lock bytes len=2 aka=ReservedBytes2 valencies set len=0..MAX8 aka=Valencies element is U16 aka=ValencyType validator bytes len=1 aka=ReservedBytes1