From 3bc38318bbe689d3083248ef3c4710744ad12ba0 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Tue, 15 Oct 2024 18:26:14 +0200 Subject: [PATCH 01/16] epic: refactor state types --- Cargo.lock | 70 +- Cargo.toml | 2 +- invoice/Cargo.toml | 3 +- invoice/src/amount.rs | 500 ----------- invoice/src/builder.rs | 55 +- invoice/src/data.rs | 293 ------- invoice/src/invoice.rs | 54 +- invoice/src/lib.rs | 8 - invoice/src/parse.rs | 103 ++- src/containers/anchors.rs | 2 +- src/containers/seal.rs | 21 +- src/contract/assignments.rs | 122 +-- src/contract/merge_reveal.rs | 101 +-- src/contract/mod.rs | 2 +- src/interface/builder.rs | 861 +----------------- src/interface/contract.rs | 334 +------ src/interface/mod.rs | 5 +- src/lib.rs | 7 +- src/persistence/index.rs | 104 +-- src/persistence/memory.rs | 224 ++--- src/persistence/mod.rs | 4 +- src/persistence/stash.rs | 19 +- src/persistence/state.rs | 32 +- src/persistence/stock.rs | 63 +- src/{stl => }/stl.rs | 106 +-- src/stl/chain.rs | 56 -- src/stl/error.rs | 39 - src/stl/mime.rs | 214 ----- src/stl/mod.rs | 44 - src/stl/specs.rs | 410 --------- stl/RGBContract@0.11.0.sta | 52 -- stl/RGBContract@0.11.0.stl | Bin 2623 -> 0 bytes stl/RGBContract@0.11.0.sty | 111 --- stl/RGBStd@0.11.0.sta | 479 +++++----- stl/RGBStd@0.11.0.stl | Bin 18876 -> 18172 bytes stl/RGBStd@0.11.0.sty | 141 ++- stl/RGBStorage@0.11.0.sta | 331 ++++--- stl/RGBStorage@0.11.0.stl | Bin 13104 -> 11620 bytes stl/RGBStorage@0.11.0.sty | 191 ++-- stl/Transfer.vesper | 1586 ++++++---------------------------- stl/src/main.rs | 26 +- 41 files changed, 1143 insertions(+), 5632 deletions(-) delete mode 100644 invoice/src/amount.rs delete mode 100644 invoice/src/data.rs rename src/{stl => }/stl.rs (54%) delete mode 100644 src/stl/chain.rs delete mode 100644 src/stl/error.rs delete mode 100644 src/stl/mime.rs delete mode 100644 src/stl/mod.rs delete mode 100644 src/stl/specs.rs delete mode 100644 stl/RGBContract@0.11.0.sta delete mode 100644 stl/RGBContract@0.11.0.stl delete mode 100644 stl/RGBContract@0.11.0.sty diff --git a/Cargo.lock b/Cargo.lock index e5bc4d83..28d602ca 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -33,7 +33,6 @@ dependencies = [ "amplify_num", "amplify_syn", "ascii", - "rand", "serde", "stringly_conversions", "wasm-bindgen", @@ -150,6 +149,12 @@ dependencies = [ "sha2", ] +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + [[package]] name = "base64" version = "0.22.1" @@ -177,12 +182,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" @@ -235,7 +234,7 @@ dependencies = [ "amplify", "chrono", "commit_verify", - "secp256k1 0.30.0", + "secp256k1", "serde", "strict_encoding", "strict_types", @@ -268,7 +267,7 @@ dependencies = [ "base85", "bp-consensus", "commit_verify", - "secp256k1 0.30.0", + "secp256k1", "serde", "strict_encoding", ] @@ -433,12 +432,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "fast32" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a35a73237400bde66c82e38387343f90d7182a2f2f22729e096a2abd57d75db9" - [[package]] name = "fluent-uri" version = "0.1.4" @@ -568,12 +561,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" @@ -686,7 +673,7 @@ dependencies = [ [[package]] name = "rgb-core" version = "0.11.0-beta.9" -source = "git+https://github.com/RGB-WG/rgb-core?branch=develop#50027495bf5e464f0e49edf65417f8caed837a39" +source = "git+https://github.com/RGB-WG/rgb-core?branch=feat/fungible-nonconf#8267ce26b1edf905553a49e5dcc42d5f2f0df338" dependencies = [ "aluvm", "amplify", @@ -695,8 +682,6 @@ dependencies = [ "chrono", "commit_verify", "getrandom", - "mime", - "secp256k1-zkp", "serde", "single_use_seals", "strict_encoding", @@ -710,9 +695,9 @@ version = "0.11.0-beta.9" dependencies = [ "amplify", "baid64", + "base58", "bp-core", "bp-invoice", - "fast32", "fluent-uri", "indexmap", "percent-encoding", @@ -720,7 +705,6 @@ dependencies = [ "rgb-core", "serde", "strict_encoding", - "strict_types", ] [[package]] @@ -788,17 +772,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" @@ -820,29 +793,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 f5b96320..55db1cec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -107,4 +107,4 @@ bp-dbc = { git = "https://github.com/BP-WG/bp-core", branch = "develop" } bp-seals = { git = "https://github.com/BP-WG/bp-core", branch = "develop" } bp-core = { git = "https://github.com/BP-WG/bp-core", branch = "develop" } bp-invoice = { git = "https://github.com/BP-WG/bp-std", branch = "develop" } -rgb-core = { git = "https://github.com/RGB-WG/rgb-core", branch = "develop" } +rgb-core = { git = "https://github.com/RGB-WG/rgb-core", branch = "feat/fungible-nonconf" } diff --git a/invoice/Cargo.toml b/invoice/Cargo.toml index 05673093..ff70bc69 100644 --- a/invoice/Cargo.toml +++ b/invoice/Cargo.toml @@ -17,10 +17,9 @@ name = "rgbinvoice" [dependencies] amplify = { workspace = true } +base58 = "0.2.0" baid64 = { workspace = true } -fast32 = "1.0.3" strict_encoding = { workspace = true } -strict_types = { workspace = true } bp-core = { workspace = true } bp-invoice = { workspace = true } rgb-core = { workspace = true } diff --git a/invoice/src/amount.rs b/invoice/src/amount.rs deleted file mode 100644 index 9007f085..00000000 --- a/invoice/src/amount.rs +++ /dev/null @@ -1,500 +0,0 @@ -// RGB wallet library for smart contracts on Bitcoin & Lightning network -// -// 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. -// -// 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::cmp::Ordering; -use std::fmt; -use std::fmt::{Display, Formatter, Write}; -use std::iter::Sum; -use std::num::{ParseIntError, TryFromIntError}; -use std::str::FromStr; - -use bp::Sats; -use rgb::{FungibleState, RevealedValue}; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; -use strict_encoding::{StrictDeserialize, StrictSerialize, VariantError}; -use strict_types::StrictVal; - -use crate::LIB_NAME_RGB_CONTRACT; - -pub const ENC_BASE32_NODIGIT: &[u8; 32] = b"abcdefghkmnABCDEFGHKMNPQRSTVWXYZ"; -fast32::make_base32_alpha!(BASE32_NODIGIT, DEC_BASE32_NODIGIT, ENC_BASE32_NODIGIT); - -#[derive( - Wrapper, WrapperMut, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default, From -)] -#[wrapper(Add, Sub, Mul, Div, Rem)] -#[wrapper_mut(AddAssign, SubAssign, MulAssign, DivAssign, RemAssign)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct Amount( - #[from] - #[from(u32)] - #[from(u16)] - #[from(u8)] - #[from(Sats)] - u64, -); - -impl StrictSerialize for Amount {} -impl StrictDeserialize for Amount {} - -impl From for Amount { - fn from(value: RevealedValue) -> Self { Amount(value.value.as_u64()) } -} - -impl From for Amount { - fn from(state: FungibleState) -> Self { Amount(state.as_u64()) } -} - -impl From for FungibleState { - fn from(amount: Amount) -> Self { FungibleState::Bits64(amount.0) } -} - -impl Amount { - pub const ZERO: Self = Amount(0); - - pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { - value.unwrap_uint::().into() - } - - pub fn with_precision(amount: u64, precision: impl Into) -> Self { - precision.into().unchecked_convert(amount) - } - - pub fn with_precision_checked(amount: u64, precision: impl Into) -> Option { - precision.into().checked_convert(amount) - } - - pub fn value(self) -> u64 { self.0 } - - pub fn split(self, precision: impl Into) -> (u64, u64) { - let precision = precision.into(); - let int = self.floor(precision); - let fract = self.rem(precision); - (int, fract) - } - - pub fn round(&self, precision: impl Into) -> u64 { - let precision = precision.into(); - let mul = precision.multiplier(); - if self.0 == 0 { - return 0; - } - let inc = 2 * self.rem(precision) / mul; - self.0 / mul + inc - } - - pub fn ceil(&self, precision: impl Into) -> u64 { - let precision = precision.into(); - if self.0 == 0 { - return 0; - } - let inc = if self.rem(precision) > 0 { 1 } else { 0 }; - self.0 / precision.multiplier() + inc - } - - pub fn floor(&self, precision: impl Into) -> u64 { - if self.0 == 0 { - return 0; - } - self.0 / precision.into().multiplier() - } - - pub fn rem(&self, precision: impl Into) -> u64 { - self.0 % precision.into().multiplier() - } - - pub fn saturating_add(&self, other: impl Into) -> Self { - self.0.saturating_add(other.into().0).into() - } - pub fn saturating_sub(&self, other: impl Into) -> Self { - self.0.saturating_sub(other.into().0).into() - } - - pub fn saturating_add_assign(&mut self, other: impl Into) { - *self = self.0.saturating_add(other.into().0).into(); - } - pub fn saturating_sub_assign(&mut self, other: impl Into) { - *self = self.0.saturating_sub(other.into().0).into(); - } - - #[must_use] - pub fn checked_add(&self, other: impl Into) -> Option { - self.0.checked_add(other.into().0).map(Self) - } - #[must_use] - pub fn checked_sub(&self, other: impl Into) -> Option { - self.0.checked_sub(other.into().0).map(Self) - } - - #[must_use] - pub fn checked_add_assign(&mut self, other: impl Into) -> Option<()> { - *self = self.0.checked_add(other.into().0).map(Self)?; - Some(()) - } - #[must_use] - pub fn checked_sub_assign(&mut self, other: impl Into) -> Option<()> { - *self = self.0.checked_sub(other.into().0).map(Self)?; - Some(()) - } -} - -impl Sum for Amount { - fn sum>(iter: I) -> Self { - iter.fold(Amount::ZERO, |sum, value| sum.saturating_add(value)) - } -} - -impl Sum for Amount { - fn sum>(iter: I) -> Self { - iter.fold(Amount::ZERO, |sum, value| sum.saturating_add(value)) - } -} - -impl Display for Amount { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - let bytes = self.0.to_le_bytes(); - let pos = bytes.iter().rposition(|b| *b != 0).unwrap_or(0) + 1; - let s = BASE32_NODIGIT.encode(&bytes[..pos]); - f.write_str(&s) - } -} - -impl FromStr for Amount { - type Err = fast32::DecodeError; - - fn from_str(s: &str) -> Result { - let amount = BASE32_NODIGIT.decode_str(s)?; - let len = amount.len(); - if len > 8 { - return Err(fast32::DecodeError::InvalidLength { - length: amount.len(), - }); - } - let mut le = [0u8; 8]; - le[..len].copy_from_slice(&amount); - Ok(Amount(u64::from_le_bytes(le))) - } -} - -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default)] -#[repr(u8)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT, tags = repr, into_u8, try_from_u8)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub enum Precision { - Indivisible = 0, - Deci = 1, - Centi = 2, - Milli = 3, - DeciMilli = 4, - CentiMilli = 5, - Micro = 6, - DeciMicro = 7, - #[default] - CentiMicro = 8, - Nano = 9, - DeciNano = 10, - CentiNano = 11, - Pico = 12, - DeciPico = 13, - CentiPico = 14, - Femto = 15, - DeciFemto = 16, - CentiFemto = 17, - Atto = 18, -} -impl StrictSerialize for Precision {} -impl StrictDeserialize for Precision {} - -impl Precision { - pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { value.unwrap_enum() } - pub const fn decimals(self) -> u8 { self as u8 } - - pub const fn multiplier(self) -> u64 { - match self { - Precision::Indivisible => 1, - Precision::Deci => 10, - Precision::Centi => 100, - Precision::Milli => 1000, - Precision::DeciMilli => 10_000, - Precision::CentiMilli => 100_000, - Precision::Micro => 1_000_000, - Precision::DeciMicro => 10_000_000, - Precision::CentiMicro => 100_000_000, - Precision::Nano => 1_000_000_000, - Precision::DeciNano => 10_000_000_000, - Precision::CentiNano => 100_000_000_000, - Precision::Pico => 1_000_000_000_000, - Precision::DeciPico => 10_000_000_000_000, - Precision::CentiPico => 100_000_000_000_000, - Precision::Femto => 1_000_000_000_000_000, - Precision::DeciFemto => 10_000_000_000_000_000, - Precision::CentiFemto => 100_000_000_000_000_000, - Precision::Atto => 1_000_000_000_000_000_000, - } - } - - pub fn unchecked_convert(self, amount: impl Into) -> Amount { - (amount.into() * self.multiplier()).into() - } - - pub fn checked_convert(self, amount: impl Into) -> Option { - amount - .into() - .checked_mul(self.multiplier()) - .map(Amount::from) - } - pub fn saturating_convert(self, amount: impl Into) -> Amount { - amount.into().saturating_mul(self.multiplier()).into() - } -} - -impl From for u16 { - fn from(value: Precision) -> Self { value as u8 as u16 } -} - -impl From for u32 { - fn from(value: Precision) -> Self { value as u8 as u32 } -} - -impl From for u64 { - fn from(value: Precision) -> Self { value as u8 as u64 } -} - -#[derive(Copy, Clone, Eq, PartialEq, Debug, Display, Error)] -#[display("invalid precision")] -pub struct PrecisionError; - -#[derive(Getters, Copy, Clone, Eq, PartialEq, Hash, Debug)] -pub struct CoinAmount { - #[getter(as_copy)] - int: u64, - #[getter(as_copy)] - fract: u64, - #[getter(as_copy)] - precision: Precision, -} - -impl CoinAmount { - pub fn new(amount: impl Into, precision: impl Into) -> Self { - let precision = precision.into(); - let amount = amount.into(); - let (int, fract) = amount.split(precision); - CoinAmount { - int, - fract, - precision, - } - } - - pub fn with( - int: u64, - fract: u64, - precision: impl Into, - ) -> Result { - let precision = precision.into(); - // 2^64 ~ 10^19 < 10^18 (18 is max value for Precision enum) - let pow = 10u64.pow(precision.decimals() as u32); - // number of decimals can't be larger than the smallest possible integer - if fract >= pow { - return Err(PrecisionError); - } - Ok(CoinAmount { - int, - fract, - precision, - }) - } - - pub(crate) fn to_amount_unchecked(self) -> Amount { - // 2^64 ~ 10^19 < 10^18 (18 is max value for Precision enum) - let pow = 10u64.pow(self.precision.decimals() as u32); - // number of decimals can't be larger than the smallest possible integer - self.int - .checked_mul(pow) - .expect("CoinAmount type garantees are broken") - .checked_add(self.fract) - .expect( - "integer has at least the same number of zeros in the lowest digits as much as \ - decimals has digits at most, so overflow is not possible", - ) - .into() - } -} - -impl Display for CoinAmount { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - if ![' ', '_'].contains(&f.fill()) { - panic!("disallowed fill character {} in coin amount formatting string", f.fill()) - } - if f.precision().is_some() { - panic!("formatting precision must not be used for coin amounts") - } - let fill = &f.fill().to_string(); - let to_chunks = |s: &str| -> String { - s.chars() - .rev() - .collect::() - .as_bytes() - .chunks(3) - .map(<[u8]>::to_owned) - .map(|mut chunk| unsafe { - chunk.reverse(); - String::from_utf8_unchecked(chunk) - }) - .rev() - .collect::>() - .join(fill) - }; - let mut int = self.int.to_string(); - if f.alternate() { - int = to_chunks(&int); - } - f.write_str(&int)?; - if self.fract > 0 || f.alternate() { - f.write_char('.')?; - let mut float = self.fract.to_string(); - let len = float.len(); - let decimals = self.precision.decimals() as usize; - match len.cmp(&decimals) { - Ordering::Less => { - float = format!("{:0>width$}{float}", "", width = decimals - len); - } - Ordering::Equal => {} - Ordering::Greater => panic!("float precision overflow for coin amount {self:?}"), - } - if f.alternate() { - float = to_chunks(&float); - } else { - float = float.trim_end_matches('0').to_string(); - } - f.write_str(&float)?; - } - if !f.alternate() { - write!(f, "~{}", self.precision.decimals())?; - } - Ok(()) - } -} - -#[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] -#[display(doc_comments)] -pub enum AmountParseError { - /// invalid amount integer part - {0} - InvalidInt(ParseIntError), - /// invalid amount fractional part - {0} - InvalidFract(ParseIntError), - /// invalid amount precision - {0} - InvalidPrecision(ParseIntError), - - /// invalid amount precision exceeding 18 - #[from(TryFromIntError)] - PrecisionOverflow, - - /// invalid amount precision exceeding 18 - #[from] - UnknownPrecision(VariantError), -} - -impl FromStr for CoinAmount { - type Err = AmountParseError; - - fn from_str(s: &str) -> Result { - let s = s.replace([' ', '_'], ""); - let (int, remain) = s.split_once('.').unwrap_or_else(|| (&s, "0")); - let (fract, precision) = remain.split_once('~').unwrap_or((remain, "")); - let precision = if precision.is_empty() { - fract.len() as u64 - } else { - precision - .parse() - .map_err(AmountParseError::InvalidPrecision)? - }; - let int: u64 = int.parse().map_err(AmountParseError::InvalidInt)?; - let fract: u64 = fract.parse().map_err(AmountParseError::InvalidFract)?; - let precision = u8::try_from(precision)?; - Ok(CoinAmount { - int, - fract, - precision: Precision::try_from(precision)?, - }) - } -} - -#[cfg(test)] -mod test { - use super::*; - - #[test] - #[allow(clippy::inconsistent_digit_grouping)] - fn int_trailing_zeros() { - let amount = CoinAmount::new(10_000__43_608_195u64, Precision::default()); - assert_eq!(amount.int(), 10_000); - assert_eq!(amount.fract(), 436_081_95); - assert_eq!(amount.precision(), Precision::default()); - assert_eq!(format!("{amount}"), "10000.43608195~8"); - assert_eq!(format!("{amount: >#}"), "10 000.43 608 195"); - } - - #[test] - #[allow(clippy::inconsistent_digit_grouping)] - fn sub_fraction() { - let amount = CoinAmount::new(10__00_008_195u64, Precision::default()); - assert_eq!(amount.int(), 10); - assert_eq!(amount.fract(), 8195); - assert_eq!(amount.precision(), Precision::default()); - assert_eq!(format!("{amount}"), "10.00008195~8"); - assert_eq!(format!("{amount:#}"), "10.00 008 195"); - } - - #[test] - #[allow(clippy::inconsistent_digit_grouping)] - fn small_fraction() { - let amount = CoinAmount::new(10__00_000_500u64, Precision::default()); - assert_eq!(amount.int(), 10); - assert_eq!(amount.fract(), 500); - assert_eq!(amount.precision(), Precision::default()); - assert_eq!(format!("{amount}"), "10.000005~8"); - assert_eq!(format!("{amount:_>#}"), "10.00_000_500"); - } - - #[test] - #[allow(clippy::inconsistent_digit_grouping)] - fn zero_fraction() { - let amount = CoinAmount::new(10__00_000_000u64, Precision::default()); - assert_eq!(amount.int(), 10); - assert_eq!(amount.fract(), 0); - assert_eq!(amount.precision(), Precision::default()); - assert_eq!(format!("{amount}"), "10~8"); - assert_eq!(format!("{amount:_>#}"), "10.00_000_000"); - } -} diff --git a/invoice/src/builder.rs b/invoice/src/builder.rs index 17f2da31..00c9d7af 100644 --- a/invoice/src/builder.rs +++ b/invoice/src/builder.rs @@ -21,11 +21,11 @@ use std::str::FromStr; -use rgb::ContractId; -use strict_encoding::{FieldName, TypeName}; +use rgb::{AttachId, ContractId, State}; +use strict_encoding::{FieldName, StrictSerialize, TypeName}; use crate::invoice::{Beneficiary, InvoiceState, RgbInvoice, RgbTransport, XChainNet}; -use crate::{Allocation, Amount, CoinAmount, NonFungible, Precision, TransportParseError}; +use crate::TransportParseError; #[derive(Clone, Eq, PartialEq, Debug)] pub struct RgbInvoiceBuilder(RgbInvoice); @@ -40,7 +40,7 @@ impl RgbInvoiceBuilder { operation: None, assignment: None, beneficiary: beneficiary.into(), - owned_state: InvoiceState::Void, + owned_state: InvoiceState::Any, expiry: None, unknown_query: none!(), }) @@ -78,49 +78,22 @@ impl RgbInvoiceBuilder { self } - pub fn set_amount_raw(mut self, amount: impl Into) -> Self { - self.0.owned_state = InvoiceState::Amount(amount.into()); + pub fn set_state(mut self, state: impl StrictSerialize) -> Self { + self.0.owned_state = InvoiceState::Specific(State::new(state)); self } - pub fn set_amount( - mut self, - integer: u64, - decimals: u64, - precision: Precision, - ) -> Result { - let amount = match CoinAmount::with(integer, decimals, precision) { - Ok(amount) => amount, - Err(_) => return Err(self), - } - .to_amount_unchecked(); - self.0.owned_state = InvoiceState::Amount(amount); + pub fn set_attachment(mut self, attach_id: AttachId) -> Result { + self.0.owned_state = match self.0.owned_state { + InvoiceState::Any | InvoiceState::Attach(_) => InvoiceState::Attach(attach_id), + InvoiceState::Specific(mut state) => { + state.attach = Some(attach_id); + InvoiceState::Specific(state) + } + }; Ok(self) } - pub fn set_allocation_raw(mut self, allocation: impl Into) -> Self { - self.0.owned_state = InvoiceState::Data(NonFungible::RGB21(allocation.into())); - self - } - - pub fn set_allocation(self, token_index: u32, fraction: u64) -> Result { - Ok(self.set_allocation_raw(Allocation::with(token_index, fraction))) - } - - /// # Safety - /// - /// The function may cause the loss of the information about the precise - /// amount of the asset, since f64 type doesn't provide full precision - /// required for that. - pub unsafe fn set_amount_approx(self, amount: f64, precision: Precision) -> Result { - if amount <= 0.0 { - return Err(self); - } - let coins = amount.floor(); - let cents = amount - coins; - self.set_amount(coins as u64, cents as u64, precision) - } - pub fn set_expiry_timestamp(mut self, expiry: i64) -> Self { self.0.expiry = Some(expiry); self diff --git a/invoice/src/data.rs b/invoice/src/data.rs deleted file mode 100644 index 7eaa93f7..00000000 --- a/invoice/src/data.rs +++ /dev/null @@ -1,293 +0,0 @@ -// RGB wallet library for smart contracts on Bitcoin & Lightning network -// -// 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. -// -// 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::str::FromStr; - -use rgb::{DataState, RevealedData}; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; -use strict_encoding::{StrictDeserialize, StrictSerialize}; -use strict_types::StrictVal; - -use crate::LIB_NAME_RGB_CONTRACT; - -#[derive(Clone, Eq, PartialEq, Hash, Debug, Display)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub enum NonFungible { - #[display(inner)] - RGB21(Allocation), -} - -impl FromStr for NonFungible { - type Err = AllocationParseError; - fn from_str(s: &str) -> Result { - let allocation = Allocation::from_str(s)?; - Ok(NonFungible::RGB21(allocation)) - } -} - -#[derive(Clone, PartialEq, Eq, Debug, Display, Error, From)] -#[display(inner)] -pub enum AllocationParseError { - #[display(doc_comments)] - /// invalid token index {0}. - InvalidIndex(String), - - #[display(doc_comments)] - /// invalid fraction {0}. - InvalidFraction(String), - - #[display(doc_comments)] - /// allocation must have format @. - WrongFormat, -} - -#[derive( - Wrapper, WrapperMut, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default, From -)] -#[wrapper(Display, FromStr, Add, Sub, Mul, Div, Rem)] -#[wrapper_mut(AddAssign, SubAssign, MulAssign, DivAssign, RemAssign)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct TokenIndex(u32); - -#[derive( - Wrapper, WrapperMut, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Default, From -)] -#[wrapper(Display, FromStr, Add, Sub, Mul, Div, Rem)] -#[wrapper_mut(AddAssign, SubAssign, MulAssign, DivAssign, RemAssign)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct OwnedFraction(u64); - -impl OwnedFraction { - pub const ZERO: Self = OwnedFraction(0); - - pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { - value.unwrap_uint::().into() - } - - pub fn value(self) -> u64 { self.0 } - - pub fn saturating_add(&self, other: impl Into) -> Self { - self.0.saturating_add(other.into().0).into() - } - pub fn saturating_sub(&self, other: impl Into) -> Self { - self.0.saturating_sub(other.into().0).into() - } - - pub fn saturating_add_assign(&mut self, other: impl Into) { - *self = self.0.saturating_add(other.into().0).into(); - } - pub fn saturating_sub_assign(&mut self, other: impl Into) { - *self = self.0.saturating_sub(other.into().0).into(); - } - - #[must_use] - pub fn checked_add(&self, other: impl Into) -> Option { - self.0.checked_add(other.into().0).map(Self) - } - #[must_use] - pub fn checked_sub(&self, other: impl Into) -> Option { - self.0.checked_sub(other.into().0).map(Self) - } - - #[must_use] - pub fn checked_add_assign(&mut self, other: impl Into) -> Option<()> { - *self = self.0.checked_add(other.into().0).map(Self)?; - Some(()) - } - #[must_use] - pub fn checked_sub_assign(&mut self, other: impl Into) -> Option<()> { - *self = self.0.checked_sub(other.into().0).map(Self)?; - Some(()) - } -} - -#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Default, Display)] -#[display("{1}@{0}")] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -pub struct Allocation(TokenIndex, OwnedFraction); - -impl Allocation { - pub fn with(index: impl Into, fraction: impl Into) -> Allocation { - Allocation(index.into(), fraction.into()) - } - - pub fn token_index(self) -> TokenIndex { self.0 } - - pub fn fraction(self) -> OwnedFraction { self.1 } -} - -impl StrictSerialize for Allocation {} -impl StrictDeserialize for Allocation {} - -impl From for Allocation { - fn from(data: RevealedData) -> Self { - Allocation::from_strict_serialized(data.value.into()).expect("invalid allocation data") - } -} - -impl From for Allocation { - fn from(state: DataState) -> Self { - Allocation::from_strict_serialized(state.into()).expect("invalid allocation data") - } -} - -impl From for DataState { - fn from(allocation: Allocation) -> Self { - DataState::from( - allocation - .to_strict_serialized() - .expect("invalid allocation data"), - ) - } -} - -impl FromStr for Allocation { - type Err = AllocationParseError; - - fn from_str(s: &str) -> Result { - if !s.contains('@') { - return Err(AllocationParseError::WrongFormat); - } - - match s.split_once('@') { - Some((fraction, token_index)) => Ok(Allocation( - token_index - .parse() - .map_err(|_| AllocationParseError::InvalidIndex(token_index.to_owned()))?, - fraction - .parse() - .map_err(|_| AllocationParseError::InvalidFraction(fraction.to_lowercase()))?, - )), - None => Err(AllocationParseError::WrongFormat), - } - } -} - -#[cfg(test)] -mod test { - use strict_types::value::StrictNum; - - use super::*; - - #[test] - fn owned_fraction_from_str() { - let owned_fraction = match OwnedFraction::from_str("1") { - Ok(value) => value, - Err(_) => OwnedFraction::ZERO, - }; - - assert_eq!(owned_fraction.value(), 1); - assert_eq!(format!("{owned_fraction}"), "1"); - } - - #[test] - fn owned_fraction_from_strict_val() { - // note that the strict number is u128 but not u64 - let owned_fraction = - OwnedFraction::from_strict_val_unchecked(&StrictVal::Number(StrictNum::Uint(1))); - - assert_eq!(owned_fraction.value(), 1); - assert_eq!(format!("{owned_fraction}"), "1"); - } - - #[test] - fn owned_fraction_add_assign() { - let mut owned_fraction = match OwnedFraction::from_str("1") { - Ok(value) => value, - Err(_) => OwnedFraction::ZERO, - }; - - let _ = owned_fraction.checked_add_assign(OwnedFraction::ZERO); - assert_eq!(owned_fraction.value(), 1); - assert_eq!(format!("{owned_fraction}"), "1"); - } - - #[test] - fn owned_fraction_add() { - let owned_fraction = match OwnedFraction::from_str("1") { - Ok(value) => value, - Err(_) => OwnedFraction::ZERO, - }; - - let owned = match owned_fraction.checked_add(OwnedFraction::ZERO) { - Some(value) => value, - None => OwnedFraction::ZERO, - }; - assert_eq!(owned.value(), 1); - assert_eq!(format!("{owned}"), "1"); - } - - #[test] - fn owned_fraction_sub() { - let owned_fraction = match OwnedFraction::from_str("1") { - Ok(value) => value, - Err(_) => OwnedFraction::ZERO, - }; - - let other_fraction = match OwnedFraction::from_str("1") { - Ok(value) => value, - Err(_) => OwnedFraction::ZERO, - }; - - let owned = match owned_fraction.checked_sub(other_fraction) { - Some(value) => value, - None => OwnedFraction::ZERO, - }; - assert_eq!(owned.value(), 0); - assert_eq!(format!("{owned}"), "0"); - } - - #[test] - fn owned_fraction_sub_assign() { - let mut owned_fraction = match OwnedFraction::from_str("1") { - Ok(value) => value, - Err(_) => OwnedFraction::ZERO, - }; - - let other_fraction = match OwnedFraction::from_str("1") { - Ok(value) => value, - Err(_) => OwnedFraction::ZERO, - }; - - let _ = owned_fraction.checked_sub_assign(other_fraction); - assert_eq!(owned_fraction.value(), 0); - assert_eq!(format!("{owned_fraction}"), "0"); - } -} diff --git a/invoice/src/invoice.rs b/invoice/src/invoice.rs index 853bd702..f48f5b75 100644 --- a/invoice/src/invoice.rs +++ b/invoice/src/invoice.rs @@ -19,18 +19,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::str::FromStr; - use amplify::{ByteArray, Bytes32}; use bp::seals::txout::CloseMethod; use bp::{InvalidPubkey, OutputPk, PubkeyHash, ScriptHash, WPubkeyHash, WScriptHash}; use indexmap::IndexMap; use invoice::{AddressNetwork, AddressPayload, Network}; -use rgb::{AttachId, ContractId, Layer1, SecretSeal}; +use rgb::{AttachId, ContractId, Layer1, SecretSeal, State}; use strict_encoding::{FieldName, TypeName}; -use crate::{Amount, NonFungible}; - #[derive(Clone, Eq, PartialEq, Hash, Debug)] #[non_exhaustive] pub enum RgbTransport { @@ -41,39 +37,29 @@ pub enum RgbTransport { UnspecifiedMeans, } -#[derive(Clone, PartialEq, Eq, Debug, Display, Error, From)] -#[display(inner)] -pub enum InvoiceStateError { - #[display(doc_comments)] - /// could not parse as amount, data, or attach: {0}. - ParseError(String), -} - -#[derive(Clone, Eq, PartialEq, Hash, Debug, Display)] +#[derive(Clone, Eq, PartialEq, Hash, Debug)] pub enum InvoiceState { - #[display("")] - Void, - #[display("{0}")] - Amount(Amount), - #[display(inner)] - Data(NonFungible), - #[display(inner)] + Any, + Specific(State), Attach(AttachId), } -impl FromStr for InvoiceState { - type Err = InvoiceStateError; - fn from_str(s: &str) -> Result { - if s.is_empty() { - Ok(InvoiceState::Void) - } else if let Ok(amount) = Amount::from_str(s) { - Ok(InvoiceState::Amount(amount)) - } else if let Ok(data) = NonFungible::from_str(s) { - Ok(InvoiceState::Data(data)) - } else if let Ok(attach) = AttachId::from_str(s) { - Ok(InvoiceState::Attach(attach)) - } else { - Err(InvoiceStateError::ParseError(s.to_owned())) +impl InvoiceState { + pub fn is_any(&self) -> bool { matches!(self, InvoiceState::Any) } + + pub fn state(&self) -> Option<&State> { + match self { + InvoiceState::Any => None, + InvoiceState::Specific(s) => Some(s), + InvoiceState::Attach(_) => None, + } + } + + pub fn attach_id(&self) -> Option { + match self { + InvoiceState::Any => None, + InvoiceState::Specific(s) => s.attach, + InvoiceState::Attach(id) => Some(*id), } } } diff --git a/invoice/src/lib.rs b/invoice/src/lib.rs index a798caeb..d2820bc8 100644 --- a/invoice/src/lib.rs +++ b/invoice/src/lib.rs @@ -21,8 +21,6 @@ #[macro_use] extern crate amplify; -#[macro_use] -extern crate strict_encoding; extern crate rgbcore as rgb; #[cfg(feature = "serde")] extern crate serde_crate as serde; @@ -34,17 +32,11 @@ pub use ::invoice::*; mod invoice; mod parse; mod builder; -mod amount; -mod data; -pub use amount::{Amount, AmountParseError, CoinAmount, Precision, PrecisionError}; pub use builder::RgbInvoiceBuilder; -pub use data::{Allocation, NonFungible, OwnedFraction, TokenIndex}; pub use parse::{InvoiceParseError, TransportParseError}; pub use crate::invoice::{ Beneficiary, ChainNet, InvoiceState, Pay2Vout, Pay2VoutError, RgbInvoice, RgbTransport, XChainNet, }; - -pub const LIB_NAME_RGB_CONTRACT: &str = "RGBContract"; diff --git a/invoice/src/parse.rs b/invoice/src/parse.rs index 08e4a37e..e2136f79 100644 --- a/invoice/src/parse.rs +++ b/invoice/src/parse.rs @@ -24,13 +24,16 @@ use std::io::{Cursor, Write}; use std::num::ParseIntError; use std::str::FromStr; +use amplify::confinement::{self, SmallBlob}; +use amplify::Wrapper; use baid64::{Baid64ParseError, DisplayBaid64, FromBaid64Str}; +use base58::{FromBase58, ToBase58}; use fluent_uri::enc::EStr; use fluent_uri::Uri; use indexmap::IndexMap; use invoice::{AddressPayload, UnknownNetwork}; use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; -use rgb::{ContractId, SecretSeal}; +use rgb::{ContractId, SecretSeal, State, StateData}; use strict_encoding::{InvalidRString, TypeName}; use crate::invoice::{ @@ -65,6 +68,22 @@ pub enum TransportParseError { InvalidTransportHost(String), } +#[derive(Debug, Display, Error, From)] +#[display(doc_comments)] +pub enum InvoiceStateError { + #[from] + /// invalid invoice state Base58 encoding. + Base58(base58::FromBase58Error), + + #[from] + /// invoice state size exceeded. + Len(confinement::Error), + + #[from] + /// invalid invoice state encoding - {0} + Deserialize(strict_encoding::DeserializeError), +} + #[derive(Debug, Display, Error, From)] #[display(doc_comments)] pub enum InvoiceParseError { @@ -72,8 +91,11 @@ pub enum InvoiceParseError { #[display(inner)] Uri(fluent_uri::ParseError), - /// invalid invoice. - Invalid, + /// absent invoice URI scheme name. + AbsentScheme, + + /// invalid invoice scheme {0}. + InvalidScheme(String), /// RGB invoice must not contain any URI authority data, including empty /// one. @@ -88,8 +110,9 @@ pub enum InvoiceParseError { /// assignment data is missed from the invoice. AssignmentMissed, - /// invalid invoice scheme {0}. - InvalidScheme(String), + #[from] + #[display(inner)] + InvalidState(InvoiceStateError), /// no invoice transport has been provided. NoTransport, @@ -115,7 +138,7 @@ pub enum InvoiceParseError { #[from] #[display(inner)] - Id(baid64::Baid64ParseError), + Id(Baid64ParseError), /// can't recognize beneficiary "{0}": it should be either a bitcoin address /// or a blinded UTXO seal. @@ -125,10 +148,6 @@ pub enum InvoiceParseError { #[display(inner)] Num(ParseIntError), - /// can't recognize amount "{0}": it should be valid rgb21 allocation - /// data. - Data(String), - #[from] /// invalid interface name. IfaceName(InvalidRString), @@ -158,6 +177,30 @@ impl RgbInvoice { } } +impl Display for InvoiceState { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + match self { + InvoiceState::Any => Ok(()), + InvoiceState::Specific(state) => f.write_str(&state.value.to_base58()), + // TODO: Support attachment through invoice params + InvoiceState::Attach(_) => Ok(()), + } + } +} + +impl FromStr for InvoiceState { + type Err = InvoiceStateError; + fn from_str(s: &str) -> Result { + if s.is_empty() { + return Ok(InvoiceState::Any); + } + let data = s.from_base58()?; + let data = SmallBlob::try_from(data)?; + let data = StateData::from_inner(data); + Ok(InvoiceState::Specific(State::from(data))) + } +} + impl Display for RgbTransport { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { @@ -293,6 +336,7 @@ impl FromStr for XChainNet { impl Display for RgbInvoice { fn fmt(&self, f: &mut Formatter) -> fmt::Result { + // TODO: Support attachment through invoice params let amt = self.owned_state.to_string(); if let Some(contract) = self.contract { let id = if f.alternate() { @@ -352,9 +396,10 @@ impl FromStr for RgbInvoice { type Err = InvoiceParseError; fn from_str(s: &str) -> Result { + // TODO: Support attachment through invoice params let uri = Uri::parse(s)?; - let scheme = uri.scheme().ok_or(InvoiceParseError::Invalid)?; + let scheme = uri.scheme().ok_or(InvoiceParseError::AbsentScheme)?; if scheme.as_str() != "rgb" { return Err(InvoiceParseError::InvalidScheme(scheme.to_string())); } @@ -392,18 +437,14 @@ impl FromStr for RgbInvoice { let Some(assignment) = path.next() else { return Err(InvoiceParseError::AssignmentMissed); }; - let (amount, beneficiary) = assignment + let (state, beneficiary) = assignment .as_str() .split_once('+') .map(|(a, b)| (Some(a), Some(b))) .unwrap_or((Some(assignment.as_str()), None)); - // TODO: support other state types - let (beneficiary_str, value) = match (beneficiary, amount) { - (Some(b), Some(a)) => ( - b, - InvoiceState::from_str(a).map_err(|_| InvoiceParseError::Data(a.to_string()))?, - ), - (None, Some(b)) => (b, InvoiceState::Void), + let (beneficiary_str, value) = match (beneficiary, state) { + (Some(b), Some(a)) => (b, InvoiceState::from_str(a)?), + (None, Some(b)) => (b, InvoiceState::Any), _ => unreachable!(), }; @@ -472,22 +513,34 @@ fn map_query_params(uri: &Uri<&str>) -> Result, Invoice #[cfg(test)] mod test { use super::*; - use crate::Amount; #[test] fn parse() { // rgb20/rgb25 parameters - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + T5FhUZEHbQu4B+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); - assert_eq!(invoice.owned_state, InvoiceState::Amount(Amount::from(100u64))); + assert_eq!( + invoice.owned_state, + InvoiceState::Specific(State::from(StateData::from_checked(vec![ + 8, 0, 100, 0, 0, 0, 0, 0, 0, 0 + ]))) + ); assert_eq!(invoice.to_string(), invoice_str); assert_eq!(format!("{invoice:#}"), invoice_str.replace('-', "")); // rgb21 parameters - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB21/1@1+bc:\ - utxob:zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F"; + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB21/\ + 5QsfkEcyanohXadePHZ+bc:utxob:\ + zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); + assert_eq!( + invoice.owned_state, + InvoiceState::Specific(State::from(StateData::from_checked(vec![ + 12, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 + ]))) + ); assert_eq!(invoice.to_string(), invoice_str); assert_eq!(format!("{invoice:#}"), invoice_str.replace('-', "")); @@ -590,7 +643,7 @@ mod test { let invoice_str = "2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX/~/bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F"; let result = RgbInvoice::from_str(invoice_str); - assert!(matches!(result, Err(InvoiceParseError::Invalid))); + assert!(matches!(result, Err(InvoiceParseError::AbsentScheme))); // invalid scheme let invoice_str = "bad:2WBcas9-yjzEvGufY-9GEgnyMj7-beMNMWA8r-sPHtV1nPU-TMsGMQX/~/bc:utxob:\ diff --git a/src/containers/anchors.rs b/src/containers/anchors.rs index 2c7c1671..0a346a0c 100644 --- a/src/containers/anchors.rs +++ b/src/containers/anchors.rs @@ -36,7 +36,7 @@ use rgb::{ use strict_encoding::StrictDumb; use crate::containers::Dichotomy; -use crate::{MergeReveal, MergeRevealError, TypedAssignsExt, LIB_NAME_RGB_STD}; +use crate::{MergeReveal, MergeRevealError, LIB_NAME_RGB_STD}; #[derive(Clone, Eq, PartialEq, Debug, Display, Error)] #[display("state transition {0} is not a part of the bundle.")] diff --git a/src/containers/seal.rs b/src/containers/seal.rs index 49dc3079..6e044604 100644 --- a/src/containers/seal.rs +++ b/src/containers/seal.rs @@ -24,7 +24,7 @@ use bp::seals::txout::{BlindSeal, CloseMethod, SealTxid}; use bp::secp256k1::rand::{thread_rng, RngCore}; use bp::Vout; -use rgb::{GraphSeal, Layer1, SecretSeal, TxoSeal, XChain}; +use rgb::{Assign, ExposedSeal, GraphSeal, Layer1, SecretSeal, State, XChain}; use crate::LIB_NAME_RGB_STD; @@ -109,7 +109,7 @@ impl From for GraphSeal { /// Seal used by operation builder which can be either revealed or concealed. #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, From)] -pub enum BuilderSeal { +pub enum BuilderSeal { Revealed(XChain), #[from] Concealed(XChain), @@ -119,11 +119,26 @@ impl From>> for BuilderSeal> { fn from(seal: XChain>) -> Self { BuilderSeal::Revealed(seal) } } -impl BuilderSeal { +impl BuilderSeal { pub fn layer1(&self) -> Layer1 { match self { BuilderSeal::Revealed(x) => x.layer1(), BuilderSeal::Concealed(x) => x.layer1(), } } + + pub fn assignment(self, state: State) -> Assign { + match self { + BuilderSeal::Revealed(seal) => Assign::Revealed { + seal, + state, + lock: none!(), + }, + BuilderSeal::Concealed(seal) => Assign::Confidential { + seal, + state, + lock: none!(), + }, + } + } } diff --git a/src/contract/assignments.rs b/src/contract/assignments.rs index d4967520..f6be139a 100644 --- a/src/contract/assignments.rs +++ b/src/contract/assignments.rs @@ -24,51 +24,12 @@ use std::collections::HashMap; use std::fmt::Debug; use std::hash::Hash; -use amplify::confinement::SmallVec; -use commit_verify::Conceal; -use invoice::Amount; use rgb::vm::WitnessOrd; -use rgb::{ - Assign, AssignAttach, AssignData, AssignFungible, AssignRights, AssignmentType, AttachState, - DataState, ExposedSeal, ExposedState, OpId, Opout, RevealedAttach, RevealedData, RevealedValue, - TypedAssigns, VoidState, XChain, XOutputSeal, XWitnessId, -}; +use rgb::{AssignmentType, ExposedSeal, OpId, Opout, State, XChain, XOutputSeal, XWitnessId}; use strict_encoding::{StrictDecode, StrictDumb, StrictEncode}; use crate::LIB_NAME_RGB_STD; -/// Trait used by contract state. Unlike [`ExposedState`] it doesn't allow -/// concealment of the state, i.e. may contain incomplete data without blinding -/// factors, asset tags etc. -pub trait KnownState: Debug + StrictDumb + StrictEncode + StrictDecode + Eq + Clone + Hash { - const IS_FUNGIBLE: bool; -} - -impl KnownState for () { - const IS_FUNGIBLE: bool = false; -} -impl KnownState for VoidState { - const IS_FUNGIBLE: bool = false; -} -impl KnownState for DataState { - const IS_FUNGIBLE: bool = false; -} -impl KnownState for Amount { - const IS_FUNGIBLE: bool = true; -} -impl KnownState for AttachState { - const IS_FUNGIBLE: bool = false; -} -impl KnownState for RevealedValue { - const IS_FUNGIBLE: bool = true; -} -impl KnownState for RevealedData { - const IS_FUNGIBLE: bool = false; -} -impl KnownState for RevealedAttach { - const IS_FUNGIBLE: bool = false; -} - #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_STD)] @@ -83,7 +44,7 @@ pub struct WitnessInfo { } #[allow(clippy::derived_hash_with_manual_eq)] -#[derive(Copy, Clone, Eq, Hash, Debug)] +#[derive(Clone, Eq, Hash, Debug)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = LIB_NAME_RGB_STD)] #[cfg_attr( @@ -91,14 +52,14 @@ pub struct WitnessInfo { derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "camelCase") )] -pub struct OutputAssignment { +pub struct OutputAssignment { pub opout: Opout, pub seal: XOutputSeal, pub state: State, pub witness: Option, } -impl PartialEq for OutputAssignment { +impl PartialEq for OutputAssignment { fn eq(&self, other: &Self) -> bool { // We ignore difference in witness transactions, state and seal definitions here // in order to support updates from the ephemeral state of the lightning @@ -113,11 +74,11 @@ impl PartialEq for OutputAssignment { } } -impl PartialOrd for OutputAssignment { +impl PartialOrd for OutputAssignment { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for OutputAssignment { +impl Ord for OutputAssignment { fn cmp(&self, other: &Self) -> Ordering { if self == other { return Ordering::Equal; @@ -129,7 +90,7 @@ impl Ord for OutputAssignment { } } -impl OutputAssignment { +impl OutputAssignment { /// # Panics /// /// If the processing is done on invalid stash data, the seal is @@ -175,16 +136,6 @@ impl OutputAssignment { } } - /// Transmutes output assignment from one form of state to another - pub fn transmute>(self) -> OutputAssignment { - OutputAssignment { - opout: self.opout, - seal: self.seal, - state: self.state.into(), - witness: self.witness, - } - } - pub fn check_witness(&self, filter: &HashMap) -> bool { match self.witness { None => true, @@ -194,62 +145,3 @@ impl OutputAssignment { } } } - -pub trait TypedAssignsExt { - fn reveal_seal(&mut self, seal: XChain); - - fn filter_revealed_seals(&self) -> Vec>; -} - -impl TypedAssignsExt for TypedAssigns { - fn reveal_seal(&mut self, seal: XChain) { - fn reveal( - vec: &mut SmallVec>, - revealed: XChain, - ) { - for assign in vec.iter_mut() { - match assign { - Assign::ConfidentialSeal { seal, state, lock } - if *seal == revealed.conceal() => - { - *assign = Assign::Revealed { - seal: revealed, - state: state.clone(), - lock: *lock, - } - } - Assign::Confidential { seal, state, lock } if *seal == revealed.conceal() => { - *assign = Assign::ConfidentialState { - seal: revealed, - state: *state, - lock: *lock, - } - } - _ => {} - } - } - } - - match self { - TypedAssigns::Declarative(v) => reveal(v, seal), - TypedAssigns::Fungible(v) => reveal(v, seal), - TypedAssigns::Structured(v) => reveal(v, seal), - TypedAssigns::Attachment(v) => reveal(v, seal), - } - } - - fn filter_revealed_seals(&self) -> Vec> { - match self { - TypedAssigns::Declarative(s) => { - s.iter().filter_map(AssignRights::revealed_seal).collect() - } - TypedAssigns::Fungible(s) => { - s.iter().filter_map(AssignFungible::revealed_seal).collect() - } - TypedAssigns::Structured(s) => s.iter().filter_map(AssignData::revealed_seal).collect(), - TypedAssigns::Attachment(s) => { - s.iter().filter_map(AssignAttach::revealed_seal).collect() - } - } - } -} diff --git a/src/contract/merge_reveal.rs b/src/contract/merge_reveal.rs index b662f5a5..a8975f24 100644 --- a/src/contract/merge_reveal.rs +++ b/src/contract/merge_reveal.rs @@ -21,13 +21,13 @@ use std::collections::BTreeMap; -use amplify::confinement::Confined; +use amplify::confinement::{Confined, NonEmptyVec}; use amplify::Wrapper; use bp::Txid; use commit_verify::{mpc, Conceal}; use rgb::{ - Assign, Assignments, BundleId, ExposedSeal, ExposedState, Extension, Genesis, OpId, Operation, - Transition, TransitionBundle, TypedAssigns, + Assign, Assignments, BundleId, ExposedSeal, Extension, Genesis, OpId, Operation, Transition, + TransitionBundle, TypedAssigns, }; #[derive(Copy, Clone, Eq, PartialEq, Debug, Display, Error, From)] @@ -90,7 +90,7 @@ pub trait MergeRevealContract: Sized { } */ -impl MergeReveal for Assign { +impl MergeReveal for Assign { fn merge_reveal(self, other: Self) -> Result { debug_assert_eq!(self.conceal(), other.conceal()); match (self, other) { @@ -98,102 +98,19 @@ impl MergeReveal for Assign (_, state @ Assign::Revealed { .. }) | (state @ Assign::Revealed { .. }, _) => { Ok(state) } - - // ConfidentialAmount + ConfidentialSeal = Revealed - ( - Assign::ConfidentialSeal { - state, lock: lock1, .. - }, - Assign::ConfidentialState { - seal, lock: lock2, .. - }, - ) => { - debug_assert_eq!(lock1, lock2); - Ok(Assign::Revealed { - seal, - state, - lock: lock1, - }) - } - - // ConfidentialSeal + ConfidentialAmount = Revealed - ( - Assign::ConfidentialState { - seal, lock: lock1, .. - }, - Assign::ConfidentialSeal { - state, lock: lock2, .. - }, - ) => { - debug_assert_eq!(lock1, lock2); - Ok(Assign::Revealed { - seal, - state, - lock: lock1, - }) - } - - // if self and other is of same variant return self - (state @ Assign::ConfidentialState { .. }, Assign::ConfidentialState { .. }) => { - Ok(state) - } - (state @ Assign::ConfidentialSeal { .. }, Assign::ConfidentialSeal { .. }) => Ok(state), - // Anything + Confidential = Anything - (state, Assign::Confidential { .. }) | (Assign::Confidential { .. }, state) => { - Ok(state) - } + (state, Assign::Confidential { .. }) => Ok(state), } } } impl MergeReveal for TypedAssigns { fn merge_reveal(self, other: Self) -> Result { - match (self, other) { - (TypedAssigns::Declarative(first_vec), TypedAssigns::Declarative(second_vec)) => { - let mut result = Vec::with_capacity(first_vec.len()); - for (first, second) in first_vec.into_iter().zip(second_vec.into_iter()) { - result.push(first.merge_reveal(second)?); - } - Ok(TypedAssigns::Declarative( - Confined::try_from(result).expect("collection of the same size"), - )) - } - - (TypedAssigns::Fungible(first_vec), TypedAssigns::Fungible(second_vec)) => { - let mut result = Vec::with_capacity(first_vec.len()); - for (first, second) in first_vec.into_iter().zip(second_vec.into_iter()) { - result.push(first.merge_reveal(second)?); - } - Ok(TypedAssigns::Fungible( - Confined::try_from(result).expect("collection of the same size"), - )) - } - - (TypedAssigns::Structured(first_vec), TypedAssigns::Structured(second_vec)) => { - let mut result = Vec::with_capacity(first_vec.len()); - for (first, second) in first_vec.into_iter().zip(second_vec.into_iter()) { - result.push(first.merge_reveal(second)?); - } - Ok(TypedAssigns::Structured( - Confined::try_from(result).expect("collection of the same size"), - )) - } - - (TypedAssigns::Attachment(first_vec), TypedAssigns::Attachment(second_vec)) => { - let mut result = Vec::with_capacity(first_vec.len()); - for (first, second) in first_vec.into_iter().zip(second_vec.into_iter()) { - result.push(first.merge_reveal(second)?); - } - Ok(TypedAssigns::Attachment( - Confined::try_from(result).expect("collection of the same size"), - )) - } - // No other patterns possible, should not reach here - _ => { - unreachable!("Assignments::consensus_commitments is broken") - } + let mut result = Vec::with_capacity(self.len()); + for (first, second) in self.into_iter().zip(other.into_iter()) { + result.push(first.merge_reveal(second)?); } + Ok(TypedAssigns::from(NonEmptyVec::from_checked(result))) } } diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 624830ed..96298642 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -22,7 +22,7 @@ mod assignments; mod merge_reveal; -pub use assignments::{KnownState, OutputAssignment, TypedAssignsExt, WitnessInfo}; +pub use assignments::{OutputAssignment, WitnessInfo}; pub use merge_reveal::{MergeReveal, MergeRevealError}; use rgb::vm::OrdOpRef; use rgb::{ExtensionType, OpId, TransitionType, XWitnessId}; diff --git a/src/interface/builder.rs b/src/interface/builder.rs index eb8a01c4..7fc6c13e 100644 --- a/src/interface/builder.rs +++ b/src/interface/builder.rs @@ -21,19 +21,15 @@ #![allow(clippy::result_large_err)] -use std::collections::{BTreeMap, HashSet}; +use std::collections::btree_map::Entry; -use amplify::confinement::{Confined, SmallOrdSet, TinyOrdMap, U16}; -use amplify::{confinement, Wrapper}; +use amplify::confinement::{self, Confined, SmallOrdSet, TinyOrdMap}; use chrono::Utc; -use invoice::{Allocation, Amount}; use rgb::validation::Scripts; use rgb::{ - validation, AltLayer1, AltLayer1Set, AssetTag, AssetTags, Assign, AssignmentType, Assignments, - AttachState, BlindingFactor, ContractId, DataState, ExposedSeal, FungibleType, Genesis, - GenesisSeal, GlobalState, GraphSeal, Identity, Input, Layer1, MetadataError, Opout, - OwnedStateSchema, RevealedAttach, RevealedData, RevealedValue, Schema, Transition, - TransitionType, TypedAssigns, XChain, XOutpoint, + validation, AltLayer1, AltLayer1Set, AssignmentType, Assignments, ContractId, ExposedSeal, + Genesis, GenesisSeal, GlobalState, GraphSeal, Identity, Input, Layer1, MetadataError, Opout, + OwnedStateSchema, Schema, State, Transition, TransitionType, TypedAssigns, XChain, XOutpoint, }; use rgbcore::{GlobalStateSchema, GlobalStateType, MetaType, Metadata, ValencyType}; use strict_encoding::{FieldName, SerializeError, StrictSerialize}; @@ -42,7 +38,6 @@ use strict_types::{decode, SemId, TypeSystem}; use crate::containers::{BuilderSeal, ContainerVer, Contract, ValidConsignment}; use crate::interface::resolver::DumbResolver; use crate::interface::{Iface, IfaceImpl, TransitionIface}; -use crate::persistence::PersistedState; use crate::Outpoint; #[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] @@ -164,23 +159,6 @@ impl ContractBuilder { } } - pub fn deterministic( - issuer: Identity, - iface: Iface, - schema: Schema, - iimpl: IfaceImpl, - types: TypeSystem, - scripts: Scripts, - ) -> Self { - Self { - builder: OperationBuilder::deterministic(iface, schema, iimpl, types), - testnet: true, - alt_layers1: none!(), - scripts, - issuer, - } - } - pub fn type_system(&self) -> &TypeSystem { self.builder.type_system() } pub fn set_mainnet(mut self) -> Self { @@ -208,21 +186,6 @@ impl ContractBuilder { Ok(self) } - #[inline] - pub fn asset_tag(&self, name: impl Into) -> Result { - self.builder.asset_tag(name) - } - - #[inline] - pub fn add_asset_tag( - mut self, - name: impl Into, - asset_tag: AssetTag, - ) -> Result { - self.builder = self.builder.add_asset_tag(name, asset_tag)?; - Ok(self) - } - #[inline] pub fn global_type(&self, name: &FieldName) -> Option { self.builder.global_type(name) @@ -261,60 +224,19 @@ impl ContractBuilder { Ok(self) } - pub fn add_owned_state_det( - mut self, - name: impl Into, - seal: impl Into>, - state: PersistedState, - ) -> Result { - let seal = seal.into(); - self.check_layer1(seal.layer1())?; - self.builder = self.builder.add_owned_state_det(name, seal, state)?; - Ok(self) - } - - pub fn add_rights( - mut self, - name: impl Into, - seal: impl Into>, - ) -> Result { - let seal = seal.into(); - self.check_layer1(seal.layer1())?; - self.builder = self.builder.add_rights(name, seal)?; - Ok(self) - } - - pub fn add_fungible_state( - mut self, - name: impl Into, - seal: impl Into>, - value: impl Into, - ) -> Result { - let name = name.into(); - let seal = seal.into(); - self.check_layer1(seal.layer1())?; - self.builder.init_asset_tag(name.clone())?; - self.builder = self.builder.add_fungible_state(name, seal, value)?; - Ok(self) - } - - pub fn add_fungible_state_det( + pub fn add_owned_state_raw( mut self, name: impl Into, seal: impl Into>, - value: impl Into, - blinding: BlindingFactor, + state: State, ) -> Result { - let name = name.into(); let seal = seal.into(); self.check_layer1(seal.layer1())?; - let tag = self.builder.init_asset_tag(name.clone())?; - let state = RevealedValue::with_blinding(value.into(), blinding, tag); - self.builder = self.builder.add_fungible_state_det(name, seal, state)?; + self.builder = self.builder.add_owned_state_raw(name, seal, state)?; Ok(self) } - pub fn add_data( + pub fn add_owned_state( mut self, name: impl Into, seal: impl Into>, @@ -322,51 +244,11 @@ impl ContractBuilder { ) -> Result { let seal = seal.into(); self.check_layer1(seal.layer1())?; - self.builder = self.builder.add_data(name, seal, value)?; - Ok(self) - } - - pub fn add_data_det( - mut self, - name: impl Into, - seal: impl Into>, - data: RevealedData, - ) -> Result { - let seal = seal.into(); - self.check_layer1(seal.layer1())?; - self.builder = self.builder.add_data_det(name, seal, data)?; - Ok(self) - } - - pub fn add_attachment( - mut self, - name: impl Into, - seal: impl Into>, - attachment: AttachState, - ) -> Result { - let seal = seal.into(); - self.check_layer1(seal.layer1())?; - self.builder = self.builder.add_attachment(name, seal, attachment)?; - Ok(self) - } - - pub fn add_attachment_det( - mut self, - name: impl Into, - seal: impl Into>, - attachment: RevealedAttach, - ) -> Result { - let seal = seal.into(); - self.check_layer1(seal.layer1())?; - self.builder = self.builder.add_attachment_det(name, seal, attachment)?; + self.builder = self.builder.add_owned_state(name, seal, value)?; Ok(self) } pub fn issue_contract(self) -> Result, BuilderError> { - debug_assert!( - !self.builder.deterministic, - "for issuing deterministic contracts please use issue_contract_det method" - ); self.issue_contract_raw(Utc::now().timestamp()) } @@ -374,16 +256,11 @@ impl ContractBuilder { self, timestamp: i64, ) -> Result, BuilderError> { - debug_assert!( - self.builder.deterministic, - "for issuing deterministic contracts please use deterministic constructor" - ); self.issue_contract_raw(timestamp) } fn issue_contract_raw(self, timestamp: i64) -> Result, BuilderError> { - let (schema, iface, iimpl, global, assignments, types, asset_tags) = - self.builder.complete(None); + let (schema, iface, iimpl, global, assignments, types) = self.builder.complete(); let genesis = Genesis { ffv: none!(), @@ -392,7 +269,6 @@ impl ContractBuilder { timestamp, testnet: self.testnet, alt_layers1: self.alt_layers1, - asset_tags, metadata: empty!(), globals: global, assignments, @@ -436,7 +312,7 @@ pub struct TransitionBuilder { builder: OperationBuilder, nonce: u64, transition_type: TransitionType, - inputs: TinyOrdMap, + inputs: TinyOrdMap, } impl TransitionBuilder { @@ -450,16 +326,6 @@ impl TransitionBuilder { Self::with(contract_id, iface, schema, iimpl, TransitionType::BLANK, types) } - pub fn blank_transition_det( - contract_id: ContractId, - iface: Iface, - schema: Schema, - iimpl: IfaceImpl, - types: TypeSystem, - ) -> Self { - Self::deterministic(contract_id, iface, schema, iimpl, TransitionType::BLANK, types) - } - pub fn default_transition( contract_id: ContractId, iface: Iface, @@ -475,21 +341,6 @@ impl TransitionBuilder { Ok(Self::with(contract_id, iface, schema, iimpl, transition_type, types)) } - pub fn default_transition_det( - contract_id: ContractId, - iface: Iface, - schema: Schema, - iimpl: IfaceImpl, - types: TypeSystem, - ) -> Result { - let transition_type = iface - .default_operation - .as_ref() - .and_then(|name| iimpl.transition_type(name)) - .ok_or(BuilderError::NoOperationSubtype)?; - Ok(Self::deterministic(contract_id, iface, schema, iimpl, transition_type, types)) - } - pub fn named_transition( contract_id: ContractId, iface: Iface, @@ -505,21 +356,6 @@ impl TransitionBuilder { Ok(Self::with(contract_id, iface, schema, iimpl, transition_type, types)) } - pub fn named_transition_det( - contract_id: ContractId, - iface: Iface, - schema: Schema, - iimpl: IfaceImpl, - transition_name: impl Into, - types: TypeSystem, - ) -> Result { - let transition_name = transition_name.into(); - let transition_type = iimpl - .transition_type(&transition_name) - .ok_or(BuilderError::TransitionNotFound(transition_name))?; - Ok(Self::deterministic(contract_id, iface, schema, iimpl, transition_type, types)) - } - fn with( contract_id: ContractId, iface: Iface, @@ -537,23 +373,6 @@ impl TransitionBuilder { } } - fn deterministic( - contract_id: ContractId, - iface: Iface, - schema: Schema, - iimpl: IfaceImpl, - transition_type: TransitionType, - types: TypeSystem, - ) -> Self { - Self { - contract_id, - builder: OperationBuilder::deterministic(iface, schema, iimpl, types), - nonce: u64::MAX, - transition_type, - inputs: none!(), - } - } - pub fn type_system(&self) -> &TypeSystem { self.builder.type_system() } pub fn transition_type(&self) -> TransitionType { self.transition_type } @@ -563,31 +382,6 @@ impl TransitionBuilder { self } - #[inline] - pub fn asset_tag(&self, name: impl Into) -> Result { - self.builder.asset_tag(name) - } - - #[inline] - pub fn add_asset_tag( - mut self, - name: impl Into, - asset_tag: AssetTag, - ) -> Result { - self.builder = self.builder.add_asset_tag(name, asset_tag)?; - Ok(self) - } - - #[inline] - pub fn add_asset_tag_raw( - mut self, - type_id: AssignmentType, - asset_tag: AssetTag, - ) -> Result { - self.builder = self.builder.add_asset_tag_raw(type_id, asset_tag)?; - Ok(self) - } - #[inline] pub fn add_metadata( mut self, @@ -608,7 +402,7 @@ impl TransitionBuilder { Ok(self) } - pub fn add_input(mut self, opout: Opout, state: PersistedState) -> Result { + pub fn add_input(mut self, opout: Opout, state: State) -> Result { self.inputs.insert(Input::with(opout), state)?; Ok(self) } @@ -642,165 +436,39 @@ impl TransitionBuilder { pub fn meta_name(&self, type_id: MetaType) -> &FieldName { self.builder.meta_name(type_id) } - pub fn add_owned_state_det( - mut self, - name: impl Into, - seal: impl Into>, - state: PersistedState, - ) -> Result { - self.builder = self.builder.add_owned_state_det(name, seal, state)?; - Ok(self) - } - pub fn add_owned_state_raw( - mut self, - type_id: AssignmentType, - seal: impl Into>, - state: PersistedState, - ) -> Result { - if matches!(state, PersistedState::Amount(_, _, tag) if self.builder.asset_tag_raw(type_id)? != tag) - { - return Err(BuilderError::AssetTagInvalid(type_id)); - } - self.builder = self.builder.add_owned_state_raw(type_id, seal, state)?; - Ok(self) - } - - pub fn add_rights( mut self, name: impl Into, seal: impl Into>, + state: State, ) -> Result { - self.builder = self.builder.add_rights(name, seal)?; + self.builder = self.builder.add_owned_state_raw(name, seal, state)?; Ok(self) } - pub fn add_fungible_default_state( - self, - seal: impl Into>, - value: u64, - ) -> Result { - let assignment_name = self.default_assignment()?.clone(); - self.add_fungible_state(assignment_name, seal.into(), value) - } - - pub fn add_fungible_default_state_det( - self, - seal: impl Into>, - value: u64, - blinding: BlindingFactor, - ) -> Result { - let assignment_name = self.default_assignment()?.clone(); - self.add_fungible_state_det(assignment_name, seal.into(), value, blinding) - } - - pub fn add_fungible_state( - mut self, - name: impl Into, - seal: impl Into>, - value: impl Into, - ) -> Result { - self.builder = self.builder.add_fungible_state(name.into(), seal, value)?; - Ok(self) - } - - pub fn add_fungible_state_det( - mut self, - name: impl Into, - seal: impl Into>, - value: impl Into, - blinding: BlindingFactor, - ) -> Result { - let name = name.into(); - let type_id = self - .builder - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name.clone()))?; - let tag = self.builder.asset_tag_raw(type_id)?; - let state = RevealedValue::with_blinding(value.into(), blinding, tag); - - self.builder = self.builder.add_fungible_state_det(name, seal, state)?; - Ok(self) - } - - pub fn add_fungible_state_raw( - mut self, - type_id: AssignmentType, - seal: impl Into>, - value: impl Into, - blinding: BlindingFactor, - ) -> Result { - let tag = self.builder.asset_tag_raw(type_id)?; - let state = RevealedValue::with_blinding(value.into(), blinding, tag); - self.builder = self.builder.add_fungible_state_raw(type_id, seal, state)?; - Ok(self) - } - - pub fn add_data( + pub fn add_owned_state( mut self, name: impl Into, seal: impl Into>, value: impl StrictSerialize, ) -> Result { - self.builder = self.builder.add_data(name, seal, value)?; - Ok(self) - } - - pub fn add_data_det( - mut self, - name: impl Into, - seal: impl Into>, - data: RevealedData, - ) -> Result { - self.builder = self.builder.add_data_det(name, seal, data)?; + self.builder = self.builder.add_owned_state(name, seal, value)?; Ok(self) } - pub fn add_data_raw( - mut self, - type_id: AssignmentType, - seal: impl Into>, - allocation: impl Into, - blinding: u64, - ) -> Result { - let revealed_state = RevealedData::with_salt(allocation.into(), blinding.into()); - self.builder = self.builder.add_data_raw(type_id, seal, revealed_state)?; - Ok(self) - } - - pub fn add_data_default( + pub fn add_owned_state_default( self, seal: impl Into>, value: impl StrictSerialize, ) -> Result { let assignment_name = self.default_assignment()?.clone(); - self.add_data(assignment_name, seal.into(), value) - } - - pub fn add_attachment( - mut self, - name: impl Into, - seal: impl Into>, - attachment: AttachState, - ) -> Result { - self.builder = self.builder.add_attachment(name, seal, attachment)?; - Ok(self) - } - - pub fn add_attachment_det( - mut self, - name: impl Into, - seal: impl Into>, - attachment: RevealedAttach, - ) -> Result { - self.builder = self.builder.add_attachment_det(name, seal, attachment)?; - Ok(self) + self.add_owned_state(assignment_name, seal.into(), value) } pub fn has_inputs(&self) -> bool { !self.inputs.is_empty() } pub fn complete_transition(self) -> Result { - let (_, _, _, global, assignments, _, _) = self.builder.complete(Some(&self.inputs)); + let (_, _, _, global, assignments, _) = self.builder.complete(); let transition = Transition { ffv: none!(), @@ -828,17 +496,10 @@ pub struct OperationBuilder { schema: Schema, iface: Iface, iimpl: IfaceImpl, - asset_tags: AssetTags, - deterministic: bool, global: GlobalState, meta: Metadata, - rights: TinyOrdMap>, 1, U16>>, - fungible: - TinyOrdMap, RevealedValue>, 1, U16>>, - data: TinyOrdMap, RevealedData>, 1, U16>>, - attachments: - TinyOrdMap, RevealedAttach>, 1, U16>>, + assignments: Assignments, // TODO: add valencies types: TypeSystem, } @@ -849,34 +510,10 @@ impl OperationBuilder { schema, iface, iimpl, - asset_tags: none!(), - deterministic: false, global: none!(), + assignments: none!(), meta: none!(), - rights: none!(), - fungible: none!(), - attachments: none!(), - data: none!(), - - types, - } - } - - fn deterministic(iface: Iface, schema: Schema, iimpl: IfaceImpl, types: TypeSystem) -> Self { - OperationBuilder { - schema, - iface, - iimpl, - asset_tags: none!(), - deterministic: true, - - global: none!(), - meta: none!(), - rights: none!(), - fungible: none!(), - attachments: none!(), - data: none!(), types, } @@ -938,68 +575,6 @@ impl OperationBuilder { .expect("schema should match interface: must be checked by the constructor") } - pub fn asset_tag(&self, name: impl Into) -> Result { - let name = name.into(); - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name.clone()))?; - self.asset_tag_raw(type_id) - } - - #[inline] - fn asset_tag_raw(&self, type_id: AssignmentType) -> Result { - self.asset_tags - .get(&type_id) - .ok_or(BuilderError::AssetTagMissed(type_id)) - .copied() - } - - #[inline] - pub fn add_asset_tag( - self, - name: impl Into, - asset_tag: AssetTag, - ) -> Result { - let name = name.into(); - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; - - self.add_asset_tag_raw(type_id, asset_tag) - } - - #[inline] - pub fn add_asset_tag_raw( - mut self, - type_id: AssignmentType, - asset_tag: AssetTag, - ) -> Result { - if self.fungible.contains_key(&type_id) { - return Err(BuilderError::AssetTagAutomatic(type_id)); - } - - self.asset_tags.insert(type_id, asset_tag)?; - Ok(self) - } - - pub fn init_asset_tag(&mut self, name: impl Into) -> Result { - let name = name.into(); - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; - - if let Some(tag) = self.asset_tags.get(&type_id) { - Ok(*tag) - } else { - let asset_tag = AssetTag::new_random( - format!("{}/{}", self.schema.schema_id(), self.iface.iface_id()), - type_id, - ); - self.asset_tags.insert(type_id, asset_tag)?; - Ok(asset_tag) - } - } - pub fn add_metadata( mut self, name: impl Into, @@ -1038,411 +613,41 @@ impl OperationBuilder { Ok(self) } - fn add_owned_state_det( - self, - name: impl Into, - seal: impl Into>, - state: PersistedState, - ) -> Result { - debug_assert!( - self.deterministic, - "to add owned state in deterministic way the builder has to be created using \ - deterministic constructor" - ); - let name = name.into(); - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name.clone()))?; - self.add_owned_state_raw(type_id, seal, state) - } - fn add_owned_state_raw( - self, - type_id: AssignmentType, - seal: impl Into>, - state: PersistedState, - ) -> Result { - match state { - PersistedState::Void => self.add_rights_raw(type_id, seal), - PersistedState::Amount(value, blinding, tag) => { - if self.asset_tag_raw(type_id)? != tag { - return Err(BuilderError::AssetTagInvalid(type_id)); - } - - self.add_fungible_state_raw( - type_id, - seal, - RevealedValue::with_blinding(value, blinding, tag), - ) - } - PersistedState::Data(data, salt) => { - self.add_data_raw(type_id, seal, RevealedData::with_salt(data, salt)) - } - PersistedState::Attachment(attach, salt) => self.add_attachment_raw( - type_id, - seal, - RevealedAttach::with_salt(attach.id, attach.media_type, salt), - ), - } - } - - fn add_rights( - self, - name: impl Into, - seal: impl Into>, - ) -> Result { - let name = name.into(); - - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; - - self.add_rights_raw(type_id, seal) - } - - fn add_rights_raw( mut self, - type_id: AssignmentType, - seal: impl Into>, - ) -> Result { - let state_schema = self.state_schema(type_id); - if *state_schema != OwnedStateSchema::Declarative { - return Err(BuilderError::InvalidStateType(type_id)); - } - - let seal = seal.into(); - match self.rights.get_mut(&type_id) { - Some(assignments) => { - assignments.push(seal)?; - } - None => { - self.rights.insert(type_id, Confined::with(seal))?; - } - } - - Ok(self) - } - - fn add_fungible_state( - self, - name: impl Into, - seal: impl Into>, - value: impl Into, - ) -> Result { - debug_assert!( - !self.deterministic, - "for adding state to deterministic contracts you have to use add_*_det methods" - ); - - let name = name.into(); - - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; - let tag = self.asset_tag_raw(type_id)?; - - let state = RevealedValue::new_random_blinding(value.into(), tag); - self.add_fungible_state_raw(type_id, seal, state) - } - - fn add_fungible_state_det( - self, name: impl Into, seal: impl Into>, - state: RevealedValue, + state: State, ) -> Result { - debug_assert!( - self.deterministic, - "to add owned state in deterministic way the builder has to be created using \ - deterministic constructor" - ); - let name = name.into(); let type_id = self .assignments_type(&name) .ok_or(BuilderError::AssignmentNotFound(name))?; - self.add_fungible_state_raw(type_id, seal, state) - } - fn add_fungible_state_raw( - mut self, - type_id: AssignmentType, - seal: impl Into>, - state: RevealedValue, - ) -> Result { - let state_schema = self.state_schema(type_id); - if *state_schema != OwnedStateSchema::Fungible(FungibleType::Unsigned64Bit) { - return Err(BuilderError::InvalidStateType(type_id)); - } + let assignment = seal.into().assignment(state); - let seal = seal.into(); - match self.fungible.get_mut(&type_id) { - Some(assignments) => { - assignments.insert(seal, state)?; + match self.assignments.entry(type_id)? { + Entry::Vacant(entry) => { + entry.insert(TypedAssigns::with(assignment)); } - None => { - self.fungible - .insert(type_id, Confined::with((seal, state)))?; + Entry::Occupied(mut entry) => { + entry.get_mut().push(assignment)?; } } - Ok(self) } - fn add_data( + fn add_owned_state( self, name: impl Into, seal: impl Into>, value: impl StrictSerialize, ) -> Result { - debug_assert!( - !self.deterministic, - "for adding state to deterministic contracts you have to use add_*_det methods" - ); - - let name = name.into(); - let serialized = value.to_strict_serialized::()?; - let state = DataState::from(serialized); - - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; - - self.add_data_raw(type_id, seal, RevealedData::new_random_salt(state)) + self.add_owned_state_raw(name, seal, State::new(value)) } - fn add_data_det( - self, - name: impl Into, - seal: impl Into>, - state: RevealedData, - ) -> Result { - debug_assert!( - self.deterministic, - "to add owned state in deterministic way the builder has to be created using \ - deterministic constructor" - ); - - let name = name.into(); - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; - - self.add_data_raw(type_id, seal, state) - } - - fn add_data_raw( - mut self, - type_id: AssignmentType, - seal: impl Into>, - state: RevealedData, - ) -> Result { - let state_schema = self.state_schema(type_id); - if let OwnedStateSchema::Structured(_) = *state_schema { - let seal = seal.into(); - match self.data.get_mut(&type_id) { - Some(assignments) => { - assignments.insert(seal, state)?; - } - None => { - self.data.insert(type_id, Confined::with((seal, state)))?; - } - } - } else { - return Err(BuilderError::InvalidStateType(type_id)); - } - Ok(self) - } - - fn add_attachment( - self, - name: impl Into, - seal: impl Into>, - state: AttachState, - ) -> Result { - debug_assert!( - !self.deterministic, - "for adding state to deterministic contracts you have to use add_*_det methods" - ); - - let name = name.into(); - - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; - - self.add_attachment_raw( - type_id, - seal, - RevealedAttach::new_random_salt(state.id, state.media_type), - ) - } - - fn add_attachment_det( - self, - name: impl Into, - seal: impl Into>, - state: RevealedAttach, - ) -> Result { - debug_assert!( - self.deterministic, - "to add owned state in deterministic way the builder has to be created using \ - deterministic constructor" - ); - - let name = name.into(); - - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; - - self.add_attachment_raw(type_id, seal, state) - } - - fn add_attachment_raw( - mut self, - type_id: AssignmentType, - seal: impl Into>, - state: RevealedAttach, - ) -> Result { - let state_schema = self.state_schema(type_id); - if let OwnedStateSchema::Attachment(_) = *state_schema { - let seal = seal.into(); - match self.attachments.get_mut(&type_id) { - Some(assignments) => { - assignments.insert(seal, state)?; - } - None => { - self.attachments - .insert(type_id, Confined::with((seal, state)))?; - } - } - } else { - return Err(BuilderError::InvalidStateType(type_id)); - } - Ok(self) - } - - fn complete( - self, - inputs: Option<&TinyOrdMap>, - ) -> (Schema, Iface, IfaceImpl, GlobalState, Assignments, TypeSystem, AssetTags) { - let owned_state = self.fungible.into_iter().map(|(id, vec)| { - let mut blindings = Vec::with_capacity(vec.len()); - let mut vec = vec - .into_iter() - .map(|(seal, value)| { - blindings.push(value.blinding); - match seal { - BuilderSeal::Revealed(seal) => Assign::Revealed { - seal, - state: value, - lock: none!(), - }, - BuilderSeal::Concealed(seal) => Assign::ConfidentialSeal { - seal, - state: value, - lock: none!(), - }, - } - }) - .collect::>(); - if let Some(assignment) = vec.last_mut() { - blindings.pop(); - let state = assignment - .as_revealed_state_mut() - .expect("builder always operates revealed state"); - let mut inputs = inputs - .map(|i| { - i.iter() - .filter(|(out, _)| out.prev_out.ty == id) - .map(|(_, ts)| match ts { - PersistedState::Amount(_, blinding, _) => *blinding, - _ => panic!("previous state has invalid type"), - }) - .collect::>() - }) - .unwrap_or_default(); - if inputs.is_empty() { - inputs = vec![BlindingFactor::EMPTY]; - } - state.blinding = BlindingFactor::zero_balanced(inputs, blindings).expect( - "malformed set of blinding factors; probably random generator is broken", - ); - } - let state = Confined::try_from_iter(vec).expect("at least one element"); - let state = TypedAssigns::Fungible(state); - (id, state) - }); - let owned_data = self.data.into_iter().map(|(id, vec)| { - let vec_data = vec.into_iter().map(|(seal, value)| match seal { - BuilderSeal::Revealed(seal) => Assign::Revealed { - seal, - state: value, - lock: none!(), - }, - BuilderSeal::Concealed(seal) => Assign::ConfidentialSeal { - seal, - state: value, - lock: none!(), - }, - }); - let state_data = Confined::try_from_iter(vec_data).expect("at least one element"); - let state_data = TypedAssigns::Structured(state_data); - (id, state_data) - }); - let owned_rights = self.rights.into_iter().map(|(id, vec)| { - let vec_data = vec.into_iter().map(|seal| match seal { - BuilderSeal::Revealed(seal) => Assign::Revealed { - seal, - state: none!(), - lock: none!(), - }, - BuilderSeal::Concealed(seal) => Assign::ConfidentialSeal { - seal, - state: none!(), - lock: none!(), - }, - }); - let state_data = Confined::try_from_iter(vec_data).expect("at least one element"); - let state_data = TypedAssigns::Declarative(state_data); - (id, state_data) - }); - let owned_attachments = self.attachments.into_iter().map(|(id, vec)| { - let vec_data = vec.into_iter().map(|(seal, value)| match seal { - BuilderSeal::Revealed(seal) => Assign::Revealed { - seal, - state: value, - lock: none!(), - }, - BuilderSeal::Concealed(seal) => Assign::ConfidentialSeal { - seal, - state: value, - lock: none!(), - }, - }); - let state_data = Confined::try_from_iter(vec_data).expect("at least one element"); - let state_data = TypedAssigns::Attachment(state_data); - (id, state_data) - }); - - let owned_state = Confined::try_from_iter(owned_state).expect("same size"); - let owned_data = Confined::try_from_iter(owned_data).expect("same size"); - let owned_rights = Confined::try_from_iter(owned_rights).expect("same size"); - let owned_attachments = Confined::try_from_iter(owned_attachments).expect("same size"); - - let mut assignments = Assignments::from_inner(owned_state); - assignments - .extend(Assignments::from_inner(owned_data).into_inner()) - .expect("too many assignments"); - assignments - .extend(Assignments::from_inner(owned_rights).into_inner()) - .expect("too many assignments"); - assignments - .extend(Assignments::from_inner(owned_attachments).into_inner()) - .expect("too many assignments"); - - (self.schema, self.iface, self.iimpl, self.global, assignments, self.types, self.asset_tags) + fn complete(self) -> (Schema, Iface, IfaceImpl, GlobalState, Assignments, TypeSystem) { + (self.schema, self.iface, self.iimpl, self.global, self.assignments, self.types) } } diff --git a/src/interface/contract.rs b/src/interface/contract.rs index 2709a054..5f03b6d5 100644 --- a/src/interface/contract.rs +++ b/src/interface/contract.rs @@ -22,19 +22,14 @@ use std::borrow::Borrow; use std::collections::{BTreeSet, HashMap, HashSet}; -use invoice::{Allocation, Amount}; -use rgb::{ - AssignmentType, AttachState, ContractId, DataState, OpId, RevealedAttach, RevealedData, - RevealedValue, Schema, VoidState, XOutpoint, XOutputSeal, XWitnessId, -}; -use strict_encoding::{FieldName, StrictDecode, StrictDumb, StrictEncode}; +use rgb::{AssignmentType, ContractId, OpId, Schema, State, XOutputSeal, XWitnessId}; +use strict_encoding::FieldName; use strict_types::{StrictVal, TypeSystem}; -use crate::contract::{KnownState, OutputAssignment, WitnessInfo}; +use crate::contract::{OutputAssignment, WitnessInfo}; use crate::info::ContractInfo; use crate::interface::{AssignmentsFilter, IfaceImpl}; use crate::persistence::ContractStateRead; -use crate::LIB_NAME_RGB_STD; #[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] #[display(doc_comments)] @@ -43,58 +38,6 @@ pub enum ContractError { FieldNameUnknown(FieldName), } -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display, From)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_STD, tags = custom)] -#[display(inner)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub enum AllocatedState { - #[from(())] - #[from(VoidState)] - #[display("~")] - #[strict_type(tag = 0, dumb)] - Void, - - #[from] - #[from(RevealedValue)] - #[strict_type(tag = 1)] - Amount(Amount), - - #[from] - #[from(RevealedData)] - #[from(Allocation)] - #[strict_type(tag = 2)] - Data(DataState), - - #[from] - #[from(RevealedAttach)] - #[strict_type(tag = 3)] - Attachment(AttachState), -} - -impl KnownState for AllocatedState { - const IS_FUNGIBLE: bool = false; -} - -impl AllocatedState { - fn unwrap_fungible(&self) -> Amount { - match self { - AllocatedState::Amount(amount) => *amount, - _ => panic!("unwrapping non-fungible state"), - } - } -} - -pub type OwnedAllocation = OutputAssignment; -pub type RightsAllocation = OutputAssignment; -pub type FungibleAllocation = OutputAssignment; -pub type DataAllocation = OutputAssignment; -pub type AttachAllocation = OutputAssignment; - #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Display)] #[cfg_attr( feature = "serde", @@ -118,12 +61,12 @@ pub struct ContractOp { pub direction: OpDirection, pub ty: AssignmentType, pub opids: BTreeSet, - pub state: AllocatedState, + pub state: State, pub to: BTreeSet, pub witness: Option, } -fn reduce_to_ty(allocations: impl IntoIterator) -> AssignmentType { +fn reduce_to_ty(allocations: impl IntoIterator) -> AssignmentType { allocations .into_iter() .map(|a| a.opout.ty) @@ -135,9 +78,7 @@ fn reduce_to_ty(allocations: impl IntoIterator) -> Assig } impl ContractOp { - fn non_fungible_genesis( - our_allocations: HashSet, - ) -> impl ExactSizeIterator { + fn genesis(our_allocations: HashSet) -> impl ExactSizeIterator { our_allocations.into_iter().map(|a| Self { direction: OpDirection::Issued, ty: a.opout.ty, @@ -148,9 +89,9 @@ impl ContractOp { }) } - fn non_fungible_sent( + fn sent( witness: WitnessInfo, - ext_allocations: HashSet, + ext_allocations: HashSet, ) -> impl ExactSizeIterator { ext_allocations.into_iter().map(move |a| Self { direction: OpDirection::Sent, @@ -162,9 +103,9 @@ impl ContractOp { }) } - fn non_fungible_received( + fn received( witness: WitnessInfo, - our_allocations: HashSet, + our_allocations: HashSet, ) -> impl ExactSizeIterator { our_allocations.into_iter().map(move |a| Self { direction: OpDirection::Received, @@ -175,57 +116,6 @@ impl ContractOp { witness: Some(witness), }) } - - fn fungible_genesis(our_allocations: HashSet) -> Self { - let to = our_allocations.iter().map(|a| a.seal).collect(); - let opids = our_allocations.iter().map(|a| a.opout.op).collect(); - let issued = our_allocations - .iter() - .map(|a| a.state.unwrap_fungible()) - .sum(); - Self { - direction: OpDirection::Issued, - ty: reduce_to_ty(our_allocations), - opids, - state: AllocatedState::Amount(issued), - to, - witness: None, - } - } - - fn fungible_sent(witness: WitnessInfo, ext_allocations: HashSet) -> Self { - let opids = ext_allocations.iter().map(|a| a.opout.op).collect(); - let to = ext_allocations.iter().map(|a| a.seal).collect(); - let amount = ext_allocations - .iter() - .map(|a| a.state.unwrap_fungible()) - .sum(); - Self { - direction: OpDirection::Sent, - ty: reduce_to_ty(ext_allocations), - opids, - state: AllocatedState::Amount(amount), - to, - witness: Some(witness), - } - } - - fn fungible_received(witness: WitnessInfo, our_allocations: HashSet) -> Self { - let opids = our_allocations.iter().map(|a| a.opout.op).collect(); - let to = our_allocations.iter().map(|a| a.seal).collect(); - let amount = our_allocations - .iter() - .map(|a| a.state.unwrap_fungible()) - .sum(); - Self { - direction: OpDirection::Received, - ty: reduce_to_ty(our_allocations), - opids, - state: AllocatedState::Amount(amount), - to, - witness: Some(witness), - } - } } /// Contract state is an in-memory structure providing API to read structured @@ -272,148 +162,54 @@ impl ContractIface { })) } - fn extract_state<'c, A, U>( + pub fn assignments_by<'c>( &'c self, - state: impl IntoIterator> + 'c, - name: impl Into, filter: impl AssignmentsFilter + 'c, - ) -> Result> + 'c, ContractError> - where - A: Clone + KnownState + 'c, - U: From + KnownState + 'c, - { - Ok(self - .extract_state_unfiltered(state, name)? - .filter(move |outp| filter.should_include(outp.seal, outp.witness))) + ) -> impl Iterator + 'c { + self.state + .assignments() + .filter(move |outp| filter.should_include(outp.seal, outp.witness)) } - fn extract_state_unfiltered<'c, A, U>( + pub fn assignments_by_type<'c>( &'c self, - state: impl IntoIterator> + 'c, name: impl Into, - ) -> Result> + 'c, ContractError> - where - A: Clone + KnownState + 'c, - U: From + KnownState + 'c, - { + filter: impl AssignmentsFilter + 'c, + ) -> Result + 'c, ContractError> { let name = name.into(); let type_id = self .iface .assignments_type(&name) .ok_or(ContractError::FieldNameUnknown(name))?; - Ok(state - .into_iter() - .filter(move |outp| outp.opout.ty == type_id) - .cloned() - .map(OutputAssignment::::transmute)) - } - - pub fn rights<'c>( - &'c self, - name: impl Into, - filter: impl AssignmentsFilter + 'c, - ) -> Result + 'c, ContractError> { - self.extract_state(self.state.rights_all(), name, filter) - } - - pub fn fungible<'c>( - &'c self, - name: impl Into, - filter: impl AssignmentsFilter + 'c, - ) -> Result + 'c, ContractError> { - self.extract_state(self.state.fungible_all(), name, filter) - } - - pub fn data<'c>( - &'c self, - name: impl Into, - filter: impl AssignmentsFilter + 'c, - ) -> Result + 'c, ContractError> { - self.extract_state(self.state.data_all(), name, filter) - } - - pub fn attachments<'c>( - &'c self, - name: impl Into, - filter: impl AssignmentsFilter + 'c, - ) -> Result + 'c, ContractError> { - self.extract_state(self.state.attach_all(), name, filter) - } - - pub fn allocations<'c>( - &'c self, - filter: impl AssignmentsFilter + Copy + 'c, - ) -> impl Iterator + 'c { - fn f<'a, S, U>( - filter: impl AssignmentsFilter + 'a, - state: impl IntoIterator> + 'a, - ) -> impl Iterator> + 'a - where - S: Clone + KnownState + 'a, - U: From + KnownState + 'a, - { - state - .into_iter() - .filter(move |outp| filter.should_include(outp.seal, outp.witness)) - .cloned() - .map(OutputAssignment::::transmute) - } - - f(filter, self.state.rights_all()) - .map(OwnedAllocation::from) - .chain(f(filter, self.state.fungible_all()).map(OwnedAllocation::from)) - .chain(f(filter, self.state.data_all()).map(OwnedAllocation::from)) - .chain(f(filter, self.state.attach_all()).map(OwnedAllocation::from)) - } - - pub fn outpoint_allocations( - &self, - outpoint: XOutpoint, - ) -> impl Iterator + '_ { - self.allocations(outpoint) + Ok(self + .assignments_by(filter) + .filter(move |outp| outp.opout.ty == type_id)) } pub fn history( &self, - filter_outpoints: impl AssignmentsFilter + Clone, - filter_witnesses: impl AssignmentsFilter + Clone, - ) -> Vec { - self.history_fungible(filter_outpoints.clone(), filter_witnesses.clone()) - .into_iter() - .chain(self.history_rights(filter_outpoints.clone(), filter_witnesses.clone())) - .chain(self.history_data(filter_outpoints.clone(), filter_witnesses.clone())) - .chain(self.history_attach(filter_outpoints, filter_witnesses)) - .collect() - } - - fn operations<'c, T: KnownState + 'c, I: Iterator>>( - &'c self, - state: impl Fn(&'c S) -> I, filter_outpoints: impl AssignmentsFilter, filter_witnesses: impl AssignmentsFilter, - ) -> Vec - where - AllocatedState: From, - { + ) -> Vec { // get all allocations which ever belonged to this wallet and store them by witness id - let mut allocations_our_outpoint = state(&self.state) + let mut allocations_our_outpoint = self + .state + .assignments() .filter(move |outp| filter_outpoints.should_include(outp.seal, outp.witness)) .fold(HashMap::<_, HashSet<_>>::new(), |mut map, a| { - map.entry(a.witness) - .or_default() - .insert(a.clone().transmute::()); + map.entry(a.witness).or_default().insert(a.clone()); map }); // get all allocations which has a witness transaction belonging to this wallet - let mut allocations_our_witness = state(&self.state) + let mut allocations_our_witness = self + .state + .assignments() .filter(move |outp| filter_witnesses.should_include(outp.seal, outp.witness)) .fold(HashMap::<_, HashSet<_>>::new(), |mut map, a| { let witness = a.witness.expect( "all empty witnesses must be already filtered out by wallet.filter_witness()", ); - map.entry(witness) - .or_default() - .insert(a.clone().transmute::()); + map.entry(witness).or_default().insert(a.clone()); map }); @@ -427,12 +223,8 @@ impl ContractIface { // reconstruct contract history from the wallet perspective let mut ops = Vec::with_capacity(witness_ids.len() + 1); // add allocations with no witness to the beginning of the history - if let Some(genesis_allocations) = allocations_our_outpoint.remove(&None) { - if T::IS_FUNGIBLE { - ops.push(ContractOp::fungible_genesis(genesis_allocations)); - } else { - ops.extend(ContractOp::non_fungible_genesis(genesis_allocations)); - } + if let Some(genesis_state) = allocations_our_outpoint.remove(&None) { + ops.extend(ContractOp::genesis(genesis_state)); } for witness_id in witness_ids { let our_outpoint = allocations_our_outpoint.remove(&Some(witness_id)); @@ -444,38 +236,26 @@ impl ContractIface { // we own both allocation and witness transaction: these allocations are changes and // outgoing payments. The difference between the change and the payments are whether // a specific allocation is listed in the first tuple pattern field. - (Some(our_allocations), Some(all_allocations)) => { + (Some(our_assignments), Some(all_assignments)) => { // all_allocations - our_allocations = external payments - let ext_allocations = all_allocations - .difference(&our_allocations) + let ext_assignments = all_assignments + .difference(&our_assignments) .cloned() .collect::>(); // This was a blank state transition with no external payment - if ext_allocations.is_empty() { + if ext_assignments.is_empty() { continue; } - if T::IS_FUNGIBLE { - ops.push(ContractOp::fungible_sent(witness_info, ext_allocations)) - } else { - ops.extend(ContractOp::non_fungible_sent(witness_info, ext_allocations)) - } + ops.extend(ContractOp::sent(witness_info, ext_assignments)) } // the same as above, but the payment has no change - (None, Some(ext_allocations)) => { - if T::IS_FUNGIBLE { - ops.push(ContractOp::fungible_sent(witness_info, ext_allocations)) - } else { - ops.extend(ContractOp::non_fungible_sent(witness_info, ext_allocations)) - } + (None, Some(ext_assignments)) => { + ops.extend(ContractOp::sent(witness_info, ext_assignments)) } // we own allocation but the witness transaction was made by other wallet: // this is an incoming payment to us. - (Some(our_allocations), None) => { - if T::IS_FUNGIBLE { - ops.push(ContractOp::fungible_received(witness_info, our_allocations)) - } else { - ops.extend(ContractOp::non_fungible_received(witness_info, our_allocations)) - } + (Some(our_assignments), None) => { + ops.extend(ContractOp::received(witness_info, our_assignments)) } // these can't get into the `witness_ids` due to the used filters (None, None) => unreachable!("broken allocation filters"), @@ -485,38 +265,6 @@ impl ContractIface { ops } - pub fn history_fungible( - &self, - filter_outpoints: impl AssignmentsFilter, - filter_witnesses: impl AssignmentsFilter, - ) -> Vec { - self.operations(|state| state.fungible_all(), filter_outpoints, filter_witnesses) - } - - pub fn history_rights( - &self, - filter_outpoints: impl AssignmentsFilter, - filter_witnesses: impl AssignmentsFilter, - ) -> Vec { - self.operations(|state| state.rights_all(), filter_outpoints, filter_witnesses) - } - - pub fn history_data( - &self, - filter_outpoints: impl AssignmentsFilter, - filter_witnesses: impl AssignmentsFilter, - ) -> Vec { - self.operations(|state| state.data_all(), filter_outpoints, filter_witnesses) - } - - pub fn history_attach( - &self, - filter_outpoints: impl AssignmentsFilter, - filter_witnesses: impl AssignmentsFilter, - ) -> Vec { - self.operations(|state| state.attach_all(), filter_outpoints, filter_witnesses) - } - pub fn witness_info(&self, witness_id: XWitnessId) -> Option { let ord = self.state.witness_ord(witness_id)?; Some(WitnessInfo { diff --git a/src/interface/mod.rs b/src/interface/mod.rs index 496ce87e..e4bd759f 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -33,10 +33,7 @@ mod contractum; mod inheritance; pub use builder::{BuilderError, ContractBuilder, TransitionBuilder, TxOutpoint}; -pub use contract::{ - AllocatedState, AttachAllocation, ContractError, ContractIface, ContractOp, DataAllocation, - FungibleAllocation, OpDirection, OwnedAllocation, RightsAllocation, -}; +pub use contract::{ContractError, ContractIface, ContractOp, OpDirection}; pub use contractum::IfaceDisplay; pub use filter::{AssignmentsFilter, FilterExclude, FilterIncludeAll}; pub use iface::{ diff --git a/src/lib.rs b/src/lib.rs index d428aa06..a67d7a3d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,13 +46,10 @@ mod contract; pub mod info; pub use bp::{Outpoint, Txid}; -pub use contract::{ - KnownState, MergeReveal, MergeRevealError, OutputAssignment, TypedAssignsExt, WitnessInfo, -}; -pub use invoice::{Allocation, Amount, CoinAmount, OwnedFraction, Precision, TokenIndex}; +pub use contract::{MergeReveal, MergeRevealError, OutputAssignment, WitnessInfo}; pub use rgb::prelude::*; pub use rgb::rgbasm; -pub use stl::{LIB_NAME_RGB_CONTRACT, LIB_NAME_RGB_STD, LIB_NAME_RGB_STORAGE}; +pub use stl::{LIB_NAME_RGB_STD, LIB_NAME_RGB_STORAGE}; /// BIP32 derivation index for outputs which may contain assigned RGB state. pub const RGB_NATIVE_DERIVATION_INDEX: u32 = 9; diff --git a/src/persistence/index.rs b/src/persistence/index.rs index b07b831c..2f0ac19e 100644 --- a/src/persistence/index.rs +++ b/src/persistence/index.rs @@ -26,9 +26,8 @@ use std::fmt::Debug; use amplify::confinement; use nonasync::persistence::{CloneNoPersistence, Persisting}; use rgb::{ - Assign, AssignmentType, BundleId, ContractId, ExposedState, Extension, Genesis, GenesisSeal, - GraphSeal, OpId, Operation, Opout, TransitionBundle, TypedAssigns, XChain, XOutputSeal, - XWitnessId, + Assign, AssignmentType, BundleId, ContractId, Extension, Genesis, GenesisSeal, GraphSeal, OpId, + Operation, Opout, TransitionBundle, XChain, XOutputSeal, XWitnessId, }; use crate::containers::{ConsignmentExt, ToWitnessId, WitnessBundle}; @@ -185,25 +184,9 @@ impl Index

{ fn index_genesis(&mut self, id: ContractId, genesis: &Genesis) -> Result<(), IndexError

> { let opid = genesis.id(); - for (type_id, assign) in genesis.assignments.iter() { - match assign { - TypedAssigns::Declarative(vec) => { - self.provider - .index_genesis_assignments(id, vec, opid, *type_id)?; - } - TypedAssigns::Fungible(vec) => { - self.provider - .index_genesis_assignments(id, vec, opid, *type_id)?; - } - TypedAssigns::Structured(vec) => { - self.provider - .index_genesis_assignments(id, vec, opid, *type_id)?; - } - TypedAssigns::Attachment(vec) => { - self.provider - .index_genesis_assignments(id, vec, opid, *type_id)?; - } - } + for (type_id, assigns) in genesis.assignments.iter() { + self.provider + .index_genesis_assignments(id, assigns, opid, *type_id)?; } Ok(()) } @@ -214,25 +197,9 @@ impl Index

{ extension: &Extension, ) -> Result<(), IndexError

> { let opid = extension.id(); - for (type_id, assign) in extension.assignments.iter() { - match assign { - TypedAssigns::Declarative(vec) => { - self.provider - .index_genesis_assignments(id, vec, opid, *type_id)?; - } - TypedAssigns::Fungible(vec) => { - self.provider - .index_genesis_assignments(id, vec, opid, *type_id)?; - } - TypedAssigns::Structured(vec) => { - self.provider - .index_genesis_assignments(id, vec, opid, *type_id)?; - } - TypedAssigns::Attachment(vec) => { - self.provider - .index_genesis_assignments(id, vec, opid, *type_id)?; - } - } + for (type_id, assigns) in extension.assignments.iter() { + self.provider + .index_genesis_assignments(id, assigns, opid, *type_id)?; } Ok(()) } @@ -250,45 +217,14 @@ impl Index

{ for (opid, transition) in &bundle.known_transitions { self.provider.register_operation(*opid, bundle_id)?; - for (type_id, assign) in transition.assignments.iter() { - match assign { - TypedAssigns::Declarative(vec) => { - self.provider.index_transition_assignments( - contract_id, - vec, - *opid, - *type_id, - witness_id, - )?; - } - TypedAssigns::Fungible(vec) => { - self.provider.index_transition_assignments( - contract_id, - vec, - *opid, - *type_id, - witness_id, - )?; - } - TypedAssigns::Structured(vec) => { - self.provider.index_transition_assignments( - contract_id, - vec, - *opid, - *type_id, - witness_id, - )?; - } - TypedAssigns::Attachment(vec) => { - self.provider.index_transition_assignments( - contract_id, - vec, - *opid, - *type_id, - witness_id, - )?; - } - } + for (type_id, assigns) in transition.assignments.iter() { + self.provider.index_transition_assignments( + contract_id, + assigns, + *opid, + *type_id, + witness_id, + )?; } } @@ -413,18 +349,18 @@ pub trait IndexWriteProvider: StoreTransaction { bundle_id: BundleId, ) -> Result>; - fn index_genesis_assignments( + fn index_genesis_assignments( &mut self, contract_id: ContractId, - vec: &[Assign], + vec: &[Assign], opid: OpId, type_id: AssignmentType, ) -> Result<(), IndexWriteError>; - fn index_transition_assignments( + fn index_transition_assignments( &mut self, contract_id: ContractId, - vec: &[Assign], + vec: &[Assign], opid: OpId, type_id: AssignmentType, witness_id: XWitnessId, diff --git a/src/persistence/memory.rs b/src/persistence/memory.rs index 5b5d229e..1bd3098e 100644 --- a/src/persistence/memory.rs +++ b/src/persistence/memory.rs @@ -29,8 +29,8 @@ use std::{iter, mem}; use aluvm::library::{Lib, LibId}; use amplify::confinement::{ - self, Confined, LargeOrdMap, LargeOrdSet, MediumBlob, MediumOrdMap, MediumOrdSet, SmallOrdMap, - TinyOrdMap, TinyOrdSet, + self, Confined, LargeOrdMap, LargeOrdSet, MediumBlob, MediumOrdMap, MediumOrdSet, SmallBlob, + SmallOrdMap, TinyOrdMap, TinyOrdSet, }; use amplify::num::u24; use bp::dbc::tapret::TapretCommitment; @@ -42,11 +42,10 @@ use rgb::vm::{ OrdOpRef, UnknownGlobalStateType, WitnessOrd, }; use rgb::{ - Assign, AssignmentType, Assignments, AssignmentsRef, AttachId, AttachState, BundleId, - ContractId, DataState, ExposedSeal, ExposedState, Extension, FungibleState, Genesis, - GenesisSeal, GlobalStateType, GraphSeal, Identity, OpId, Operation, Opout, RevealedAttach, - RevealedData, RevealedValue, Schema, SchemaId, SecretSeal, Transition, TransitionBundle, - TypedAssigns, VoidState, XChain, XOutpoint, XOutputSeal, XWitnessId, + Assign, AssignmentType, Assignments, AssignmentsRef, AttachId, BundleId, ContractId, + ExposedSeal, Extension, Genesis, GenesisSeal, GlobalStateType, GraphSeal, Identity, OpId, + Operation, Opout, Schema, SchemaId, SecretSeal, Transition, TransitionBundle, XChain, + XOutpoint, XOutputSeal, XWitnessId, }; use strict_encoding::{StrictDeserialize, StrictSerialize}; use strict_types::TypeSystem; @@ -61,7 +60,7 @@ use super::{ use crate::containers::{ AnchorSet, ContentId, ContentRef, ContentSigs, SealWitness, SigBlob, Supplement, TrustLevel, }; -use crate::contract::{GlobalOut, KnownState, OpWitness, OutputAssignment}; +use crate::contract::{GlobalOut, OpWitness, OutputAssignment}; use crate::interface::{Iface, IfaceClass, IfaceId, IfaceImpl, IfaceRef}; use crate::LIB_NAME_RGB_STORAGE; @@ -566,10 +565,7 @@ impl StateReadProvider for MemState { .values() .flat_map(|state| state.known.keys()) .any(|out| out.witness_id() == id) - || unfiltered.rights.iter().any(|a| a.witness == id) - || unfiltered.fungibles.iter().any(|a| a.witness == id) - || unfiltered.data.iter().any(|a| a.witness == id) - || unfiltered.attach.iter().any(|a| a.witness == id) + || unfiltered.state.iter().any(|a| a.witness == id) }) .map(|(id, ord)| (*id, *ord)) .collect(); @@ -684,7 +680,7 @@ impl StateWriteProvider for MemState { #[strict_type(lib = LIB_NAME_RGB_STORAGE)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] pub struct MemGlobalState { - known: LargeOrdMap, + known: LargeOrdMap, limit: u24, } @@ -721,10 +717,7 @@ pub struct MemContractState { contract_id: ContractId, #[getter(skip)] global: TinyOrdMap, - rights: LargeOrdSet>, - fungibles: LargeOrdSet>, - data: LargeOrdSet>, - attach: LargeOrdSet>, + state: LargeOrdSet, } impl MemContractState { @@ -739,10 +732,7 @@ impl MemContractState { schema_id: schema.schema_id(), contract_id, global, - rights: empty!(), - fungibles: empty!(), - data: empty!(), - attach: empty!(), + state: empty!(), } } @@ -817,46 +807,30 @@ impl MemContractState { opid: OpId, assignments: &Assignments, ) { - fn process( - contract_state: &mut LargeOrdSet>, - assignments: &[Assign], - opid: OpId, - ty: AssignmentType, - witness_id: Option, - ) { + for (ty, assignments) in assignments.iter() { for (no, seal, state) in assignments .iter() .enumerate() - .filter_map(|(n, a)| a.to_revealed().map(|(seal, state)| (n, seal, state))) + .filter_map(|(n, a)| a.revealed_seal().map(|seal| (n, seal, a.as_state()))) { let assigned_state = match witness_id { - Some(witness_id) => { - OutputAssignment::with_witness(seal, witness_id, state, opid, ty, no as u16) + Some(witness_id) => OutputAssignment::with_witness( + seal, + witness_id, + state.clone(), + opid, + *ty, + no as u16, + ), + None => { + OutputAssignment::with_no_witness(seal, state.clone(), opid, *ty, no as u16) } - None => OutputAssignment::with_no_witness(seal, state, opid, ty, no as u16), }; - contract_state + self.state .push(assigned_state) .expect("contract state exceeded 2^32 items, which is unrealistic"); } } - - for (ty, assignments) in assignments.iter() { - match assignments { - TypedAssigns::Declarative(assignments) => { - process(&mut self.rights, assignments, opid, *ty, witness_id) - } - TypedAssigns::Fungible(assignments) => { - process(&mut self.fungibles, assignments, opid, *ty, witness_id) - } - TypedAssigns::Structured(assignments) => { - process(&mut self.data, assignments, opid, *ty, witness_id) - } - TypedAssigns::Attachment(assignments) => { - process(&mut self.attach, assignments, opid, *ty, witness_id) - } - } - } } } @@ -876,12 +850,12 @@ impl> ContractStateAccess for MemContract { &self, ty: GlobalStateType, ) -> Result, UnknownGlobalStateType> { - type Src<'a> = &'a BTreeMap; - type FilteredIter<'a> = Box + 'a>; + type Src<'a> = &'a BTreeMap; + type FilteredIter<'a> = Box + 'a>; struct Iter<'a> { src: Src<'a>, iter: FilteredIter<'a>, - last: Option<(GlobalOrd, &'a DataState)>, + last: Option<(GlobalOrd, &'a SmallBlob)>, depth: u24, constructor: Box) -> FilteredIter<'a> + 'a>, } @@ -893,7 +867,7 @@ impl> ContractStateAccess for MemContract { } } impl<'a> GlobalStateIter for Iter<'a> { - type Data = &'a DataState; + type Data = &'a SmallBlob; fn size(&mut self) -> u24 { let iter = self.swap(); // TODO: Consuming iterator just to count items is highly inefficient, but I do @@ -964,64 +938,20 @@ impl> ContractStateAccess for MemContract { Ok(GlobalContractState::new(iter)) } - fn rights(&self, outpoint: XOutpoint, ty: AssignmentType) -> u32 { - self.unfiltered - .borrow() - .rights - .iter() - .filter(|assignment| { - assignment.seal.to_outpoint() == outpoint && assignment.opout.ty == ty - }) - .filter(|assignment| assignment.check_witness(&self.filter)) - .count() as u32 - } - - fn fungible( - &self, - outpoint: XOutpoint, - ty: AssignmentType, - ) -> impl DoubleEndedIterator { - self.unfiltered - .borrow() - .fungibles - .iter() - .filter(move |assignment| { - assignment.seal.to_outpoint() == outpoint && assignment.opout.ty == ty - }) - .filter(|assignment| assignment.check_witness(&self.filter)) - .map(|assignment| assignment.state.value) - } - - fn data( - &self, - outpoint: XOutpoint, - ty: AssignmentType, - ) -> impl DoubleEndedIterator> { - self.unfiltered - .borrow() - .data - .iter() - .filter(move |assignment| { - assignment.seal.to_outpoint() == outpoint && assignment.opout.ty == ty - }) - .filter(|assignment| assignment.check_witness(&self.filter)) - .map(|assignment| &assignment.state.value) - } - - fn attach( + fn state( &self, outpoint: XOutpoint, ty: AssignmentType, - ) -> impl DoubleEndedIterator> { + ) -> impl DoubleEndedIterator> { self.unfiltered .borrow() - .attach + .state .iter() .filter(move |assignment| { assignment.seal.to_outpoint() == outpoint && assignment.opout.ty == ty }) .filter(|assignment| assignment.check_witness(&self.filter)) - .map(|assignment| &assignment.state.file) + .map(|assignment| &assignment.state) } } @@ -1088,37 +1018,10 @@ impl> ContractStateRead for MemContract { } #[inline] - fn rights_all(&self) -> impl Iterator> { - self.unfiltered - .borrow() - .rights - .iter() - .filter(|assignment| assignment.check_witness(&self.filter)) - } - - #[inline] - fn fungible_all(&self) -> impl Iterator> { - self.unfiltered - .borrow() - .fungibles - .iter() - .filter(|assignment| assignment.check_witness(&self.filter)) - } - - #[inline] - fn data_all(&self) -> impl Iterator> { + fn assignments(&self) -> impl Iterator { self.unfiltered .borrow() - .data - .iter() - .filter(|assignment| assignment.check_witness(&self.filter)) - } - - #[inline] - fn attach_all(&self) -> impl Iterator> { - self.unfiltered - .borrow() - .attach + .state .iter() .filter(|assignment| assignment.check_witness(&self.filter)) } @@ -1419,10 +1322,10 @@ impl IndexWriteProvider for MemIndex { Ok(!present) } - fn index_genesis_assignments( + fn index_genesis_assignments( &mut self, contract_id: ContractId, - vec: &[Assign], + assignments: &[Assign], opid: OpId, type_id: AssignmentType, ) -> Result<(), IndexWriteError> { @@ -1431,31 +1334,28 @@ impl IndexWriteProvider for MemIndex { .get_mut(&contract_id) .ok_or(IndexInconsistency::ContractAbsent(contract_id))?; - for (no, assign) in vec.iter().enumerate() { + for (no, assign) in assignments.iter().enumerate() { let opout = Opout::new(opid, type_id, no as u16); - if let Assign::ConfidentialState { seal, .. } | Assign::Revealed { seal, .. } = assign { + if let Assign::Revealed { seal, .. } = assign { let output = seal .to_output_seal() .expect("genesis seals always have outpoint"); - match index.outpoint_opouts.get_mut(&output) { - Some(opouts) => { - opouts.push(opout)?; - } - None => { - index.outpoint_opouts.insert(output, medium_bset!(opout))?; - } - } + index + .outpoint_opouts + .entry(output)? + .or_default() + .push(opout)?; } } // We need two cycles due to the borrow checker - self.extend_terminals(vec, opid, type_id) + self.extend_terminals(assignments, opid, type_id) } - fn index_transition_assignments( + fn index_transition_assignments( &mut self, contract_id: ContractId, - vec: &[Assign], + assignments: &[Assign], opid: OpId, type_id: AssignmentType, witness_id: XWitnessId, @@ -1465,44 +1365,38 @@ impl IndexWriteProvider for MemIndex { .get_mut(&contract_id) .ok_or(IndexInconsistency::ContractAbsent(contract_id))?; - for (no, assign) in vec.iter().enumerate() { + for (no, assign) in assignments.iter().enumerate() { let opout = Opout::new(opid, type_id, no as u16); - if let Assign::ConfidentialState { seal, .. } | Assign::Revealed { seal, .. } = assign { + if let Assign::Revealed { seal, .. } = assign { let output = seal.try_to_output_seal(witness_id).unwrap_or_else(|_| { panic!( - "chain mismatch between assignment vout seal ({}) and witness transaction \ - ({})", - seal, witness_id + "chain mismatch between assignment vout seal {seal} and witness \ + transaction {witness_id}", ) }); - match index.outpoint_opouts.get_mut(&output) { - Some(opouts) => { - opouts.push(opout)?; - } - None => { - index.outpoint_opouts.insert(output, medium_bset!(opout))?; - } - } + index + .outpoint_opouts + .entry(output)? + .or_default() + .push(opout)?; } } // We need two cycles due to the borrow checker - self.extend_terminals(vec, opid, type_id) + self.extend_terminals(assignments, opid, type_id) } } impl MemIndex { - fn extend_terminals( + fn extend_terminals( &mut self, - vec: &[Assign], + vec: &[Assign], opid: OpId, type_id: AssignmentType, ) -> Result<(), IndexWriteError> { for (no, assign) in vec.iter().enumerate() { let opout = Opout::new(opid, type_id, no as u16); - if let Assign::Confidential { seal, .. } | Assign::ConfidentialSeal { seal, .. } = - assign - { + if let Assign::Confidential { seal, .. } = assign { self.add_terminal(*seal, opout)?; } } diff --git a/src/persistence/mod.rs b/src/persistence/mod.rs index 321f7b14..c92c389a 100644 --- a/src/persistence/mod.rs +++ b/src/persistence/mod.rs @@ -51,8 +51,8 @@ pub use stash::{ StashInconsistency, StashProvider, StashReadProvider, StashWriteProvider, }; pub use state::{ - ContractStateRead, ContractStateWrite, PersistedState, State, StateError, StateInconsistency, - StateProvider, StateReadProvider, StateWriteProvider, + ContractStateRead, ContractStateWrite, State, StateError, StateInconsistency, StateProvider, + StateReadProvider, StateWriteProvider, }; pub use stock::{ ComposeError, ConsignError, ContractIfaceError, FasciaError, InputError as StockInputError, diff --git a/src/persistence/stash.rs b/src/persistence/stash.rs index c42764e9..c1b3e083 100644 --- a/src/persistence/stash.rs +++ b/src/persistence/stash.rs @@ -299,6 +299,7 @@ impl Stash

{ ) -> Result<(TypeSystem, Scripts), StashError

> { let type_iter = schema .types() + .into_iter() .chain(ifaces.into_iter().flat_map(Iface::types)); let types = self .provider @@ -355,11 +356,10 @@ impl Stash

{ let iimpl = schema_ifaces .get(iface.iface_id()) .ok_or(StashDataError::NoIfaceImpl(schema.schema_id(), iface.iface_id()))?; - let genesis = self.provider.genesis(contract_id)?; let (types, _) = self.extract(&schema_ifaces.schema, [iface])?; - let mut builder = if let Some(transition_name) = transition_name { + let builder = if let Some(transition_name) = transition_name { TransitionBuilder::named_transition( contract_id, iface.clone(), @@ -379,12 +379,6 @@ impl Stash

{ } .expect("internal inconsistency"); - for (assignment_type, asset_tag) in genesis.asset_tags.iter() { - builder = builder - .add_asset_tag_raw(*assignment_type, *asset_tag) - .expect("tags are in bset and must not repeat"); - } - Ok(builder) } @@ -399,11 +393,9 @@ impl Stash

{ if schema_ifaces.iimpls.is_empty() { return Err(StashDataError::NoIfaceImpl(schema.schema_id(), iface.iface_id()).into()); } - let genesis = self.provider.genesis(contract_id)?; - let (types, _) = self.extract(&schema_ifaces.schema, [iface])?; - let mut builder = if let Some(iimpl) = schema_ifaces.get(iface.iface_id()) { + let builder = if let Some(iimpl) = schema_ifaces.get(iface.iface_id()) { TransitionBuilder::blank_transition( contract_id, iface.clone(), @@ -424,11 +416,6 @@ impl Stash

{ types, ) }; - for (assignment_type, asset_tag) in genesis.asset_tags.iter() { - builder = builder - .add_asset_tag_raw(*assignment_type, *asset_tag) - .expect("tags are in bset and must not repeat"); - } Ok(builder) } diff --git a/src/persistence/state.rs b/src/persistence/state.rs index 4e8c21d8..9545b776 100644 --- a/src/persistence/state.rs +++ b/src/persistence/state.rs @@ -25,14 +25,12 @@ use std::error::Error; use std::fmt::Debug; use std::iter; -use invoice::Amount; use nonasync::persistence::{CloneNoPersistence, Persisting}; use rgb::validation::{ResolveWitness, WitnessResolverError}; use rgb::vm::{ContractStateAccess, WitnessOrd}; use rgb::{ - AssetTag, AttachState, BlindingFactor, ContractId, DataState, Extension, Genesis, Operation, - RevealedAttach, RevealedData, RevealedValue, Schema, SchemaId, Transition, TransitionBundle, - VoidState, XWitnessId, + ContractId, Extension, Genesis, Operation, Schema, SchemaId, Transition, TransitionBundle, + XWitnessId, }; use crate::containers::{ConsignmentExt, ToWitnessId}; @@ -74,27 +72,6 @@ pub enum StateInconsistency { AbsentWitness(XWitnessId), } -#[derive(Clone, Eq, PartialEq, Debug, Hash)] -pub enum PersistedState { - Void, - Amount(Amount, BlindingFactor, AssetTag), - // TODO: Use RevealedData - Data(DataState, u128), - // TODO: Use RevealedAttach - Attachment(AttachState, u64), -} - -impl PersistedState { - pub(crate) fn update_blinding(&mut self, blinding: BlindingFactor) { - match self { - PersistedState::Void => {} - PersistedState::Amount(_, b, _) => *b = blinding, - PersistedState::Data(_, _) => {} - PersistedState::Attachment(_, _) => {} - } - } -} - #[derive(Debug)] pub struct State { provider: P, @@ -309,10 +286,7 @@ pub trait ContractStateRead: ContractStateAccess { fn contract_id(&self) -> ContractId; fn schema_id(&self) -> SchemaId; fn witness_ord(&self, witness_id: XWitnessId) -> Option; - fn rights_all(&self) -> impl Iterator>; - fn fungible_all(&self) -> impl Iterator>; - fn data_all(&self) -> impl Iterator>; - fn attach_all(&self) -> impl Iterator>; + fn assignments(&self) -> impl Iterator; } pub trait ContractStateWrite { diff --git a/src/persistence/stock.rs b/src/persistence/stock.rs index 4b778ca1..a295c74a 100644 --- a/src/persistence/stock.rs +++ b/src/persistence/stock.rs @@ -31,22 +31,21 @@ use bp::dbc::Method; use bp::seals::txout::CloseMethod; use bp::Vout; use chrono::Utc; -use invoice::{Amount, Beneficiary, InvoiceState, NonFungible, RgbInvoice}; +use invoice::{Beneficiary, InvoiceState, RgbInvoice}; use nonasync::persistence::{CloneNoPersistence, PersistenceError, PersistenceProvider}; use rgb::validation::{DbcProof, ResolveWitness, WitnessResolverError}; use rgb::{ - validation, AssignmentType, BlindingFactor, BundleId, ContractId, DataState, GraphSeal, - Identity, OpId, Operation, Opout, SchemaId, SecretSeal, Transition, TxoSeal, XChain, XOutpoint, - XOutputSeal, XWitnessId, + validation, AssignmentType, BundleId, ContractId, GraphSeal, Identity, OpId, Operation, Opout, + SchemaId, SecretSeal, Transition, TxoSeal, XChain, XOutpoint, XOutputSeal, XWitnessId, }; use strict_encoding::FieldName; use super::{ ContractStateRead, Index, IndexError, IndexInconsistency, IndexProvider, IndexReadProvider, - IndexWriteProvider, MemIndex, MemStash, MemState, PersistedState, SchemaIfaces, Stash, - StashDataError, StashError, StashInconsistency, StashProvider, StashReadProvider, - StashWriteProvider, State, StateError, StateInconsistency, StateProvider, StateReadProvider, - StateWriteProvider, StoreTransaction, + IndexWriteProvider, MemIndex, MemStash, MemState, SchemaIfaces, Stash, StashDataError, + StashError, StashInconsistency, StashProvider, StashReadProvider, StashWriteProvider, State, + StateError, StateInconsistency, StateProvider, StateReadProvider, StateWriteProvider, + StoreTransaction, }; use crate::containers::{ AnchorSet, AnchoredBundleMismatch, Batch, BuilderSeal, ClientBundle, Consignment, ContainerVer, @@ -62,7 +61,7 @@ use crate::interface::{ }; use crate::MergeRevealError; -pub type ContractAssignments = HashMap>; +pub type ContractAssignments = HashMap>; #[derive(Debug, Display, Error, From)] #[display(inner)] @@ -617,48 +616,14 @@ impl Stock { let state = self.contract_state(contract_id)?; let mut res = - HashMap::>::with_capacity(outputs.len()); + HashMap::>::with_capacity(outputs.len()); - for item in state.fungible_all() { - let outpoint = item.seal.into(); - if outputs.contains::(&outpoint) { - res.entry(item.seal).or_default().insert( - item.opout, - PersistedState::Amount( - item.state.value.into(), - item.state.blinding, - item.state.tag, - ), - ); - } - } - - for item in state.data_all() { - let outpoint = item.seal.into(); - if outputs.contains::(&outpoint) { - res.entry(item.seal).or_default().insert( - item.opout, - PersistedState::Data(item.state.value.clone(), item.state.salt), - ); - } - } - - for item in state.rights_all() { + for item in state.assignments() { let outpoint = item.seal.into(); if outputs.contains::(&outpoint) { res.entry(item.seal) .or_default() - .insert(item.opout, PersistedState::Void); - } - } - - for item in state.attach_all() { - let outpoint = item.seal.into(); - if outputs.contains::(&outpoint) { - res.entry(item.seal).or_default().insert( - item.opout, - PersistedState::Attachment(item.state.clone().into(), item.state.salt), - ); + .insert(item.opout, item.state.clone()); } } @@ -783,7 +748,7 @@ impl Stock { // 2. Collect secret seals from terminal transitions to add to the consignment terminals for typed_assignments in transition.assignments.values() { for index in 0..typed_assignments.len_u16() { - let seal = typed_assignments.to_confidential_seals()[index as usize]; + let seal = typed_assignments.confidential_seals()[index as usize]; if secret_seal == Some(seal) { let res = terminals.insert(bundle_id, seal); assert_eq!(res, None); @@ -920,7 +885,6 @@ impl Stock { beneficiary_vout, u64::MAX, allocator, - |_, _| BlindingFactor::random(), |_, _| rand::random(), ) } @@ -937,7 +901,6 @@ impl Stock { beneficiary_vout: Option>, priority: u64, allocator: impl Fn(ContractId, AssignmentType, VelocityHint) -> Option, - pedersen_blinder: impl Fn(ContractId, AssignmentType) -> BlindingFactor, seal_blinder: impl Fn(ContractId, AssignmentType) -> u64, ) -> Result> { let layer1 = invoice.layer1(); @@ -1153,7 +1116,7 @@ impl Stock { // 3. Prepare other transitions // Enumerate state let mut spent_state = - HashMap::>>::new(); + HashMap::>>::new(); for id in self.contracts_assigning(prev_outputs.iter().copied())? { // Skip current contract if id == contract_id { diff --git a/src/stl/stl.rs b/src/stl.rs similarity index 54% rename from src/stl/stl.rs rename to src/stl.rs index c0243564..1ebfc6a6 100644 --- a/src/stl/stl.rs +++ b/src/stl.rs @@ -19,38 +19,44 @@ // See the License for the specific language governing permissions and // limitations under the License. +use amplify::IoError; +use baid64::Baid64ParseError; pub use bp::bc::stl::bp_tx_stl; pub use bp::stl::bp_core_stl; -#[allow(unused_imports)] pub use commit_verify::stl::{commit_verify_stl, LIB_ID_COMMIT_VERIFY}; -use invoice::{Allocation, Amount}; pub use rgb::stl::{aluvm_stl, rgb_commit_stl, rgb_logic_stl, LIB_ID_RGB_COMMIT, LIB_ID_RGB_LOGIC}; use strict_types::stl::{std_stl, strict_types_stl}; -use strict_types::typesys::SystemBuilder; -use strict_types::{CompileError, LibBuilder, SemId, SymbolicSys, TypeLib, TypeSystem}; +use strict_types::{typesys, CompileError, LibBuilder, TypeLib}; -use super::{ - AssetSpec, BurnMeta, ContractSpec, ContractTerms, Error, IssueMeta, MediaType, - LIB_NAME_RGB_CONTRACT, LIB_NAME_RGB_STORAGE, -}; use crate::containers::{Contract, Kit, Transfer}; use crate::persistence::{MemIndex, MemStash, MemState}; -use crate::stl::ProofOfReserves; -use crate::LIB_NAME_RGB_STD; -/// Strict types id for the library providing standard data types which may be -/// used in RGB smart contracts. -pub const LIB_ID_RGB_STORAGE: &str = - "stl:mG$H7b6I-$T8qp18-07PSNeA-rbEBNS5-$J5X4y0-1vPxRWg#channel-vortex-bandit"; +pub const LIB_NAME_RGB_STD: &str = "RGBStd"; +pub const LIB_NAME_RGB_STORAGE: &str = "RGBStorage"; /// Strict types id for the library providing standard data types which may be /// used in RGB smart contracts. -pub const LIB_ID_RGB_CONTRACT: &str = - "stl:!r5yXt4a-v3XXv0M-E9Z6eoh-BFZweik-fxS6CB4-8AaO!MM#rover-annual-disney"; +pub const LIB_ID_RGB_STORAGE: &str = + "stl:iayFnuhB-sjXxWhi-Pp!FSyO-astclK4-icTXDwX-O0Fb4F4#floor-avatar-lazarus"; /// Strict types id for the library representing of RGB StdLib data types. pub const LIB_ID_RGB_STD: &str = - "stl:JhUC5JgH-Kwps4cO-ZNUklUj-UP6boFp-OY!18Kx-xOSJaVQ#hair-magnum-helena"; + "stl:vdvotNKl-wGrtjuT-Q4qXt4U-UVQlDMB-ONCuwLd-ORBWRTw#zebra-twist-tango"; + +#[allow(dead_code)] +#[derive(Debug, From)] +pub enum Error { + #[from(std::io::Error)] + Io(IoError), + #[from] + Baid64(Baid64ParseError), + #[from] + Compile(CompileError), + #[from] + Link1(typesys::Error), + #[from] + Link2(Vec), +} fn _rgb_std_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_RGB_STD), tiny_bset! { @@ -69,23 +75,6 @@ fn _rgb_std_stl() -> Result { .compile() } -fn _rgb_contract_stl() -> Result { - LibBuilder::new(libname!(LIB_NAME_RGB_CONTRACT), tiny_bset! { - std_stl().to_dependency(), - bp_tx_stl().to_dependency() - }) - .transpile::() - .transpile::() - .transpile::() - .transpile::() - .transpile::() - .transpile::() - .transpile::() - .transpile::() - .transpile::() - .compile() -} - fn _rgb_storage_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_RGB_STORAGE), tiny_bset! { std_stl().to_dependency(), @@ -107,65 +96,16 @@ fn _rgb_storage_stl() -> Result { /// Generates strict type library representation of RGB StdLib data types. pub fn rgb_std_stl() -> TypeLib { _rgb_std_stl().expect("invalid strict type RGBStd library") } -/// Generates strict type library providing standard data types which may be -/// used in RGB smart contracts. -pub fn rgb_contract_stl() -> TypeLib { - _rgb_contract_stl().expect("invalid strict type RGBContract library") -} - /// Generates strict type library providing standard storage for state, contract /// state and index. pub fn rgb_storage_stl() -> TypeLib { _rgb_storage_stl().expect("invalid strict type RGBStorage library") } -#[derive(Debug)] -pub struct StandardTypes(SymbolicSys); - -impl Default for StandardTypes { - fn default() -> Self { StandardTypes::new() } -} - -impl StandardTypes { - pub fn new() -> Self { - Self::try_with([std_stl(), bp_tx_stl(), rgb_contract_stl()]) - .expect("error in standard RGBContract type system") - } - - pub fn with(lib: TypeLib) -> Self { - Self::try_with([std_stl(), bp_tx_stl(), rgb_contract_stl(), lib]) - .expect("error in standard RGBContract type system") - } - - #[allow(clippy::result_large_err)] - fn try_with(libs: impl IntoIterator) -> Result { - let mut builder = SystemBuilder::new(); - for lib in libs.into_iter() { - builder = builder.import(lib)?; - } - let sys = builder.finalize()?; - Ok(Self(sys)) - } - - pub fn type_system(&self) -> TypeSystem { self.0.as_types().clone() } - - pub fn get(&self, name: &'static str) -> SemId { - *self.0.resolve(name).unwrap_or_else(|| { - panic!("type '{name}' is absent in standard RGBContract type library") - }) - } -} - #[cfg(test)] mod test { use super::*; - #[test] - fn contract_lib_id() { - let lib = rgb_contract_stl(); - assert_eq!(lib.id().to_string(), LIB_ID_RGB_CONTRACT); - } - #[test] fn std_lib_id() { let lib = rgb_std_stl(); diff --git a/src/stl/chain.rs b/src/stl/chain.rs deleted file mode 100644 index b3d055c3..00000000 --- a/src/stl/chain.rs +++ /dev/null @@ -1,56 +0,0 @@ -// RGB standard library for working with smart contracts on Bitcoin & Lightning -// -// 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. -// -// 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 amplify::confinement::SmallBlob; -use amplify::ByteArray; -use bp::{Outpoint, Txid}; -use strict_encoding::{StrictDeserialize, StrictSerialize}; -use strict_types::StrictVal; - -use super::LIB_NAME_RGB_CONTRACT; - -#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, From)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT, dumb = ProofOfReserves::new(strict_dumb!(), strict_dumb!()))] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -pub struct ProofOfReserves { - pub utxo: Outpoint, - pub proof: SmallBlob, -} -impl StrictSerialize for ProofOfReserves {} -impl StrictDeserialize for ProofOfReserves {} - -impl ProofOfReserves { - pub fn new(utxo: Outpoint, proof: SmallBlob) -> ProofOfReserves { - ProofOfReserves { utxo, proof } - } - - pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { - let utxo = value.unwrap_struct("utxo"); - let txid = Txid::from_slice_unsafe(utxo.unwrap_struct("txid").unwrap_bytes()); - let vout: u32 = utxo.unwrap_struct("vout").unwrap_uint(); - let utxo = Outpoint::new(txid, vout); - - let proof = SmallBlob::from_checked(value.unwrap_struct("proof").unwrap_bytes().into()); - - Self { utxo, proof } - } -} diff --git a/src/stl/error.rs b/src/stl/error.rs deleted file mode 100644 index 72f9767c..00000000 --- a/src/stl/error.rs +++ /dev/null @@ -1,39 +0,0 @@ -// RGB standard library for working with smart contracts on Bitcoin & Lightning -// -// 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. -// -// 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 amplify::IoError; -use baid64::Baid64ParseError; -use strict_types::{typesys, CompileError}; - -#[allow(dead_code)] -#[derive(Debug, From)] -pub(super) enum Error { - #[from(std::io::Error)] - Io(IoError), - #[from] - Baid64(Baid64ParseError), - #[from] - Compile(CompileError), - #[from] - Link1(typesys::Error), - #[from] - Link2(Vec), -} diff --git a/src/stl/mime.rs b/src/stl/mime.rs deleted file mode 100644 index 4f9c2188..00000000 --- a/src/stl/mime.rs +++ /dev/null @@ -1,214 +0,0 @@ -// RGB standard library for working with smart contracts on Bitcoin & Lightning -// -// 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. -// -// 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. - -#![allow(unused_braces)] - -use std::fmt::{self, Debug}; -use std::str::FromStr; - -use strict_encoding::stl::AlphaSmall; -use strict_encoding::{ - RString, RestrictedCharSet, StrictDeserialize, StrictDumb, StrictEncode, StrictSerialize, -}; -use strict_types::StrictVal; - -use super::LIB_NAME_RGB_CONTRACT; - -#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Debug, Hash)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -pub struct MediaType { - #[strict_type(rename = "type")] - #[cfg_attr(feature = "serde", serde(rename = "type"))] - pub ty: MediaRegName, - pub subtype: Option, - pub charset: Option, -} -impl StrictDumb for MediaType { - fn strict_dumb() -> Self { MediaType::with("text/plain") } -} -impl StrictSerialize for MediaType {} -impl StrictDeserialize for MediaType {} - -impl MediaType { - /// # Safety - /// - /// Panics is the provided string is an invalid type specifier. - pub fn with(s: &'static str) -> Self { - let (ty, subty) = s.split_once('/').expect("invalid static media type string"); - MediaType { - ty: MediaRegName::from(ty), - subtype: if subty == "*" { None } else { Some(MediaRegName::from(subty)) }, - charset: None, - } - } - - pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { - let ty = MediaRegName::from_strict_val_unchecked(value.unwrap_struct("type")); - let subtype = value - .unwrap_struct("subtype") - .unwrap_option() - .map(MediaRegName::from_strict_val_unchecked); - let charset = value - .unwrap_struct("charset") - .unwrap_option() - .map(MediaRegName::from_strict_val_unchecked); - Self { - ty, - subtype, - charset, - } - } -} - -impl fmt::Display for MediaType { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!( - f, - "{}/{}", - self.ty, - if let Some(subty) = &self.subtype { subty.to_string() } else { s!("*") } - ) - } -} - -#[derive(Wrapper, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, From)] -#[wrapper(Deref, Display, FromStr)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT, dumb = { MediaRegName::from("dumb") })] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct MediaRegName(RString); - -impl_ident_type!(MediaRegName); -impl_ident_subtype!(MediaRegName); - -impl MediaRegName { - pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { - MediaRegName::from_str(&value.unwrap_string()).expect("invalid media reg name") - } -} - -#[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)] -#[derive(StrictDumb, StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT, tags = repr, into_u8, try_from_u8)] -#[display(inner)] -#[repr(u8)] -#[allow(non_camel_case_types)] -pub enum MimeChar { - #[display("!")] - Excl = b'!', - #[display("#")] - Hash = b'#', - #[display("$")] - Dollar = b'$', - #[display("&")] - Amp = b'&', - #[display("+")] - Plus = b'+', - #[display("-")] - Dash = b'-', - #[display(".")] - Dot = b'.', - #[display("0")] - Zero = b'0', - #[display("1")] - One = b'1', - #[display("2")] - Two = b'2', - #[display("3")] - Three = b'3', - #[display("4")] - Four = b'4', - #[display("5")] - Five = b'5', - #[display("6")] - Six = b'6', - #[display("7")] - Seven = b'7', - #[display("8")] - Eight = b'8', - #[display("9")] - Nine = b'9', - #[display("^")] - Caret = b'^', - #[display("_")] - Lodash = b'_', - #[strict_type(dumb)] - #[display("a")] - a = b'a', - #[display("b")] - b = b'b', - #[display("c")] - c = b'c', - #[display("d")] - d = b'd', - #[display("e")] - e = b'e', - #[display("f")] - f = b'f', - #[display("g")] - g = b'g', - #[display("h")] - h = b'h', - #[display("i")] - i = b'i', - #[display("j")] - j = b'j', - #[display("k")] - k = b'k', - #[display("l")] - l = b'l', - #[display("m")] - m = b'm', - #[display("n")] - n = b'n', - #[display("o")] - o = b'o', - #[display("p")] - p = b'p', - #[display("q")] - q = b'q', - #[display("r")] - r = b'r', - #[display("s")] - s = b's', - #[display("t")] - t = b't', - #[display("u")] - u = b'u', - #[display("v")] - v = b'v', - #[display("w")] - w = b'w', - #[display("x")] - x = b'x', - #[display("y")] - y = b'y', - #[display("z")] - z = b'z', -} - -impl RestrictedCharSet for MimeChar {} diff --git a/src/stl/mod.rs b/src/stl/mod.rs deleted file mode 100644 index d2d84c82..00000000 --- a/src/stl/mod.rs +++ /dev/null @@ -1,44 +0,0 @@ -// RGB standard library for working with smart contracts on Bitcoin & Lightning -// -// 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. -// -// 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. - -mod specs; -#[allow(clippy::module_inception)] -mod stl; -mod error; -mod mime; -mod chain; - -pub use chain::ProofOfReserves; -use error::Error; -pub use invoice::LIB_NAME_RGB_CONTRACT; -pub use mime::{MediaRegName, MediaType}; -pub use specs::{ - Article, AssetSpec, Attachment, BurnMeta, ContractSpec, ContractTerms, Details, IssueMeta, - Name, RicardianContract, Ticker, -}; -pub use stl::{ - aluvm_stl, bp_core_stl, bp_tx_stl, commit_verify_stl, rgb_commit_stl, rgb_contract_stl, - rgb_logic_stl, rgb_std_stl, rgb_storage_stl, StandardTypes, LIB_ID_RGB_COMMIT, - LIB_ID_RGB_CONTRACT, LIB_ID_RGB_LOGIC, LIB_ID_RGB_STD, LIB_ID_RGB_STORAGE, -}; - -pub const LIB_NAME_RGB_STD: &str = "RGBStd"; -pub const LIB_NAME_RGB_STORAGE: &str = "RGBStorage"; diff --git a/src/stl/specs.rs b/src/stl/specs.rs deleted file mode 100644 index f51afc5d..00000000 --- a/src/stl/specs.rs +++ /dev/null @@ -1,410 +0,0 @@ -// RGB standard library for working with smart contracts on Bitcoin & Lightning -// -// 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. -// -// 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. - -#![allow(unused_braces)] // caused by rustc unable to understand strict_dumb - -use std::fmt::{self, Debug, Formatter}; -use std::hash::{Hash, Hasher}; -use std::str::FromStr; - -use amplify::confinement::{Confined, NonEmptyString, SmallOrdSet, SmallString, U8}; -use amplify::Bytes32; -use invoice::Precision; -use strict_encoding::stl::{Alpha, AlphaNum, AsciiPrintable}; -use strict_encoding::{ - InvalidRString, RString, StrictDeserialize, StrictDumb, StrictEncode, StrictSerialize, - StrictType, -}; -use strict_types::StrictVal; - -use super::{MediaType, ProofOfReserves, LIB_NAME_RGB_CONTRACT}; - -#[derive(Clone, Eq, PartialEq, Hash, Debug, Default)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub struct BurnMeta { - pub burn_proofs: SmallOrdSet, -} -impl StrictSerialize for BurnMeta {} -impl StrictDeserialize for BurnMeta {} - -#[derive(Clone, Eq, PartialEq, Hash, Debug, Default)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub struct IssueMeta { - pub reserves: SmallOrdSet, -} -impl StrictSerialize for IssueMeta {} -impl StrictDeserialize for IssueMeta {} - -#[derive(Wrapper, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, From)] -#[wrapper(Deref, Display, FromStr)] -#[derive(StrictDumb, StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT, dumb = { Article::from("DUMB") })] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct Article(RString); - -impl_ident_type!(Article); -impl_ident_subtype!(Article); - -#[derive(Wrapper, Clone, Ord, PartialOrd, Eq, From)] -#[wrapper(Deref, Display, FromStr)] -#[derive(StrictDumb, StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT, dumb = { Ticker::from("DUMB") })] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct Ticker(RString); - -impl PartialEq for Ticker { - fn eq(&self, other: &Self) -> bool { - self.as_str() - .to_uppercase() - .eq(&other.as_str().to_uppercase()) - } -} - -impl Hash for Ticker { - fn hash(&self, state: &mut H) { self.as_str().to_uppercase().hash(state) } -} - -impl_ident_type!(Ticker); -impl_ident_subtype!(Ticker); - -#[derive(Wrapper, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, From)] -#[wrapper(Deref, Display, FromStr)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct Name(RString); - -impl StrictSerialize for Name {} -impl StrictDeserialize for Name {} - -impl_ident_type!(Name); -impl_ident_subtype!(Name); - -impl Name { - pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { - Name::from_str(&value.unwrap_string()).unwrap() - } -} - -#[derive(Wrapper, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, From)] -#[wrapper(Deref, Display)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct Details(NonEmptyString); -impl StrictSerialize for Details {} -impl StrictDeserialize for Details {} - -impl AsRef for Details { - #[inline] - fn as_ref(&self) -> &str { self.0.as_str() } -} - -impl Details { - pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { - Details::from_str(&value.unwrap_string()).unwrap() - } -} - -impl StrictDumb for Details { - fn strict_dumb() -> Self { - Self(Confined::try_from(s!("Dumb long description which is stupid and so on...")).unwrap()) - } -} - -impl FromStr for Details { - type Err = InvalidRString; - - fn from_str(s: &str) -> Result { - let s = Confined::try_from_iter(s.chars())?; - Ok(Self(s)) - } -} - -impl From<&'static str> for Details { - fn from(s: &'static str) -> Self { Self::from_str(s).expect("invalid details") } -} - -impl TryFrom for Details { - type Error = InvalidRString; - - fn try_from(name: String) -> Result { - let s = Confined::try_from(name)?; - Ok(Self(s)) - } -} - -impl Debug for Details { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - f.debug_tuple("ContractDetails") - .field(&self.as_str()) - .finish() - } -} - -#[derive(Clone, Eq, PartialEq, Hash, Debug)] -#[derive(StrictDumb, StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub struct AssetSpec { - pub ticker: Ticker, - pub name: Name, - pub details: Option

, - pub precision: Precision, -} -impl StrictSerialize for AssetSpec {} -impl StrictDeserialize for AssetSpec {} - -impl AssetSpec { - pub fn new(ticker: &'static str, name: &'static str, precision: Precision) -> AssetSpec { - AssetSpec { - ticker: Ticker::from(ticker), - name: Name::from(name), - details: None, - precision, - } - } - - pub fn with( - ticker: &str, - name: &str, - precision: Precision, - details: Option<&str>, - ) -> Result { - Ok(AssetSpec { - ticker: Ticker::try_from(ticker.to_owned())?, - name: Name::try_from(name.to_owned())?, - details: details.map(Details::from_str).transpose()?, - precision, - }) - } - - pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { - let ticker = value.unwrap_struct("ticker").unwrap_string(); - let name = value.unwrap_struct("name").unwrap_string(); - let details = value - .unwrap_struct("details") - .unwrap_option() - .map(StrictVal::unwrap_string); - let precision = value.unwrap_struct("precision").unwrap_enum(); - Self { - ticker: Ticker::from_str(&ticker).expect("invalid asset ticker"), - name: Name::from_str(&name).expect("invalid asset name"), - details: details - .as_deref() - .map(Details::from_str) - .transpose() - .expect("invalid asset details"), - precision, - } - } - - pub fn ticker(&self) -> &str { self.ticker.as_str() } - - pub fn name(&self) -> &str { self.name.as_str() } - - pub fn details(&self) -> Option<&str> { self.details.as_ref().map(|d| d.as_str()) } -} - -#[derive(Clone, Eq, PartialEq, Hash, Debug)] -#[derive(StrictDumb, StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub struct ContractSpec { - pub article: Option
, - pub name: Name, - pub details: Option
, - pub precision: Precision, -} -impl StrictSerialize for ContractSpec {} -impl StrictDeserialize for ContractSpec {} - -impl ContractSpec { - pub fn new(name: &'static str, precision: Precision) -> ContractSpec { - ContractSpec { - article: None, - name: Name::from(name), - details: None, - precision, - } - } - - pub fn with( - article: &str, - name: &str, - precision: Precision, - details: Option<&str>, - ) -> Result { - Ok(ContractSpec { - article: Some(Article::try_from(article.to_owned())?), - name: Name::try_from(name.to_owned())?, - details: details.map(Details::from_str).transpose()?, - precision, - }) - } - - pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { - let article = value.unwrap_struct("article").unwrap_option(); - let name = value.unwrap_struct("name").unwrap_string(); - let details = value - .unwrap_struct("details") - .unwrap_option() - .map(StrictVal::unwrap_string); - let precision = value.unwrap_struct("precision").unwrap_enum(); - Self { - article: article.map(|val| { - Article::from_str(&val.unwrap_string()).expect("invalid contract article") - }), - name: Name::from_str(&name).expect("invalid contract name"), - details: details - .as_deref() - .map(Details::from_str) - .transpose() - .expect("invalid contract details"), - precision, - } - } - - pub fn article(&self) -> Option<&str> { self.article.as_ref().map(|a| a.as_str()) } - - pub fn name(&self) -> &str { self.name.as_str() } - - pub fn details(&self) -> Option<&str> { self.details.as_ref().map(|d| d.as_str()) } -} - -#[derive(Clone, Eq, PartialEq, Hash, Debug, Display, Default)] -#[display(inner)] -#[derive(StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", transparent) -)] -pub struct RicardianContract(SmallString); -impl StrictSerialize for RicardianContract {} -impl StrictDeserialize for RicardianContract {} - -impl AsRef for RicardianContract { - #[inline] - fn as_ref(&self) -> &str { self.0.as_str() } -} - -impl FromStr for RicardianContract { - type Err = InvalidRString; - - fn from_str(s: &str) -> Result { - let s = Confined::try_from_iter(s.chars())?; - Ok(Self(s)) - } -} - -#[derive(Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub struct Attachment { - #[strict_type(rename = "type")] - #[cfg_attr(feature = "serde", serde(rename = "type"))] - pub ty: MediaType, - pub digest: Bytes32, -} -impl StrictSerialize for Attachment {} -impl StrictDeserialize for Attachment {} - -impl Attachment { - pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { - let ty = MediaType::from_strict_val_unchecked(value.unwrap_struct("type")); - let digest = value - .unwrap_struct("digest") - .unwrap_bytes() - .try_into() - .expect("invalid digest"); - Self { ty, digest } - } -} - -#[derive(Clone, Eq, PartialEq, Hash, Debug)] -#[derive(StrictDumb, StrictType, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_CONTRACT)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub struct ContractTerms { - pub text: RicardianContract, - pub media: Option, -} -impl StrictSerialize for ContractTerms {} -impl StrictDeserialize for ContractTerms {} - -impl ContractTerms { - pub fn from_strict_val_unchecked(value: &StrictVal) -> Self { - let text = RicardianContract::from_str(&value.unwrap_struct("text").unwrap_string()) - .expect("invalid text"); - let media = value - .unwrap_struct("media") - .unwrap_option() - .map(Attachment::from_strict_val_unchecked); - Self { text, media } - } -} diff --git a/stl/RGBContract@0.11.0.sta b/stl/RGBContract@0.11.0.sta deleted file mode 100644 index 50e247d3..00000000 --- a/stl/RGBContract@0.11.0.sta +++ /dev/null @@ -1,52 +0,0 @@ ------BEGIN STRICT TYPE LIB----- -Id: stl:!r5yXt4a-v3XXv0M-E9Z6eoh-BFZweik-fxS6CB4-8AaO!MM#rover-annual-disney -Name: RGBContract -Dependencies: - Std#ralph-blue-lucky, - Bitcoin#signal-color-cipher -Check-SHA256: 6347d5f0a4c36a074fd3b6abb98041f64798a4a233e1742a352edc330dddbf3d - -3sOfyLvL<$a$#e10?I5NZ-bfLFbqC#o>4E?M+l67UG^w8*<_XZ#%uyqCj(P-Wc6$lVk7oBr%DNv+($;q -`HHK!gIHa)*%m(-e#9sm3I{@IbYpL6ZUP5FX>?<6X>J1mA>%$n#j0HLDJN5-IKgM_J7b(p+0MPGk2Gl) -y2(Rz1Xgc#bfbbo^UK%K(4i9Ajp1M~R@C@!4#dQE#lUD;OiKi1Rs>XdX=LbXK+Rkw`Mu(V|7oQWGN(Z+ -AyvH&RuaL#N1_Q*>km07$+g7b@t4MVjY>G@u4Q3HlB(d+LiLJm-R=h;`?dxDG*c -V`*tna%paKVPb4$UtT8V#RWVYMMP0s#-L?ApehHE`!Nx1aisd$7U5G>2tjOcXkkuuZGt0!^mXvL0b>G|!UaKWaA;xq7YGF1t^|4b)vt7`JJJH?>OpeZskt`?6&l-r#0;SdL2Phn -VN-2kY-|(&3PEgaZ)0I}X>V=?0s&*k#ka7f`< -Z^7s3P_GJP!FFFM4E? -M+l67UG^w8*<_XZ#%uyqCxRn@^mXvL0b>G|!T<;Y$}AplgPGkh3_fq3 -Q7_j=2#kPT_9!;lWR>~GYywm#UtT8V#RWVYMMP0s#-L?ApehHE`!Nx1aisd$7U5G>00000000009{>OV -000002|;snWpq<;Wn%^e26Sm-Yh`i)TX!suv0v9m0LPL+_79KRH|I99{YEOV7tT#ZPWpkW1a4t%WdVR* -#k^Az$U%@qU7>2Bz={du0O&G0&#r1CLJBFZ06hm}WprU_Y;ynv0ssVVZ*FA(00035b8l^B00jX7KPz&# -#IG7-47St%2#c>Z5R>jkTb_MKDq#SE1Nsg8a>I`c#0nSFF19TD^=GS9xE -uuG0V@n0eeL3DIsV`yzV!Z000000RR600000001QKKZgg^CV{}t+Wn%^e2Vrt_X=7|<00aU61a5C`WdHyG0R(ezZDjxj0ReXZ -@I5NQHT;&p7LREnfs~VQpmrfL_JCQxeEQkVIXfYN5c23F83hGCI$$Y9m4l -DXjoK2V`Y*VQFl000aU61a5C`WdHyG0R(ezZDjxj0RcZNa<{~<8ep?nYaleMc%`0D|O6 -*W?Lsa%E#_b7^mG0bK*c7mcZoem^?%L*to!bRZoO^d~aUzM`;8jz95VA`L@tZgg^CV{}wya&2=40t9qr -cys|6%am^tlg}6qop{{FTg974FaQ3n`}K{nn9PGH_DcZ;ZDnL>VE_aI00eGtZe;)f009JZZ*64&1pxs= -s(;1y^<+=wqOM*VsgOd=>xYy=<4kft^@4w~Gv0~^L}hegX>4-^0RRX90RaF2000000RI300000000~KR -b9H4+WprT%0SIzsb7gXNWpe-t0S?j{I~j%e^V!Z000000RR60 -0000001QoKWNBeiWoJ%dZDj=k00ja9$}AplgPGkh3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#`4m;t2@#H=ITLm*{QiV2NfFIf5Z%-00;p*(W0Hqt(%d1CNN)#sHFQL7%(bMbH%I*cn#*O0A6zd00000 -0000#0000000009O=VnH0sEektM3d!V}qV`yP= -b7gb@1OfmAZf|a7000011aog~WdH>M0UWS(jugTGj1K^e=F-$2o*6gc%@3Ir#hQL8;m&)Yy9iBbZDm7f -VR8d41Z8+*Y#{__VRL9B24rt+Y+-UF17U4&CIoP7b#p5OWMOk?Edyk4bS?yXWpZyY18;6+F#~jWZ!!gR -XmVv`GX!RDb#gQWW@&b1H3M^Lcs2!dWp-t5Hw9&BXJ~Xd1a4_=WjO_7VRB`3UIuJ$WMOk?UjboZ0b*hS -V`BkiWC3Mm0cK_aXJ-LuXaQ+y0cvUiYij{)YyoX;0d8&qZ*Ku`Z~<{~0djHyb8`W7bOCjB0d{r)cXt7J -cma8N0eX4_PGN0j1pxpB0s_h`9&dx0-7pM3Z=O*v*GCA9fL-<|HrZsA`NnJlR3}KjBNr;@ghiU?gEXK9 -KMDE{F?;HZBRuDVqlk6qmbd^20?I5NZ-bfLFbqC#o>4E?M+l67UG^w8*<_XZ#%uyqCrG{{7b@t4MVjY> -G@u4Q3HlB(d+LiLJm-R=h;`?dxBvhE0000004D$d0000001Z!fZe?Ufa$#e1X>V=?0RR992~cunV`+0~ -Z*Bt<3u$g-X?AIIX<}?;00d-ZV`%{eV`Xl1X#xdpX>4q10|{hhV`)ukY;0)+3S(t%bZJd#Y;0)-1#M|# -a&HC+WMyM%O=)9tZwCrvWo~q7O=)9tZwLf#VQy~;2xMhrX-;8oZwd)xWo~q7PGN3u3j}a!V{Z%yWMyM% -P-$at4GCjqZggo-X=85=1!iS!bZ-v{WMyM%MrCbuZx9M&Wo~q7MrCbuZxIAxbaZbL4^VP%Z)Q(sQe|^x -a&~2N1_A_iba-z9^=uPjBlbC`N(qzPM@Gr{imSMTSY5T*7C#t%#3&jH=xRXCTqXIv;)MTcr4cfxK`S9u -y$)6q!N22#m0-mN1#oh2Z)N}p002M$0000000030{{R300000HQfXsha%5>?ZbNTwbaG*1bOiwb2mk>9 -0000000030{{R3000006RB2;tWpV`p00ja9$}AplgPGkh3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#f+K+R -b@1)9wcJs8k=}EVt)knrbu3HL<`ZBK}4mD(Ht7Eb~PSIG^Pk1R1r{!lqsV^M5AQ(;7`h`rTmdf|Cw**^?URB z9pCFAOJk#=Sw`S+LXcgWG@32hb!Up(e0E>TH3V`pqVY?_P+D9EG%{QItTi6eAk|a>T!Vezf)Q%16P0 zsRw2?nwcWIau+nN9N%~5w+;Q&7hYk9v=jZ8o$*NbZup^n!}e8Hg(^uDjMC2q zo2MuecQ(K$q-(>X-JK=VD;1IIXC716+}{*1x3l=b$71J>(;ix$pr~X{Qoyrmn3Xx< zt`(d6=AwluE6!KKd6gl`EzhTV8S)Q4YZ=j&x=f{|je0y$G!zG{e0Gt4K%q6TA|qe`K~zdDCr|_pr58-* zGRLmYhNxVca1}?yxyCr3YAw%0A=L;81*(u-&4V0RQ81~zE~_~fx$vpB*K_mD@Xnbh zUc`hP_qm#|DDl|`hfxMMK(Id3`hBYRkJ^fb8T)hh*Kbs}BVA#0nvUiML}`L+k$FlI z3OGgc2r5HRhGn4iM}YFI0U{UxkrTO7mScW|+t)w$t2P~*F?8!6F)Q}1jSaz(;*Q15 z9cm*735u6e0y5+lpR(%mqR2UqquY0_6~>P8dJ-7cbhheve0k)bS#N8!f`Aix17rk+ z3>6BE5Y)N1zFa@H_Secws$l=*n!33u38vN*eZ$3ktg0wSw@N`$Igl3+C4wv%i>RVR zj!BTbRRB%41d}l!V z`}-ZpZJ?VS@l@iD%Fzf*JH2w_W2doJ+YJfU)DbFDXZIgr6i~~9$*GYQuwO_ z5Pf)^wYP^%x?6QL)33TBsEPH!2r83P|c56#}GgvM*<-5%pr8 z7oj6-Dh~3HGr`x&S%S^Or7$N^D(bi+V zk+&YvnBDKyAep@LFi4~msO?^)NwuqxJ4*Pi<6`;nb4aNtQhM+DjnVr?hPO3(?iz00 zT@>7Qbxq}WN?y#i)%vSr>r$K0OOy zjvI^5Jg}zfr0{HHiN=KuzEE*_{_T+YJ(tXmnNJQ5$Jrn zClxS|jIrGjZ1c%BRMg1>+$bM5gkng_BoU=FLlKmeI1^xm#DtU#Gf*^5$;gN+Bq_nM3a3 - Copyright (C) 2023-2024 LNP/BP Standards Association. All rights reserved. - License: Apache-2.0 --} - -@context -typelib RGBContract - -import Std#ralph-blue-lucky - use AsciiPrintable#ultra-sunset-format - use AlphaNum#window-tractor-alamo - use Alpha#citizen-bicycle-stretch - use AlphaSmall#magnum-martin-soviet - -import Bitcoin#signal-color-cipher - use Vout#brush-gloria-heroic - use Txid#shallow-light-reverse - use Outpoint#logo-alamo-madam - - -@mnemonic(blonde-slang-mobile) -data Allocation : TokenIndex, OwnedFraction - -@mnemonic(monica-tornado-page) -data Amount : U64 - -@mnemonic(infant-father-exhibit) -data Article : Std.Alpha, [Std.AlphaNum ^ ..0x1f] - -@mnemonic(alaska-archive-mailbox) -data AssetSpec : ticker Ticker - , name Name - , details Details? - , precision Precision - -@mnemonic(mono-bagel-falcon) -data Attachment : type MediaType, digest [Byte ^ 32] - -@mnemonic(ivory-speed-finish) -data BurnMeta : burnProofs {ProofOfReserves} - -@mnemonic(hawaii-winter-orca) -data ContractSpec : article Article? - , name Name - , details Details? - , precision Precision - -@mnemonic(voodoo-toga-meaning) -data ContractTerms : text RicardianContract, media Attachment? - -@mnemonic(trivial-halt-nobody) -data Details : [Unicode ^ 1..0xff] - -@mnemonic(alias-analog-icon) -data IssueMeta : reserves {ProofOfReserves} - -@mnemonic(taboo-pogo-exile) -data MediaRegName : Std.AlphaSmall, [MimeChar ^ ..0x3f] - -@mnemonic(brother-burma-book) -data MediaType : type MediaRegName - , subtype MediaRegName? - , charset MediaRegName? - -@mnemonic(amber-alarm-satire) -data MimeChar : excl#33 | hash#35 | dollar | amp#38 - | plus#43 | dash#45 | dot | zero#48 - | one | two | three | four - | five | six | seven | eight - | nine | caret#94 | lodash | a#97 - | b | c | d | e - | f | g | h | i - | j | k | l | m - | n | o | p | q - | r | s | t | u - | v | w | x | y - | z - - -@mnemonic(lexicon-monitor-madonna) -data Name : Std.AsciiPrintable, [Std.AsciiPrintable ^ ..0x27] - -@mnemonic(mission-person-armor) -data OwnedFraction : U64 - -@mnemonic(vendor-anita-british) -data Precision : indivisible | deci | centi | milli - | deciMilli | centiMilli | micro | deciMicro - | centiMicro | nano | deciNano | centiNano - | pico | deciPico | centiPico | femto - | deciFemto | centiFemto | atto - - -@mnemonic(harmony-dolby-golf) -data ProofOfReserves : utxo Bitcoin.Outpoint, proof [Byte] - -@mnemonic(bernard-right-pablo) -data RicardianContract : [Unicode] - -@mnemonic(newton-corona-aloha) -data Ticker : Std.Alpha, [Std.AlphaNum ^ ..0x7] - -@mnemonic(giraffe-correct-modest) -data TokenIndex : U32 - - diff --git a/stl/RGBStd@0.11.0.sta b/stl/RGBStd@0.11.0.sta index 5c9d924c..f1d81936 100644 --- a/stl/RGBStd@0.11.0.sta +++ b/stl/RGBStd@0.11.0.sta @@ -1,20 +1,20 @@ -----BEGIN STRICT TYPE LIB----- -Id: stl:JhUC5JgH-Kwps4cO-ZNUklUj-UP6boFp-OY!18Kx-xOSJaVQ#hair-magnum-helena +Id: stl:vdvotNKl-wGrtjuT-Q4qXt4U-UVQlDMB-ONCuwLd-ORBWRTw#zebra-twist-tango Name: RGBStd Dependencies: - RGBCommit#harvest-person-orion, StrictTypes#century-comrade-chess, BPCore#austin-story-retro, AluVM#congo-archive-folio, CommitVerify#miller-pancake-elastic, + RGBCommit#printer-window-alpine, Std#ralph-blue-lucky, Bitcoin#signal-color-cipher -Check-SHA256: 6a9228bc3dd61ed396d19a0d3e71c3a3dfc999d232e57ec13c1488bb0b6eeb91 +Check-SHA256: 9c8622031666c98c3fbaacf4d05380087e07145e9901c83988c8071f09cd9cca -22w{tQ*>kpAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{j2~tNwLvL+uX>>*EqhH(h&*4NaBbD49mT$3z|G4nQgoFBhHh%l@K06L}1!AJ%| -P(yEWWnyqOe<9`Lptgpr6F_xjAC6(~TLj#*ewiHU&X!byiJ!10COKearHwcS=7M7YzYaI8*bv -hMOc?)(rkC#nUDXLvL+uX>?X)a%pCH$}AplgPGkh3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#15kpMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r3sZD*X=8L$d2nTORuk6O)Q5AKbFW;J +EQ>MoHhG*Mzd(pEtONi$rOUxc20~CnZ*pZ~a5aA+<>R2XhQO_4{AcS-HH^7AVzASV8M4NYxyCjHL2Pwa +O?m?z-)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OCJaMwZEb0ER%LQ&W_hoT#`k1y;WQvCHXeDDEB)y- +4aXJJr*xW72o5QK9=-`uM?ynyZEb0E$}AplgPGkh3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#15DT%6aZ| SrJerP1pIOD57`7Ol|-ogQ6Pjg~y>s-v>!^VNPLfWv4Jz0xkJm$nc4yMWR2J-cc#Q6SofWC)gp7L6!Sc @@ -43,239 +43,228 @@ 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 -Z0H=mhJ>?uV^xB4~9n`Dx!RtcK)nwJGn -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 -wgM1*ibOB -_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jgmDd%EKc;pw+KsVi?D}qDSkO*B!5Mb*xG|_(S5o&00;m8 -KmY&$000000RR900000000000000000RR6000000019(yXKrD1b#i5M015%()D=(>(T2L(qY0=?Nz4Ev5gyU5%_yeyFzybaG*C -b7p070?I5NZ-bfLFbqC#o>4E?M+l67UG^w8*<_XZ#%uyqCt-#n(R;4&W&+>mb;*F>vukd;=m`ygb@x#_ ->`RmOO$l^ma&2jDVQg~%3IZTkC#?5~OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#i;{(leIk>g)RqK0VQ|M -wn6X+txo3vSYd;;z)HQ~0$c(hS0}9Zh)e@b7^w|AXg`>_lQgbaV_>=c$Ts04O39g -2dD_h*R5>c*5<{j?6T%|znQ^KeoD%bg94CLCf*q;P?fLY7qq^#2NiM*3T1e7Wo~n6Z*Fq{2?8KjC#?5~ -OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#i>)L^XdU9;lkvmMR*4bh)jz;q`~Q5Z+&x=I0QQSl+6GD00000 -00960|Nj60000MKb#7#AWpe-t0nT^OmoUfeVvhY+ARw!>`>M$upk~C-sV(3xjy;4dI{*Lx000000RR90 -{{R3000whoXk~3-0w7l>toMja192_(UwD?W=?zm*&IhOn$k(lG-qz;DsX2RKhRF9oualB}P71SaJfwx= -uHX^JIK`}#x3$o4Af`kVHyQ&~TYCSRqgWgjZ$<5FZnj -cuT6B5B6)POqpHCTrHl4#QtZa;zni70000000000{{R30000003v+dFaBO95Wo~qH00{wOJ=2M>OG#EL -&$!Mwbx&PZdlOljoA7|k;k>s6qoa5|8f~f~{V{&P5baMa+0%CAAe<9`L -ptgpr6F_xjAC6(~TLj#*ewiHWCD_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jgmDd%EKc;p -w+KsVi?D}qDSkO*B!5Mb*xG|_(S5o&00;m8KmY&$000000RR900000000000000000RR6000000019(y -XKrD1b#i5M015%()D=(>(T2L(qY0=?N_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jp9m~TI>-W|y2ahx -3nF|Vuawki#7NH?S|Q-Q!u2{b0tIPiVPjm(ZiUQ7;QU9z@vLsQUy3b9HcVYybrT0cSFYzzA^b -6`Drj_fC5M7<0km5x1u)VS{2*yf9yYl?p>|ZggdCbW&wz1OxyEb7N>_ZD9Zf0RkXbC#?5~OapN(_Fs6G -vFQy{P|gRa2*}s1Y~I%9#i^81)7t~9tEf?*r}jS36zkMYeK9}${s8)2BzjZ?kPra}XJu|>b7^w`1pxve -S0}9Zh)e@2rNlD$O59e#ogQsB77jPl+h5j^*S;F -1!-nsV`TsZ0RcP8z<~n@;VY|KA!vt$qMEp^75#kD_Tqj3WXX=Y(#Wl3#tYybrT0anNlc)Z3! -7CPHT_+Dq|&?jn_(4)LjFAF^$MA+G=`wK&FZggdCbW>?(a|Hna3IZTkC#?5~OapN(_Fs6GvFQy{P|gRa -2*}s1Y~I%9#i_RFfQB3>bs~EXcCXx(drQcb3B`Fx$)^%va$Ar)C7b~v#}{qTDnK1gUZ=~4IPtBJuMnKC -WEcQ$kD_ZvQg;gh000000000A000000000EMR;^&ZgXjGZb@cgV`T;j2yJg~GYywm# -VTK~nd#>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0000000000{{R30000002WM<= -Vqt7^015&{>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+p_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jHo-KZ`k;Xmr`<4sJYKN!!u{G5u+^j1 -lf!PF4>GEG0000000000{{R30000003t@9}X=iS2Wo~qH015&{>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7 -Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+p_lQgbaV_>=c$Ts04O39g2dD_h -*R5>c*5<{jHo-KZ`k;Xmr`<4sJYKN!!u{G5u+^j1lf!PF4>GEG0000000000{{R30000002XbX(Wo2!1 -00{y`>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+pa{vhfMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r -8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0000000000{{R300000024!+`Z*p@02?9mxqhH(h -&Z4!V_T!KN -I`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+pa{vhfMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{ -AMw{vgzX#P!9p!}0yp?_0000000000{{R300000024!+`Z*p@02?9mxqhH(hNn`*70ssVVZ*FA(00035b8l^B00jX8Me3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C -`}q*rYXqYdo~D%m7H6OD0<^0n_2##VWXRdjy=DB@qgYOj2y$g{b!l>CWCF@89&dx0-7pM3Z=O*v*GCA9 -fL-<|HrZsA`NnJlR3~AEBGG%U@MZ$v=XJ?|;InIPy66cFfOYp#JM2r7_Du+Fb!>ELaBO7)$}AplgPGkh -3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#VTK~nd#>Z4!V_T!KNI`QJ|h6;Zj -^jB$MPK+?7Lu3>C`4HJt76^nC$%1sKzB<;EQA|)S-x88IWKN#S$#@T&w`gPtX>Mp`a%psP00;p)%D{mG -2;nQMTOnwNgyXhzrB~SH04;UKo5i(1Vxw^Y00000000300000000009bZKp6b97;CZ~y>E2yJC_VPs)+ -VE_sOMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!} -0yp?_0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*=q!&6rQG)02XJT?*g=|B=zREie$*y(7k2+ -*P~cYjQ{`u000000RI300000001IbqZ(?C=Q*>c;WdI5SMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C -`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0m=yGke?j1l!xqXd>q7+-P0pRHy9#PwIC -`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0ZXaKh^f@$D{A?t{IfX>#}PNp!L%7{0GY9x -pq!KXGXMYp000000RI3000000010+sY-Mg^X=QT&3IavyqhH(hb7^w{b?qhoJW!8=sKG~^&Ni^C7tcO}co=3CQC(GPVoWSC3v_Z} -ZgXjLX>V?G015&{>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+p< -?Hl01LM?X!H~4Y^Hx3&bJ$HXE2K+s|vHZ6#&ske5?JSDZAfr}PGrQJ;0000000000{{R30000003T1e7 -Wo~n6Z*Fq{3IavyqhH(hD`aAk5~bZKvH00aU61a5C`WdHyG0R(ezZDjxj0RlzpqhH(hC`}q*r35LOoBKkGaY9#cS7Qj{WgyAGcS>>g~&^g7bS0}9Zh)e@p#+${pKVqYC33O>~Wpi|4ZEyepNC<6ZbYWy+bYTDq0lk5UVp0y6#Opn49V(cQc;WdI2QadI6-(bd|-i#!&GYaF>qoh8ar -da{vheR)?jU+FZ2DLr`QR#xHIKjC^A48Li8o -%k$8HEod=_0000000000{{R30000003v_Z}ZgXjLX>V?G00{v&KD$)QXhhr5^*YH=BF-=c -yOsxg-v9sr000000RI300000000w1pa&K~T00{xZXXT7NJOW`Spw3o_*cmz+=1%_1gm*5-D79nn{HtC7 -00000000300000000009WMy_`Y;SO7asnV%C#?5~OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#i_RFfQB3> -bs~EXcCXx(drQcb3B`Fx$)^%va$Ar)C7cFHZE$Q!WCZ~L2LJ#-AOHhPX>#x3$o4Af`kVHyQ&~TYC -SRqgV00000000300000000008b7N>_ZDDj_00{yhS0}9Zh)e@ite$I%(jAWg00000000300000000006X=!b6Y;yn!0fbj(2M`|< -m3T|4oDcSEr%ah$$XqR+hQ$77qvA$o%>V!Z000000RI300000001I<Z4!V_T!KNI`QJ|h6;Zj -^jB$MPK+?7Lu3>C`4HLtfv$so3kRF1PV2}fOp_vjQ6FdFHId|lr&gK9B00000 -0096000000000VeX=iR>bairNa{vkf;?xyT5z&Ua+M@}mOiDpYxh>^^GknUxTJ!XL#OUcE0frb5ENEw7 -&f?o%+)B!ZpG}K!%4G?I4vp$|ttu*CMF0Q*000000RI300000000>QQWNBt;WpV=p2w`G#baG*1bN~o% -c4cyMX=G&q1!ie(VQl{xPGN0jWJYOaY-B-mb7^O8ZDnqBRC#b^1_J_VWC9>pC#?5~OapN(_Fs6GvFQy{ -P|gRa2*}s1Y~I%9#i@t>;$>KfZ0H=mhJ>?uVC`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_2y$g}WpZ|9WCD5v -9p7nv%krpqNFdAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jWOW`w -sTH9-LlJ`2|Ay5Z(?oEikl{+~pis;@Q*TJ#1a4t%WdcR&qhH(he1kloHngE|MP08BSqsWn@NaWo%?eY;R&=Y*Tb$ -bY)a|aAgJq0%>FdAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{j)$WoGNre1kloHngE|MP05>8=lWn@NaWo%?kWprUwd2nS00|IGe0w7l>toMja192_( -UwD?W=?zm*&IhOn$k(lG-qz;DsdeN{_}|Wp0vpvv$c&#PW69R$ltr%da5t5w^x+8!q6BVXZDj&Q>Z4!V -_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+pFdAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c -*5<{jG*S<)6P6lYy(#<=BR_>s@(?%#f7ArN-=Rj?7Ns(11a4t%WdcR&qhH(hR6Lh9EroO>_{O=WapR$**)WfhrcWXrXy +KnGOwA#t$mH2bG7pQ)aE=^FQF!@KkQhzLn;aCLM|VQ?5o)zidWvABmX&uCxQ{9vUAsn@)h(<^=)@3p(i +4FwHHWo~72X>(I!Xk~3-9zxS>Jw1!&_U?o#2Tebz`mr;62_Hls_?@=CN?W&A7(sJ$X=iS2Wo~qHLTqVn +WK(5fY*ct@WFNs;Mn8g^E-G}MMdwWnpYo +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 +_Du+KWpQ~GYywm#VTK~nd#>D0(t`--)Viz +@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OCWX;GxmM3|zUzx)^-Ue}@Gdf&9Z>i^jdP;%w2}rc(FkN>V^DH$ +Z)O5k6V}(%hjW>8uUwNXi!t*yd7K}=K!`A`1OPgv%fU!TPS0G>=uAF%>iaxCSnRl2&38AmXJiCw9urEN +I6IdHVs&n0Y-IwkjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&U5Y50a7uJ<-M7OQflyV@Mab5n=! +H;MEOu8QHCUOto;Lu_efZgfI*Ze(m_RAF#(Wpq$-Z*OJ>0|;$!V^DH$Z)O5|10COKearHwcS=7M7YzYa +I8*bvhMOc?)(rkC#nUE*(LK3V&vL%&i(~ao9rExlGMgPx_&tqtqVlwo1}@PEWMX4ba&K>D0#*~&*VKn| +nRBmPlPrrd^EP>$AHP6|FsuXsI;G3ONDsCjm_HirtB!lh<{Yi-S-!KI0_27BH<@sVme~^s3>gzWr(Vh90i>HaQlna;3Z49L94~hwnFu^bM|x;hSDQ +ln_I2ZgXj8Zf#|5bY@{}b7ck%2XuJC38-{*D7fZ(%hZo23R4S;p` +Q9JBQllDysbY*gFX>MU`a{vkguZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZm1ACLTJsO2B2U!6n +cg?mz@CdC==Kxq?gSEg)z2E{|0>gzT1jg8iEuMbtv-q +j6g$b#7A9pc!|f`I$jaRzSe2A1ONa4000000RR600000000(DfZe??6a{{l8#`k1y;WQvCHXeDDEB)y- +4aXJJr*xW72o5QK9=@@-=^kqQ3p1gNv;!SgAcC?bFoBOEj`UQU^i2<9K8XrtcywiMb7^mGa{vhfuZ_m{ +WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZmMUfRWItFa66}**i<`OQ2EZhKerVdFGX`Iyqxh%1D00000 +00000|NsC0000002V!+@WNc+~00{xUy6-By=#m2(e>#dd8JhNj{K`{D^pB*Cos?7;=^Nhw0000000030 +|Ns9000006b7N>_ZD9hhjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&S;{P@I>nnK4))Pys{0{baMa+0b@PWiLgsa +Rw~c9&Ny{YCK_TCaeS`x+X~XLW@}|UwEzGB000000RI300000000ne;aAk7>Me3tp+xFv-0Xp&G?S=|} +9rRaeU`~uMrbA>C`}q*r{eiB7ehUYis7~w1CQOqefKeZ3;Wd%uopqe!>_vj92XkX`X>fFN00{zOa5aA+ +<>R2XhQO_4{AcS-HH^7AVzASV8M4NYxyCjU1gEwF5PXV6FZDLo1#Vec_~kix7WfVQ#Sd|CM9$^_00000 +000001ONa40000BVRUq1V`yzuJC38-{*D7fZ(%hZo23R4S;p`Q9JBQllDysbY*gFX>MU`a{vkguZ_m{WNzU!AS*T=d6X;t +=`;<;71O75notN1DSsZm1ACLTJsO2B2U!6ncg?mz@CdC==Kxq?gSEg)z2E{|0>gzT1jg8iEuMbtv-qj6g$b#7A9pc!|f`I$jaRzSe2A1ONa4000000RR6000000 +00(DfZe??6a{{l8#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=@@-=^kqQ3p1gNv;!SgAcC?bFoBOE +j`UQU^i2<9K8XrtcywiMb7^mGa{vhfuZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZmMUfRWItFa6 +6}**i<`OQ2EZhKerVdFGX`Iyqxh%1D0000000000|NsC0000002V!+@WNc+~00{xUy6-By=#m2(e>#dd +8JhNj{K`{D^pB*Cos?7;=^Nhw0000000030|Ns9000006b7N>_ZD9hhjmGz6Zs9Z_D>fc^lq>z|G!4fU +)2DQrPzVkwe;&S;{P@I>nnK4))Pys{0{baMa+0b@PWiLgsaRw~c9&Ny{YCK_TCaeS`x+X~XLW@}|UwEzGB000000RI30 +0000000ne;aAk7>Me3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r{eiB7ehUYis7~w1CQOqefKeZ3 +;Wd%uopqe!>_vj92XkX`X>fFN00{zOa5aA+<>R2XhQO_4{AcS-HH^7AVzASV8M4NYxyCjU1gEwF5PXV6 +FZDLo1#Vec_~kix7WfVQ#Sd|CM9$^_00000000001ONa40000BVRUq1V`yzMh5R%LPn0Rnb10trKJZggdCbV+0c1po$fV`yb>gzLZka+XJhss8OG%_CC-Q>(otsF+cqN0Qy}ddQ=3E5CI2gWo~72X>$Mt0Rpd$#`k1y;WQvCHXeDD +EB)y-4aXJJr*xW72o5QK9=@LlEJ-@Z0;0Ob-P{Wzd?2rs)M&&=&l*}G;Jw22Ix+$UX=Y(#WdH>M0XxdT +fddHPE2~=}XorO3wsWOd*yR8%b;g^;wLfB`aRUiyW?^GxNo{a!00jX7R>%){yv9NnI@?D0UT5ggCu*0_ +qr6cs3q2l0*x9K21O;<-aByq@1pxtPGKatjaO)MCM&b8PdjA-6!Qv6Orzv5BVpF^@Ux1YgLvL<$Wo~p* +Wo85f00whoXk~3-00jX8uZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZmlv2~%1FNg3QJ<&wKF}2F +)J=UcKm7gx`duV?R0NO^0S9MgZe??6a{vVa0>gzMlvz +Njk^^qPoT1+zTRnAg`3vXv9d*8d@RXy~6c6G6Dr@W?^Gx00jX7JIcU;0|?p +#+${pKVqYC0|{wnVPj=UZE$P=1pxt8$PakD#zGc4+eY|aXXwx;YM0QXyiqR;Jsw2Z*{J&qLvL<$Wo~p+ +X=if<0RRdDuZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZmw&;L{94K`ndk%K5+?9Jv$dw7jc}U5p +5@2#$kUJ%u0U^g1ZO|$}9Zg=R%ZE7et&pz}oUddU0B(<>YerIc3jqKC00000015yA0000001icXbY*UH +X>V>xW?^Gx1_=mlZ)9m^X=QQ&lpOD6#%EY0CLclTa6hZC<#>ZODNcTE%yi#yB_`&o2ybw7X>V>}Yy!$G +9&dx0-7pM3Z=O*v*GCA9fL-<|HrZsA`NnJlR3~AEBGG%U@MZ$v=XJ?|;InIPy66cFfOYp#JM2r7_Du+F +WprU=VRT^t2?9mxqhH(hu=2wF+7z(Wqt=tdZk`V^s(Ana000000093000000000YNb8~5DZf#|5 +baMa-0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*&DQ20rFt3ZOHs70;T-agdg$OP=xIp;K4#I +cLF!~assc7#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=u=2wF+7z(Wqt=td +Zk`V^s(Ana000000093000000000MaWn^V#ZF2w#0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP +*&DQ20rFt3ZOHs70;T-agdg$OP=xIp;K4#IcLF!~asU7T000000RI3000000010+sY-Mg^X=QT&2?9mx +qhH(hC`}q*r35LOoBKkGa +Y9#cS7Qj{WgyAGcS>>g~&^g7C`}q*r8?;yf@?frQ$owe+rTo-{ +AMw{vgzX#P!9p!}0yp?_3`b>dWpinBNoHYVWd;TaZEs|0W@%+|0hAo?WyWV%Bqkq0>u^7-u;qAzHYrYi +ZOnAva3v<@st9dmbYWy+bYTDq0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*&DQ20rFt3ZOHs7 +0;T-agdg$OP=xIp;K4#IcLF!~asU7T000000RI300000000(DmZ(?C=a{vkgMe3tp+xFv-0Xp&G?S=|} +9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0>gzBa)$q57bK6Q|uUfIMEX^1}Vv6tLB!)|10-o)0prc>n+a000000RI3000000 +01IJrb7^O8ZDnqBa{vkgMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{ +AMw{vgzX#P!9p!}0yp?_0>gzBa)$q57bK6Q|uUfIMEX +^1}Vv6tLB!)|10-o)0prc>n+a000000RI3000000010+sY-Mg^X=QT&2?9mxqhH(hC`}q*r35LOoBKkGaY9#cS7Qj{WgyAGcS>>g~ +&^g7ioJpYH;+t0eX2w~A!Q+0eaZ{MVyc +PK^k1WpQ~GYywm#VTK~nd#>yWpZgcQkwbf~^M){{|8P%hsR +k~m~ep32F151Y4WWC&?)Xk~I~baMa*0XxdTfddHPE2~=}XorO3wsWOd*yR8%b;g^;wLfB`aR2}S00000 +0RI3000000010$yZDn(GVQp{#07wXJWprU=VRT^t3IavyqhH(hZ4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C +`4HJ_1fvw5rj-B|XP@r^w5ufb=C_Ju$l1`nW&GEpSWb-q0000000030000000000BXKZg`VQf=$VRU5x +3IavyqhH(h}`A;#FO3ABStqEB2u*`(KJ8e4#|W70000000030000000000BVRLh7XKrm}Zgg`1 +3IavyqhH(ha{vkg +Me3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_ +0X}Q-^^?(m0E0zBOZWn(@&jfq2YNoZ;ZAl)>;YPDKL7v#000000RI300000000(DfZe??6a{+bjCH_26 +kAtYeN1V@6CZgT(%0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_ +Fs4If6Z`oP*&DQ20rFt3ZOHs70;T-agdg$OP=xIp;K4#IcLF!~asf9E8yY=#e=i37J-o5}w=U0FTPy7> +iqjyYR#Y>))`9>4000000093000000000VQcywiMb7^mGa{vkgMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uM +rbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0XSPta$W&i*H000000RI300000001#wlW?^+~bWd<)a$$67Z*Bkt0ssVVZ*FA(00035b8l^B00jX8 +Me3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_ +24!+`Z*p@03IavyqhH(h>gzP9Lqh8!q$B6|*YuiTY;OURW8#d%1{rxIXtTaY^?oCir}VPj=U +WCZ~L2LJ#-AOHzTW?^GxNo{a!1`P*xWpZ_ZDC1d0>gzLZka+XJhss8OG%_CC-Q>(otsF+cqN +0Qy}ddQ=3E5C>^yVPj=UWC1(Mz<~n@;VY|KA!vt$qMEp^75#kD_Tqj3pzX>Db5bYX39002k` +ZDn*}WMOn+00{xTfrw&K4w%I2J!>5*n2+UEn$VY06ag%An>_FbOoG7x0000000030000000000BXKZg` +VQf=$VRU5x2?23(9Y)dB+Qf@I7Kdvbxk#NQ%2Ip^oEeXABZ7(pf`tG8000000093000000000YNb8~5D +Zf#|5baMa+0huBwu~C-QVH212O0vm-vwNnjOqUO({d!Yj6^~`qZ~y=R000000RI3000000010+sY-Mg^ +X=QT&2?17zrJCAYw97+KWFy8eZUu~dV(l5N%b&~h(10yyF^B*F000000093000000000Yga$#@6C +ZgT($0XROpRQe`%bQtg9OuU(MB+3^mE|~AfiD0OzeAWk8kN^Mx000000RI3000000019PzbY*UHX>V?G +00{wU#AUTvyg$3{N++IppJQl5+tKwp$xtHBFa^7o2YcTD00000000300000000006WpZ+Fa&rI)0mEnI +j6FO8VJD!@R*BddIvVCq{>+4TF2^XfWAFT{UH||9000000RI3000000010Gec4cgDaAk4=uZ_m{WNzU! +AS*T=d6X;t=`;<;71O75notN1DSsZmw&;L{94K`ndk%K5+?9Jv$dw7jc}U5p5@2#$kUJ%u2y=8{bY($e +X#uslLXEmL6-F5v>3G|uUigF$Iw^!m+g!OaP0#x3$o4Af` +kVHyQ&~TYCSRqgV00000000300000000008b7N>_ZDDj_00{!GjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQr +PzVkwe;&S;{P@Z4!V_T!KN +I`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HLtfv$so3kRF1PV2}fOp_vjQ6FdFHId|lr +&gK9B000000096000000000VeX=iR>bairNa{vkf;?xyT5z&Ua+M@}mOiDpYxh>^^GknUxTJ!XL#OUcE +0frb5ENEw7&f?o%+)B!ZpG}K!%4G?I4vp$|ttu*CMF0Q*000000RI300000000>QQWNBt;WpV=p2w`G# +baG*1bN~o%c4cyMX=G&q1!ie(VQl{xPGN0jWJYOaY-B-mb7^O8ZDnqBRC#b^1_J_VWCE{^#`k1y;WQvC +HXeDDEB)y-4aXJJr*xW72o5QK9=?bE;$>KfZ0H=mhJ>?uVC`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_2y$g} +WpZ|9WCD5v9p7nv%krpqNFduZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1 +DSsZmWOW`wsTH9-LlJ`2|Ay5Z(?oEikl{+~pis;@Q*TJ#1a4t%WdcR&qhH(he1kloHngE|MP06;5GoWn@NaWo%?t -VQgh?V|i40aAgJq0%>FdAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jM(yUq2ps*m=2xUDT;RqC -gn#@WzFu~@adfH5^@&-|1a4t%WdcR&qhH(he1kloHngE|MP04o+chWn@-ia%o|1bagle0|IGe00035ZeeX@0!8Yh -U)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*$IZhiz50p(P||0m=?fQ^Mv6fMp@;h#Lzj#&aRFSj|g&Q -b7gXNWn=<+10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUG5>JtwI*nu%&Q~z;Vl^%5wS6(#;{6ajG -64wDPk{-(nPj_x*WJzXWV`T&e00Uuec>n+a0S0nuXJ~YD0000224QV)b#8P30009AVQzUuVRT^t000CD -VQzUrbaY{3XaE2J1q5VabYTDm0RlzpqhH(hioJ -pYH;+t0eX2w~A!Q+0eaZ{MVycPK^psbz)a(bZ%vHa|8ka1ax?5WB>&L0`+VYVk7oBr%DNv+($;q`HHK! -gIHa)*%m(-e#9sm3ZsHT^UK%K(4i9Ajp1M~R@C@!4#dQE#lUD;OiKi1RsjNZcmM?f0`+VYVk7oBr%DNv -+($;q`HHK!gIHa)*%m(-e#9sm3dMUNn!oosZgNI|twmNZeC(lYZa*g7-2eQ3Yy;-pL1po(RWoBV@Y;*ts009Pc +6&DQwR5(-fxrUo0The1kloHngE|MP08BSqsWn@NaWo%?e +Y;R&=Y*Tb$bY)a|aAgJq0%>FduZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZm)$WoGNre1kloHngE|MP05>8=lWn@NaWo%?kWprUwd2nS00|IGe0>gzIEhH_}|Wp0vpvv$c&#PW69R$ltr%da5t5w^x+8!q6BVX +ZDj&Q>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+pFduZ_m{WNzU!AS*T=d6X;t=`;<; +71O75notN1DSsZmG*S<)6P6lYy(#<=BR_>s@(?%#f7ArN-=Rj?7Ns(11a4t%WdcR&qhH(he1kloHngE|MP06;5Go +Wn@NaWo%?tVQgh?V|i40aAgJq0%>FduZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZmM(yUq2ps*m +=2xUDT;RqCgn#@WzFu~@adfH5^@&-|1a4t%WdcR&qhH(he1kloHngE|MP04o+chWn@-ia%o|1bagle0|IGe00035 +ZeeX@0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*$IZhiz50p(P||0m=?fQ^Mv6fMp@;h#Lzj# +&aRFSj|g&Qb7gXNWn=<+10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUG5>JtwI*nu%&Q~z;Vl^%5w +S6(#;{6ajG64wDPk{-(nPj_x*WJzXWV`T&e00Uuec>n+a0S0nuXJ~YD0000224QV)b#8P30009AVQzUu +VRT^t000CDVQzUrbaY{3XaE2J1q5VabYTDm0RlzpqhH(hioJpYH;+t0eX2w~A!Q+0eaZ{MVycPK^psbz)a(bZ%vHa|8ka1ax?5WB>&L0`+VYVk7oBr%DNv ++($;q`HHK!gIHa)*%m(-e#9sm3ZsHT^UK%K(4i9Ajp1M~R@C@!4#dQE#lUD;OiKi1RsjNZcmM?f0`+VY +Vk7oBr%DNv+($;q`HHK!gIHa)*%m(-e#9sm3dMUNn!oosZgNI|twmNZeC(lYZa*g7-2eQ3Yy;-pLpZg6#U0%CAAe<9`Lptgpr6F_xjAC6(~TLj#*ewiHf`^rCgHqw;r~cW`-QaCLM7VsJHo +A?4$swuZp1Wc+9AOf`(TIbyKWjTy4WkGaM+ZSSEb;k|42*wg~2q@3^Lq|9zft}OB~jx>)hO73S(hx +V^4K-aCLM7VsJHoA?4$swuZp1Wc+9AOf`(TIbyKWjTy4WkGaM+ZSSEb;k|42*wg~2q@3^Lq|9zft} +OB~jx>)hO73S(hxV?$_RZf9izVsJHoA?4$swuZp1Wc+9AOf`(TIbyKWjTy4WkGaM+ZSSEb;k|42*w +g~2q@3^Lq|9zft}OB~jx>)hO72UB%$aBN9r1pxpD002NB00~odaByr%bY*P>1po(RWoBV@Y;*ts009Pc d2nS;ZvX`W0006J2y}UHWlmvjWdH>M0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*;5t>gcQkw bf~^M){{|8P%hsRk~m~ep32F151Y4WWD*HxX=Q9=PGN0j00jX8Me3tp+xFv-0Xp&G?S=|}9rRaeU`~uM rbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_6AN}>a%o|1bWUMyWdH>M0!8YhU)%QM @@ -284,19 +273,19 @@ VQ>Wj015$yz}|oy`cC#6Uw2{wE+Sw~);*uMH+9Bf@aCY-RuiZDn*}0S0GmZ(?C=0tIh(Ze?Tx 2XWo~161PWnub7^O8ZDnqB1qWwkZe??6a|Q}@a$#@6CZU+fvcywiMb7^mG2nl6)V`Xr3X>V=` 3R87(aBO95Wo~o^1PNnrZggdCbV+0Z2AHk4+Bm{3x%H=p>4!*u&n~Wpi|4 -ZEyepNC#tbWnpx0asnV%C#?5~OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#i_RFfQB3>bs~EXcCXx(drQcb +ZEyepNC#tbWnpx0assc7#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=^8dfQB3>bs~EXcCXx(drQcb 3B`Fx$)^%va$Ar)C7cUkZfdKHyBH|__hx_vscRWAu^w2r{b^x;wDWyGXd29 kG60)seH8)H{-R`;$q)jqasX>@6CZb@cgV`T;j 2yJg~GYywm#VTK~nd#>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_ 0000000000{{R30000002WM<=Vqt7^015&{>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1 -V6JV*{3!yZ{M3XW@z+p_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jHo-KZ +V6JV*{3!yZ{M3XW@z+pGEG0000000000{{R300000025D|^b#!w83IavyqhH(hfc^lq>z|G!4fU)2DQrPzVkwe;&Rz!8D=zpn(&o-7tVWUa<1Q{n`|;)uYyv!)~4rGOBq10000000030 000000000BVRLh7XKrm}Zgg`13IavyqhH(hfc^lq>z|G!4fU)2DQrPzVkwe;&Rz!8D=zpn(&o -7tVWUa<1Q{n`|;)uYyv!)~4rGOBq100000000300000000009c42H~ZewX>a{vhfMe3tp+xFv-0Xp&G ?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0000000000{{R30 0000024!+`Z*p@02?9mxqhH(huJC38-{*D7fZ(%hZo23R4S;p`Q9JBQllDyoR%LQdZvz4Xb}#?}b}<1BS7~%^Wpi^vb#7#AWd;HY -aCKr=X>@L7b8`Y9S0}9Zh)e@zVQyn+Z*pa1LUnFrY-Mu+hzwODL;*@eYE_8FVm19wjO(ZbIvDI)B0PALl`~a8 +aCKr=X>@L7b8`Z(jmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&T7wrKJIUBJXnP(l%Y$cDDuY1Bm# +?@QxYCjWldxIc>zVQyn+Z*pa1LUnFrY-Mu+fFLn>K7eW<<9zC -----END STRICT TYPE LIB----- diff --git a/stl/RGBStd@0.11.0.stl b/stl/RGBStd@0.11.0.stl index aa9bc8cd62d4d4adf1cd9f0232c7acd89251db46..f341116026f0a76ec56b6e9ce2b2b6d8f2c80c94 100644 GIT binary patch delta 3337 zcmeHJX;4#F7$reM76Jr_ngGd*ppvi@5F*5|2m!JoOfFQ zVxkyu$znNJLx&o)Y(s=Ia7V8O&(K?G6u)+fmsjDFks&3+FvREBSi^#i7%GRV-FK>W zY4qupvq2bcW~^99Js%b5lU?D&knewZj7D~USZneqgl3^pBAv)?>cgkWysT7_aIs7# zPL#_0Bx0$MD-uX}nPKuY+vTcl4jHZ3RXJbYZcwg{H0O7}x^+dh+b?`D&n=Ir4?=Nd zAjUYd919I12q&@5u{SOZAyva+FYC&@X4!NUScee?N_wl#kp5v0u@D4cqZt7^h;A&D zL`7`bmGZ>QDaYZSp8T+Ju$j2>w*Fa%hIC9ord%YIiBqH?)dvFkI3xR|U8S}Y=9%mT z2d@pflExhc>(iHRiyigY9@Xqileyw>L6Vd>frKj;$iYjTo3pYDbMsIs$&ju5GaPyF zH{D9WS?0{#upcwEjw6r@fXX-)w6P$t+9U}eOqb8!J)ymG>_ux} z<_1J(X6%;wZ1bX{F_C)V%SK(p3DH>!)Z5)cP3>u4569JK40Nq*I8bp4dUAic1NM(y z<3~EZmlgJIW{h1sY5=NDV-*c&`YA~hxCIA`8uhJLK-nkfI&UqVQ=;KjXhKZlyz>o% zL{gDVENk*j2=~90;^^qShI!<5p4B(bi((^uzo>N`;56qtJ*JqyQT#o@#loiZMK-_h zF}l2M=yKKes-(v83w7Vm(5q}kuldYZ6IYpx<)xtoIvwPbO1KcXj&1F}H#k3qy<9h9 zR?|#WmuiezjcsE?I~ZMx@P>g}lF=I#A_bCkkqp!kBEfnyTkx}4G~k=l-8BgY*V`W* zuk~hL-aK07P>%0u%c99csR7 zby3F68(x^N!K(^-EBM}Jro6Ow=k!aL3MC?ao$b(ippyitwH8nH5p?iiHdR4N+LST2 zDJE0nG}wo%-)(MJhW(&Ho|Jroip7fh}~z_A<5n_`EhR@acOAbsJo0d53o<(#))en6CrUPz7qGj-CV@CX5U(?dmTC)e zF#cwJgNoOx%%_J&NgYMa?5APGCEeJa<;lDt_n`4=HiUq!usVjugh%}^*2jLl|G8Ko zhE@Y&=Gnuls{5-z;L_SK6?4`#H9zD{kdHh56Wq8sp_6YMMSpbk6)n!M`afdNExny~7NrHaa cbbZ$x8~@E7E&30}%cJ5F`kt?Q+%^{T7xQzLJ^%m! delta 4240 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 diff --git a/stl/RGBStd@0.11.0.sty b/stl/RGBStd@0.11.0.sty index 25c3be31..fe69e9d0 100644 --- a/stl/RGBStd@0.11.0.sty +++ b/stl/RGBStd@0.11.0.sty @@ -1,5 +1,5 @@ {- - Id: stl:JhUC5JgH-Kwps4cO-ZNUklUj-UP6boFp-OY!18Kx-xOSJaVQ#hair-magnum-helena + Id: stl:vdvotNKl-wGrtjuT-Q4qXt4U-UVQlDMB-ONCuwLd-ORBWRTw#zebra-twist-tango Name: RGBStd Version: 0.11.0 Description: RGB standard library @@ -11,76 +11,6 @@ @context typelib RGBStd -import RGBCommit#harvest-person-orion - use ExtensionSchema#active-eddie-empty - use BundleId#carmen-farmer-diesel - use AttachState#lady-japan-fiesta - use GlobalValues#pilot-boris-alice - use MetaValue#split-package-recycle - use InputMap#octavia-north-gram - use GenesisSchema#iron-forbid-hamlet - use AltLayer1Set#flute-flex-bottle - use OwnedStateSchema#python-snake-capsule - use AssetTags#anita-nice-deliver - use VoidState#email-snow-safari - use DataState#short-noise-postal - use TransitionType#picture-reflex-brigade - use Occurrences#source-olga-mirage - use AssignVoidStateBlindSealTxPtr#profit-granite-fuji - use Schema#vocal-hammer-logic - use MediaType#isabel-heaven-north - use AssignmentsBlindSealTxPtr#village-result-bahama - use ValencyType#aloha-dublin-brush - use PedersenCommitment#pupil-scale-jerome - use ConcealedFungible#story-shrink-aloha - use GlobalStateSchema#silk-college-august - use Extension#ambient-greek-jackson - use AssignRevealedAttachBlindSealTxid#local-memo-modern - use TypedAssignsBlindSealTxid#garlic-project-zigzag - use AssignRevealedDataBlindSealTxid#fantasy-monica-jump - use AssignmentsBlindSealTxid#electra-bishop-helena - use ExtensionType#apropos-scoop-viva - use RevealedFungible#origin-iris-insect - use ConcealedData#ivan-tripod-young - use MetaType#quebec-mission-quota - use TransitionSchema#jumbo-matrix-normal - use TypedAssignsBlindSealTxPtr#airline-video-travel - use AssignRevealedDataBlindSealTxPtr#ritual-license-arcade - use XChainBlindSealTxid#dynamic-life-brown - use AttachId#factor-hair-everest - use BlindingFactor#animal-plume-minus - use AssignmentType#secret-penguin-limit - use XChainBlindSealTxPtr#senator-limbo-raymond - use Opout#yoga-samba-karma - use AssignVoidStateBlindSealTxid#senior-beyond-cement - use SchemaId#ramirez-patron-simon - use OpId#picnic-single-gloria - use ContractId#uniform-welcome-papa - use FungibleState#guide-poker-coconut - use Inputs#herman-liberal-galaxy - use XChainPubWitness#carrot-import-nova - use TransitionBundle#mambo-anita-plate - use Identity#smart-pioneer-nominal - use AltLayer1#edison-survive-nitro - use AssetTag#slang-amber-club - use Input#actor-minus-multi - use GlobalStateType#yoga-quick-jasmine - use Transition#tactic-arcade-manager - use AssignRevealedAttachBlindSealTxPtr#wave-comet-arnold - use Ffv#pigment-career-hippie - use AssignRevealedValueBlindSealTxPtr#cuba-needle-salami - use XChainSecretSeal#alex-griffin-left - use Valencies#light-letter-comet - use GlobalState#stadium-barcode-bazaar - use Redeemed#mile-lady-perfect - use RevealedAttach#slalom-phantom-voyage - use Genesis#round-sound-nectar - use Metadata#member-nobody-imitate - use FungibleType#matrix-optimal-sinatra - use ConcealedAttach#meter-arizona-albino - use RevealedData#olivia-copper-stamp - use AssignRevealedValueBlindSealTxid#photo-jump-silicon - import StrictTypes#century-comrade-chess use VariantName#theory-austin-before use FieldName#present-flute-herman @@ -126,6 +56,56 @@ import CommitVerify#miller-pancake-elastic use ReservedBytes4#young-goblin-academy use ReservedBytes8#rudolf-tape-adrian +import RGBCommit#printer-window-alpine + use ExtensionSchema#active-eddie-empty + use BundleId#carmen-farmer-diesel + use MetaValue#split-package-recycle + use InputMap#octavia-north-gram + use GenesisSchema#iron-forbid-hamlet + use AssignmentsBlindSealTxid#private-lesson-compare + use TypedAssignsBlindSealTxPtr#arsenal-immune-martin + use AssignmentsBlindSealTxPtr#ship-panic-magic + use AltLayer1Set#flute-flex-bottle + use TypedAssignsBlindSealTxid#siren-float-child + use TransitionType#picture-reflex-brigade + use Occurrences#source-olga-mirage + use Extension#capital-police-factor + use ValencyType#aloha-dublin-brush + use GlobalState#mouse-bambino-brigade + use GlobalStateSchema#silk-college-august + use OwnedStateSchema#cover-shampoo-weather + use ExtensionType#apropos-scoop-viva + use MetaType#quebec-mission-quota + use TransitionSchema#jumbo-matrix-normal + use StateData#nissan-pattern-inside + use XChainBlindSealTxid#dynamic-life-brown + use AttachId#factor-hair-everest + use AssignmentType#secret-penguin-limit + use XChainBlindSealTxPtr#senator-limbo-raymond + use Opout#yoga-samba-karma + use SchemaId#ramirez-patron-simon + use OpId#picnic-single-gloria + use Schema#eternal-block-totem + use ContractId#uniform-welcome-papa + use State#octavia-kermit-fast + use Inputs#herman-liberal-galaxy + use XChainPubWitness#carrot-import-nova + use Genesis#sincere-block-graph + use AssignBlindSealTxid#light-basket-trick + use Transition#race-korea-capital + use Identity#smart-pioneer-nominal + use AltLayer1#edison-survive-nitro + use GlobalValues#verona-iris-senator + use Input#actor-minus-multi + use GlobalStateType#yoga-quick-jasmine + use Ffv#pigment-career-hippie + use XChainSecretSeal#alex-griffin-left + use Valencies#light-letter-comet + use Redeemed#mile-lady-perfect + use AssignBlindSealTxPtr#alamo-dallas-caesar + use Metadata#member-nobody-imitate + use TransitionBundle#final-numeric-berlin + import Std#ralph-blue-lucky use AlphaCaps#picnic-soprano-aurora use AsciiPrintable#ultra-sunset-format @@ -176,17 +156,17 @@ data AssignIface : ownedState OwnedIface , required Std.Bool , multiple Std.Bool -@mnemonic(scoop-deluxe-action) +@mnemonic(monaco-pilot-nitro) data ClientBundleOpretProof : mpcProof CommitVerify.MerkleProof , dbcProof BPCore.OpretProof , bundle RGBCommit.TransitionBundle -@mnemonic(fame-iris-habitat) +@mnemonic(lithium-shrink-actor) data ClientBundleTapretProof : mpcProof CommitVerify.MerkleProof , dbcProof BPCore.TapretProof , bundle RGBCommit.TransitionBundle -@mnemonic(tango-hotel-jamaica) +@mnemonic(center-saddle-annual) data Consignmentfalse : version ContainerVer , transfer Std.Bool , terminals {RGBCommit.BundleId -> RGBCommit.XChainSecretSeal} @@ -201,7 +181,7 @@ data Consignmentfalse : version ContainerVer , attachments {RGBCommit.AttachId -> [Byte ^ ..0xffffff]} , signatures {ContentId -> ^ ..0xff ContentSigs} -@mnemonic(postage-canary-oxygen) +@mnemonic(permit-simon-summer) data Consignmenttrue : version ContainerVer , transfer Std.Bool , terminals {RGBCommit.BundleId -> RGBCommit.XChainSecretSeal} @@ -279,7 +259,7 @@ data Iface : version VerNo @mnemonic(nova-cola-carbon) data IfaceId : [Byte ^ 32] -@mnemonic(chris-earth-pony) +@mnemonic(sphere-emotion-east) data IfaceImpl : version VerNo , schemaId RGBCommit.SchemaId , ifaceId IfaceId @@ -292,11 +272,12 @@ data IfaceImpl : version VerNo , extensions {NamedFieldExtensionType ^ ..0xff} , errors {NamedVariantu8 ^ ..0xff} , developer RGBCommit.Identity + , stateAbi StateAbi @mnemonic(seminar-data-table) data ImplId : [Byte ^ 32] -@mnemonic(sultan-dexter-lotus) +@mnemonic(polka-neptune-star) data Kit : version ContainerVer , ifaces {Iface ^ ..0xff} , schemata {RGBCommit.Schema ^ ..0xff} @@ -360,6 +341,12 @@ data PubWitness : txid Bitcoin.Txid @mnemonic(insect-cello-avalon) data SigBlob : [Byte ^ 1..0x1000] +@mnemonic(thermos-demo-fragile) +data StateAbi : regInput AluVM.LibSite + , regOutput AluVM.LibSite + , calcOutput AluVM.LibSite + , calcChange AluVM.LibSite + @mnemonic(pilot-claudia-minute) data SupplId : [Byte ^ 32] diff --git a/stl/RGBStorage@0.11.0.sta b/stl/RGBStorage@0.11.0.sta index 3a12b1b6..8ef355eb 100644 --- a/stl/RGBStorage@0.11.0.sta +++ b/stl/RGBStorage@0.11.0.sta @@ -1,24 +1,24 @@ -----BEGIN STRICT TYPE LIB----- -Id: stl:mG$H7b6I-$T8qp18-07PSNeA-rbEBNS5-$J5X4y0-1vPxRWg#channel-vortex-bandit +Id: stl:iayFnuhB-sjXxWhi-Pp!FSyO-astclK4-icTXDwX-O0Fb4F4#floor-avatar-lazarus Name: RGBStorage Dependencies: - RGBCommit#harvest-person-orion, - RGBStd#hair-magnum-helena, StrictTypes#century-comrade-chess, BPCore#austin-story-retro, AluVM#congo-archive-folio, CommitVerify#miller-pancake-elastic, - RGBLogic#import-boxer-seminar, + RGBCommit#printer-window-alpine, + RGBStd#zebra-twist-tango, Std#ralph-blue-lucky, + RGBLogic#ohio-electra-dilemma, Bitcoin#signal-color-cipher -Check-SHA256: 1b751fa1bbeea231625cc17129d356fefecb85e0974f343cadf022d6c227ad17 +Check-SHA256: b78e8c45504383900212ce4d621bac70640f73758b4785d2451f48687eebdc7c -3Q|WxQ*>`~VP|CtAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{j2~tNwLvL+uX>=wP0_2znD++Ak -!AD4^=04ZLvBczwX;cPMM?zC{WJT(uU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*$Y#2 -a%p39RC#b^b5;}9*VKn|nRBmPlPrrd^EP>$AHP6|FsuXsI;G3ONCrYsLvM0rVsJHoA?4$swuZp1Wc+9A -Of`(TIbyKWjTy4WkGaM+1wm|eR!w>X9p7nv%krpqN@X!nKLI&Lh~GYywm#15`~VP|CtMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r3sZD*X=8L$d2nTORuk6O)Q5AK +bFW;JEQ>MoHhG*Mzd(pEtONi$rOUxc20~CnZ*pZ~a5aA+<>R2XhQO_4{AcS-HH^7AVzASV8M4NYxyCjH +L2PwaO?m?z-)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OCJaMwZEb0ER%LQ&W_hoT#`k1y;WQvCHXeDD +EB)y-4aXJJr*xW72o5QK9=-`uM?ynyZEb0Ez1!%t(xt#^?T+No;-&53MHNC&%mm{?y8_)g5LQJz22w{t +Q*>m?EFN!zncXl9K5w2;FV{y1jDTJCC^p$-mHEbO0#qjhQ*>nKQ=pGEdKZ=MPb)<*m$;LvDR$csb;@mC +=QtLlJD!;cQb$5eZ)a&^^=uPjBlbC`N(qzPM@Gr{imSMTSY5T*7C#t%#3&jH2SRCdV{d702?arHbyiIV 01^bJwgM1*ibOBDT%6aZ|SrJerP1pIOD57`7Ol|-ogQ6Pjg~y>s-v>!^VNPLfWv4Jz0xkJm$nc4y MWR2J-cc#Q6SofWC)gp7L6!Sc3I$AQVo7AP4Jk3r!|EoW{Zi$060oMN(jLzPuNboiNpoRS @@ -51,173 +51,150 @@ H8-hI70Bv^+*0?ef%0)>Q3WPbltNdpi4*91)SI!>2Tf&jb75y?IG#g>Clv)aMjKgwAH@`bu1x<7g|G$} _h5K%L=laq&yA1JoJ^{7>oKLkF4~iax8KK|47hp@Qe|^xa&~28LV0v$b1}=fEj#9D^K)f#Cf|Xn@L3mU 0Z2&n-dr?jcD1Ll0RawDWpib6c4cHjd30rSGT61bmh)A>-9G+(AKhLw+s!eDmlO2>&}_PPHjCBJR|r&c Wo1rpWM%K_6AuO0fiYoI|8ZKC9(55{UNs2(LOhfb*8wh)9?K3=Wpib6c4cHjd30rSH2#7XN#A(BKKz&v -`r;e6DUv<<*U}c>;b184%wsNMHUptBVZ#B!U% +`r;e6DUv<<*U}c>CH184%wsNMHUptBVZ#B!U% rHo-i1kG~VoNp!e_~i}U4@G!%Wo~n6Z*Eg#Xk~3-1ACLTJsO2B2U!6ncg?mz@CdC==Kxq?gSEg)z2E{| -2tsvkWNc+gWC^x^65s1c;WeUUgB8EM+V1n+T -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 -*TS*H2rNlD$O59e#ogQsB77jPl+h5j -^*S;FAXg`>_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{j?6T%|znQ^KeoD%bg94CLCf*q;P?fLY7qq^# -2NiM*0000000000{{R30000001#@+9aBKhy0wxs#KG(vr#N>%-R0f!> -x7s+uExGllhUte$e$Op^sMk_Bzn7+|3$axzr2q*6CKUqYmH4o{!1*GOa*TS*H_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{juZ@?{0aPfN4Did>Ze%hHN@6KP -lLd+s#TneAz-EYx0000000000|NsC0000003T1e7Wo~n6Z*Fq{3IZTkC#?5~OapN(_Fs6GvFQy{P|gRa -2*}s1Y~I%9#i^CZ=6W7=VqesjRYGc!>wZFzp>JB4@xD;^wu&SY_r(GrS0}9Zh)e@_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jiECIT&Bl;lSX#$ms8AQN7m&qYKG(vr#N>%-RL5UwIaVYs3AVDiqia*@S>E2s&92Kh -8W}@zf2sFIAOHXW000000RR90{{R3001IJsbYWv?ZDnqBa{vkgAXg`>_lQgbaV_>=c$Ts04O39g2dD_h -*R5>c*5<{jgmDd%EKc;pw+KsVi?D}qDSkO*B!5Mb*xG|_(S5o&00;m8KmY&$000000RR900000000000 -000000RR600000001I_lQgbaV_>=c$Ts04O39g2dD_h*R5>c*5<{jkGsO? -N19ILP2yc~f4%w>xYW^+v~7{W03rq(;firJ0000000000|Ns90000003UqmJWm9=`bY*PC`}q*r{eiB7ehUYis7~w1CQOqefKeZ3;Wd%uopqe!>_vj93Tb3zZggpM -X=QT&3IZTkC#?5~OapN(_Fs6GvFQy{P|gRa2*}s1Y~I%9#i_RFfQB3>bs~EXcCXx(drQcb3B`Fx$)^%v -a$Ar)C7c2#6$0d#2P+C};lr6VNhMM>59zuEq~<=?!m-5UiD^`#;91nsu+1H%suE1D6u@lRoC;S?XbB(j -&QSOSPz0a=0000000030{{R3000004Y-wV1015(Pa5aA+<>R2XhQO_4{AcS-HH^7AVzASV8M4NYxyCl9 -FjWFA`CQ2GiK9iLKbGE6DZmrA4)G`0A&^0p`%?-6VsJHoA?4$swuZp1Wc+9AOf`(TIbyKWjTy4WkGaM+ -5(KBV0uX$PL@)I=)&*`^S@`8Scoz5#{lyP)a751L0000000000|Nj60000001aoO;a{vkgCKUqYmH4o{!1*GOa*TS*H^^GknUxTJ!XL#OUcE0wxs#KG(vr#N>%-RE8K3ENEw7&f?o%+)B!ZpG}K!%4G?I4vp$|ttu*CMF0Q*00000 -0RR600000000>QGZBuk%bY%tt33q99Ze??GWpe-u0w7l>toMja192_(UwD?W=?zm*&IhOn$k(lG-qz;D -sflY?CC$c=UszhlV5m?Ru@{iVU*wrVdeH+Q@FPbX@dBEuZK_k`JKyPG=Rp7@Nbf+-FrJ*HF>i&!wTZgU -Bh_-dLdY0XT`|v$|M|2EBF6^D+OST}`A!+zFZPFTn&AKd0000000960|Nj60000SNZ*FvQVPkZ2015&i -S0}9Zh)e@2rNlD$O59e#ogQsB77jPl+h5j^*S;E -cA8SzdwhWF9dgX`>ZnjA*51^hO#z=?KV_fm3KoU?0000000000{{R3000000 +2tsvkWNc+gWE3Slj!?y>j|MdwWnpYo +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 +{{R30000001#@+9aBKhy0=?Vlw9=)(YVD5X(Bh@-;YAffP|O75Lc0RpIS^JwJO-Gpx7s+uExGllhUte$ +e$Op^sMk_Bzn7+|3$axzr2q*6z1!%t(xt#^?T+No;-&53MHNC&%mm{?y8_)g5LQJzV?EP}uuDl+D$lsi +ICW4a8e$Z2e6I7`3evG=Yh^sO0000000000{{R30000000000000000{{R30000002V!+@WNc+~015)H +jmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&RAdy}<28ig(gSpg+?&9*`C2(3=%09avzwZKZf-~wC% +uZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZm{b~4y9C9`4X%pen_fPY +0000000000|NsC0000003T1e7Wo~n6Z*Fq{3IeZ<#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=?^x +=6W7=VqesjRYGc!>wZFzp>JB4@xD;^wu&SY_r(IQjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&R? +krgyL25hbsyp?a}5-x=-+yHc@4oMPeoYe!lEU|R}0000000030|Ns9000009cWHEPWpi_7a{vkguZ_m{ +WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZmiECIT&Bl;lSX#$ms8AQN7m&qYE2s&92Kh8W}@zf2sFIAOHXW +000000RR90{{R3001IJsbYWv?ZDnqBa{vkguZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZmgmDd% +EKc;pw+KsVi?D}qDSkO*B!5Mb*xG|_(S5o&00;m8KmY&$000000RR900000000000000000RR6000000 +01I +xYW^+v~7{W03rq(;firJ0000000000|Ns90000003UqmJWm9=`bY*PC`}q*r{eiB7ehUYis7~w1CQOqefKeZ3;Wd%uopqe!>_vj93Tb3zZggpMX=QT&3IeZ<#`k1y +;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=^8dfQB3>bs~EXcCXx(drQcb3B`Fx$)^%va$Ar)C7c4i+vv2? +rNCR2XhQO_4{AcS-HH^7AVzASV8M4NYxyCl9FjWFA`CQ2GiK9iL +KbGE6DZmrA4)G`0A&^0p`%?-6VsJHoA?4$swuZp1Wc+9AOf`(TIbyKWjTy4WkGaM+5(KBV0uX$PL@)I= +)&*`^S@`8Scoz5#{lyP)a751L0000000000|Nj60000001aoO;a{vkgz1!%t(xt#^?T+No;-&53MHNC& +%mm{?y8_)g5LQJz;?xyT5z&Ua+M@}mOiDpYxh>^^GknUxTJ!XL#OUcE0=?Vlw9=)(YVD5X(Bh@-;YAff +P|O75Lc0RpIS^JwJcbw$ENEw7&f?o%+)B!ZpG}K!%4G?I4vp$|ttu*CMF0Q*000000RR600000000>QG +ZBuk%bY%tt33q99Ze??GWpe-u0>gzKLsCCC$c=Uszhl +V5m?Ru@{iVU*wrVdeH+Q@FPbX@dD>lppP|r7nSZ$D@8DuxRa_WcH0nj%57ffI2NNjo|$sHLdY0XT`|v$ +|M|2EBF6^D+OST}`A!+zFZPFTn&AKd0000000960|Nj60000SNZ*FvQVPkZ2015)HjmGz6Zs9Z_D>fc^ +lq>z|G!4fU)2DQrPzVkwe;&S{2rNlD$O59e#ogQsB77jPl+h5j^*S;E4$E#+hX^`zsZ&Tl +gCG9;!;p0|>d6h~fj!Md?2W%$0000000000{{R3000000 -----END STRICT TYPE LIB----- diff --git a/stl/RGBStorage@0.11.0.stl b/stl/RGBStorage@0.11.0.stl index 29e2bdda2817d518b0a000782bd5db9ec3e3610b..948dd4ca60be646faafeccd9df39ff83afb2c88d 100644 GIT binary patch delta 3146 zcma)8do+}39CnFj#(fwyVtlisn2Tv#D-~l9Dj8-fC2E*aqnRNyQ>wL73^s}CRkT{E z+*`MhN~_DBN<~|#4rXnMvN=oIwTvW4+mZV@h1qVqW*r#{ zrus2*&w~o`c9p68wm7nXq2=kt1;;!!st4-b|gyM1yrNggDA{igurSSEnT|* z#hW1|WoD39`B<&XZnUkh?dbRCnwN(+t_43B;}y17!&g5GkXm0NFxNna4r zVnnG!w{op3X|&?*j2G~|rBdN$iIgQ0O86WBPsB}R%M$EXRi)5&G-KAKe)FhSxqgj# zWcT|Ax2le^LI%@a({Z}^sZ(NsME3c~wV@q?J;TRu$AUo&$-{BKUZ~kw3?t&+^&y?A zSM0ZyIZJ1eIx=k7W&>G0C(h&lrw1V)Ts8=&_#MKzdgzO)aF>q6y};5_X}@U6N{j=s z!sCy0FVJe`Xum|6Kq3{!NkFe5jk;WwZTHSRaf!>xJA=;naYx=Z`SO$q^}>T;O-!QH z*}%YG6c@!4ab!FhkQ%u%lq&T7;%xlPCCU#WIwxP7WO*7=>aZP=udL@j9;ga44c;LU z@F&m$PV^RmmnxgjnOG4~B z1DBJT^}05zk>s;;8GEz8${OM3j|7=SdG4F(FOUeNLTLjtCdB7KoTDRSlY8mMbn6<% z;)qb@_6p|#-=;MBbAtKQO#fp9A-~~jCh3nn!%x>v%J2(|qPg z)NwI}n}FhJ^p{OcpcTt;yxY#a=lhWTcIz8#Q4_8%d&JnI{_fb&A&N>7QaezAH=LTl z8lFflkb+7Q0=Afofsch9D7Od)3>?{QBu1~Tz3)tgr+Z71I)|2P^rSxhiMll}KR2~2 zdE6n=;)^yleg!o+GSIhla(XWuO(RsP-4|J&NhogWvc4hZq`z9QZ^Wo7qbEPoGsl#h z@K3)ixr8qgfJc^Fv>oa^XANpoe9=DGXM>85Rf+w@YJ5j#(~^ERE}$E8I9JT|ck>@d z2gdNC1%cvt5uoBb0Mm*K+N}y4cN9M_(B0(T>$mzTZ~S0&>4R^reUcUwoL-RPhKWx* zeAIAitdobOVA~uD=yXEB^Er7=1;gUA7_a88lryidr0sgLxC1=fL!Zn$N5tCxwYqR3IDi3eF3pxSW3Iq1G|Soaue(tX}h zLQrPi2h=uYb)AIJ83=5JfngE@>?UF1z)BJc4jLwfQfHu~ler1x>p-iE?PzdPO)@C@ zncgpXlj zpPh47d+Y U;FeMU-lc7RzaO|9{<-=821vhYH2?qr delta 4647 zcma)Admxng8a8qpGs9rrFEg&W3?{OayGTir8QBmG^BGffkr^UtToR>1KPB1d9MT2J zZHpY2u_UEBvMO6HU08Hk<=9F%GbZg;XV2&RW4`(0{hs%IpWpMm-#hax@N&d9SwBxV z5|Zs#&(5i~5Z#F2xIi7O*{bk$ds9gTXsOFBn5@|?x3YW4_1SmoU@m4K=JLt7D zz?O|{3^mcu>$5jh3Eg++ zvGW*^B<4;`%sBPdXOqmBf99AvUyMQ`WpT4QZJ8XS-}S@>1bu4Mksw3Pp1u zmPleuh{g4a+#{WB*GPUy4-S4)TX!s(+@<*oNedO=+7c^QpE{$khRq5Wv<6Yv#;|Dg zFa}6KujHM3JB~0J=07X-h?7QTcxO76w2pwb|HsIZ-3#FP7P$!YYdwPJ%Zm| ze=@;(T0U2`e+?UCPBKYEY%DC!uH@8AvThl;Uj|A-B#OgKd(q2wDA%n`pf2i-> zp$2d$6>&Nh45BSUneH7^mOCU@uThpS9pMvx{%y~5Lhd`MUi8^V>C-Vs&R`dt{6r)a zg@LfuDamZy702g_0&fP$ob{trh!6EP1-9QgH;%-7re0VXz+h5%)iz9**fy5dGTV!p z$tNdXVBO=aUt-ygM^^LiygKcq@i$ZmRGF+ZnkSdtyv^%Xcs3}w=7BzhOOko~U2-mlc=VR^i74Q|w~Id6s9t z+yaMm7HushTrl;3vRs`bXvqy$JQ0u{bw4tO`PxnE^k8l6;oI>Z1;xKN&>cH1v_#qe zm!kyiR^jkqT+RYG%bS^$9wz2^Zs=Og4?BGQxcd>p-0g{K5+SMNww?t%QV#(1Iflj#srMktis0;`= zVM!)8vQAxSliHv$J4@5dYc%~h=N*}a<8+!&>|&473-l^w1l2CgATX(e2Lo6puTKrS zDYfzZR6wD9)@ft4Wl3B8tt5^R^ibu6zrGA`vXT8WPhX>TRckCsX7Eixd{x_Q{D^c~3JS#^FQM3<}nAo*x?D<;s;%N(o4>l{V;C)=_ z@i_Dj1~p%M?Ieo6HA=~q*p{#dL; zSnX8MYMB}JQUd2c2@ylli`5G~IN#$rl1`o}(UQiBS?T`}<4AQcDKn^+)hywENbvaw zAMc7=crz?M^EJl;E!QYUB1~(vlwKl$wekbU?auK${(EBK-Qhmu9+WQ4Ql=i)Xxk9? zdaVWHZcj&m)}|P4R18<73E{k6gkBg4C>633y(_28J49k+)a`&fDOfAK3TwB0pIOd7 z4()s}d~5Qt&ffuu+6N&jMZi?m)O3G9gfteXbUbdu#UJITcb@ak-_{vyUU=Z=Ia=|P zwNN*5eFP;OTF;DP01N>SxT+_Cqna7WQG3Sg*=-p!dPTE^dU@5I4*zasl+LXaBmc>p zFH8C5MrNTE87+F@EdX%t1!~k4_#P6+8`tdpHPvT7v*1W&dyj+<_ouBFXZ)LYY5!fl z3taZjXZ;jqcOkJ($@Xbo?~|~>ZN+-vpnC4=sq^=T($^_wm+jZcuPEJ9yS}#n1ESqh zr~RbZlgUntVD+zIKaZLkZ4EyOJltLevUJ?wgC=$K;e)bth=7XIGn1C#ENndMsp7EN zt8fH(U}t$e(8kNc2Wl$dd5D$Q*QKv|P0u)^X|>kt3LR%1b1uBCmv^sjj_>evsKZ|D z(>4F;E)`9uMRGY}NO8E$6z(j9fIQ*HyxoPdOY!fO#+f+{fXH&ye# zU8v!#D1!YHSc*~S> z5%qP!8a*TUz#$}F7hd8*^^PwEj;Ox`lRYxV1E9YGzBpl834Y(x}=I73AfvMOmaUmM`R`wSwW diff --git a/stl/RGBStorage@0.11.0.sty b/stl/RGBStorage@0.11.0.sty index e6631235..805aadf7 100644 --- a/stl/RGBStorage@0.11.0.sty +++ b/stl/RGBStorage@0.11.0.sty @@ -1,5 +1,5 @@ {- - Id: stl:mG$H7b6I-$T8qp18-07PSNeA-rbEBNS5-$J5X4y0-1vPxRWg#channel-vortex-bandit + Id: stl:iayFnuhB-sjXxWhi-Pp!FSyO-astclK4-icTXDwX-O0Fb4F4#floor-avatar-lazarus Name: RGBStorage Version: 0.11.0 Description: RGB storage library @@ -11,80 +11,111 @@ @context typelib RGBStorage -import RGBCommit#harvest-person-orion +import StrictTypes#century-comrade-chess + use VariantName#theory-austin-before + use FieldName#present-flute-herman + use Primitive#deliver-arrow-boxer + use TySemId#popcorn-super-young + use FieldSemId#spiral-road-marco + use TypeName#edgar-carol-mystery + use UnnamedFieldsSemId#freedom-degree-gregory + use SemId#logic-absorb-hilton + use Variant#humor-regard-promise + use Sizing#courage-alien-salon + use NamedFieldsSemId#solar-salad-smoke + use EnumVariants#dispute-natasha-vega + use VariantInfoSemId#museum-edward-mirror + use UnionVariantsSemId#santana-address-pepper + use TypeSystem#adrian-boris-sponsor + +import BPCore#austin-story-retro + use TapretNodePartner#roger-member-educate + use ExplicitSealTxid#nova-roger-campus + use TapretProof#marco-border-sample + use TapretPathProof#kiwi-mirror-paris + use Method#bali-boris-plasma + use TapretRightBranch#miracle-patriot-touch + use BlindSealTxPtr#fortune-iron-salmon + use OpretProof#good-village-flex + use AnchorMerkleBlockTapretProof#ventura-palma-trumpet + use AnchorMerkleBlockOpretProof#sheriff-alex-degree + use SecretSeal#dollar-iris-wizard + use BlindSealTxid#media-judge-anita + use TxPtr#italian-july-eddie + +import AluVM#congo-archive-folio + use Lib#gate-biology-optimal + use LibSite#ultra-grace-message + use IsaName#taboo-olympic-cloud + use LibId#germany-culture-olivia + use IsaSeg#size-shake-olga + use LibSeg#lemon-philips-horse + +import CommitVerify#miller-pancake-elastic + use ProtocolId#shadow-eclipse-program + use Message#druid-blitz-rover + use MerkleHash#horse-popcorn-bundle + use MerkleBlock#pegasus-delta-eddie + use ReservedBytes1#origin-roger-relax + use ReservedBytes2#florida-libra-circus + use TreeNode#kansas-scarlet-ricardo + use ReservedBytes4#young-goblin-academy + use ReservedBytes8#rudolf-tape-adrian + +import RGBCommit#printer-window-alpine use ExtensionSchema#active-eddie-empty use BundleId#carmen-farmer-diesel - use AttachState#lady-japan-fiesta - use GlobalValues#pilot-boris-alice use MetaValue#split-package-recycle use InputMap#octavia-north-gram use GenesisSchema#iron-forbid-hamlet + use AssignmentsBlindSealTxid#private-lesson-compare + use TypedAssignsBlindSealTxPtr#arsenal-immune-martin + use AssignmentsBlindSealTxPtr#ship-panic-magic use AltLayer1Set#flute-flex-bottle - use OwnedStateSchema#python-snake-capsule - use AssetTags#anita-nice-deliver - use VoidState#email-snow-safari - use DataState#short-noise-postal + use TypedAssignsBlindSealTxid#siren-float-child use TransitionType#picture-reflex-brigade use Occurrences#source-olga-mirage - use AssignVoidStateBlindSealTxPtr#profit-granite-fuji - use Schema#vocal-hammer-logic - use MediaType#isabel-heaven-north - use AssignmentsBlindSealTxPtr#village-result-bahama + use Extension#capital-police-factor use ValencyType#aloha-dublin-brush - use PedersenCommitment#pupil-scale-jerome - use ConcealedFungible#story-shrink-aloha + use GlobalState#mouse-bambino-brigade use GlobalStateSchema#silk-college-august - use Extension#ambient-greek-jackson - use AssignRevealedAttachBlindSealTxid#local-memo-modern - use TypedAssignsBlindSealTxid#garlic-project-zigzag - use AssignRevealedDataBlindSealTxid#fantasy-monica-jump - use AssignmentsBlindSealTxid#electra-bishop-helena + use OwnedStateSchema#cover-shampoo-weather use ExtensionType#apropos-scoop-viva - use RevealedFungible#origin-iris-insect - use ConcealedData#ivan-tripod-young use MetaType#quebec-mission-quota use TransitionSchema#jumbo-matrix-normal use Layer1#camilla-basket-justin - use TypedAssignsBlindSealTxPtr#airline-video-travel - use AssignRevealedDataBlindSealTxPtr#ritual-license-arcade + use StateData#nissan-pattern-inside use XChainBlindSealTxid#dynamic-life-brown use AttachId#factor-hair-everest - use BlindingFactor#animal-plume-minus use AssignmentType#secret-penguin-limit use XChainTxid#liquid-river-absorb use XChainBlindSealTxPtr#senator-limbo-raymond use Opout#yoga-samba-karma - use AssignVoidStateBlindSealTxid#senior-beyond-cement use SchemaId#ramirez-patron-simon use OpId#picnic-single-gloria + use Schema#eternal-block-totem use ContractId#uniform-welcome-papa - use FungibleState#guide-poker-coconut + use State#octavia-kermit-fast use Inputs#herman-liberal-galaxy - use TransitionBundle#mambo-anita-plate + use Genesis#sincere-block-graph + use AssignBlindSealTxid#light-basket-trick + use Transition#race-korea-capital use Identity#smart-pioneer-nominal use AltLayer1#edison-survive-nitro - use AssetTag#slang-amber-club + use GlobalValues#verona-iris-senator use XChainExplicitSealTxid#acid-nepal-melon use Input#actor-minus-multi use GlobalStateType#yoga-quick-jasmine - use Transition#tactic-arcade-manager - use AssignRevealedAttachBlindSealTxPtr#wave-comet-arnold use Ffv#pigment-career-hippie - use AssignRevealedValueBlindSealTxPtr#cuba-needle-salami use XChainSecretSeal#alex-griffin-left use Valencies#light-letter-comet - use GlobalState#stadium-barcode-bazaar use Redeemed#mile-lady-perfect - use RevealedAttach#slalom-phantom-voyage - use Genesis#round-sound-nectar + use AssignBlindSealTxPtr#alamo-dallas-caesar use Metadata#member-nobody-imitate - use FungibleType#matrix-optimal-sinatra use XChainPubWitness#figure-gram-wave - use ConcealedAttach#meter-arizona-albino - use RevealedData#olivia-copper-stamp - use AssignRevealedValueBlindSealTxid#photo-jump-silicon + use TransitionBundle#final-numeric-berlin -import RGBStd#hair-magnum-helena +import RGBStd#zebra-twist-tango use PubWitness#paper-visa-storm use ContentRef#polo-ramirez-parker use SigBlob#insect-cello-avalon @@ -96,92 +127,35 @@ import RGBStd#hair-magnum-helena use IfaceId#nova-cola-carbon use ValencyIface#buzzer-holiday-fiber use Annotations#spend-linda-romeo + use IfaceImpl#coconut-snake-formula use AssignIface#fractal-baker-outside use VerNo#textile-next-stretch use NamedFieldValencyType#invest-apollo-inca use ImplId#seminar-data-table use SupplSub#canoe-denmark-short - use OutputAssignmentRevealedData#dinner-honey-saturn use Supplement#caviar-zebra-precise use SupplId#pilot-claudia-minute - use OutputAssignmentRevealedAttach#miami-diagram-mineral use NamedFieldExtensionType#tuna-archer-melon use NamedFieldGlobalStateType#museum-ohio-arizona use GenesisIface#rocket-paradox-press + use SchemaIfaces#popcorn-rider-panel use AnchorSet#pluto-plasma-diagram - use IfaceImpl#permit-learn-samba use ContentSigs#oval-sister-triton use SupplItem#jargon-orchid-forget use Modifier#saturn-escort-jordan use NamedFieldAssignmentType#origin-caramel-flipper + use OutputAssignment#chicago-neuron-concept use TrustLevel#cobra-script-albino + use StateAbi#thermos-demo-fragile use NamedFieldMetaType#prefix-carmen-artist use NamedVariantu8#star-pilgrim-pilgrim use OpWitness#valid-toronto-gibson use SealWitness#cotton-lopez-isabel use GlobalIface#concert-combat-charm - use SchemaIfaces#fossil-nepal-airline - use OutputAssignmentRevealedValue#aspect-caramel-diana use SupplMap#sailor-observe-bundle use OwnedIface#delphi-athlete-fresh use ContentId#scarlet-portal-office use GlobalOut#capital-agatha-bruno - use OutputAssignmentVoidState#mars-alabama-public - -import StrictTypes#century-comrade-chess - use VariantName#theory-austin-before - use FieldName#present-flute-herman - use Primitive#deliver-arrow-boxer - use TySemId#popcorn-super-young - use FieldSemId#spiral-road-marco - use TypeName#edgar-carol-mystery - use UnnamedFieldsSemId#freedom-degree-gregory - use SemId#logic-absorb-hilton - use Variant#humor-regard-promise - use Sizing#courage-alien-salon - use NamedFieldsSemId#solar-salad-smoke - use EnumVariants#dispute-natasha-vega - use VariantInfoSemId#museum-edward-mirror - use UnionVariantsSemId#santana-address-pepper - use TypeSystem#adrian-boris-sponsor - -import BPCore#austin-story-retro - use TapretNodePartner#roger-member-educate - use ExplicitSealTxid#nova-roger-campus - use TapretProof#marco-border-sample - use TapretPathProof#kiwi-mirror-paris - use Method#bali-boris-plasma - use TapretRightBranch#miracle-patriot-touch - use BlindSealTxPtr#fortune-iron-salmon - use OpretProof#good-village-flex - use AnchorMerkleBlockTapretProof#ventura-palma-trumpet - use AnchorMerkleBlockOpretProof#sheriff-alex-degree - use SecretSeal#dollar-iris-wizard - use BlindSealTxid#media-judge-anita - use TxPtr#italian-july-eddie - -import AluVM#congo-archive-folio - use Lib#gate-biology-optimal - use LibSite#ultra-grace-message - use IsaName#taboo-olympic-cloud - use LibId#germany-culture-olivia - use IsaSeg#size-shake-olga - use LibSeg#lemon-philips-horse - -import CommitVerify#miller-pancake-elastic - use ProtocolId#shadow-eclipse-program - use Message#druid-blitz-rover - use MerkleHash#horse-popcorn-bundle - use MerkleBlock#pegasus-delta-eddie - use ReservedBytes1#origin-roger-relax - use ReservedBytes2#florida-libra-circus - use TreeNode#kansas-scarlet-ricardo - use ReservedBytes4#young-goblin-academy - use ReservedBytes8#rudolf-tape-adrian - -import RGBLogic#import-boxer-seminar - use WitnessPos#cliff-enrico-nominal - use WitnessOrd#frank-ohio-forum import Std#ralph-blue-lucky use AlphaCaps#picnic-soprano-aurora @@ -194,6 +168,10 @@ import Std#ralph-blue-lucky use AlphaCapsLodash#duet-hammer-labor use AlphaSmallLodash#pioneer-eagle-spell +import RGBLogic#ohio-electra-dilemma + use WitnessPos#cliff-enrico-nominal + use WitnessOrd#frank-ohio-forum + import Bitcoin#signal-color-cipher use SeqNo#copper-verbal-ingrid use TxIn#slang-cherry-gizmo @@ -220,17 +198,14 @@ import Bitcoin#signal-color-cipher @mnemonic(carol-salute-aroma) data ContractIndex : publicOpouts {RGBCommit.Opout ^ ..0xffffff}, outpointOpouts {RGBCommit.XChainExplicitSealTxid -> ^ ..0xffffff {RGBCommit.Opout ^ ..0xffffff}} -@mnemonic(shake-square-wizard) +@mnemonic(carbon-arena-ivan) data MemContractState : schemaId RGBCommit.SchemaId , contractId RGBCommit.ContractId , global {RGBCommit.GlobalStateType -> ^ ..0xff MemGlobalState} - , rights {RGBStd.OutputAssignmentVoidState ^ ..0xffffffff} - , fungibles {RGBStd.OutputAssignmentRevealedValue ^ ..0xffffffff} - , data {RGBStd.OutputAssignmentRevealedData ^ ..0xffffffff} - , attach {RGBStd.OutputAssignmentRevealedAttach ^ ..0xffffffff} + , state {RGBStd.OutputAssignment ^ ..0xffffffff} -@mnemonic(gilbert-torpedo-digital) -data MemGlobalState : known {RGBStd.GlobalOut -> ^ ..0xffffffff RGBCommit.DataState}, limit U24 +@mnemonic(mary-mineral-frame) +data MemGlobalState : known {RGBStd.GlobalOut -> ^ ..0xffffffff RGBCommit.StateData}, limit U24 @mnemonic(savage-joshua-clone) data MemIndex : opBundleIndex {RGBCommit.OpId -> ^ ..0xffffff RGBCommit.BundleId} @@ -239,7 +214,7 @@ data MemIndex : opBundleIndex {RGBCommit.OpId -> ^ ..0xffffff RGBCommit , contractIndex {RGBCommit.ContractId -> ^ ..0xff ContractIndex} , terminalIndex {RGBCommit.XChainSecretSeal -> ^ ..0xffffff {RGBCommit.Opout ^ ..0xff}} -@mnemonic(level-open-morph) +@mnemonic(kinetic-deal-blast) data MemStash : schemata {RGBCommit.SchemaId -> ^ ..0xff RGBStd.SchemaIfaces} , ifaces {RGBStd.IfaceId -> ^ ..0xff RGBStd.Iface} , geneses {RGBCommit.ContractId -> ^ ..0xff RGBCommit.Genesis} diff --git a/stl/Transfer.vesper b/stl/Transfer.vesper index ca6ac774..36c8e481 100644 --- a/stl/Transfer.vesper +++ b/stl/Transfer.vesper @@ -48,211 +48,43 @@ Consignmenttrue rec testnet enum Bool false=0 true=1 altLayers1 set len=0..MAX8 aka=AltLayer1Set AltLayer1 enum liquid=1 - assetTags map len=0..MAX8 aka=AssetTags - key is U16 aka=AssignmentType - value bytes len=32 aka=AssetTag metadata map len=0..MAX8 aka=Metadata key is U16 aka=MetaType value bytes len=0..MAX16 aka=MetaValue 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 aka=StateData assignments map len=0..MAX8 aka=AssignmentsBlindSealTxid key is U16 aka=AssignmentType - value union TypedAssignsBlindSealTxid - declarative list len=0..MAX16 wrapped tag=0 - AssignVoidStateBlindSealTxid 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 - AssignRevealedValueBlindSealTxid 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 - AssignRevealedDataBlindSealTxid 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 - AssignRevealedAttachBlindSealTxid 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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=TypedAssignsBlindSealTxid + AssignBlindSealTxid 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 aka=StateData + some bytes len=32 option wrapped aka=AttachId tag=1 + lock bytes len=2 aka=ReservedBytes2 + revealed rec tag=1 + seal union XChainBlindSealTxid + bitcoin rec BlindSealTxid wrapped tag=0 + method enum Method opretFirst=0 tapretFirst=1 + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 + liquid rec BlindSealTxid wrapped tag=1 + method enum Method opretFirst=0 tapretFirst=1 + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 + state rec State + reserved bytes len=1 aka=ReservedBytes1 + value bytes len=0..MAX16 aka=StateData + 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 @@ -268,202 +100,37 @@ Consignmenttrue 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 aka=StateData assignments map len=0..MAX8 aka=AssignmentsBlindSealTxid key is U16 aka=AssignmentType - value union TypedAssignsBlindSealTxid - declarative list len=0..MAX16 wrapped tag=0 - AssignVoidStateBlindSealTxid 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 - AssignRevealedValueBlindSealTxid 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 - AssignRevealedDataBlindSealTxid 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 - AssignRevealedAttachBlindSealTxid 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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 XChainBlindSealTxid - bitcoin rec BlindSealTxid wrapped tag=0 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - vout is U32 aka=Vout - blinding is U64 - liquid rec BlindSealTxid wrapped tag=1 - method enum Method opretFirst=0 tapretFirst=1 - txid bytes len=32 aka=Txid - 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=TypedAssignsBlindSealTxid + AssignBlindSealTxid 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 aka=StateData + some bytes len=32 option wrapped aka=AttachId tag=1 + lock bytes len=2 aka=ReservedBytes2 + revealed rec tag=1 + seal union XChainBlindSealTxid + bitcoin rec BlindSealTxid wrapped tag=0 + method enum Method opretFirst=0 tapretFirst=1 + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 + liquid rec BlindSealTxid wrapped tag=1 + method enum Method opretFirst=0 tapretFirst=1 + txid bytes len=32 aka=Txid + vout is U32 aka=Vout + blinding is U64 + state rec State + reserved bytes len=1 aka=ReservedBytes1 + value bytes len=0..MAX16 aka=StateData + some bytes len=32 option wrapped aka=AttachId tag=1 + lock bytes len=2 aka=ReservedBytes2 redeemed map len=0..MAX8 aka=Redeemed key is U16 aka=ValencyType value bytes len=32 aka=OpId @@ -472,272 +139,79 @@ Consignmenttrue rec validator bytes len=1 aka=ReservedBytes1 witness bytes len=2 aka=ReservedBytes2 bundles set len=0..MAX32 - WitnessBundle rec - anchoredBundles union AnchoredBundles - tapret rec ClientBundleTapretProof wrapped tag=0 - mpcProof rec MerkleProof - pos is U32 - cofactor is U16 - path list len=0..32 - element bytes len=32 aka=MerkleHash - dbcProof rec TapretProof - pathProof rec TapretPathProof - some union TapretNodePartner option wrapped tag=1 - rightBranch rec TapretRightBranch wrapped tag=2 - nonce is U8 - bundle rec TransitionBundle - closeMethod enum Method opretFirst=0 tapretFirst=1 - inputMap map len=1..MAX16 aka=InputMap - key is U32 aka=Vout - value bytes len=32 aka=OpId - knownTransitions map len=1..MAX16 - key bytes len=32 aka=OpId - value rec Transition - ffv is U16 aka=Ffv - contractId bytes len=32 aka=ContractId - nonce is U64 - transitionType is U16 aka=TransitionType - metadata map len=0..MAX8 aka=Metadata - key is U16 aka=MetaType - value bytes len=0..MAX16 aka=MetaValue - 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 - inputs set len=0..MAX16 aka=Inputs - Input rec - prevOut rec Opout - op bytes len=32 aka=OpId - ty is U16 aka=AssignmentType - no is U16 - 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 + WitnessBundle rec + anchoredBundles union AnchoredBundles + tapret rec ClientBundleTapretProof wrapped tag=0 + mpcProof rec MerkleProof + pos is U32 + cofactor is U16 + path list len=0..32 + element bytes len=32 aka=MerkleHash + dbcProof rec TapretProof + pathProof rec TapretPathProof + some union TapretNodePartner option wrapped tag=1 + rightBranch rec TapretRightBranch wrapped tag=2 + nonce is U8 + bundle rec TransitionBundle + closeMethod enum Method opretFirst=0 tapretFirst=1 + inputMap map len=1..MAX16 aka=InputMap + key is U32 aka=Vout + value bytes len=32 aka=OpId + knownTransitions map len=1..MAX16 + key bytes len=32 aka=OpId + value rec Transition + ffv is U16 aka=Ffv + contractId bytes len=32 aka=ContractId + nonce is U64 + transitionType is U16 aka=TransitionType + metadata map len=0..MAX8 aka=Metadata + key is U16 aka=MetaType + value bytes len=0..MAX16 aka=MetaValue + 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=StateData + inputs set len=0..MAX16 aka=Inputs + Input rec + prevOut rec Opout + op bytes len=32 aka=OpId + ty is U16 aka=AssignmentType + no is U16 + reserved bytes len=2 aka=ReservedBytes2 + assignments map len=0..MAX8 aka=AssignmentsBlindSealTxPtr + key is U16 aka=AssignmentType + 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 aka=StateData + 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 aka=StateData + 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 @@ -767,7 +241,7 @@ Consignmenttrue 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 aka=StateData inputs set len=0..MAX16 aka=Inputs Input rec prevOut rec Opout @@ -777,231 +251,38 @@ Consignmenttrue 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 aka=StateData + 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 aka=StateData + 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 @@ -1036,7 +317,7 @@ Consignmenttrue 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 aka=StateData inputs set len=0..MAX16 aka=Inputs Input rec prevOut rec Opout @@ -1046,231 +327,38 @@ Consignmenttrue 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 aka=StateData + 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 aka=StateData + 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 @@ -1300,7 +388,7 @@ Consignmenttrue 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 aka=StateData inputs set len=0..MAX16 aka=Inputs Input rec prevOut rec Opout @@ -1310,231 +398,38 @@ Consignmenttrue 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 aka=StateData + 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 aka=StateData + 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 @@ -1556,11 +451,9 @@ Consignmenttrue 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 @@ -1776,6 +669,19 @@ Consignmenttrue rec name ascii aka=VariantName first=AlphaSmallLodash rest=AlphaNumLodash len=1..100 reserved bytes len=4 aka=ReservedBytes4 developer ascii aka=Identity first=AsciiPrintable rest=AsciiPrintable len=1..4096 + stateAbi rec StateAbi + regInput rec LibSite + lib bytes len=32 aka=LibId + pos is U16 + regOutput rec LibSite + lib bytes len=32 aka=LibId + pos is U16 + calcOutput rec LibSite + lib bytes len=32 aka=LibId + pos is U16 + calcChange rec LibSite + lib bytes len=32 aka=LibId + pos is U16 supplements set len=0..MAX8 Supplement rec contentId union ContentRef diff --git a/stl/src/main.rs b/stl/src/main.rs index 3cf24119..f41e32da 100644 --- a/stl/src/main.rs +++ b/stl/src/main.rs @@ -26,8 +26,8 @@ use std::io::Write; use commit_verify::CommitmentLayout; use rgbstd::containers::Transfer; use rgbstd::stl::{ - aluvm_stl, bp_core_stl, bp_tx_stl, commit_verify_stl, rgb_commit_stl, rgb_contract_stl, - rgb_logic_stl, rgb_std_stl, rgb_storage_stl, + aluvm_stl, bp_core_stl, bp_tx_stl, commit_verify_stl, rgb_commit_stl, rgb_logic_stl, + rgb_std_stl, rgb_storage_stl, }; use strict_types::stl::{std_stl, strict_types_stl}; use strict_types::{parse_args, StlFormat, SystemBuilder}; @@ -36,28 +36,6 @@ fn main() { let (_, dir) = parse_args(); let dir = dir.unwrap_or_else(|| "./stl".to_owned()); - let contract_stl = rgb_contract_stl(); - contract_stl - .serialize(StlFormat::Binary, Some(&dir), "0.11.0", None) - .expect("unable to write to the file"); - contract_stl - .serialize(StlFormat::Armored, Some(&dir), "0.11.0", None) - .expect("unable to write to the file"); - contract_stl - .serialize( - StlFormat::Source, - Some(&dir), - "0.11.0", - Some( - " - Description: Types for writing RGB contracts and interfaces - Author: Dr Maxim Orlovsky - Copyright (C) 2023-2024 LNP/BP Standards Association. All rights reserved. - License: Apache-2.0", - ), - ) - .expect("unable to write to the file"); - let rgb_std = rgb_std_stl(); rgb_std .serialize(StlFormat::Binary, Some(&dir), "0.11.0", None) From c3ef1e3f79eccabc9f8e938c130f931e0013262c Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Tue, 15 Oct 2024 23:22:35 +0200 Subject: [PATCH 02/16] iface: make invoice state calculable with AluVM --- src/containers/file.rs | 2 - src/interface/builder.rs | 115 ++++++++++++----------- src/interface/calc.rs | 192 ++++++++++++++++++++++++++++++++++++++ src/interface/contract.rs | 11 --- src/interface/iimpl.rs | 3 +- src/interface/mod.rs | 2 + src/persistence/memory.rs | 18 ++-- src/persistence/stash.rs | 9 ++ src/persistence/stock.rs | 131 ++++++-------------------- 9 files changed, 303 insertions(+), 180 deletions(-) create mode 100644 src/interface/calc.rs diff --git a/src/containers/file.rs b/src/containers/file.rs index 4cd722c0..02a567b8 100644 --- a/src/containers/file.rs +++ b/src/containers/file.rs @@ -273,7 +273,6 @@ mod test { issuer: Default::default(), testnet: Default::default(), alt_layers1: Default::default(), - asset_tags: Default::default(), metadata: Default::default(), globals: Default::default(), assignments: Default::default(), @@ -371,7 +370,6 @@ mod test { issuer: Default::default(), testnet: Default::default(), alt_layers1: Default::default(), - asset_tags: Default::default(), metadata: Default::default(), globals: Default::default(), assignments: Default::default(), diff --git a/src/interface/builder.rs b/src/interface/builder.rs index 7fc6c13e..2ba1d8c3 100644 --- a/src/interface/builder.rs +++ b/src/interface/builder.rs @@ -29,7 +29,7 @@ use rgb::validation::Scripts; use rgb::{ validation, AltLayer1, AltLayer1Set, AssignmentType, Assignments, ContractId, ExposedSeal, Genesis, GenesisSeal, GlobalState, GraphSeal, Identity, Input, Layer1, MetadataError, Opout, - OwnedStateSchema, Schema, State, Transition, TransitionType, TypedAssigns, XChain, XOutpoint, + Schema, State, Transition, TransitionType, TypedAssigns, XChain, XOutpoint, }; use rgbcore::{GlobalStateSchema, GlobalStateType, MetaType, Metadata, ValencyType}; use strict_encoding::{FieldName, SerializeError, StrictSerialize}; @@ -37,7 +37,7 @@ use strict_types::{decode, SemId, TypeSystem}; use crate::containers::{BuilderSeal, ContainerVer, Contract, ValidConsignment}; use crate::interface::resolver::DumbResolver; -use crate::interface::{Iface, IfaceImpl, TransitionIface}; +use crate::interface::{Iface, IfaceImpl, StateCalc, StateCalcError, TransitionIface}; use crate::Outpoint; #[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] @@ -68,19 +68,7 @@ pub enum BuilderError { /// state `{0}` provided to the builder has invalid type. InvalidStateType(AssignmentType), - /// asset tag for state `{0}` must be added before any fungible state of - /// the same type. - AssetTagMissed(AssignmentType), - - /// asset tag for state `{0}` was already automatically created. Please call - /// `add_asset_tag` before adding any fungible state to the builder. - AssetTagAutomatic(AssignmentType), - - /// state data for state type `{0}` are invalid: asset tag doesn't match the - /// tag defined by the contract. - AssetTagInvalid(AssignmentType), - - /// interface doesn't specifies default operation name, thus an explicit + /// interface doesn't specify default operation name, thus an explicit /// operation type must be provided with `set_operation_type` method. NoOperationSubtype, @@ -90,6 +78,10 @@ pub enum BuilderError { /// {0} is not supported by the contract genesis. InvalidLayer1(Layer1), + #[from] + #[display(inner)] + Calc(StateCalcError), + #[from] #[display(inner)] StrictEncode(SerializeError), @@ -226,13 +218,13 @@ impl ContractBuilder { pub fn add_owned_state_raw( mut self, - name: impl Into, + type_id: AssignmentType, seal: impl Into>, state: State, ) -> Result { let seal = seal.into(); self.check_layer1(seal.layer1())?; - self.builder = self.builder.add_owned_state_raw(name, seal, state)?; + self.builder = self.builder.add_owned_state_raw(type_id, seal, state)?; Ok(self) } @@ -306,13 +298,15 @@ impl ContractBuilder { } } -#[derive(Clone, Debug)] +#[derive(Debug)] pub struct TransitionBuilder { contract_id: ContractId, builder: OperationBuilder, nonce: u64, transition_type: TransitionType, inputs: TinyOrdMap, + // TODO: Remove option once we have blank builder + calc: Option, } impl TransitionBuilder { @@ -323,7 +317,7 @@ impl TransitionBuilder { iimpl: IfaceImpl, types: TypeSystem, ) -> Self { - Self::with(contract_id, iface, schema, iimpl, TransitionType::BLANK, types) + Self::with(contract_id, iface, schema, iimpl, TransitionType::BLANK, types, None) } pub fn default_transition( @@ -332,13 +326,15 @@ impl TransitionBuilder { schema: Schema, iimpl: IfaceImpl, types: TypeSystem, + scripts: Scripts, ) -> Result { let transition_type = iface .default_operation .as_ref() .and_then(|name| iimpl.transition_type(name)) .ok_or(BuilderError::NoOperationSubtype)?; - Ok(Self::with(contract_id, iface, schema, iimpl, transition_type, types)) + let calc = StateCalc::new(scripts, iimpl.state_abi); + Ok(Self::with(contract_id, iface, schema, iimpl, transition_type, types, Some(calc))) } pub fn named_transition( @@ -348,12 +344,14 @@ impl TransitionBuilder { iimpl: IfaceImpl, transition_name: impl Into, types: TypeSystem, + scripts: Scripts, ) -> Result { let transition_name = transition_name.into(); let transition_type = iimpl .transition_type(&transition_name) .ok_or(BuilderError::TransitionNotFound(transition_name))?; - Ok(Self::with(contract_id, iface, schema, iimpl, transition_type, types)) + let calc = StateCalc::new(scripts, iimpl.state_abi); + Ok(Self::with(contract_id, iface, schema, iimpl, transition_type, types, Some(calc))) } fn with( @@ -363,6 +361,7 @@ impl TransitionBuilder { iimpl: IfaceImpl, transition_type: TransitionType, types: TypeSystem, + calc: Option, ) -> Self { Self { contract_id, @@ -370,6 +369,7 @@ impl TransitionBuilder { nonce: u64::MAX, transition_type, inputs: none!(), + calc, } } @@ -403,6 +403,9 @@ impl TransitionBuilder { } pub fn add_input(mut self, opout: Opout, state: State) -> Result { + if let Some(calc) = &mut self.calc { + calc.reg_input(opout.ty, &state)?; + } self.inputs.insert(Input::with(opout), state)?; Ok(self) } @@ -430,39 +433,54 @@ impl TransitionBuilder { self.builder.valency_type(name) } + #[inline] pub fn valency_name(&self, type_id: ValencyType) -> &FieldName { self.builder.valency_name(type_id) } pub fn meta_name(&self, type_id: MetaType) -> &FieldName { self.builder.meta_name(type_id) } + /// NB: Doesn't process the state with VM pub fn add_owned_state_raw( mut self, - name: impl Into, + type_id: AssignmentType, seal: impl Into>, state: State, ) -> Result { - self.builder = self.builder.add_owned_state_raw(name, seal, state)?; + self.builder = self.builder.add_owned_state_raw(type_id, seal, state)?; Ok(self) } - pub fn add_owned_state( + pub fn fulfill_owned_state( mut self, - name: impl Into, + type_id: AssignmentType, seal: impl Into>, - value: impl StrictSerialize, - ) -> Result { - self.builder = self.builder.add_owned_state(name, seal, value)?; - Ok(self) - } - - pub fn add_owned_state_default( - self, + state: State, + ) -> Result<(Self, Option), BuilderError> { + let calc = self + .calc + .as_mut() + .expect("you must not call fulfill_owned_state for the blank transition builder"); + let state = calc.calc_output(type_id, &state)?; + self.builder = self + .builder + .add_owned_state_raw(type_id, seal, state.sufficient)?; + Ok((self, state.insufficient)) + } + + pub fn add_owned_state_change( + mut self, + type_id: AssignmentType, seal: impl Into>, - value: impl StrictSerialize, ) -> Result { - let assignment_name = self.default_assignment()?.clone(); - self.add_owned_state(assignment_name, seal.into(), value) + let calc = self + .calc + .as_mut() + .expect("you must not call add_owned_state_change for the blank transition builder"); + if let Some(state) = calc.calc_change(type_id)? { + self.builder = self.builder.add_owned_state_raw(type_id, seal, state)?; + } + Ok(self) } pub fn has_inputs(&self) -> bool { !self.inputs.is_empty() } @@ -514,7 +532,6 @@ impl OperationBuilder { global: none!(), assignments: none!(), meta: none!(), - types, } } @@ -551,14 +568,6 @@ impl OperationBuilder { self.iimpl.valency_name(ty).expect("internal inconsistency") } - #[inline] - fn state_schema(&self, type_id: AssignmentType) -> &OwnedStateSchema { - self.schema - .owned_types - .get(&type_id) - .expect("schema should match interface: must be checked by the constructor") - } - #[inline] fn meta_schema(&self, type_id: MetaType) -> &SemId { self.schema @@ -615,16 +624,10 @@ impl OperationBuilder { fn add_owned_state_raw( mut self, - name: impl Into, + type_id: AssignmentType, seal: impl Into>, state: State, ) -> Result { - let name = name.into(); - - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; - let assignment = seal.into().assignment(state); match self.assignments.entry(type_id)? { @@ -644,7 +647,13 @@ impl OperationBuilder { seal: impl Into>, value: impl StrictSerialize, ) -> Result { - self.add_owned_state_raw(name, seal, State::new(value)) + let name = name.into(); + + let type_id = self + .assignments_type(&name) + .ok_or(BuilderError::AssignmentNotFound(name))?; + + self.add_owned_state_raw(type_id, seal, State::new(value)) } fn complete(self) -> (Schema, Iface, IfaceImpl, GlobalState, Assignments, TypeSystem) { diff --git a/src/interface/calc.rs b/src/interface/calc.rs new file mode 100644 index 00000000..50a6fd50 --- /dev/null +++ b/src/interface/calc.rs @@ -0,0 +1,192 @@ +// RGB standard library for working with smart contracts on Bitcoin & Lightning +// +// 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. +// +// 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 aluvm::data::ByteStr; +use aluvm::library::{LibId, LibSite}; +use aluvm::reg::{Reg16, Reg32, RegA, RegR, RegS}; +use amplify::num::{u256, u4}; +use amplify::{ByteArray, Wrapper}; +use rgb::validation::Scripts; +use rgb::{AssignmentType, AttachId, StateData}; + +use crate::LIB_NAME_RGB_STD; + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display, Error)] +#[display(doc_comments)] +pub enum StateCalcError { + /// reserved byte value {0} is not 0x00 for assignment type {1}. + InvalidReserved(AssignmentType, u8), + /// error registering input state of type {0} - {1}. + InputReg(AssignmentType, String), + /// error registering output state of type {0} - {1}. + OutputReg(AssignmentType, String), + /// error computing output state of type {0} - {1}. + OutputCalc(AssignmentType, String), + /// error computing change state of type {0} - {1}. + ChangeCalc(AssignmentType, String), + /// failed script for calculating output state of type {0}; please update interface + /// implementation for the schema + InsufficientState(AssignmentType), +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] +#[strict_type(lib = LIB_NAME_RGB_STD)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", rename_all = "camelCase") +)] +pub struct StateAbi { + pub reg_input: LibSite, + pub reg_output: LibSite, + pub calc_output: LibSite, + pub calc_change: LibSite, +} + +impl StateAbi { + pub fn lib_ids(&self) -> impl Iterator { + [self.reg_input, self.reg_output, self.calc_output, self.calc_change] + .into_iter() + .map(|site| site.lib) + } +} + +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +pub struct AllocatedState { + pub sufficient: rgb::State, + pub insufficient: Option, +} + +#[derive(Debug)] +pub struct StateCalc { + vm: aluvm::Vm, + abi: StateAbi, + scripts: Scripts, +} + +impl StateCalc { + pub fn new(scripts: Scripts, abi: StateAbi) -> Self { + let vm = aluvm::Vm::new(); + Self { vm, abi, scripts } + } + + fn run(&mut self, site: LibSite) -> Result<(), String> { + if !self.vm.exec(site, |id| self.scripts.get(&id), &()) { + if let Some(err) = self.vm.registers.get_s(RegS::from(15)).cloned() { + return Err(err.to_string()); + } + } + Ok(()) + } + + fn put_state(&mut self, ty: AssignmentType, state: &rgb::State) { + self.vm + .registers + .set_n(RegA::A16, Reg32::Reg0, Some(ty.to_inner())); + assert_eq!(state.reserved, none!()); + self.vm.registers.set_n(RegA::A8, Reg32::Reg0, Some(0u8)); + self.vm + .registers + .set_s(RegS::from(0), Some(ByteStr::with(&state.value))); + self.vm.registers.set_n( + RegR::R256, + Reg32::Reg0, + state.attach.map(|a| u256::from_le_bytes(a.to_byte_array())), + ); + } + + fn fetch_state( + &self, + ty: AssignmentType, + idx: Reg16, + ) -> Result, StateCalcError> { + let Some(value) = self.vm.registers.get_s(RegS::from(u4::from(idx))) else { + return Ok(None); + }; + let reserved = self + .vm + .registers + .get_n(RegA::A8, idx) + .map(|n| u8::from(n)) + .unwrap_or_default(); + let attach = self + .vm + .registers + .get_n(RegR::R256, idx) + .map(|n| AttachId::from_byte_array(u256::from(n).to_le_bytes())); + if reserved != 0x00 { + return Err(StateCalcError::InvalidReserved(ty, reserved)); + } + Ok(Some(rgb::State { + reserved: none!(), + value: StateData::from_checked(value.to_vec()), + attach, + })) + } + + pub fn reg_input( + &mut self, + ty: AssignmentType, + state: &rgb::State, + ) -> Result<(), StateCalcError> { + self.put_state(ty, state); + self.run(self.abi.reg_input) + .map_err(|err| StateCalcError::InputReg(ty, err)) + } + + pub fn reg_output( + &mut self, + ty: AssignmentType, + state: &rgb::State, + ) -> Result<(), StateCalcError> { + self.put_state(ty, state); + self.run(self.abi.reg_output) + .map_err(|err| StateCalcError::OutputReg(ty, err)) + } + + pub fn calc_output( + &mut self, + ty: AssignmentType, + state: &rgb::State, + ) -> Result { + self.put_state(ty, state); + self.run(self.abi.calc_output) + .map_err(|err| StateCalcError::OutputCalc(ty, err))?; + let Some(sufficient) = self.fetch_state(ty, Reg16::Reg0)? else { + return Err(StateCalcError::InsufficientState(ty)); + }; + let insufficient = self.fetch_state(ty, Reg16::Reg1)?; + Ok(AllocatedState { + sufficient, + insufficient, + }) + } + + pub fn calc_change( + &mut self, + ty: AssignmentType, + ) -> Result, StateCalcError> { + self.run(self.abi.calc_change) + .map_err(|err| StateCalcError::ChangeCalc(ty, err))?; + self.fetch_state(ty, Reg16::Reg0) + } +} diff --git a/src/interface/contract.rs b/src/interface/contract.rs index 5f03b6d5..a5113fdf 100644 --- a/src/interface/contract.rs +++ b/src/interface/contract.rs @@ -66,17 +66,6 @@ pub struct ContractOp { pub witness: Option, } -fn reduce_to_ty(allocations: impl IntoIterator) -> AssignmentType { - allocations - .into_iter() - .map(|a| a.opout.ty) - .reduce(|ty1, ty2| { - assert_eq!(ty1, ty2); - ty1 - }) - .expect("empty list of allocations") -} - impl ContractOp { fn genesis(our_allocations: HashSet) -> impl ExactSizeIterator { our_allocations.into_iter().map(|a| Self { diff --git a/src/interface/iimpl.rs b/src/interface/iimpl.rs index 1e528ed1..69f9eb76 100644 --- a/src/interface/iimpl.rs +++ b/src/interface/iimpl.rs @@ -36,7 +36,7 @@ use strict_encoding::{FieldName, StrictDumb, VariantName}; use strict_types::encoding::{StrictDecode, StrictEncode, StrictType}; use crate::interface::iface::IfaceId; -use crate::interface::{Iface, VerNo}; +use crate::interface::{Iface, StateAbi, VerNo}; use crate::{ReservedBytes, LIB_NAME_RGB_STD}; pub trait SchemaTypeIndex: @@ -228,6 +228,7 @@ pub struct IfaceImpl { pub extensions: TinyOrdSet>, pub errors: TinyOrdSet>, pub developer: Identity, + pub state_abi: StateAbi, } impl IfaceImpl { diff --git a/src/interface/mod.rs b/src/interface/mod.rs index e4bd759f..4e0edd21 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -31,8 +31,10 @@ mod filter; pub(crate) mod resolver; mod contractum; mod inheritance; +mod calc; pub use builder::{BuilderError, ContractBuilder, TransitionBuilder, TxOutpoint}; +pub use calc::{AllocatedState, StateAbi, StateCalc, StateCalcError}; pub use contract::{ContractError, ContractIface, ContractOp, OpDirection}; pub use contractum::IfaceDisplay; pub use filter::{AssignmentsFilter, FilterExclude, FilterIncludeAll}; diff --git a/src/persistence/memory.rs b/src/persistence/memory.rs index 1bd3098e..cb14ee79 100644 --- a/src/persistence/memory.rs +++ b/src/persistence/memory.rs @@ -29,8 +29,8 @@ use std::{iter, mem}; use aluvm::library::{Lib, LibId}; use amplify::confinement::{ - self, Confined, LargeOrdMap, LargeOrdSet, MediumBlob, MediumOrdMap, MediumOrdSet, SmallBlob, - SmallOrdMap, TinyOrdMap, TinyOrdSet, + self, Confined, LargeOrdMap, LargeOrdSet, MediumBlob, MediumOrdMap, MediumOrdSet, SmallOrdMap, + TinyOrdMap, TinyOrdSet, }; use amplify::num::u24; use bp::dbc::tapret::TapretCommitment; @@ -44,8 +44,8 @@ use rgb::vm::{ use rgb::{ Assign, AssignmentType, Assignments, AssignmentsRef, AttachId, BundleId, ContractId, ExposedSeal, Extension, Genesis, GenesisSeal, GlobalStateType, GraphSeal, Identity, OpId, - Operation, Opout, Schema, SchemaId, SecretSeal, Transition, TransitionBundle, XChain, - XOutpoint, XOutputSeal, XWitnessId, + Operation, Opout, Schema, SchemaId, SecretSeal, StateData, Transition, TransitionBundle, + XChain, XOutpoint, XOutputSeal, XWitnessId, }; use strict_encoding::{StrictDeserialize, StrictSerialize}; use strict_types::TypeSystem; @@ -680,7 +680,7 @@ impl StateWriteProvider for MemState { #[strict_type(lib = LIB_NAME_RGB_STORAGE)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] pub struct MemGlobalState { - known: LargeOrdMap, + known: LargeOrdMap, limit: u24, } @@ -850,12 +850,12 @@ impl> ContractStateAccess for MemContract { &self, ty: GlobalStateType, ) -> Result, UnknownGlobalStateType> { - type Src<'a> = &'a BTreeMap; - type FilteredIter<'a> = Box + 'a>; + type Src<'a> = &'a BTreeMap; + type FilteredIter<'a> = Box + 'a>; struct Iter<'a> { src: Src<'a>, iter: FilteredIter<'a>, - last: Option<(GlobalOrd, &'a SmallBlob)>, + last: Option<(GlobalOrd, &'a StateData)>, depth: u24, constructor: Box) -> FilteredIter<'a> + 'a>, } @@ -867,7 +867,7 @@ impl> ContractStateAccess for MemContract { } } impl<'a> GlobalStateIter for Iter<'a> { - type Data = &'a SmallBlob; + type Data = &'a StateData; fn size(&mut self) -> u24 { let iter = self.swap(); // TODO: Consuming iterator just to count items is highly inefficient, but I do diff --git a/src/persistence/stash.rs b/src/persistence/stash.rs index c1b3e083..bd0dba10 100644 --- a/src/persistence/stash.rs +++ b/src/persistence/stash.rs @@ -312,6 +312,7 @@ impl Stash

{ let lib = self.provider.lib(id)?; scripts.insert(id, lib.clone()); } + // TODO: Make sure we have all the libs including their dependencies let scripts = Scripts::try_from(scripts) .map_err(|_| StashDataError::TooManyLibs(schema.schema_id()))?; @@ -358,6 +359,12 @@ impl Stash

{ .ok_or(StashDataError::NoIfaceImpl(schema.schema_id(), iface.iface_id()))?; let (types, _) = self.extract(&schema_ifaces.schema, [iface])?; + let mut scripts = BTreeMap::new(); + for id in iimpl.state_abi.lib_ids() { + let lib = self.provider.lib(id)?; + scripts.insert(id, lib.clone()); + } + let scripts = Scripts::from_checked(scripts); let builder = if let Some(transition_name) = transition_name { TransitionBuilder::named_transition( @@ -367,6 +374,7 @@ impl Stash

{ iimpl.clone(), transition_name.into(), types, + scripts, ) } else { TransitionBuilder::default_transition( @@ -375,6 +383,7 @@ impl Stash

{ schema.clone(), iimpl.clone(), types, + scripts, ) } .expect("internal inconsistency"); diff --git a/src/persistence/stock.rs b/src/persistence/stock.rs index a295c74a..1d8191a7 100644 --- a/src/persistence/stock.rs +++ b/src/persistence/stock.rs @@ -31,7 +31,7 @@ use bp::dbc::Method; use bp::seals::txout::CloseMethod; use bp::Vout; use chrono::Utc; -use invoice::{Beneficiary, InvoiceState, RgbInvoice}; +use invoice::{Beneficiary, RgbInvoice}; use nonasync::persistence::{CloneNoPersistence, PersistenceError, PersistenceProvider}; use rgb::validation::{DbcProof, ResolveWitness, WitnessResolverError}; use rgb::{ @@ -230,6 +230,9 @@ pub enum ComposeError { /// the invoice contains no interface information. NoIface, + /// the invoice lacks specific state information. + NoInvoiceState, + /// the invoice requirements can't be fulfilled using available assets or /// smart contract state. InsufficientState, @@ -904,6 +907,11 @@ impl Stock { seal_blinder: impl Fn(ContractId, AssignmentType) -> u64, ) -> Result> { let layer1 = invoice.layer1(); + let invoice_state = invoice + .owned_state + .state() + .ok_or(ComposeError::NoInvoiceState)? + .clone(); let prev_outputs = prev_outputs .into_iter() .map(|o| o.into()) @@ -961,7 +969,6 @@ impl Stock { // allocate a different state transition spending them as a change. let mut alt_builder = self.transition_builder(contract_id, iface.clone(), invoice.operation.clone())?; - let mut alt_inputs = Vec::::new(); let layer1 = invoice.beneficiary.chain_network().layer1(); let beneficiary = match (invoice.beneficiary.into_inner(), beneficiary_vout) { @@ -983,16 +990,7 @@ impl Stock { // 2. Prepare transition let mut main_inputs = Vec::::new(); - let mut sum_inputs = Amount::ZERO; - let mut sum_alt = Amount::ZERO; - let mut data_inputs = vec![]; - let mut data_main = true; - let lookup_state = - if let InvoiceState::Data(NonFungible::RGB21(allocation)) = &invoice.owned_state { - Some(DataState::from(*allocation)) - } else { - None - }; + let mut alt_inputs = Vec::::new(); for (output, list) in self.contract_assignments_for(contract_id, prev_outputs.iter().copied())? @@ -1002,7 +1000,7 @@ impl Stock { } else { alt_inputs.push(output) }; - for (opout, mut state) in list { + for (opout, state) in list { if output.method() == method { main_builder = main_builder.add_input(opout, state.clone())?; } else { @@ -1010,109 +1008,34 @@ impl Stock { } if opout.ty != assignment_id { let seal = output_for_assignment(contract_id, opout.ty)?; - state.update_blinding(pedersen_blinder(contract_id, assignment_id)); if output.method() == method { main_builder = main_builder.add_owned_state_raw(opout.ty, seal, state)?; } else { alt_builder = alt_builder.add_owned_state_raw(opout.ty, seal, state)?; } - } else if let PersistedState::Amount(value, _, _) = state { - sum_inputs += value; - if output.method() != method { - sum_alt += value; - } - } else if let PersistedState::Data(value, _) = state { - if lookup_state.as_ref() == Some(&value) && output.method() != method { - data_main = false; - } - data_inputs.push(value); } } } - // Add payments to beneficiary and change - match invoice.owned_state.clone() { - InvoiceState::Amount(amt) => { - // Pay beneficiary - if sum_inputs < amt { - return Err(ComposeError::InsufficientState.into()); - } - - let sum_main = sum_inputs - sum_alt; - let (paid_main, paid_alt) = - if sum_main < amt { (sum_main, amt - sum_main) } else { (amt, Amount::ZERO) }; - let blinding_beneficiary = pedersen_blinder(contract_id, assignment_id); - - if paid_main > Amount::ZERO { - main_builder = main_builder.add_fungible_state_raw( - assignment_id, - beneficiary, - paid_main, - blinding_beneficiary, - )?; - } - if paid_alt > Amount::ZERO { - alt_builder = alt_builder.add_fungible_state_raw( - assignment_id, - beneficiary, - paid_alt, - blinding_beneficiary, - )?; - } - let blinding_change = pedersen_blinder(contract_id, assignment_id); - let change_seal = output_for_assignment(contract_id, assignment_id)?; - - // Pay change - if sum_main > paid_main { - main_builder = main_builder.add_fungible_state_raw( - assignment_id, - change_seal, - sum_main - paid_main, - blinding_change, - )?; - } - if sum_alt > paid_alt { - alt_builder = alt_builder.add_fungible_state_raw( - assignment_id, - change_seal, - sum_alt - paid_alt, - blinding_change, - )?; - } - } - InvoiceState::Data(data) => match data { - NonFungible::RGB21(allocation) => { - let lookup_state = DataState::from(allocation); - if !data_inputs.into_iter().any(|x| x == lookup_state) { - return Err(ComposeError::InsufficientState.into()); - } - - let seal = seal_blinder(contract_id, assignment_id); - if data_main { - main_builder = main_builder.add_data_raw( - assignment_id, - beneficiary, - allocation, - seal, - )?; - } else { - alt_builder = alt_builder.add_data_raw( - assignment_id, - beneficiary, - allocation, - seal, - )?; - } - } - }, - _ => { - todo!( - "only PersistedState::Amount and PersistedState::Allocation are currently \ - supported" - ) + // Add payments to beneficiary + let (builder, partial_state) = + main_builder.fulfill_owned_state(assignment_id, beneficiary, invoice_state)?; + main_builder = builder; + if let Some(partial_state) = partial_state { + let (builder, remaining_state) = + alt_builder.fulfill_owned_state(assignment_id, beneficiary, partial_state)?; + alt_builder = builder; + if let Some(_) = remaining_state { + // TODO: Add information about remaining state to the error + return Err(ComposeError::InsufficientState.into()); } } + // Pay change + let change_seal = output_for_assignment(contract_id, assignment_id)?; + main_builder = main_builder.add_owned_state_change(assignment_id, change_seal)?; + alt_builder = alt_builder.add_owned_state_change(assignment_id, change_seal)?; + // 3. Prepare other transitions // Enumerate state let mut spent_state = From 8f7020c5a04d019e2fb376d95031be1fecfdedf6 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Tue, 15 Oct 2024 23:59:09 +0200 Subject: [PATCH 03/16] iface: add abiloity to select inputs for a given state to ContractIface --- Cargo.lock | 2 +- src/interface/calc.rs | 6 +++++- src/interface/contract.rs | 22 +++++++++++++++++++++- src/persistence/stash.rs | 19 +++++++++++++------ src/persistence/stock.rs | 2 ++ 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28d602ca..2cdf0702 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ version = 3 [[package]] name = "aluvm" version = "0.11.0-beta.9" -source = "git+https://github.com/AluVM/rust-aluvm?branch=develop#24bff9f61570ea26d14e86aa5e127937aa122440" +source = "git+https://github.com/AluVM/rust-aluvm?branch=develop#7adf61dbe4a3b39834bc3d665800024d66658e9c" dependencies = [ "amplify", "ascii-armor", diff --git a/src/interface/calc.rs b/src/interface/calc.rs index 50a6fd50..32043aa1 100644 --- a/src/interface/calc.rs +++ b/src/interface/calc.rs @@ -76,7 +76,7 @@ pub struct AllocatedState { pub insufficient: Option, } -#[derive(Debug)] +#[derive(Clone, Debug)] pub struct StateCalc { vm: aluvm::Vm, abi: StateAbi, @@ -189,4 +189,8 @@ impl StateCalc { .map_err(|err| StateCalcError::ChangeCalc(ty, err))?; self.fetch_state(ty, Reg16::Reg0) } + + pub fn is_sufficient_for(&self, ty: AssignmentType, state: &rgb::State) -> bool { + self.clone().calc_output(ty, state).is_ok() + } } diff --git a/src/interface/contract.rs b/src/interface/contract.rs index a5113fdf..f3fca6d8 100644 --- a/src/interface/contract.rs +++ b/src/interface/contract.rs @@ -22,13 +22,14 @@ use std::borrow::Borrow; use std::collections::{BTreeSet, HashMap, HashSet}; +use rgb::validation::Scripts; use rgb::{AssignmentType, ContractId, OpId, Schema, State, XOutputSeal, XWitnessId}; use strict_encoding::FieldName; use strict_types::{StrictVal, TypeSystem}; use crate::contract::{OutputAssignment, WitnessInfo}; use crate::info::ContractInfo; -use crate::interface::{AssignmentsFilter, IfaceImpl}; +use crate::interface::{AssignmentsFilter, IfaceImpl, StateCalc}; use crate::persistence::ContractStateRead; #[derive(Clone, Eq, PartialEq, Debug, Display, Error, From)] @@ -115,6 +116,7 @@ pub struct ContractIface { pub schema: Schema, pub iface: IfaceImpl, pub types: TypeSystem, + pub scripts: Scripts, pub info: ContractInfo, } @@ -175,6 +177,24 @@ impl ContractIface { .filter(move |outp| outp.opout.ty == type_id)) } + pub fn assignments_fulfilling<'c, K: Ord + 'c>( + &'c self, + name: impl Into, + filter: impl AssignmentsFilter + 'c, + state: &'c State, + sorting: impl FnMut(&&OutputAssignment) -> K, + ) -> Result + 'c, ContractError> { + let mut selected = self.assignments_by_type(name, filter)?.collect::>(); + selected.sort_by_key(sorting); + let mut calc = StateCalc::new(self.scripts.clone(), self.iface.state_abi); + Ok(selected.into_iter().take_while(move |a| { + if calc.reg_input(a.opout.ty, &a.state).is_err() { + return false; + } + calc.is_sufficient_for(a.opout.ty, state) + })) + } + pub fn history( &self, filter_outpoints: impl AssignmentsFilter, diff --git a/src/persistence/stash.rs b/src/persistence/stash.rs index bd0dba10..a5822a7b 100644 --- a/src/persistence/stash.rs +++ b/src/persistence/stash.rs @@ -292,6 +292,18 @@ impl Stash

{ .map_err(StashError::ReadProvider) } + pub(super) fn scripts<'a>( + &self, + lib_ids: impl IntoIterator, + ) -> Result> { + let mut scripts = BTreeMap::new(); + for id in lib_ids { + let lib = self.provider.lib(id)?; + scripts.insert(id, lib.clone()); + } + Ok(Scripts::from_checked(scripts)) + } + pub(super) fn extract<'a>( &self, schema: &Schema, @@ -359,12 +371,7 @@ impl Stash

{ .ok_or(StashDataError::NoIfaceImpl(schema.schema_id(), iface.iface_id()))?; let (types, _) = self.extract(&schema_ifaces.schema, [iface])?; - let mut scripts = BTreeMap::new(); - for id in iimpl.state_abi.lib_ids() { - let lib = self.provider.lib(id)?; - scripts.insert(id, lib.clone()); - } - let scripts = Scripts::from_checked(scripts); + let scripts = self.scripts(iimpl.state_abi.lib_ids())?; let builder = if let Some(transition_name) = transition_name { TransitionBuilder::named_transition( diff --git a/src/persistence/stock.rs b/src/persistence/stock.rs index 1d8191a7..a142358e 100644 --- a/src/persistence/stock.rs +++ b/src/persistence/stock.rs @@ -579,6 +579,7 @@ impl Stock { state, schema: schema_ifaces.schema.clone(), iface: iimpl.clone(), + scripts: self.stash.scripts(iimpl.state_abi.lib_ids())?, types, info, })) @@ -604,6 +605,7 @@ impl Stock { state, schema: schema_ifaces.schema.clone(), iface: iimpl.clone(), + scripts: self.stash.scripts(iimpl.state_abi.lib_ids())?, types, info, }) From 3c4dcd4254c907d0b439b31f75eccb80c2d0fa01 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 17 Oct 2024 00:27:16 +0200 Subject: [PATCH 04/16] iface: use StrictVal instead of State in ContractOp --- Cargo.lock | 5 +- Cargo.toml | 2 +- src/interface/contract.rs | 102 +++++++++++++++++++++++--------------- 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2cdf0702..3f6459a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -526,6 +526,7 @@ checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", "hashbrown", + "serde", ] [[package]] @@ -910,9 +911,9 @@ dependencies = [ [[package]] name = "strict_types" -version = "2.7.0" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f16e8855a575633815f01482ac927ebaca3d2485aec8e17226c6826de29154e" +checksum = "3188d65ee78a90da3545df762a1363b5b4f9c3b845f182a18fc40ae991c235ce" dependencies = [ "amplify", "ascii-armor", diff --git a/Cargo.toml b/Cargo.toml index 55db1cec..e4200e51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,7 @@ nonasync = "0.1.0" ascii-armor = "0.7.2" baid64 = "0.2.2" strict_encoding = "2.7.0" -strict_types = "2.7.0" +strict_types = "2.7.1" commit_verify = { version = "0.11.0-beta.9", features = ["stl"] } bp-core = { version = "0.11.0-beta.9", features = ["stl"] } bp-invoice = { version = "0.11.0-beta.9" } diff --git a/src/interface/contract.rs b/src/interface/contract.rs index f3fca6d8..fe9db18b 100644 --- a/src/interface/contract.rs +++ b/src/interface/contract.rs @@ -22,8 +22,9 @@ use std::borrow::Borrow; use std::collections::{BTreeSet, HashMap, HashSet}; +use amplify::confinement::SmallBlob; use rgb::validation::Scripts; -use rgb::{AssignmentType, ContractId, OpId, Schema, State, XOutputSeal, XWitnessId}; +use rgb::{AssignmentType, AttachId, ContractId, OpId, Schema, State, XOutputSeal, XWitnessId}; use strict_encoding::FieldName; use strict_types::{StrictVal, TypeSystem}; @@ -52,59 +53,50 @@ pub enum OpDirection { Sent, } -#[derive(Clone, Eq, PartialEq, Hash, Debug)] +#[derive(Clone, Eq, PartialEq, Debug)] #[cfg_attr( feature = "serde", derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase", tag = "type") + serde(crate = "serde_crate", rename_all = "camelCase") )] pub struct ContractOp { pub direction: OpDirection, pub ty: AssignmentType, pub opids: BTreeSet, - pub state: State, + pub state: StrictVal, + pub attach_id: Option, pub to: BTreeSet, pub witness: Option, } impl ContractOp { - fn genesis(our_allocations: HashSet) -> impl ExactSizeIterator { - our_allocations.into_iter().map(|a| Self { - direction: OpDirection::Issued, - ty: a.opout.ty, - opids: bset![a.opout.op], - state: a.state, - to: bset![a.seal], - witness: None, - }) + fn new( + direction: OpDirection, + assignment: OutputAssignment, + value: StrictVal, + witness: Option, + ) -> Self { + Self { + direction, + ty: assignment.opout.ty, + opids: bset![assignment.opout.op], + state: value, + attach_id: assignment.state.attach, + to: bset![assignment.seal], + witness, + } } - fn sent( - witness: WitnessInfo, - ext_allocations: HashSet, - ) -> impl ExactSizeIterator { - ext_allocations.into_iter().map(move |a| Self { - direction: OpDirection::Sent, - ty: a.opout.ty, - opids: bset![a.opout.op], - state: a.state, - to: bset![a.seal], - witness: Some(witness), - }) + fn issued(assignment: OutputAssignment, value: StrictVal) -> Self { + Self::new(OpDirection::Issued, assignment, value, None) } - fn received( - witness: WitnessInfo, - our_allocations: HashSet, - ) -> impl ExactSizeIterator { - our_allocations.into_iter().map(move |a| Self { - direction: OpDirection::Received, - ty: a.opout.ty, - opids: bset![a.opout.op], - state: a.state, - to: bset![a.seal], - witness: Some(witness), - }) + fn received(assignment: OutputAssignment, value: StrictVal, witness: WitnessInfo) -> Self { + Self::new(OpDirection::Received, assignment, value, Some(witness)) + } + + fn sent(assignment: OutputAssignment, value: StrictVal, witness: WitnessInfo) -> Self { + Self::new(OpDirection::Sent, assignment, value, Some(witness)) } } @@ -121,6 +113,19 @@ pub struct ContractIface { } impl ContractIface { + fn assignment_value(&self, ty: AssignmentType, value: &SmallBlob) -> StrictVal { + let sem_id = self + .schema + .owned_types + .get(&ty) + .expect("invalid contract state") + .sem_id; + self.types + .strict_deserialize_type(sem_id, value.as_slice()) + .expect("invalid contract state") + .unbox() + } + pub fn contract_id(&self) -> ContractId { self.state.contract_id() } /// # Panics @@ -233,7 +238,10 @@ impl ContractIface { let mut ops = Vec::with_capacity(witness_ids.len() + 1); // add allocations with no witness to the beginning of the history if let Some(genesis_state) = allocations_our_outpoint.remove(&None) { - ops.extend(ContractOp::genesis(genesis_state)); + for assignment in genesis_state { + let value = self.assignment_value(assignment.opout.ty, &assignment.state.value); + ops.push(ContractOp::issued(assignment, value)) + } } for witness_id in witness_ids { let our_outpoint = allocations_our_outpoint.remove(&Some(witness_id)); @@ -255,16 +263,28 @@ impl ContractIface { if ext_assignments.is_empty() { continue; } - ops.extend(ContractOp::sent(witness_info, ext_assignments)) + for assignment in ext_assignments { + let value = + self.assignment_value(assignment.opout.ty, &assignment.state.value); + ops.push(ContractOp::sent(assignment, value, witness_info)) + } } // the same as above, but the payment has no change (None, Some(ext_assignments)) => { - ops.extend(ContractOp::sent(witness_info, ext_assignments)) + for assignment in ext_assignments { + let value = + self.assignment_value(assignment.opout.ty, &assignment.state.value); + ops.push(ContractOp::sent(assignment, value, witness_info)) + } } // we own allocation but the witness transaction was made by other wallet: // this is an incoming payment to us. (Some(our_assignments), None) => { - ops.extend(ContractOp::received(witness_info, our_assignments)) + for assignment in our_assignments { + let value = + self.assignment_value(assignment.opout.ty, &assignment.state.value); + ops.push(ContractOp::received(assignment, value, witness_info)) + } } // these can't get into the `witness_ids` due to the used filters (None, None) => unreachable!("broken allocation filters"), From 10ee5cc0047c368472ca18f21b9d7c5eaf9617e8 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 17 Oct 2024 01:41:37 +0200 Subject: [PATCH 05/16] iface: provide clients with owned state in form of StrictVal --- .../{assignments.rs => allocation.rs} | 16 +- src/contract/mod.rs | 4 +- src/interface/contract.rs | 145 +++++++++++---- src/interface/mod.rs | 2 +- src/lib.rs | 2 +- src/persistence/memory.rs | 22 +-- src/persistence/state.rs | 4 +- src/stl.rs | 2 +- stl/RGBStorage@0.11.0.sta | 176 +++++++++--------- stl/RGBStorage@0.11.0.stl | Bin 11620 -> 11614 bytes stl/RGBStorage@0.11.0.sty | 8 +- 11 files changed, 228 insertions(+), 153 deletions(-) rename src/contract/{assignments.rs => allocation.rs} (92%) diff --git a/src/contract/assignments.rs b/src/contract/allocation.rs similarity index 92% rename from src/contract/assignments.rs rename to src/contract/allocation.rs index f6be139a..cb3cdc64 100644 --- a/src/contract/assignments.rs +++ b/src/contract/allocation.rs @@ -43,6 +43,8 @@ pub struct WitnessInfo { pub ord: WitnessOrd, } +/// Allocation is an owned state assignment, equipped with information about the operation defining +/// the assignment and the witness id, containing the commitment to the operation. #[allow(clippy::derived_hash_with_manual_eq)] #[derive(Clone, Eq, Hash, Debug)] #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] @@ -52,14 +54,14 @@ pub struct WitnessInfo { derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "camelCase") )] -pub struct OutputAssignment { +pub struct Allocation { pub opout: Opout, pub seal: XOutputSeal, pub state: State, pub witness: Option, } -impl PartialEq for OutputAssignment { +impl PartialEq for Allocation { fn eq(&self, other: &Self) -> bool { // We ignore difference in witness transactions, state and seal definitions here // in order to support updates from the ephemeral state of the lightning @@ -74,11 +76,11 @@ impl PartialEq for OutputAssignment { } } -impl PartialOrd for OutputAssignment { +impl PartialOrd for Allocation { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for OutputAssignment { +impl Ord for Allocation { fn cmp(&self, other: &Self) -> Ordering { if self == other { return Ordering::Equal; @@ -90,7 +92,7 @@ impl Ord for OutputAssignment { } } -impl OutputAssignment { +impl Allocation { /// # Panics /// /// If the processing is done on invalid stash data, the seal is @@ -103,7 +105,7 @@ impl OutputAssignment { ty: AssignmentType, no: u16, ) -> Self { - OutputAssignment { + Allocation { opout: Opout::new(opid, ty, no), seal: seal.try_to_output_seal(witness_id).expect( "processing contract from unverified/invalid stash: witness seal chain doesn't \ @@ -125,7 +127,7 @@ impl OutputAssignment { ty: AssignmentType, no: u16, ) -> Self { - OutputAssignment { + Allocation { opout: Opout::new(opid, ty, no), seal: seal.to_output_seal().expect( "processing contract from unverified/invalid stash: seal must have txid \ diff --git a/src/contract/mod.rs b/src/contract/mod.rs index 96298642..cc0c48f2 100644 --- a/src/contract/mod.rs +++ b/src/contract/mod.rs @@ -19,10 +19,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -mod assignments; +mod allocation; mod merge_reveal; -pub use assignments::{OutputAssignment, WitnessInfo}; +pub use allocation::{Allocation, WitnessInfo}; pub use merge_reveal::{MergeReveal, MergeRevealError}; use rgb::vm::OrdOpRef; use rgb::{ExtensionType, OpId, TransitionType, XWitnessId}; diff --git a/src/interface/contract.rs b/src/interface/contract.rs index fe9db18b..1452779f 100644 --- a/src/interface/contract.rs +++ b/src/interface/contract.rs @@ -22,13 +22,16 @@ use std::borrow::Borrow; use std::collections::{BTreeSet, HashMap, HashSet}; +use amplify::confinement; use amplify::confinement::SmallBlob; use rgb::validation::Scripts; -use rgb::{AssignmentType, AttachId, ContractId, OpId, Schema, State, XOutputSeal, XWitnessId}; -use strict_encoding::FieldName; -use strict_types::{StrictVal, TypeSystem}; +use rgb::{ + AssignmentType, AttachId, ContractId, OpId, Opout, Schema, State, XOutputSeal, XWitnessId, +}; +use strict_encoding::{FieldName, SerializeError, StrictSerialize}; +use strict_types::{typify, SemId, StrictVal, TypeSystem}; -use crate::contract::{OutputAssignment, WitnessInfo}; +use crate::contract::{Allocation, WitnessInfo}; use crate::info::ContractInfo; use crate::interface::{AssignmentsFilter, IfaceImpl, StateCalc}; use crate::persistence::ContractStateRead; @@ -38,6 +41,30 @@ use crate::persistence::ContractStateRead; pub enum ContractError { /// field name {0} is unknown to the contract interface FieldNameUnknown(FieldName), + + /// the provided state object is invalid; {0} + #[from] + Typify(typify::Error), + + /// the provided state exceeds maximum allowed length when serialized. + #[from] + Strict(SerializeError), +} + +/// Allocation is an owned state assignment, equipped with information about the operation defining +/// the assignment and the witness id, containing the commitment to the operation. +#[derive(Clone, PartialEq, Eq, Debug)] +#[cfg_attr( + feature = "serde", + derive(Serialize, Deserialize), + serde(crate = "serde_crate", rename_all = "camelCase") +)] +pub struct Output { + pub opout: Opout, + pub seal: XOutputSeal, + pub state: StrictVal, + pub attach_id: Option, + pub witness: Option, } #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Display)] @@ -72,7 +99,7 @@ pub struct ContractOp { impl ContractOp { fn new( direction: OpDirection, - assignment: OutputAssignment, + assignment: Allocation, value: StrictVal, witness: Option, ) -> Self { @@ -87,15 +114,15 @@ impl ContractOp { } } - fn issued(assignment: OutputAssignment, value: StrictVal) -> Self { + fn issued(assignment: Allocation, value: StrictVal) -> Self { Self::new(OpDirection::Issued, assignment, value, None) } - fn received(assignment: OutputAssignment, value: StrictVal, witness: WitnessInfo) -> Self { + fn received(assignment: Allocation, value: StrictVal, witness: WitnessInfo) -> Self { Self::new(OpDirection::Received, assignment, value, Some(witness)) } - fn sent(assignment: OutputAssignment, value: StrictVal, witness: WitnessInfo) -> Self { + fn sent(assignment: Allocation, value: StrictVal, witness: WitnessInfo) -> Self { Self::new(OpDirection::Sent, assignment, value, Some(witness)) } } @@ -113,19 +140,50 @@ pub struct ContractIface { } impl ContractIface { - fn assignment_value(&self, ty: AssignmentType, value: &SmallBlob) -> StrictVal { - let sem_id = self - .schema + fn assignment_type(&self, name: impl Into) -> Result { + let name = name.into(); + self.iface + .assignments_type(&name) + .ok_or(ContractError::FieldNameUnknown(name)) + } + + fn assignment_sem_id(&self, ty: AssignmentType) -> SemId { + self.schema .owned_types .get(&ty) .expect("invalid contract state") - .sem_id; + .sem_id + } + + fn assignment_value(&self, ty: AssignmentType, value: &SmallBlob) -> StrictVal { self.types - .strict_deserialize_type(sem_id, value.as_slice()) + .strict_deserialize_type(self.assignment_sem_id(ty), value.as_slice()) .expect("invalid contract state") .unbox() } + fn allocation_to_output(&self, a: &Allocation) -> Output { + Output { + opout: a.opout, + seal: a.seal, + state: self.assignment_value(a.opout.ty, &a.state.value), + attach_id: a.state.attach, + witness: a.witness, + } + } + + fn state_convert( + &self, + ty: AssignmentType, + value: StrictVal, + ) -> Result { + let t = self.types.typify(value, self.assignment_sem_id(ty))?; + Ok(self + .types + .strict_serialize_type::<{ confinement::U16 }>(&t)? + .to_strict_serialized()?) + } + pub fn contract_id(&self) -> ContractId { self.state.contract_id() } /// # Panics @@ -158,46 +216,63 @@ impl ContractIface { })) } - pub fn assignments_by<'c>( + pub fn allocations<'c>( &'c self, filter: impl AssignmentsFilter + 'c, - ) -> impl Iterator + 'c { + ) -> impl Iterator + 'c { self.state .assignments() - .filter(move |outp| filter.should_include(outp.seal, outp.witness)) + .filter(move |a| filter.should_include(a.seal, a.witness)) + } + + pub fn outputs<'c>( + &'c self, + filter: impl AssignmentsFilter + 'c, + ) -> impl Iterator + 'c { + self.allocations(filter) + .map(|a| self.allocation_to_output(a)) } - pub fn assignments_by_type<'c>( + pub fn outputs_by_type<'c>( &'c self, name: impl Into, filter: impl AssignmentsFilter + 'c, - ) -> Result + 'c, ContractError> { - let name = name.into(); - let type_id = self - .iface - .assignments_type(&name) - .ok_or(ContractError::FieldNameUnknown(name))?; + ) -> Result + 'c, ContractError> { + let type_id = self.assignment_type(name)?; Ok(self - .assignments_by(filter) + .outputs(filter) .filter(move |outp| outp.opout.ty == type_id)) } - pub fn assignments_fulfilling<'c, K: Ord + 'c>( + pub fn output_selection<'c, K: Ord + 'c>( &'c self, name: impl Into, filter: impl AssignmentsFilter + 'c, - state: &'c State, - sorting: impl FnMut(&&OutputAssignment) -> K, - ) -> Result + 'c, ContractError> { - let mut selected = self.assignments_by_type(name, filter)?.collect::>(); + value: StrictVal, + attach: Option, + sorting: impl FnMut(&&Allocation) -> K, + ) -> Result + 'c, ContractError> { + let type_id = self.assignment_type(name)?; + let mut selected = self + .allocations(filter) + .filter(move |a| a.opout.ty == type_id) + .collect::>(); selected.sort_by_key(sorting); let mut calc = StateCalc::new(self.scripts.clone(), self.iface.state_abi); - Ok(selected.into_iter().take_while(move |a| { - if calc.reg_input(a.opout.ty, &a.state).is_err() { - return false; - } - calc.is_sufficient_for(a.opout.ty, state) - })) + let state = State { + reserved: none!(), + value: self.state_convert(type_id, value)?.into(), + attach, + }; + Ok(selected + .into_iter() + .take_while(move |a| { + if calc.reg_input(a.opout.ty, &a.state).is_err() { + return false; + } + calc.is_sufficient_for(a.opout.ty, &state) + }) + .map(|a| self.allocation_to_output(a))) } pub fn history( diff --git a/src/interface/mod.rs b/src/interface/mod.rs index 4e0edd21..78403f1b 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -35,7 +35,7 @@ mod calc; pub use builder::{BuilderError, ContractBuilder, TransitionBuilder, TxOutpoint}; pub use calc::{AllocatedState, StateAbi, StateCalc, StateCalcError}; -pub use contract::{ContractError, ContractIface, ContractOp, OpDirection}; +pub use contract::{ContractError, ContractIface, ContractOp, OpDirection, Output}; pub use contractum::IfaceDisplay; pub use filter::{AssignmentsFilter, FilterExclude, FilterIncludeAll}; pub use iface::{ diff --git a/src/lib.rs b/src/lib.rs index a67d7a3d..58f9e507 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -46,7 +46,7 @@ mod contract; pub mod info; pub use bp::{Outpoint, Txid}; -pub use contract::{MergeReveal, MergeRevealError, OutputAssignment, WitnessInfo}; +pub use contract::{Allocation, MergeReveal, MergeRevealError, WitnessInfo}; pub use rgb::prelude::*; pub use rgb::rgbasm; pub use stl::{LIB_NAME_RGB_STD, LIB_NAME_RGB_STORAGE}; diff --git a/src/persistence/memory.rs b/src/persistence/memory.rs index cb14ee79..81acbf70 100644 --- a/src/persistence/memory.rs +++ b/src/persistence/memory.rs @@ -60,7 +60,7 @@ use super::{ use crate::containers::{ AnchorSet, ContentId, ContentRef, ContentSigs, SealWitness, SigBlob, Supplement, TrustLevel, }; -use crate::contract::{GlobalOut, OpWitness, OutputAssignment}; +use crate::contract::{Allocation, GlobalOut, OpWitness}; use crate::interface::{Iface, IfaceClass, IfaceId, IfaceImpl, IfaceRef}; use crate::LIB_NAME_RGB_STORAGE; @@ -565,7 +565,7 @@ impl StateReadProvider for MemState { .values() .flat_map(|state| state.known.keys()) .any(|out| out.witness_id() == id) - || unfiltered.state.iter().any(|a| a.witness == id) + || unfiltered.owned.iter().any(|a| a.witness == id) }) .map(|(id, ord)| (*id, *ord)) .collect(); @@ -717,7 +717,7 @@ pub struct MemContractState { contract_id: ContractId, #[getter(skip)] global: TinyOrdMap, - state: LargeOrdSet, + owned: LargeOrdSet, } impl MemContractState { @@ -732,7 +732,7 @@ impl MemContractState { schema_id: schema.schema_id(), contract_id, global, - state: empty!(), + owned: empty!(), } } @@ -814,7 +814,7 @@ impl MemContractState { .filter_map(|(n, a)| a.revealed_seal().map(|seal| (n, seal, a.as_state()))) { let assigned_state = match witness_id { - Some(witness_id) => OutputAssignment::with_witness( + Some(witness_id) => Allocation::with_witness( seal, witness_id, state.clone(), @@ -822,11 +822,9 @@ impl MemContractState { *ty, no as u16, ), - None => { - OutputAssignment::with_no_witness(seal, state.clone(), opid, *ty, no as u16) - } + None => Allocation::with_no_witness(seal, state.clone(), opid, *ty, no as u16), }; - self.state + self.owned .push(assigned_state) .expect("contract state exceeded 2^32 items, which is unrealistic"); } @@ -945,7 +943,7 @@ impl> ContractStateAccess for MemContract { ) -> impl DoubleEndedIterator> { self.unfiltered .borrow() - .state + .owned .iter() .filter(move |assignment| { assignment.seal.to_outpoint() == outpoint && assignment.opout.ty == ty @@ -1018,10 +1016,10 @@ impl> ContractStateRead for MemContract { } #[inline] - fn assignments(&self) -> impl Iterator { + fn assignments(&self) -> impl Iterator { self.unfiltered .borrow() - .state + .owned .iter() .filter(|assignment| assignment.check_witness(&self.filter)) } diff --git a/src/persistence/state.rs b/src/persistence/state.rs index 9545b776..216e63df 100644 --- a/src/persistence/state.rs +++ b/src/persistence/state.rs @@ -34,7 +34,7 @@ use rgb::{ }; use crate::containers::{ConsignmentExt, ToWitnessId}; -use crate::contract::OutputAssignment; +use crate::contract::Allocation; use crate::persistence::{StoreTransaction, UpdateRes}; #[derive(Debug, Display, Error, From)] @@ -286,7 +286,7 @@ pub trait ContractStateRead: ContractStateAccess { fn contract_id(&self) -> ContractId; fn schema_id(&self) -> SchemaId; fn witness_ord(&self, witness_id: XWitnessId) -> Option; - fn assignments(&self) -> impl Iterator; + fn assignments(&self) -> impl Iterator; } pub trait ContractStateWrite { diff --git a/src/stl.rs b/src/stl.rs index 1ebfc6a6..d6e1a7a8 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -37,7 +37,7 @@ pub const LIB_NAME_RGB_STORAGE: &str = "RGBStorage"; /// Strict types id for the library providing standard data types which may be /// used in RGB smart contracts. pub const LIB_ID_RGB_STORAGE: &str = - "stl:iayFnuhB-sjXxWhi-Pp!FSyO-astclK4-icTXDwX-O0Fb4F4#floor-avatar-lazarus"; + "stl:RMDj!yyo-ca0Rmdl-pBBc50W-ciu1!P3-U8gHIqL-0Y83X50#memo-ballet-fresh"; /// Strict types id for the library representing of RGB StdLib data types. pub const LIB_ID_RGB_STD: &str = diff --git a/stl/RGBStorage@0.11.0.sta b/stl/RGBStorage@0.11.0.sta index 8ef355eb..0a7db3fc 100644 --- a/stl/RGBStorage@0.11.0.sta +++ b/stl/RGBStorage@0.11.0.sta @@ -1,5 +1,5 @@ -----BEGIN STRICT TYPE LIB----- -Id: stl:iayFnuhB-sjXxWhi-Pp!FSyO-astclK4-icTXDwX-O0Fb4F4#floor-avatar-lazarus +Id: stl:RMDj!yyo-ca0Rmdl-pBBc50W-ciu1!P3-U8gHIqL-0Y83X50#memo-ballet-fresh Name: RGBStorage Dependencies: StrictTypes#century-comrade-chess, @@ -11,7 +11,7 @@ Dependencies: Std#ralph-blue-lucky, RGBLogic#ohio-electra-dilemma, Bitcoin#signal-color-cipher -Check-SHA256: b78e8c45504383900212ce4d621bac70640f73758b4785d2451f48687eebdc7c +Check-SHA256: 1e7e30d1c26d606642c6284e6be3f07d74d165c362f24ee5def19faaca9d5330 3Q|WxQ*>`~VP|CtMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r3sZD*X=8L$d2nTORuk6O)Q5AK bFW;JEQ>MoHhG*Mzd(pEtONi$rOUxc20~CnZ*pZ~a5aA+<>R2XhQO_4{AcS-HH^7AVzASV8M4NYxyCjH @@ -109,92 +109,92 @@ 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 -WRj~^37YhpmjD0&000000RI300000000000000000RR900000000>QGZBuk%b7%$)2yfc^lq>z|G!4fU)2DQrPzVkwe;&S{2rNlD$O59e#ogQsB77jPl+h5j^*S;FuZ_m{WNzU! -AS*T=d6X;t=`;<;71O75notN1DSsZmvAF3TYWxc`p^UTx9aSKLvL!Hqk0OrrRGaio4`M!v0000000000 -{{R30000001#@+9aBKhy0=?Vlw9=)(YVD5X(Bh@-;YAffP|O75Lc0RpIS^JwJO-Gpx7s+uExGllhUte$ -e$Op^sMk_Bzn7+|3$axzr2q*6z1!%t(xt#^?T+No;-&53MHNC&%mm{?y8_)g5LQJzV?EP}uuDl+D$lsi -ICW4a8e$Z2e6I7`3evG=Yh^sO0000000000{{R30000000000000000{{R30000002V!+@WNc+~015)H -jmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&RAdy}<28ig(gSpg+?&9*`C2(3=%09avzwZKZf-~wC% -uZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZm{b~4y9C9`4X%pen_fPY -0000000000|NsC0000003T1e7Wo~n6Z*Fq{3IeZ<#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=?^x -=6W7=VqesjRYGc!>wZFzp>JB4@xD;^wu&SY_r(IQjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&R? -krgyL25hbsyp?a}5-x=-+yHc@4oMPeoYe!lEU|R}0000000030|Ns9000009cWHEPWpi_7a{vkguZ_m{ -WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZmiECIT&Bl;lSX#$ms8AQN7m&qYE2s&92Kh8W}@zf2sFIAOHXW -000000RR90{{R3001IJsbYWv?ZDnqBa{vkguZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZmgmDd% -EKc;pw+KsVi?D}qDSkO*B!5Mb*xG|_(S5o&00;m8KmY&$000000RR900000000000000000RR6000000 -01I -xYW^+v~7{W03rq(;firJ0000000000|Ns90000003UqmJWm9=`bY*PC`}q*r{eiB7ehUYis7~w1CQOqefKeZ3;Wd%uopqe!>_vj93Tb3zZggpMX=QT&3IeZ<#`k1y -;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=^8dfQB3>bs~EXcCXx(drQcb3B`Fx$)^%va$Ar)C7c4i+vv2? -rNCR2XhQO_4{AcS-HH^7AVzASV8M4NYxyCl9FjWFA`CQ2GiK9iL -KbGE6DZmrA4)G`0A&^0p`%?-6VsJHoA?4$swuZp1Wc+9AOf`(TIbyKWjTy4WkGaM+5(KBV0uX$PL@)I= -)&*`^S@`8Scoz5#{lyP)a751L0000000000|Nj60000001aoO;a{vkgz1!%t(xt#^?T+No;-&53MHNC& -%mm{?y8_)g5LQJz;?xyT5z&Ua+M@}mOiDpYxh>^^GknUxTJ!XL#OUcE0=?Vlw9=)(YVD5X(Bh@-;YAff -P|O75Lc0RpIS^JwJcbw$ENEw7&f?o%+)B!ZpG}K!%4G?I4vp$|ttu*CMF0Q*000000RR600000000>QG -ZBuk%bY%tt33q99Ze??GWpe-u0>gzKLsCCC$c=Uszhl -V5m?Ru@{iVU*wrVdeH+Q@FPbX@dD>lppP|r7nSZ$D@8DuxRa_WcH0nj%57ffI2NNjo|$sHLdY0XT`|v$ -|M|2EBF6^D+OST}`A!+zFZPFTn&AKd0000000960|Nj60000SNZ*FvQVPkZ2015)HjmGz6Zs9Z_D>fc^ -lq>z|G!4fU)2DQrPzVkwe;&S{2rNlD$O59e#ogQsB77jPl+h5j^*S;E4$E#+hX^`zsZ&Tl -gCG9;!;p0|>d6h~fj!Md?2W%$0000000000{{R3000000 +b7^O8ZDnqBRC#b^owA~_)i}*_Qj`w<0nYCCRFDc{!UsZqyzOYb66V_43PEgaZ)0I}X>V?#;91nsu+1H% +suE1D6u@lRoC;S?XbB(j&QSOSPz0a~RC0B5bWCM-Wo)&%LXEmL6-F5v>3G|uUigF$Iw^!m+g!OaP05*n2+UEn$VY06ag%An>_FbOoG7@PGN0jWJYOaY-CMkbYWC^aAm`1 +<%~T%0%0eh&Q^)o89Ex~PX5e}`A;#FO3ABStqEB2u*`(KJ8e4#|WIM{I9mVQfieVPj>~|BtqCIH`QK6F1|v)Z${_ +U85pQj^zm^DU~vi8uS+kQ+04~Y)xTs-Vzs+-~y(u)KQ?3g=q&>T!Ej;9TxQjc0+10Fg2)p3Qu=#Wn@Wa +VPj?D)D=(>(T2L(qY0=?Nkr04IdejB5_YJg;9E|1`d*r&;qSS3+uh`0YNLave-Im7x;m>=zTw_)ojDN{iR+YxT1qeJQTRI%yh?{hxxA$L2PhnVMAeXb4+h!VRLBFJq*Jt8?Abr +ta^#~Iw-!oZ%zqO(A&rh^vGm~tg_w^L2PhnVN-2kY-~(#WMOk?3sZD*X=8L$d2nTO4*&^LN2 +X=Q9=Q)O*QWK$LhgcQkwbf~^M){{|8P%hsRk~m~ep32F151Y4WWC&DwaAi(mZDnMP)DN(0hN+Kdp}ZAoN($wDX8VgT7DmW3qm%zcviBmGB|7z0dgBIJ4&sCG^VR$+2!VQzGR(<~&{!{{>E!(#o& +^pB98KZhv1GEPn8Orhb4n;8ZMQ)zl>ZfBCy0{K32d-H~a`3x8b375ImR&CF_#3#*gz1^xtuG$bzVQpn( +MrmbiWOGwxZAoO8A%m*X98W>f2s0TH8C&EH;|vtDTYgh)4~t7}WW`YoMQ(L%R$+2!VQzGDn938Qb#DiI +%LhXtBc@pg0t!L7$2{bU&sPXOO(dS=5LRJwX<=@3Np5CuQ)O*QWc?UbbJ9Xwr}~3wv^yxa@v}v^+kiGS +R2X#8M$tG2GZIy9X>V>;VRC6_vj93RHP; +Wm9=`bY*P@01ZQLZgg^CV{}PwWMy~;0t|3>gzLOBVfUz`Mi!Z}iQtl5;XwV(E`Zdd&WRj~^37YhpmjD0&000000RR900000001j_;bZ~EJ +Zgfv@Z*_EY015)HjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&TkXBWLg67cp3gzo-sO&$va11I@T +$h!rSEX2t%Czh%J2?DQ;#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=?+hynwMZT8l5kSW@l}O=!>^ +xB4~9n`Dx!RtcK)nwJ0o0000000960{{R30000000000000960{{R30000n8Wo<)mZgg^CV{}t=VRU5% +1PF6uXk~3-Nn`@AjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&S+Qq$W5tE;F{pQrXd&=l*`O?@#x +{Qdy?T_k!`1dtF4V{dMBa$#e1Nn`@AjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&S{2rNlD$O59e +#ogQsB77jPl+h5j^*S;JXKZg`VQc^j0>g +zSZuM4oQf!Y4K`P(FaQVwIle)QgI&pHa%8Z1>xis%K>dbv;0wBb*7)Id;7I5;T&_H+G%6DVUHTf +p;u=X0|Kv&#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=>}YR2^S7pk#{MS?zgMX@X{kfl~;6wBm#t +C>wDnA0009BO=WFKZe(S61_cdoa6)x%WNc+gZe(S6015)HjmGz6 +Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&S-$mV(;bz)!CmQ_M(k?Vd!kfCo{nDM?)_qK{868FUduZ_m{ +WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZm1ACLTJsO2B2U!6ncg?mz@CdC==Kxq?gSEg)z2E{|00000 +00000|Ns90000006Jm94WNc+aZ*FvQVPkYjZe(S6015)HjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkw +e;&RAdy}<28ig(gSpg+?&9*`C2(3=%09avzwZKZf-~wC%uZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1 +DSsZmp9m~TI>-W|y2ahx3nF|Vuawki#7NH?S|Q-Q!u2{b0000000000|Ns90000005@L03WNc+uX>@L7 +b8|^g)RqK0VQ|Mwn6X+txo3v +SYd;;z)HQ~0$czI0>gzKLsCCC$c=UszhlV5m?Ru@{iV +U*wrVdeH+Q@FPbX@c;k-000000RI300000000000000000RR900000001abrZgg^CV{}PwWMy~&3IeZ< +#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=@LlEJ-@Z0;0Ob-P{Wzd?2rs)M&&=&l*}G;Jw22Ix+z) +)N;MU`Np56icmN6l +uZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZm+lpEmf)o&SDDwD>KtpQ8M_qJyiO1VIUJ=H=)@ii_ +00{!GjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&S*5WIk~G+K)5%bR49t5yk` +^qQ9d000000003000000000000000000030|Nj6000008O=WFUbYXL71`P;vV`ybE<3hUv-8m3eMLapj8a{pyIM27f +oOFHbufC9*xQ=a*L`qQ5aG5b!Ay5DS000000093000000000MPWo~72Wpe-u0>gzMlvzNjk^^qPoT1+zTRnAg`3vXv9d*8d@RXy~6c6G6JuS#`k1y;WQvCHXeDD +EB)y-4aXJJr*xW72o5QK9=@@-=^kqQ3p1gNv;!SgAcC?bFoBOEj`UQU^i2<9K8XMT000000093000000 +000GZb#QQO015)V+vv2?rNCE<3hUv-8m3eMLc6Y(}}Q4NmeS)xXw6rP$n8; +6mfj6^V>gz5{!cwLKbzE(ciwC3nrXLGTEzPUiqvVS}~6O1>gzD1E0G&%-s +t`)qMZ{`v%g)H0vbfykT5^0>(1Gy}*bpQYW000000RR90{{R30010<#bZ%vHb7gY?3IeZ<#`k1y;WQvC +HXeDDEB)y-4aXJJr*xW72o5QK9=?fdSS8KIkY89@$6%;X7qJ(R#b4x^L3+^xAn+qc8}S0Y+vv2?rNCjuaWwz{0000000960{{R30000Vfd2nS@d2@7SZ30E=qhH(h&PZdlOljoA7|k;k>s6qoa5|8f~g8=WMyu2X>@62a{vkguZ_m{WNzU!AS*T= +d6X;t=`;<;71O75notN1DSsZmw&;L{94K`ndk%K5+?9Jv$dw7jc}U5p5@2#$kUJ%u0=?Vlw9=)(YVD5X +(Bh@-;YAffP|O75Lc0RpIS^JwJfh%P)X}ib9i^%gOs*8bY}uR&S59aNAMwsm_ykY{pa1{>000000RR60 +0000000eAlVsiir0%CAAe<9`Lptgpr6F_xjAC6(~TLj#*ewiHm5LE0xkJm$nc4yMWR2J-cc#Q +6SofWC)gp7L6!Sc3IbwqHGd)Hlr&gK9B000000096000000000DYX=if)3Ie^`=(N(Mz-sM|E<3hUv +-8m3eMLgov6;Kh;hPv9L38+j;K}xwT<$*JN%D`Il^nAqV=^+BW+vv2?rNCUOOvDqlqa0000000030{{R3000008O=WFUbYXO5 +1_B9pX>@L7b8}^L015)HjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&SxYgi@C#*klFTE}3hP#3Wm +ki}o*nL&Ed10e7tM;q}1=To4MHF_77?oTU4FqgQKswsBc5OvCJUgtO#qdT6Na=Svv7*ky_&y4^1v>gzMlvzNjk^^qPoT1+zTRnAg`3vXv9d*8d@RXy~6c6G6Ac7Ex1s`aa6PN-Fgk0S2h>I +cS>a?4Yu+n!-bhcpbh{4000000093000000000 -----END STRICT TYPE LIB----- diff --git a/stl/RGBStorage@0.11.0.stl b/stl/RGBStorage@0.11.0.stl index 948dd4ca60be646faafeccd9df39ff83afb2c88d..3d8ee703ca4a1251c390d95c56a78d30ba1f1635 100644 GIT binary patch delta 153 zcmaD7buVfIkA(KzO^Y^OwK!WGG==XU$54X;AUckoy1^=Nm0NW-)761SM delta 159 zcmcZ?^(1NokA&g854oGT?DySjUj6YvTh$}ui|?E@mRKy&3;8y)CVc<@JOTgGl7i9_ z$KvA5^t{~Eypql45-}XC#U+U)sgt?Yl@$mXu=%z^FpmM>>Ac`}4y)po!5;R_^8bDx ao=|H1>Ll;;M%%NlZ+iDfGeE(AC=CGMUPgBS diff --git a/stl/RGBStorage@0.11.0.sty b/stl/RGBStorage@0.11.0.sty index 805aadf7..67c9f1b5 100644 --- a/stl/RGBStorage@0.11.0.sty +++ b/stl/RGBStorage@0.11.0.sty @@ -1,5 +1,5 @@ {- - Id: stl:iayFnuhB-sjXxWhi-Pp!FSyO-astclK4-icTXDwX-O0Fb4F4#floor-avatar-lazarus + Id: stl:RMDj!yyo-ca0Rmdl-pBBc50W-ciu1!P3-U8gHIqL-0Y83X50#memo-ballet-fresh Name: RGBStorage Version: 0.11.0 Description: RGB storage library @@ -144,7 +144,7 @@ import RGBStd#zebra-twist-tango use SupplItem#jargon-orchid-forget use Modifier#saturn-escort-jordan use NamedFieldAssignmentType#origin-caramel-flipper - use OutputAssignment#chicago-neuron-concept + use Allocation#mimosa-savage-future use TrustLevel#cobra-script-albino use StateAbi#thermos-demo-fragile use NamedFieldMetaType#prefix-carmen-artist @@ -198,11 +198,11 @@ import Bitcoin#signal-color-cipher @mnemonic(carol-salute-aroma) data ContractIndex : publicOpouts {RGBCommit.Opout ^ ..0xffffff}, outpointOpouts {RGBCommit.XChainExplicitSealTxid -> ^ ..0xffffff {RGBCommit.Opout ^ ..0xffffff}} -@mnemonic(carbon-arena-ivan) +@mnemonic(dolby-mammal-pogo) data MemContractState : schemaId RGBCommit.SchemaId , contractId RGBCommit.ContractId , global {RGBCommit.GlobalStateType -> ^ ..0xff MemGlobalState} - , state {RGBStd.OutputAssignment ^ ..0xffffffff} + , owned {RGBStd.Allocation ^ ..0xffffffff} @mnemonic(mary-mineral-frame) data MemGlobalState : known {RGBStd.GlobalOut -> ^ ..0xffffffff RGBCommit.StateData}, limit U24 From 46694a58ec46495cca6689a2bb3a7a31ffefaf00 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 17 Oct 2024 02:20:17 +0200 Subject: [PATCH 06/16] iface: remove OwnedIface, change owned state inheritance mechanics --- src/interface/contractum.rs | 14 +- src/interface/iface.rs | 47 +----- src/interface/inheritance.rs | 16 +- src/interface/mod.rs | 2 +- src/stl.rs | 4 +- stl/RGBStd@0.11.0.sta | 318 +++++++++++++++++------------------ stl/RGBStd@0.11.0.stl | Bin 18172 -> 18172 bytes stl/RGBStd@0.11.0.sty | 15 +- stl/RGBStorage@0.11.0.sta | 211 ++++++++++++----------- stl/RGBStorage@0.11.0.stl | Bin 11614 -> 11571 bytes stl/RGBStorage@0.11.0.sty | 11 +- stl/Transfer.vesper | 9 +- 12 files changed, 293 insertions(+), 354 deletions(-) diff --git a/src/interface/contractum.rs b/src/interface/contractum.rs index 01cbdbe6..0fa8b927 100644 --- a/src/interface/contractum.rs +++ b/src/interface/contractum.rs @@ -28,9 +28,7 @@ use rgb::Occurrences; use strict_encoding::{FieldName, TypeName, VariantName}; use strict_types::{SemId, SymbolicSys}; -use super::{ - ArgMap, ExtensionIface, GenesisIface, Iface, IfaceId, Modifier, OwnedIface, TransitionIface, -}; +use super::{ArgMap, ExtensionIface, GenesisIface, Iface, IfaceId, Modifier, TransitionIface}; struct ArgMapDisplay<'a>(&'a ArgMap); @@ -266,13 +264,9 @@ impl<'a> Display for IfaceDisplay<'a> { write!(f, "{fname}")?; sugar(f, a.required, a.multiple)?; f.write_str(": ")?; - match a.owned_state { - OwnedIface::Any => write!(f, "AnyType")?, - OwnedIface::Amount => write!(f, "Zk64")?, - OwnedIface::AnyData => write!(f, "Any")?, - OwnedIface::AnyAttach => write!(f, "AnyAttachment")?, - OwnedIface::Rights => write!(f, "Rights")?, - OwnedIface::Data(id) => resolve(f, self.types, id)?, + match a.state_ty { + None => write!(f, "T any => T")?, + Some(id) => resolve(f, self.types, id)?, } writeln!(f)?; } diff --git a/src/interface/iface.rs b/src/interface/iface.rs index d4a904fc..684cfc1c 100644 --- a/src/interface/iface.rs +++ b/src/interface/iface.rs @@ -200,25 +200,28 @@ impl GlobalIface { serde(crate = "serde_crate", rename_all = "camelCase") )] pub struct AssignIface { - pub owned_state: OwnedIface, + pub state_ty: Option, + pub attach: Option, pub public: bool, pub required: bool, pub multiple: bool, } impl AssignIface { - pub fn public(owned_state: OwnedIface, req: Req) -> Self { + pub fn public(state_ty: Option, attach: Option, req: Req) -> Self { AssignIface { - owned_state, + state_ty, + attach, public: true, required: req.is_required(), multiple: req.is_multiple(), } } - pub fn private(owned_state: OwnedIface, req: Req) -> Self { + pub fn private(state_ty: Option, attach: Option, req: Req) -> Self { AssignIface { - owned_state, + state_ty, + attach, public: false, required: req.is_required(), multiple: req.is_multiple(), @@ -226,34 +229,6 @@ impl AssignIface { } } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = LIB_NAME_RGB_STD, tags = order)] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub enum OwnedIface { - #[strict_type(dumb)] - Any, - Rights, - Amount, - AnyData, - AnyAttach, - Data(SemId), -} - -impl OwnedIface { - pub fn sem_id(&self) -> Option { - if let Self::Data(id) = self { - Some(*id) - } else { - None - } - } -} - pub type ArgMap = TinyOrdMap; #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display, Default)] @@ -434,11 +409,7 @@ impl Iface { .values() .copied() .chain(self.global_state.values().filter_map(|i| i.sem_id)) - .chain( - self.assignments - .values() - .filter_map(|i| i.owned_state.sem_id()), - ) + .chain(self.assignments.values().filter_map(|i| i.state_ty)) } pub fn find_abstractable_impl<'a>( diff --git a/src/interface/inheritance.rs b/src/interface/inheritance.rs index 518c0595..2c746494 100644 --- a/src/interface/inheritance.rs +++ b/src/interface/inheritance.rs @@ -27,7 +27,7 @@ use rgb::{ use strict_encoding::{FieldName, TypeName}; use crate::interface::{ - ExtensionIface, GenesisIface, Iface, IfaceImpl, Modifier, OpName, OwnedIface, TransitionIface, + ExtensionIface, GenesisIface, Iface, IfaceImpl, Modifier, OpName, TransitionIface, }; #[derive(Clone, PartialEq, Eq, Debug, Display, From)] @@ -273,18 +273,6 @@ pub enum ExtensionError { InheritanceOverflow, } -impl OwnedIface { - pub fn is_superset(self, other: OwnedIface) -> bool { - if self == Self::Any { - return true; - } - if self == Self::AnyData && matches!(other, Self::Data(_)) { - return true; - } - self == other - } -} - impl Modifier { pub fn is_final(self) -> bool { self == Self::Final } pub fn can_be_overridden_by(self, other: Modifier) -> bool { @@ -401,7 +389,7 @@ impl Iface { } } Some(orig) => { - if !orig.owned_state.is_superset(e.owned_state) { + if orig.state_ty.is_some() && orig.state_ty != e.state_ty { errors.push(ExtensionError::AssignmentType(name)); } else if orig.required & !e.required { errors.push(ExtensionError::AssignmentOcc(name)); diff --git a/src/interface/mod.rs b/src/interface/mod.rs index 78403f1b..7b70ae47 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -40,7 +40,7 @@ pub use contractum::IfaceDisplay; pub use filter::{AssignmentsFilter, FilterExclude, FilterIncludeAll}; pub use iface::{ ArgMap, AssignIface, ExtensionIface, GenesisIface, GlobalIface, Iface, IfaceClass, IfaceId, - IfaceInconsistency, IfaceRef, IfaceWrapper, Modifier, OpName, OwnedIface, Req, TransitionIface, + IfaceInconsistency, IfaceRef, IfaceWrapper, Modifier, OpName, Req, TransitionIface, ValencyIface, }; pub use iimpl::{IfaceImpl, ImplId, NamedField, NamedType, NamedVariant, SchemaTypeIndex}; diff --git a/src/stl.rs b/src/stl.rs index d6e1a7a8..7507e045 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -37,11 +37,11 @@ pub const LIB_NAME_RGB_STORAGE: &str = "RGBStorage"; /// Strict types id for the library providing standard data types which may be /// used in RGB smart contracts. pub const LIB_ID_RGB_STORAGE: &str = - "stl:RMDj!yyo-ca0Rmdl-pBBc50W-ciu1!P3-U8gHIqL-0Y83X50#memo-ballet-fresh"; + "stl:lnl6QOG0-EYfOLKP-MHdEyA3-$cyUNuc-F3XmU!W-0glc1M0#alaska-phone-bagel"; /// Strict types id for the library representing of RGB StdLib data types. pub const LIB_ID_RGB_STD: &str = - "stl:vdvotNKl-wGrtjuT-Q4qXt4U-UVQlDMB-ONCuwLd-ORBWRTw#zebra-twist-tango"; + "stl:yMGmidPl-LcWFyh!-W6sQ3K5-JQ8evpO-BGuI!lA-0htx!kg#chemist-enjoy-sound"; #[allow(dead_code)] #[derive(Debug, From)] diff --git a/stl/RGBStd@0.11.0.sta b/stl/RGBStd@0.11.0.sta index f1d81936..1491d12d 100644 --- a/stl/RGBStd@0.11.0.sta +++ b/stl/RGBStd@0.11.0.sta @@ -1,5 +1,5 @@ -----BEGIN STRICT TYPE LIB----- -Id: stl:vdvotNKl-wGrtjuT-Q4qXt4U-UVQlDMB-ONCuwLd-ORBWRTw#zebra-twist-tango +Id: stl:yMGmidPl-LcWFyh!-W6sQ3K5-JQ8evpO-BGuI!lA-0htx!kg#chemist-enjoy-sound Name: RGBStd Dependencies: StrictTypes#century-comrade-chess, @@ -9,7 +9,7 @@ Dependencies: RGBCommit#printer-window-alpine, Std#ralph-blue-lucky, Bitcoin#signal-color-cipher -Check-SHA256: 9c8622031666c98c3fbaacf4d05380087e07145e9901c83988c8071f09cd9cca +Check-SHA256: 4b921710f4ab25f21c5be62b8015e9456f1d473c6aca46706d8a71155de55640 22w{tQ*>kpMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r3sZD*X=8L$d2nTORuk6O)Q5AKbFW;J EQ>MoHhG*Mzd(pEtONi$rOUxc20~CnZ*pZ~a5aA+<>R2XhQO_4{AcS-HH^7AVzASV8M4NYxyCjHL2Pwa @@ -93,7 +93,7 @@ WPQm(C)8p9*(R2SB=5|9lKCV3N0b-?Ol>0MdKRd5P6t+Da%o|1bb-?>B-g{}GTFmo{mAr>kexq=D7-RG P2^0W;fb3W1_o1UdTDNFlG6hDK5~2WhJ*PG7zYWLxz$!}&%4AY&2YWlsz$Eb5KdujWn@NaWo%?~Q)O*Q WS1d>s?i)zLD2{^84?*=6Qgx+2Ybs0Lm?xkSqB0N LAl2~i-ZdPG(X<=@3b5mt)No4(ju7iFH2b-u)>&PZdlOljoA7|k;k>s6qoa5|8f~g8rd2nS@d2@7SZ7Bc` +Rc>i-ZdPG(X<=@3b5mt)No4(ju7iFH2b-u)>&PZdlOljoA7|k;k>s6qoa5|8f~g8rd2nS@d2@7SZ72W_ L2hGcZ*pa1LUnFrY-Mu<0|5qfVQ_L~bN~eb0U2t1clvx>c=Rsq;sPX6HoL|NSa7!~_8VA>68!B7oB{=J aB^jI00jX7%7on+S(hIgz7_S^D)_zOM5Br0>DDqZ(Q0|sPobz*E~00sgEbYXCEWpn`I^CwqAYJB+ZKALhJOg5MR2m;D19&dx0-7pM3Z=O*v*GCA9fL-<|HrZsA`NnJlR3~_8cxJL| x?WKK>7x;m>=zTw_)c;WdYt27n9%urmoacppk`X2UT2wpUNE;^#pc9YB4Z1sCou)bz*F3 -V*<)79&dx0-7pM3Z=O*v*GCA9fL-<|HrZsA`NnJlR3~AEBGG%U@MZ$v=XJ?|;InIPy66cFfOYp#JM2r7 -_Du+KWpQ~GYywm#VTK~nd#>D0(t`--)Viz -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 -qhH(hC`}q*r35LOoBKkGa -Y9#cS7Qj{WgyAGcS>>g~&^g7C`}q*r8?;yf@?frQ$owe+rTo-{ -AMw{vgzX#P!9p!}0yp?_3`b>dWpinBNoHYVWd;TaZEs|0W@%+|0hAo?WyWV%Bqkq0>u^7-u;qAzHYrYi -ZOnAva3v<@st9dmbYWy+bYTDq0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*&DQ20rFt3ZOHs7 -0;T-agdg$OP=xIp;K4#IcLF!~asU7T000000RI300000000(DmZ(?C=a{vkgMe3tp+xFv-0Xp&G?S=|} -9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0>gzBa)$q57bK6Q|uUfIMEX^1}Vv6tLB!)|10-o)0prc>n+a000000RI3000000 -01IJrb7^O8ZDnqBa{vkgMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{ -AMw{vgzX#P!9p!}0yp?_0>gzBa)$q57bK6Q|uUfIMEX -^1}Vv6tLB!)|10-o)0prc>n+a000000RI3000000010+sY-Mg^X=QT&2?9mxqhH(hC`}q*r35LOoBKkGaY9#cS7Qj{WgyAGcS>>g~ -&^g7ioJpYH;+t0eX2w~A!Q+0eaZ{MVyc -PK^k1WpQ~GYywm#VTK~nd#>yWpZgcQkwbf~^M){{|8P%hsR -k~m~ep32F151Y4WWC&?)Xk~I~baMa*0XxdTfddHPE2~=}XorO3wsWOd*yR8%b;g^;wLfB`aR2}S00000 -0RI3000000010$yZDn(GVQp{#07wXJWprU=VRT^t3IavyqhH(hZ4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C -`4HJ_1fvw5rj-B|XP@r^w5ufb=C_Ju$l1`nW&GEpSWb-q0000000030000000000BXKZg`VQf=$VRU5x -3IavyqhH(h}`A;#FO3ABStqEB2u*`(KJ8e4#|W70000000030000000000BVRLh7XKrm}Zgg`1 -3IavyqhH(ha{vkg -Me3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_ -0X}Q-^^?(m0E0zBOZWn(@&jfq2YNoZ;ZAl)>;YPDKL7v#000000RI300000000(DfZe??6a{+bjCH_26 -kAtYeN1V@6CZgT(%0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_ -Fs4If6Z`oP*&DQ20rFt3ZOHs70;T-agdg$OP=xIp;K4#IcLF!~asf9E8yY=#e=i37J-o5}w=U0FTPy7> -iqjyYR#Y>))`9>4000000093000000000VQcywiMb7^mGa{vkgMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uM -rbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0XSPta$W&i*H000000RI300000001#wlW?^+~bWd<)a$$67Z*Bkt0ssVVZ*FA(00035b8l^B00jX8 -Me3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_ -24!+`Z*p@03IavyqhH(h>gzP9Lqh8!q$B6|*YuiTY;OURW8#d%1{rxIXtTaY^?oCir}VPj=U -WCZ~L2LJ#-AOHzTW?^GxNo{a!1`P*xWpZ_ZDC1d0>gzLZka+XJhss8OG%_CC-Q>(otsF+cqN -0Qy}ddQ=3E5C>^yVPj=UWC1(Mz<~n@;VY|KA!vt$qMEp^75#kD_Tqj3pzX>Db5bYX39002k` -ZDn*}WMOn+00{xTfrw&K4w%I2J!>5*n2+UEn$VY06ag%An>_FbOoG7x0000000030000000000BXKZg` -VQf=$VRU5x2?23(9Y)dB+Qf@I7Kdvbxk#NQ%2Ip^oEeXABZ7(pf`tG8000000093000000000YNb8~5D -Zf#|5baMa+0huBwu~C-QVH212O0vm-vwNnjOqUO({d!Yj6^~`qZ~y=R000000RI3000000010+sY-Mg^ -X=QT&2?17zrJCAYw97+KWFy8eZUu~dV(l5N%b&~h(10yyF^B*F000000093000000000Yga$#@6C -ZgT($0XROpRQe`%bQtg9OuU(MB+3^mE|~AfiD0OzeAWk8kN^Mx000000RI3000000019PzbY*UHX>V?G -00{wU#AUTvyg$3{N++IppJQl5+tKwp$xtHBFa^7o2YcTD00000000300000000006WpZ+Fa&rI)0mEnI -j6FO8VJD!@R*BddIvVCq{>+4TF2^XfWAFT{UH||9000000RI3000000010Gec4cgDaAk4=uZ_m{WNzU! -AS*T=d6X;t=`;<;71O75notN1DSsZmw&;L{94K`ndk%K5+?9Jv$dw7jc}U5p5@2#$kUJ%u2y=8{bY($e -X#uslLXEmL6-F5v>3G|uUigF$Iw^!m+g!OaP0#x3$o4Af` -kVHyQ&~TYCSRqgV00000000300000000008b7N>_ZDDj_00{!GjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQr -PzVkwe;&S;{P@Z4!V_T!KN -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 +ZP9(YH~bairNa{vkf;?xyT5z&Ua ++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 +B=zREie$*y(7k2+*P~cYjR +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 +aaxrgbrDxyH3fc^ +lq>z|G!4fU)2DQrPzVkwe;&SMbsj>g6`?#s5rWnKhSeO?L~x^!;Y#eFP|P}0Z%Ez*ZeeX@0!8YhU)%QM +kO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*&DQ20rFt3ZOHs70;T-agdg$OP=xIp;K4#IcLF!~atLx|b7gXN +Wn=<+10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUG5>JtwI*nu%&Q~z;Vl^%5wS6(#;{6ajG64wDP +k{-($PGN0jWJYOaY-C4lZ(?C=Q*>c;WmI`^Wd;KRX=DPgjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkw +e;&To?vf5kh_h+&YE#h%O8d1V_{UOl9{V;uR#^q%JtwI*nu%&Q~z;Vl^%5wS6(#;{6ajG64wDPk{-(vPGN0jWJYOaY-CMk +bYWC^aAgJq0%>FduZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZmb>vO>-_DBy8`Vb0jGrW9$=2qS +MXvL3He1kloHngE|MP07*1hrWn@NaWo%?ra$#@6CZd7@2Wd;KRX=DPgjmGz6 +Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&RxQV*^ZmKt8YDf|&5KZQ>65I6*X)C9iYp+?yjr7~y)ZeeX@ +0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*&DQ20rFt3ZOHs70;T-agdg$OP=xIp;K4#IcLF!~ +atLx|b7gXNWn=<+10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUG5>JtwI*nu%&Q~z;Vl^%5wS6(#; +{6ajG64wDPk{-(yPGN0jWJYOaY-CnpY-Mg^c~p6DWd;KRX=DPgjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQr +PzVkwe;&R@?dHP>9R0ZFSEMRj;Km4qfBYZ5UUs>0bg9bqiCNABZeeX@0!8YhU)%QMkO4aJ;_ZeCe;xE! +X<$x_Fs4If6Z`oP*&DQ20rFt3ZOHs70;T-agdg$OP=xIp;K4#IcLF!~atLx|b7gXNWn=<+10COKearHw +cS=7M7YzYaI8*bvhMOc?)(rkC#nUG5>JtwI*nu%&Q~z;Vl^%5wS6(#;{6ajG64wDPk{-(rPGN0jWL9Bv +X<=@3bvOnC0%>Fb009JUVQpmsMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r35LOoBKkGaY9#cS +7Qj{WgyAGcS>>g~&^g7&L0`+VYVk7oBr%DNv +($;q`HHK!gIHa)*%m(-e#9sm3ZsHT^UK%K(4i9Ajp1M~R@C@!4#dQE#lUD;OiKi1RsjNZcmM?f0`+VY Vk7oBr%DNv+($;q`HHK!gIHa)*%m(-e#9sm3dMUNn!oosZgNI|twmNZeC(lYZa*g7-2eQ3Yy;-pLpZg6#U0%CAAe<9`Lptgp8_Mvcw;M9wpEva%PKB$lLxR8HRDYBt%9Ac~*scS^hWjPt6N{BwQjsm*;-$%ozd;zkHMYQ8YvDt&dXWl1-*ujFaOPZ*RUQ z8_qdo8_M$OIpM9wpsuyEy<=cT3umn4>?GTsvspZtJn*}5x%3nsQ^vWLbr z&Oaq9_LZf~Im^(%bVU_gL1|J>X7c2Xa*mrPieG0@uskkhS0`X`e*3;TCAF{D@0&1t zM_=v)7q5T|1v3pJ6azN*n{qKuey4bQbFN%C6LHEnzf*j|qu{;rM90c2kF~RYF8{OH zlIOUf`PqY8By$*MZk)AX&g5UllRv0SZ|2p1%SzZ#DN|PtUw@D ^ ..0xff [Byte]} -@mnemonic(baby-infant-cake) -data AssignIface : ownedState OwnedIface +@mnemonic(optic-hippie-isabel) +data AssignIface : stateTy StrictTypes.SemId? + , attach Std.Bool? , public Std.Bool , required Std.Bool , multiple Std.Bool @@ -326,14 +327,6 @@ data NamedVariantu8 : id U8 , name StrictTypes.VariantName , reserved CommitVerify.ReservedBytes4 -@mnemonic(delphi-athlete-fresh) -data OwnedIface : any () - | rights () - | amount () - | anyData () - | anyAttach () - | data StrictTypes.SemId - @mnemonic(paper-visa-storm) data PubWitness : txid Bitcoin.Txid | tx Bitcoin.Tx diff --git a/stl/RGBStorage@0.11.0.sta b/stl/RGBStorage@0.11.0.sta index 0a7db3fc..6b324b0b 100644 --- a/stl/RGBStorage@0.11.0.sta +++ b/stl/RGBStorage@0.11.0.sta @@ -1,5 +1,5 @@ -----BEGIN STRICT TYPE LIB----- -Id: stl:RMDj!yyo-ca0Rmdl-pBBc50W-ciu1!P3-U8gHIqL-0Y83X50#memo-ballet-fresh +Id: stl:lnl6QOG0-EYfOLKP-MHdEyA3-$cyUNuc-F3XmU!W-0glc1M0#alaska-phone-bagel Name: RGBStorage Dependencies: StrictTypes#century-comrade-chess, @@ -7,16 +7,16 @@ Dependencies: AluVM#congo-archive-folio, CommitVerify#miller-pancake-elastic, RGBCommit#printer-window-alpine, - RGBStd#zebra-twist-tango, + RGBStd#chemist-enjoy-sound, Std#ralph-blue-lucky, RGBLogic#ohio-electra-dilemma, Bitcoin#signal-color-cipher -Check-SHA256: 1e7e30d1c26d606642c6284e6be3f07d74d165c362f24ee5def19faaca9d5330 +Check-SHA256: 3b654f8a5eb432f7f3c40cabf94f95336a3e9973df24330917273e0b228f8e88 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 -R2X#8M$tG2GZIy9X>V>;VRC6_vj93RHP; -Wm9=`bY*P@01ZQLZgg^CV{}PwWMy~;0t|3>gzLOBVfUz`Mi!Z}iQtl5;XwV(E`Zdd&WRj~^37YhpmjD0&000000RR900000001j_;bZ~EJ -Zgfv@Z*_EY015)HjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&TkXBWLg67cp3gzo-sO&$va11I@T -$h!rSEX2t%Czh%J2?DQ;#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=?+hynwMZT8l5kSW@l}O=!>^ -xB4~9n`Dx!RtcK)nwJ0o0000000960{{R30000000000000960{{R30000n8Wo<)mZgg^CV{}t=VRU5% -1PF6uXk~3-Nn`@AjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&S+Qq$W5tE;F{pQrXd&=l*`O?@#x -{Qdy?T_k!`1dtF4V{dMBa$#e1Nn`@AjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&S{2rNlD$O59e -#ogQsB77jPl+h5j^*S;JXKZg`VQc^j0>g -zSZuM4oQf!Y4K`P(FaQVwIle)QgI&pHa%8Z1>xis%K>dbv;0wBb*7)Id;7I5;T&_H+G%6DVUHTf -p;u=X0|Kv&#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=>}YR2^S7pk#{MS?zgMX@X{kfl~;6wBm#t -C>wDnA0009BO=WFKZe(S61_cdoa6)x%WNc+gZe(S6015)HjmGz6 -Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&S-$mV(;bz)!CmQ_M(k?Vd!kfCo{nDM?)_qK{868FUduZ_m{ -WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZm1ACLTJsO2B2U!6ncg?mz@CdC==Kxq?gSEg)z2E{|00000 -00000|Ns90000006Jm94WNc+aZ*FvQVPkYjZe(S6015)HjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkw -e;&RAdy}<28ig(gSpg+?&9*`C2(3=%09avzwZKZf-~wC%uZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1 -DSsZmp9m~TI>-W|y2ahx3nF|Vuawki#7NH?S|Q-Q!u2{b0000000000|Ns90000005@L03WNc+uX>@L7 -b8|^g)RqK0VQ|Mwn6X+txo3v -SYd;;z)HQ~0$czI0>gzKLsCCC$c=UszhlV5m?Ru@{iV -U*wrVdeH+Q@FPbX@c;k-000000RI300000000000000000RR900000001abrZgg^CV{}PwWMy~&3IeZ< -#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=@LlEJ-@Z0;0Ob-P{Wzd?2rs)M&&=&l*}G;Jw22Ix+z) -)N;MU`Np56icmN6l -uZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZm+lpEmf)o&SDDwD>KtpQ8M_qJyiO1VIUJ=H=)@ii_ -00{!GjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&S*5WIk~G+K)5%bR49t5yk` -^qQ9d000000003000000000000000000030|Nj6000008O=WFUbYXL71`P;vV`ybE<3hUv-8m3eMLapj8a{pyIM27f -oOFHbufC9*xQ=a*L`qQ5aG5b!Ay5DS000000093000000000MPWo~72Wpe-u0>gzMlvzNjk^^qPoT1+zTRnAg`3vXv9d*8d@RXy~6c6G6JuS#`k1y;WQvCHXeDD -EB)y-4aXJJr*xW72o5QK9=@@-=^kqQ3p1gNv;!SgAcC?bFoBOEj`UQU^i2<9K8XMT000000093000000 -000GZb#QQO015)V+vv2?rNCE<3hUv-8m3eMLc6Y(}}Q4NmeS)xXw6rP$n8; -6mfj6^V>gz5{!cwLKbzE(ciwC3nrXLGTEzPUiqvVS}~6O1>gzD1E0G&%-s -t`)qMZ{`v%g)H0vbfykT5^0>(1Gy}*bpQYW000000RR90{{R30010<#bZ%vHb7gY?3IeZ<#`k1y;WQvC -HXeDDEB)y-4aXJJr*xW72o5QK9=?fdSS8KIkY89@$6%;X7qJ(R#b4x^L3+^xAn+qc8}S0Y+vv2?rNCjuaWwz{0000000960{{R30000Vfd2nS@d2@7SZ30E=qhH(h&PZdlOljoA7|k;k>s6qoa5|8f~g8=WMyu2X>@62a{vkguZ_m{WNzU!AS*T= -d6X;t=`;<;71O75notN1DSsZmw&;L{94K`ndk%K5+?9Jv$dw7jc}U5p5@2#$kUJ%u0=?Vlw9=)(YVD5X -(Bh@-;YAffP|O75Lc0RpIS^JwJfh%P)X}ib9i^%gOs*8bY}uR&S59aNAMwsm_ykY{pa1{>000000RR60 -0000000eAlVsiir0%CAAe<9`Lptgpr6F_xjAC6(~TLj#*ewiHm5LE0xkJm$nc4yMWR2J-cc#Q -6SofWC)gp7L6!Sc3IbwqHGd)Hlr&gK9B000000096000000000DYX=if)3Ie^`=(N(Mz-sM|E<3hUv --8m3eMLgov6;Kh;hPv9L38+j;K}xwT<$*JN%D`Il^nAqV=^+BW+vv2?rNCUOOvDqlqa0000000030{{R3000008O=WFUbYXO5 -1_B9pX>@L7b8}^L015)HjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&SxYgi@C#*klFTE}3hP#3Wm -ki}o*nL&Ed10e7tM;q}1=To4MHF_77?oTU4FqgQKswsBc5OvCJUgtO#qdT6Na=Svv7*ky_&y4^1v>gzMlvzNjk^^qPoT1+zTRnAg`3vXv9d*8d@RXy~6c6G6Ac7Ex1s`aa6PN-Fgk0S2h>I -cS>a?4Yu+n!-bhcpbh{4000000093000000000 +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 +5w0WYK++p=`bayqMEp^75#kD_Tqj3Vr!KR7RO +I1#QR=|IvOar#K!YERg2%AQl=6Lc4y4BuUum=K}#_8Itcm>%s+B6*|$00000000300000000007XJu|> +b7gY?3IeZ<#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=@LlEJ-@Z0;0Ob-P{Wzd?2rs)M&&=&l*}G +;Jw22Ix+&UjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&TExal5h{0lRojI;wCRUm@0B`|@HB98P_ +oAgZ&Vm^rg00000000300000000005b9HcVYyb)Z$ib$G)8#G2g~}h6>clrIl2GyM={OOtBk4fW8*%zb +2AHk4+Bm{3x%H=p>4!*u&nOI1#QR=|IvO +ar#JOJ=2M>OG#EL&$!Mwbxg)RqK0VQ|Mwn6X+ +txo3vSYd;;z)HQ~0$c*GjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&U5Y50a7uJ<-M7OQflyV@Ma +b5n=!H;MEOu8QHCUOton0000000030|Ns900000AWq5RDZgXjGZgT(%0>gzLm)4dLDIRU(}XWLTZugenOC;Z(5k~zEJnJiX;;E#R9L5#`k1y;WQvCHXeDDEB)y- +4aXJJr*xW72o5QK9==796*M{qY_1i&m2c(}E`==I0Cc7fNfK$C)dRUKv2_3d0000000960|Nj60000Sh +X>@L7b8}^L015)HjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&SxYgi@C#*klFTE}3hP#3Wmki}o* +nL&Ed10e7tM;q}1$ib$G)8#G2g~}h6>clrIl2GyM={OOtBk4fW8*%zb$6skVRwOM6wz9dSYg6i3-rmX0 +uFE(Y8AEY@srN=80000000000|NsC0000003t@D0VPj}*Wo~qH015)HjmGz6Zs9Z_D>fc^lq>z|G!4fU +)2DQrPzVkwe;&SsaSf9!PV~dK2uo>;u!nFdemP_$e?^hl+JkM;eY!XR2mk;;0000000000|Ns9000000 +0000000000|Nj60000003v*>-a%FT=WnpY{00{!GjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&S% +yTa&4noi_R;$3lnz4{Zl)X|Z&ZIQtMA_g1big7gn0000000030|Nj600000Aba`-PQ+acAWo-gQ>Z4!V +_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HLtfv$so3kRF1PV2}fOp_vjQ6FdFHId|>gzP9Lqh8!q$B6|*YuiTY;OURW8#d%1{ +rxIXtTaY^?oC3(fris(#Eyab(AC~IGH!G4*@$2b05w0WYK++p=`beVSS=7<6%^jtx5=^cXz--x^3Rg~O +2_Ny!Q1}E;1fT!_000000096000000000DRX<~B#3IbwqHGd)HR2XhQO_4{AcS-HH^7AVzASV8M4NY +xyCjU1gEwF5PXV6FZDLo1#Vec_~kix7WfVQ#Sd|CM9$^_0000000030{{R3000004b7^OD015)g!KR7R +OI1#QR=|IvOar#K&)D=(>(T2L(qY0=?N$ib$G +)8#G2g~}h6>clrIl2GyM={OOtBk4fW8*%zbh8PemXlG!~;@e)_O3H?xO^a~KWeI~0jp}x-Dk@(^00000 +00000|Nj60000002u)>eQ*>c;Wd;HXcWHEPWpi_7a{vkguZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1 +DSsZmiECIT&Bl;lSX#$ms8AQN7m&qYX% +7Na|!nR2^A$QV;yG0%+u`Lqfm#|FpRuujhTP8r)T_J?np;Q#;t000000RR90{{R30010DnZgg^CV{~%> +3IeZ<#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=@LlEJ-@Z0;0Ob-P{Wzd?2rs)M&&=&l*}G;Jw22 +Ix+#PeJ!|9#Bo%!^4)q3npZX#!goq#B@MRnCBuc8L!b@-0000000030000000000 -----END STRICT TYPE LIB----- diff --git a/stl/RGBStorage@0.11.0.stl b/stl/RGBStorage@0.11.0.stl index 3d8ee703ca4a1251c390d95c56a78d30ba1f1635..88c58d859b8d57018d666676535185568e82aae5 100644 GIT binary patch delta 607 zcmcZ?wK;0S9fcDImvvr#s(ZBcl>D?;N6fV+1$=z{(n4^Z@=J$H(uKb~HvW+pVpQKO zBkaaFxkF_2=6F$NW}QuS3O-YIKDww=y!swv_+9g>o*^&Jm&G``{VG}ffu-RLw_|Z} zW_q4yT4HkQ<|GMoMujZ@8~LZ^1wRrl5ueL*KX&E}frVebN&YCBA@|ltsd5SH=6#ZP z*$6sjGLMA9Gyc%D-X?ldDyw2rKLmQE+4;6kPWRcyzLu+E&6= ty;f5usA#jE`bkE@s>C(t5mq(X92l-&wKftoZt^j0MS_Ypv+IO20su~!G}8b8 delta 646 zcmdlSbuVhd9fiHOUu?Ow^g!0zz9$zREq(jYRn#fq49jDu-As2a1;SiyHvW+pV$|3y zBkabgXn9=9u1>(>{PulwN@`!P-#20Qj=tOpE?xl_3T7HcCW~9>3N=MiOH#(c}1C-H`_>1ru8{*+XL*=bw@l`^r-0oMmWWx}u89zdSEB1*~cEY;A?jJ0y3o5p?|I z2?|~W6>a{dAjU#a)no%zE5eGpR23Zvg(#s=ocvmKD`A@ss3{Xxv{O`Jv$Fb1M#3sT dN+@jR(X1mvPO<~!Qqi~uMkLstL* diff --git a/stl/RGBStorage@0.11.0.sty b/stl/RGBStorage@0.11.0.sty index 67c9f1b5..dda1de3d 100644 --- a/stl/RGBStorage@0.11.0.sty +++ b/stl/RGBStorage@0.11.0.sty @@ -1,5 +1,5 @@ {- - Id: stl:RMDj!yyo-ca0Rmdl-pBBc50W-ciu1!P3-U8gHIqL-0Y83X50#memo-ballet-fresh + Id: stl:lnl6QOG0-EYfOLKP-MHdEyA3-$cyUNuc-F3XmU!W-0glc1M0#alaska-phone-bagel Name: RGBStorage Version: 0.11.0 Description: RGB storage library @@ -115,7 +115,7 @@ import RGBCommit#printer-window-alpine use XChainPubWitness#figure-gram-wave use TransitionBundle#final-numeric-berlin -import RGBStd#zebra-twist-tango +import RGBStd#chemist-enjoy-sound use PubWitness#paper-visa-storm use ContentRef#polo-ramirez-parker use SigBlob#insect-cello-avalon @@ -123,12 +123,10 @@ import RGBStd#zebra-twist-tango use TransitionIface#axiom-parker-pyramid use NamedFieldTransitionType#express-brush-desire use ExtensionIface#model-ramirez-mentor - use Iface#violin-student-system use IfaceId#nova-cola-carbon use ValencyIface#buzzer-holiday-fiber use Annotations#spend-linda-romeo use IfaceImpl#coconut-snake-formula - use AssignIface#fractal-baker-outside use VerNo#textile-next-stretch use NamedFieldValencyType#invest-apollo-inca use ImplId#seminar-data-table @@ -146,6 +144,7 @@ import RGBStd#zebra-twist-tango use NamedFieldAssignmentType#origin-caramel-flipper use Allocation#mimosa-savage-future use TrustLevel#cobra-script-albino + use AssignIface#optic-hippie-isabel use StateAbi#thermos-demo-fragile use NamedFieldMetaType#prefix-carmen-artist use NamedVariantu8#star-pilgrim-pilgrim @@ -153,7 +152,7 @@ import RGBStd#zebra-twist-tango use SealWitness#cotton-lopez-isabel use GlobalIface#concert-combat-charm use SupplMap#sailor-observe-bundle - use OwnedIface#delphi-athlete-fresh + use Iface#citizen-oxford-norway use ContentId#scarlet-portal-office use GlobalOut#capital-agatha-bruno @@ -214,7 +213,7 @@ data MemIndex : opBundleIndex {RGBCommit.OpId -> ^ ..0xffffff RGBCommit , contractIndex {RGBCommit.ContractId -> ^ ..0xff ContractIndex} , terminalIndex {RGBCommit.XChainSecretSeal -> ^ ..0xffffff {RGBCommit.Opout ^ ..0xff}} -@mnemonic(kinetic-deal-blast) +@mnemonic(alfonso-office-suzuki) data MemStash : schemata {RGBCommit.SchemaId -> ^ ..0xff RGBStd.SchemaIfaces} , ifaces {RGBStd.IfaceId -> ^ ..0xff RGBStd.Iface} , geneses {RGBCommit.ContractId -> ^ ..0xff RGBCommit.Genesis} diff --git a/stl/Transfer.vesper b/stl/Transfer.vesper index 36c8e481..cc718eeb 100644 --- a/stl/Transfer.vesper +++ b/stl/Transfer.vesper @@ -540,13 +540,8 @@ Consignmenttrue rec assignments map len=0..MAX8 key ascii aka=FieldName first=AlphaSmallLodash rest=AlphaNumLodash len=1..100 value rec AssignIface - ownedState union OwnedIface - any is Unit tag=0 - rights is Unit tag=1 - amount is Unit tag=2 - anyData is Unit tag=3 - anyAttach is Unit tag=4 - data bytes len=32 wrapped aka=SemId tag=5 + some bytes len=32 option wrapped aka=SemId tag=1 + some enum Bool option wrapped false=0 true=1 tag=1 public enum Bool false=0 true=1 required enum Bool false=0 true=1 multiple enum Bool false=0 true=1 From 624e84c2b4d27d9ba77f7d9b5c2c25a4b6f18294 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 17 Oct 2024 02:33:46 +0200 Subject: [PATCH 07/16] persistence: add access to type system --- src/persistence/stash.rs | 16 ++++++++++++---- src/persistence/stock.rs | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/persistence/stash.rs b/src/persistence/stash.rs index a5822a7b..a1c522d4 100644 --- a/src/persistence/stash.rs +++ b/src/persistence/stash.rs @@ -304,7 +304,15 @@ impl Stash

{ Ok(Scripts::from_checked(scripts)) } - pub(super) fn extract<'a>( + pub(super) fn type_system(&self, iface: &Iface) -> Result> { + Ok(self + .provider + .type_system() + .map_err(StashError::ReadProvider)? + .extract(iface.types())?) + } + + pub(super) fn types_scripts<'a>( &self, schema: &Schema, ifaces: impl IntoIterator, @@ -344,7 +352,7 @@ impl Stash

{ .get(iface_id) .ok_or(StashDataError::NoIfaceImpl(schema_id, iface_id))?; - let (types, scripts) = self.extract(&schema_ifaces.schema, [iface])?; + let (types, scripts) = self.types_scripts(&schema_ifaces.schema, [iface])?; let builder = ContractBuilder::with( issuer, @@ -370,7 +378,7 @@ impl Stash

{ .get(iface.iface_id()) .ok_or(StashDataError::NoIfaceImpl(schema.schema_id(), iface.iface_id()))?; - let (types, _) = self.extract(&schema_ifaces.schema, [iface])?; + let types = self.type_system(iface)?; let scripts = self.scripts(iimpl.state_abi.lib_ids())?; let builder = if let Some(transition_name) = transition_name { @@ -409,7 +417,7 @@ impl Stash

{ if schema_ifaces.iimpls.is_empty() { return Err(StashDataError::NoIfaceImpl(schema.schema_id(), iface.iface_id()).into()); } - let (types, _) = self.extract(&schema_ifaces.schema, [iface])?; + let types = self.type_system(iface)?; let builder = if let Some(iimpl) = schema_ifaces.get(iface.iface_id()) { TransitionBuilder::blank_transition( diff --git a/src/persistence/stock.rs b/src/persistence/stock.rs index a142358e..273af067 100644 --- a/src/persistence/stock.rs +++ b/src/persistence/stock.rs @@ -39,6 +39,7 @@ use rgb::{ SchemaId, SecretSeal, Transition, TxoSeal, XChain, XOutpoint, XOutputSeal, XWitnessId, }; use strict_encoding::FieldName; +use strict_types::TypeSystem; use super::{ ContractStateRead, Index, IndexError, IndexInconsistency, IndexProvider, IndexReadProvider, @@ -494,6 +495,9 @@ impl Stock { pub fn iface(&self, iface: impl Into) -> Result<&Iface, StockError> { Ok(self.stash.iface(iface)?) } + pub fn type_system(&self, iface: &Iface) -> Result> { + Ok(self.stash.type_system(iface)?) + } pub fn schemata(&self) -> Result + '_, StockError> { Ok(self.stash.schemata()?.map(SchemaInfo::with)) } @@ -573,7 +577,7 @@ impl Stock { let iimpl = self.stash.impl_for::(schema_ifaces)?; let iface = self.stash.iface(iimpl.iface_id)?; - let (types, _) = self.stash.extract(&schema_ifaces.schema, [iface])?; + let types = self.stash.type_system(iface)?; Ok(C::Wrapper::with(ContractIface { state, @@ -599,7 +603,7 @@ impl Stock { ContractIfaceError::NoAbstractImpl(iface_id, schema_ifaces.schema.schema_id()) })?; - let (types, _) = self.stash.extract(&schema_ifaces.schema, [iface])?; + let types = self.stash.type_system(iface)?; Ok(ContractIface { state, @@ -678,7 +682,9 @@ impl Stock { kit.iimpls .extend(schema_ifaces.iimpls.values().cloned()) .expect("type guarantees"); - let (types, scripts) = self.stash.extract(&schema_ifaces.schema, &kit.ifaces)?; + let (types, scripts) = self + .stash + .types_scripts(&schema_ifaces.schema, &kit.ifaces)?; kit.scripts .extend(scripts.into_values()) .expect("type guarantees"); @@ -843,7 +849,9 @@ impl Stock { let terminals = Confined::try_from(terminals).map_err(|_| ConsignError::TooManyTerminals)?; - let (types, scripts) = self.stash.extract(&schema_ifaces.schema, ifaces.keys())?; + let (types, scripts) = self + .stash + .types_scripts(&schema_ifaces.schema, ifaces.keys())?; let scripts = Confined::from_iter_checked(scripts.into_values()); let supplements = Confined::try_from(supplements).map_err(|_| ConsignError::TooManySupplements)?; From 0bfe36d65dd3f5dda1eec377c85b39ade80a2f71 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 17 Oct 2024 12:50:55 +0200 Subject: [PATCH 08/16] epic: improve invoice and interface state APIs --- Cargo.lock | 2 +- invoice/src/builder.rs | 107 ++++++++++++++++--- invoice/src/parse.rs | 2 +- src/interface/builder.rs | 2 +- src/interface/calc.rs | 6 +- src/interface/contract.rs | 65 +++++++----- src/stl.rs | 4 +- stl/RGBStd@0.11.0.sta | 192 ++++++++++++++++----------------- stl/RGBStd@0.11.0.stl | Bin 18172 -> 18172 bytes stl/RGBStd@0.11.0.sty | 34 +++--- stl/RGBStorage@0.11.0.sta | 216 +++++++++++++++++++------------------- stl/RGBStorage@0.11.0.stl | Bin 11571 -> 11571 bytes stl/RGBStorage@0.11.0.sty | 64 +++++------ stl/Transfer.vesper | 24 ++--- 14 files changed, 406 insertions(+), 312 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3f6459a7..80e12cd3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -674,7 +674,7 @@ dependencies = [ [[package]] name = "rgb-core" version = "0.11.0-beta.9" -source = "git+https://github.com/RGB-WG/rgb-core?branch=feat/fungible-nonconf#8267ce26b1edf905553a49e5dcc42d5f2f0df338" +source = "git+https://github.com/RGB-WG/rgb-core?branch=feat/fungible-nonconf#75424505e4f24df90d9ee1d284c4ee25103c185b" dependencies = [ "aluvm", "amplify", diff --git a/invoice/src/builder.rs b/invoice/src/builder.rs index 00c9d7af..1805ee9e 100644 --- a/invoice/src/builder.rs +++ b/invoice/src/builder.rs @@ -21,7 +21,7 @@ use std::str::FromStr; -use rgb::{AttachId, ContractId, State}; +use rgb::{AttachId, ContractId, State, StateData}; use strict_encoding::{FieldName, StrictSerialize, TypeName}; use crate::invoice::{Beneficiary, InvoiceState, RgbInvoice, RgbTransport, XChainNet}; @@ -50,19 +50,13 @@ impl RgbInvoiceBuilder { Self::new(beneficiary).set_contract(contract_id) } - pub fn rgb20(contract_id: ContractId, beneficiary: impl Into>) -> Self { - Self::with(contract_id, beneficiary).set_interface("RGB20") - } - - pub fn rgb20_anything(beneficiary: impl Into>) -> Self { - Self::new(beneficiary).set_interface("RGB20") - } - pub fn set_contract(mut self, contract_id: ContractId) -> Self { self.0.contract = Some(contract_id); self } + /// Sets interface for the invoice. Interface can be a concrete interface (name or id), or a + /// name of an interface standard, like `RGB20`, `RGB21` etc. pub fn set_interface(mut self, name: impl Into) -> Self { self.0.iface = Some(name.into()); self @@ -78,14 +72,101 @@ impl RgbInvoiceBuilder { self } - pub fn set_state(mut self, state: impl StrictSerialize) -> Self { - self.0.owned_state = InvoiceState::Specific(State::new(state)); + /// Set the invoiced state, which includes both state data and an optional attachment + /// information. + /// + /// # Panics + /// + /// If any state information or attachment requirements are already present in the invoice. + /// + /// # See also + /// + /// - [`Self::add_state_data`], adding just state data information, not affecting attachment + /// requirements; + /// - [`Self::serialize_state_data`], for adding state data by serializing them from a state + /// object; + /// - [`Self::add_attachment`], for adding attachment requirement to an existing invoiced state + /// information. + pub fn set_state(mut self, state: State) -> Self { + if !self.0.owned_state.is_any() { + panic!("invoice already has state information"); + } + self.0.owned_state = InvoiceState::Specific(state); + self + } + + /// Add state data to the invoice. + /// + /// NB: This keeps existing attachment requirements. + /// + /// # Panics + /// + /// If the invoice already have any state information (excluding attachment requirements). + /// + /// # See also + /// + /// - [`Self::set_state`], for redefining the whole of the invoiced state, including attachment + /// requirements; + /// - [`Self::serialize_state_data`], for adding state data by serializing them from a state + /// object; + /// - [`Self::add_attachment`], for adding attachment requirement to an existing invoiced state + /// information. + pub fn add_state_data(mut self, data: StateData) -> Self { + self.0.owned_state = match self.0.owned_state { + InvoiceState::Any => InvoiceState::Specific(State::from(data)), + InvoiceState::Specific(_) => panic!("invoice already has state information"), + InvoiceState::Attach(attach_id) => InvoiceState::Specific(State::with(data, attach_id)), + }; + self + } + + /// Add state data to the invoice by strict-serializing the provided object. + /// + /// NB: This keeps existing attachment requirements. + /// + /// Use the function carefully, since the common pitfall here is to perform double serialization + /// of an already serialized data type, like `SmallBlob`. This produces an invalid state object + /// which can't be properly parsed later. + /// + /// # Panics + /// + /// If the invoice already has any state information (excluding attachment requirements). + /// + /// # See also + /// + /// - [`Self::set_state`], for redefining the whole of the invoiced state, including attachment + /// requirements; + /// - [`Self::add_state_data`], adding just state data information, not affecting attachment + /// requirements; + /// - [`Self::add_attachment`], for adding attachment requirement to an existing invoiced state + /// information. + pub fn serialize_state_data(mut self, data: impl StrictSerialize) -> Self { + self.0.owned_state = InvoiceState::Specific(State::from_serialized(data)); self } - pub fn set_attachment(mut self, attach_id: AttachId) -> Result { + /// Add attachment requirements to an invoice, keeping the rest of the invoice state information + /// unchanged. + /// + /// # Panics + /// + /// If the invoice already has attachment requirements defined. + /// + /// # See also + /// + /// - [`Self::set_state`], for redefining the whole of the invoiced state, including attachment + /// requirements; + /// - [`Self::add_state_data`], adding just state data information, not affecting attachment + /// requirements; + /// - [`Self::serialize_state_data`], for adding state data by serializing them from a state + /// object; + pub fn add_attachment(mut self, attach_id: AttachId) -> Result { self.0.owned_state = match self.0.owned_state { - InvoiceState::Any | InvoiceState::Attach(_) => InvoiceState::Attach(attach_id), + InvoiceState::Any => InvoiceState::Attach(attach_id), + InvoiceState::Attach(_) + | InvoiceState::Specific(State { + attach: Some(_), .. + }) => panic!("invoice already has attachment requirements"), InvoiceState::Specific(mut state) => { state.attach = Some(attach_id); InvoiceState::Specific(state) diff --git a/invoice/src/parse.rs b/invoice/src/parse.rs index e2136f79..49a49dca 100644 --- a/invoice/src/parse.rs +++ b/invoice/src/parse.rs @@ -181,7 +181,7 @@ impl Display for InvoiceState { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { InvoiceState::Any => Ok(()), - InvoiceState::Specific(state) => f.write_str(&state.value.to_base58()), + InvoiceState::Specific(state) => f.write_str(&state.data.to_base58()), // TODO: Support attachment through invoice params InvoiceState::Attach(_) => Ok(()), } diff --git a/src/interface/builder.rs b/src/interface/builder.rs index 2ba1d8c3..e794dad5 100644 --- a/src/interface/builder.rs +++ b/src/interface/builder.rs @@ -653,7 +653,7 @@ impl OperationBuilder { .assignments_type(&name) .ok_or(BuilderError::AssignmentNotFound(name))?; - self.add_owned_state_raw(type_id, seal, State::new(value)) + self.add_owned_state_raw(type_id, seal, State::from_serialized(value)) } fn complete(self) -> (Schema, Iface, IfaceImpl, GlobalState, Assignments, TypeSystem) { diff --git a/src/interface/calc.rs b/src/interface/calc.rs index 32043aa1..2932f775 100644 --- a/src/interface/calc.rs +++ b/src/interface/calc.rs @@ -106,7 +106,7 @@ impl StateCalc { self.vm.registers.set_n(RegA::A8, Reg32::Reg0, Some(0u8)); self.vm .registers - .set_s(RegS::from(0), Some(ByteStr::with(&state.value))); + .set_s(RegS::from(0), Some(ByteStr::with(&state.data))); self.vm.registers.set_n( RegR::R256, Reg32::Reg0, @@ -119,7 +119,7 @@ impl StateCalc { ty: AssignmentType, idx: Reg16, ) -> Result, StateCalcError> { - let Some(value) = self.vm.registers.get_s(RegS::from(u4::from(idx))) else { + let Some(data) = self.vm.registers.get_s(RegS::from(u4::from(idx))) else { return Ok(None); }; let reserved = self @@ -138,7 +138,7 @@ impl StateCalc { } Ok(Some(rgb::State { reserved: none!(), - value: StateData::from_checked(value.to_vec()), + data: StateData::from_checked(data.to_vec()), attach, })) } diff --git a/src/interface/contract.rs b/src/interface/contract.rs index 1452779f..075fafb1 100644 --- a/src/interface/contract.rs +++ b/src/interface/contract.rs @@ -23,10 +23,10 @@ use std::borrow::Borrow; use std::collections::{BTreeSet, HashMap, HashSet}; use amplify::confinement; -use amplify::confinement::SmallBlob; use rgb::validation::Scripts; use rgb::{ - AssignmentType, AttachId, ContractId, OpId, Opout, Schema, State, XOutputSeal, XWitnessId, + AssignmentType, AttachId, ContractId, OpId, Opout, Schema, State, StateData, XOutputSeal, + XWitnessId, }; use strict_encoding::{FieldName, SerializeError, StrictSerialize}; use strict_types::{typify, SemId, StrictVal, TypeSystem}; @@ -155,33 +155,52 @@ impl ContractIface { .sem_id } - fn assignment_value(&self, ty: AssignmentType, value: &SmallBlob) -> StrictVal { - self.types - .strict_deserialize_type(self.assignment_sem_id(ty), value.as_slice()) - .expect("invalid contract state") - .unbox() - } - fn allocation_to_output(&self, a: &Allocation) -> Output { Output { opout: a.opout, seal: a.seal, - state: self.assignment_value(a.opout.ty, &a.state.value), + state: self.value_from_state_raw(a.opout.ty, &a.state), attach_id: a.state.attach, witness: a.witness, } } - fn state_convert( + pub fn value_from_state_raw(&self, ty: AssignmentType, state: &State) -> StrictVal { + self.types + .strict_deserialize_type(self.assignment_sem_id(ty), state.data.as_slice()) + .expect("invalid contract state") + .unbox() + } + + pub fn value_from_state( + &self, + name: impl Into, + state: &State, + ) -> Result { + let type_id = self.assignment_type(name)?; + Ok(self.value_from_state_raw(type_id, state)) + } + + pub fn value_to_state_raw( &self, ty: AssignmentType, value: StrictVal, - ) -> Result { + ) -> Result { let t = self.types.typify(value, self.assignment_sem_id(ty))?; - Ok(self + let value = self .types .strict_serialize_type::<{ confinement::U16 }>(&t)? - .to_strict_serialized()?) + .to_strict_serialized()?; + Ok(value.into()) + } + + pub fn value_to_state( + &self, + name: impl Into, + value: StrictVal, + ) -> Result { + let type_id = self.assignment_type(name)?; + self.value_to_state_raw(type_id, value) } pub fn contract_id(&self) -> ContractId { self.state.contract_id() } @@ -248,9 +267,8 @@ impl ContractIface { &'c self, name: impl Into, filter: impl AssignmentsFilter + 'c, - value: StrictVal, - attach: Option, sorting: impl FnMut(&&Allocation) -> K, + state: &'c State, ) -> Result + 'c, ContractError> { let type_id = self.assignment_type(name)?; let mut selected = self @@ -259,18 +277,13 @@ impl ContractIface { .collect::>(); selected.sort_by_key(sorting); let mut calc = StateCalc::new(self.scripts.clone(), self.iface.state_abi); - let state = State { - reserved: none!(), - value: self.state_convert(type_id, value)?.into(), - attach, - }; Ok(selected .into_iter() .take_while(move |a| { if calc.reg_input(a.opout.ty, &a.state).is_err() { return false; } - calc.is_sufficient_for(a.opout.ty, &state) + calc.is_sufficient_for(a.opout.ty, state) }) .map(|a| self.allocation_to_output(a))) } @@ -314,7 +327,7 @@ impl ContractIface { // add allocations with no witness to the beginning of the history if let Some(genesis_state) = allocations_our_outpoint.remove(&None) { for assignment in genesis_state { - let value = self.assignment_value(assignment.opout.ty, &assignment.state.value); + let value = self.value_from_state_raw(assignment.opout.ty, &assignment.state); ops.push(ContractOp::issued(assignment, value)) } } @@ -340,7 +353,7 @@ impl ContractIface { } for assignment in ext_assignments { let value = - self.assignment_value(assignment.opout.ty, &assignment.state.value); + self.value_from_state_raw(assignment.opout.ty, &assignment.state); ops.push(ContractOp::sent(assignment, value, witness_info)) } } @@ -348,7 +361,7 @@ impl ContractIface { (None, Some(ext_assignments)) => { for assignment in ext_assignments { let value = - self.assignment_value(assignment.opout.ty, &assignment.state.value); + self.value_from_state_raw(assignment.opout.ty, &assignment.state); ops.push(ContractOp::sent(assignment, value, witness_info)) } } @@ -357,7 +370,7 @@ impl ContractIface { (Some(our_assignments), None) => { for assignment in our_assignments { let value = - self.assignment_value(assignment.opout.ty, &assignment.state.value); + self.value_from_state_raw(assignment.opout.ty, &assignment.state); ops.push(ContractOp::received(assignment, value, witness_info)) } } diff --git a/src/stl.rs b/src/stl.rs index 7507e045..d20e7c85 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -37,11 +37,11 @@ pub const LIB_NAME_RGB_STORAGE: &str = "RGBStorage"; /// Strict types id for the library providing standard data types which may be /// used in RGB smart contracts. pub const LIB_ID_RGB_STORAGE: &str = - "stl:lnl6QOG0-EYfOLKP-MHdEyA3-$cyUNuc-F3XmU!W-0glc1M0#alaska-phone-bagel"; + "stl:dYzM3Ct9-SJ8PljY-C!6hB6y-VlWvDE7-DAtNg3y-zanf6hE#media-fresh-cadet"; /// Strict types id for the library representing of RGB StdLib data types. pub const LIB_ID_RGB_STD: &str = - "stl:yMGmidPl-LcWFyh!-W6sQ3K5-JQ8evpO-BGuI!lA-0htx!kg#chemist-enjoy-sound"; + "stl:3QsSNDHr-YPIKTR9-5O!fLuv-xhcxKT2-0LWrO9b-pG15Nvw#mango-inside-shelf"; #[allow(dead_code)] #[derive(Debug, From)] diff --git a/stl/RGBStd@0.11.0.sta b/stl/RGBStd@0.11.0.sta index 1491d12d..589d596b 100644 --- a/stl/RGBStd@0.11.0.sta +++ b/stl/RGBStd@0.11.0.sta @@ -1,20 +1,20 @@ -----BEGIN STRICT TYPE LIB----- -Id: stl:yMGmidPl-LcWFyh!-W6sQ3K5-JQ8evpO-BGuI!lA-0htx!kg#chemist-enjoy-sound +Id: stl:3QsSNDHr-YPIKTR9-5O!fLuv-xhcxKT2-0LWrO9b-pG15Nvw#mango-inside-shelf Name: RGBStd Dependencies: StrictTypes#century-comrade-chess, BPCore#austin-story-retro, AluVM#congo-archive-folio, CommitVerify#miller-pancake-elastic, - RGBCommit#printer-window-alpine, + RGBCommit#trident-rover-tape, Std#ralph-blue-lucky, Bitcoin#signal-color-cipher -Check-SHA256: 4b921710f4ab25f21c5be62b8015e9456f1d473c6aca46706d8a71155de55640 +Check-SHA256: d003c3fbc2fb3bbf7c1af3b580825dfbf43f509f0b75adb51c4f3096e33e53f5 22w{tQ*>kpMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r3sZD*X=8L$d2nTORuk6O)Q5AKbFW;J EQ>MoHhG*Mzd(pEtONi$rOUxc20~CnZ*pZ~a5aA+<>R2XhQO_4{AcS-HH^7AVzASV8M4NYxyCjHL2Pwa -O?m?z-)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OCJaMwZEb0ER%LQ&W_hoT#`k1y;WQvCHXeDDEB)y- -4aXJJr*xW72o5QK9=-`uM?ynyZEb0E$}AplgPGkh3_fq3Q7_j=2#kPT_9!;lWR>~GYywm#15~GYywm#15DT%6aZ| SrJerP1pIOD57`7Ol|-ogQ6Pjg~y>s-v>!^VNPLfWv4Jz0xkJm$nc4yMWR2J-cc#Q6SofWC)gp7L6!Sc @@ -47,37 +47,37 @@ c)mXTm=OBn8@DNvJ^I(u7Ttc@lJ^C)`OzK@Qe|^xa&~28LV0v$b2tf7M?ynyZEb0EFaQH+0?er0_e!9% 6%WL6o5Q7yVM7GXa@w44CHDB`4cre!cywiMb7^mGQ)6glZD9j@leIk>g)RqK0VQ|Mwn6X+txo3vSYd;; z)HQ~0$d0}b#7#AWl3ZdB|MH$#iox7(epK^GJZz3uq*Cb2l>R6Lh9EroO>_{O=WapR$**)WfhrcWXrXy KnGOwA#t$mH2bG7pQ)aE=^FQF!@KkQhzLn;aCLM|VQ?5o)zidWvABmX&uCxQ{9vUAsn@)h(<^=)@3p(i -4FwHHWo~72X>(I!Xk~3-9zxS>Jw1!&_U?o#2Tebz`mr;62_Hls_?@=CN?W&A7(sJ$X=iS2Wo~qHLTqVn -WK(5fY*ct@WFNs;Mn8g^E-G}MMdwWnpYo -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 @@ -94,10 +94,10 @@ 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 ZP9(YH~bairNa{vkf;?xyT5z&Ua +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 @@ -179,9 +179,9 @@ v{(W1V6JV*{3!yZ{M3XW@z+pZODNcTE%yi#yB_`&o2yJC_VPs)+VE_pNMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C `}q*r8?;yf@?frQ$owe+rTo-{AMw{vgzX#P!9p!}0yp?_0000000000{{R30000002WM<=Vqt7^015&{ >Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+pGEG +dp?5NXDLVVImIB-z9!%DK7l%`-}aulY!amxHJkmcHo-KZ`k;Xmr`<4sJYKN!!u{G5u+^j1lf!PF4>GEG 0000000000{{R30000003t@9}X=iS2Wo~qH015&{>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~ -v{(W1V6JV*{3!yZ{M3XW@z+pGEG0000000000{{R300000033g#@Wo~0>Wpe-t0!8Yh U)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*&DQ20rFt3ZOHs70;T-agdg$OP=xIp;K4#IcLF!~asU7T 000000RI300000000w1pa&K~T00{y`>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI&hQW&>`ZdvN @@ -209,9 +209,9 @@ I`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+pZ4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW @z+pn8fQnYaJ?>kL6XG(3esa0W5QyJn#ohg24a)00000 0093000000000YTY;R&=Y*Tb$bY%bu0daC2M$y&U#EU!@hie?UNS!6hQhW-W8INxxf{Fuzg#Z8m00000 @@ -220,11 +220,11 @@ aS3#3ZDn(GVQp{#07wXJWprU=VRT^t2?4!n8fQnYaJ?>kL6XG(3esa0W5QyJn#ohg24a)00000 0000001I?-VQzD2bZKvHa{vheI6k{n`X+XC81LasyqR+($`>jwnD57lV5q8m)(2RS0000000000{{R30 000003T1e7Wo~n6Z*Fq{2?1%uWwlwnKfCTqC!TnpV`xO%(e*mXP$JGS1-q69d*1*6000000093000000 000JMa&m8Sa{vhe!)N7;Jv;(oC!o$&iP#xB8s<*^%!GF?$0)U9@BFJ?0000000000{{R300000031nq< -Wo&P7WpVfc^lq>z|G!4fU)2DQrPzVkwe;&TJ=zxYCD0L!x4tB5Hm3vFbl?lapNXe%X +Wo&P7WpV<0K7!h3DM#@+#URqYCg1WtfjX<-_MW+H5~UY4oBgb|=zxYCD0L!x4tB5Hm3vFbl?lapNXe%X U~*fKJ0+Y5b97;JWkF(T0kye8jk+}zMj0CEc-y32_=FESDTGMdT)8q$(GFPM`UXjDaBN9r1pxpD002NB 00T>DbOs0qc4cyNX>V=;l-_zLn%tmAe68Jly{Qj?Kss0ny)C8xzFm#1PkyMk25DwtV`Xyy2?5?}PuOqD -o>SrzbQhfr-(8uQ5TW$;8TfLT9_>sbd87aU000000093000000000PcV`ybSrzbQhfr-(8uQ5TW$;8TfLT9_>sbd87aU000000093000000000PcV`ybD+9a{vheLR+L0000000000{{R3000000 3v+dFaBO95Wo~qH00{wOJ=2M>OG#EL&$!Mwbx&PZdlOljoA7|k;k>s6q @@ -232,26 +232,26 @@ oa5|8f~f~{V{&P5baMa+0%CAAe<9`Lptgpr6F_xjAC6(~TLj#*ewiHWCD(T2L(qY0=?N>gzK8zeWmt%8=p4R=gtK{LClh6Z#kObxUW*hK +0|IGe0((A!+Gi<8@j1mH(!M6&@;-q&tKasXxoi@p7d4yxtcU*MWmt%8=p4R=gtK{LClh6Z#kObxUW*hK HnBv9xdd)uZDj&Q>Z4!V_T!KNI`QJ|h6;Zj^jB$MPK+?7Lu3>C`4HI~v{(W1V6JV*{3!yZ{M3XW@z+p< ?Hl01LM?X!H~4Z0a%FR6a&~280(t`--)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OChzJK4+YqPF=12x -aaxrgbrDxyH3fc^ -lq>z|G!4fU)2DQrPzVkwe;&SMbsj>g6`?#s5rWnKhSeO?L~x^!;Y#eFP|P}0Z%Ez*ZeeX@0!8YhU)%QM +aaxrgbrDxyH3K7!h3DM#@+#URqY +Cg1WtfjX<-_MW+H5~UY4oBgb0bsj>g6`?#s5rWnKhSeO?L~x^!;Y#eFP|P}0Z%Ez*ZeeX@0!8YhU)%QM kO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*&DQ20rFt3ZOHs70;T-agdg$OP=xIp;K4#IcLF!~atLx|b7gXN Wn=<+10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUG5>JtwI*nu%&Q~z;Vl^%5wS6(#;{6ajG64wDP -k{-($PGN0jWJYOaY-C4lZ(?C=Q*>c;WmI`^Wd;KRX=DPgjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkw -e;&To?vf5kh_h+&YE#h%O8d1V_{UOl9{V;uR#^q%c;WmI`^Wd;KRX=DO>K7!h3DM#@+#URqYCg1WtfjX<-_MW+H5~UY4 +oBgcS?vf5kh_h+&YE#h%O8d1V_{UOl9{V;uR#^q%JtwI*nu%&Q~z;Vl^%5wS6(#;{6ajG64wDPk{-(vPGN0jWJYOaY-CMk -bYWC^aAgJq0%>FduZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1DSsZmb>vO>-_DBy8`Vb0jGrW9$=2qS +bYWC^aAgJq0%>Fddp?5NXDLVVImIB-z9!%DK7l%`-}aulY!amxHJkmcb>vO>-_DBy8`Vb0jGrW9$=2qS MXvL3He1kloHngE|MP07*1hrWn@NaWo%?ra$#@6CZd7@2Wd;KRX=DPgjmGz6 -Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&RxQV*^ZmKt8YDf|&5KZQ>65I6*X)C9iYp+?yjr7~y)ZeeX@ +1=xWxVN?HcT9qDk5m#O{2>e1kloHngE|MP07*1hrWn@NaWo%?ra$#@6CZd7@2Wd;KRX=DO>K7!h3 +DM#@+#URqYCg1WtfjX<-_MW+H5~UY4oBgabQV*^ZmKt8YDf|&5KZQ>65I6*X)C9iYp+?yjr7~y)ZeeX@ 0!8YhU)%QMkO4aJ;_ZeCe;xE!X<$x_Fs4If6Z`oP*&DQ20rFt3ZOHs70;T-agdg$OP=xIp;K4#IcLF!~ atLx|b7gXNWn=<+10COKearHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUG5>JtwI*nu%&Q~z;Vl^%5wS6(#; -{6ajG64wDPk{-(yPGN0jWJYOaY-CnpY-Mg^c~p6DWd;KRX=DPgjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQr -PzVkwe;&R@?dHP>9R0ZFSEMRj;Km4qfBYZ5UUs>0bg9bqiCNABZeeX@0!8YhU)%QMkO4aJ;_ZeCe;xE! +{6ajG64wDPk{-(yPGN0jWJYOaY-CnpY-Mg^c~p6DWd;KRX=DO>K7!h3DM#@+#URqYCg1WtfjX<-_MW+H +5~UY4oBgat?dHP>9R0ZFSEMRj;Km4qfBYZ5UUs>0bg9bqiCNABZeeX@0!8YhU)%QMkO4aJ;_ZeCe;xE! X<$x_Fs4If6Z`oP*&DQ20rFt3ZOHs70;T-agdg$OP=xIp;K4#IcLF!~atLx|b7gXNWn=<+10COKearHw cS=7M7YzYaI8*bvhMOc?)(rkC#nUG5>JtwI*nu%&Q~z;Vl^%5wS6(#;{6ajG64wDPk{-(rPGN0jWL9Bv X<=@3bvOnC0%>Fb009JUVQpmsMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r35LOoBKkGaY9#cS @@ -273,19 +273,19 @@ VQ>Wj015$yz}|oy`cC#6Uw2{wE+Sw~);*uMH+9Bf@aCY-RuiZDn*}0S0GmZ(?C=0tIh(Ze?Tx 2XWo~161PWnub7^O8ZDnqB1qWwkZe??6a|Q}@a$#@6CZU+fvcywiMb7^mG2nl6)V`Xr3X>V=` 3R87(aBO95Wo~o^1PNnrZggdCbV+0Z2AHk4+Bm{3x%H=p>4!*u&n~Wpi|4 -ZEyepNC#tbWnpx0assc7#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=^8dfQB3>bs~EXcCXx(drQcb +ZEyepNC#tbWnpx0asqokg4$;(NAWquAkw}j-|{|zI;-FIp1Euir581u{j9d=fQB3>bs~EXcCXx(drQcb 3B`Fx$)^%va$Ar)C7cUkZfdKHyBH|__hx_vscRWAu^w2r{b^x;wDWyGXd29 kG60)seH8)H{-R`;$q)jqasX>@6CZb@cgV`T;j 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 Ydx2$cvNmU*$z2Q1NvskzK}O!*07-npmH+?% delta 2609 zcmey<%lN04al$%<^}WZwr{p~}QP4J%tDK_!_oWH%anZ}mOJ)Ud@M+e|?b~?Hi6c_Z z>2i*(ZTGWp?^?9jeeGBN+Gt$ODeofxWA3(nUeVjbB^-;3Gt={OQ}arSopLhsQi4+x zb3!UIQ{)duxY;+&*3&AP_jskEl0so$`HL zk*#%CH?~BD3CG?2d+Fr5X-)r?a zTsy^9T=_LK&Q<1}IvYzlT`Njb^NKU`^Cq*~C`=aRIyu>vyJhol?si7CMemc=m%q9l zzH!0qZ3@rs`RQ_Z$4rzhTm-2OW4HC?j|8JMsU|<~^v$Z#Dhah!erE zCZMEfa=U=0;or<3ZF1|rn^}sjE?T<#mdvr@;P&_ConLs@bv>LNXE#M4qzG&mFu2^zh*Ni>4lflzuU6adz11A$9(=aj>KU%Jud|FyMV&AU!T6aviW^{wg8sbKdn{Y!f1P6-iz zDSe*-3jPBDh{;x*oRONFNYM7l2E2-!<7K=U2?vcnkHY4cvSLK291UqKB|m8)J^7_< z%jAEkY9MT!f|kMNrRvd4 z#Hb`}+~xyXC)fxZ1@yz@6NUkV722yPY>qH`PlRVdMz))*Cv2nvufpas)AK|a8Ns74 zxz(I-+hg(uE``a(78?lL-NLUhIoWb0VTHEb3X^@Ti13ZH^%;VuZDzM=XC=^HxxOWA8Xup+_1 T{NVTWh@`Yfud| diff --git a/stl/RGBStd@0.11.0.sty b/stl/RGBStd@0.11.0.sty index e30b7842..1b257773 100644 --- a/stl/RGBStd@0.11.0.sty +++ b/stl/RGBStd@0.11.0.sty @@ -1,5 +1,5 @@ {- - Id: stl:yMGmidPl-LcWFyh!-W6sQ3K5-JQ8evpO-BGuI!lA-0htx!kg#chemist-enjoy-sound + Id: stl:3QsSNDHr-YPIKTR9-5O!fLuv-xhcxKT2-0LWrO9b-pG15Nvw#mango-inside-shelf Name: RGBStd Version: 0.11.0 Description: RGB standard library @@ -56,28 +56,28 @@ import CommitVerify#miller-pancake-elastic use ReservedBytes4#young-goblin-academy use ReservedBytes8#rudolf-tape-adrian -import RGBCommit#printer-window-alpine +import RGBCommit#trident-rover-tape use ExtensionSchema#active-eddie-empty use BundleId#carmen-farmer-diesel use MetaValue#split-package-recycle use InputMap#octavia-north-gram use GenesisSchema#iron-forbid-hamlet - use AssignmentsBlindSealTxid#private-lesson-compare - use TypedAssignsBlindSealTxPtr#arsenal-immune-martin - use AssignmentsBlindSealTxPtr#ship-panic-magic use AltLayer1Set#flute-flex-bottle - use TypedAssignsBlindSealTxid#siren-float-child + use Genesis#ford-acrobat-border + use AssignBlindSealTxPtr#harbor-charm-nelson use TransitionType#picture-reflex-brigade use Occurrences#source-olga-mirage - use Extension#capital-police-factor use ValencyType#aloha-dublin-brush use GlobalState#mouse-bambino-brigade use GlobalStateSchema#silk-college-august use OwnedStateSchema#cover-shampoo-weather use ExtensionType#apropos-scoop-viva + use State#aroma-sailor-manila + use AssignmentsBlindSealTxid#shelter-declare-chrome use MetaType#quebec-mission-quota use TransitionSchema#jumbo-matrix-normal use StateData#nissan-pattern-inside + use AssignmentsBlindSealTxPtr#clone-mayor-patient use XChainBlindSealTxid#dynamic-life-brown use AttachId#factor-hair-everest use AssignmentType#secret-penguin-limit @@ -87,14 +87,15 @@ import RGBCommit#printer-window-alpine use OpId#picnic-single-gloria use Schema#eternal-block-totem use ContractId#uniform-welcome-papa - use State#octavia-kermit-fast + use TransitionBundle#rubber-permit-martin + use AssignBlindSealTxid#piano-baker-lola use Inputs#herman-liberal-galaxy use XChainPubWitness#carrot-import-nova - use Genesis#sincere-block-graph - use AssignBlindSealTxid#light-basket-trick - use Transition#race-korea-capital + use TypedAssignsBlindSealTxPtr#python-baboon-money + use Extension#swing-virgo-wisdom use Identity#smart-pioneer-nominal use AltLayer1#edison-survive-nitro + use TypedAssignsBlindSealTxid#algebra-fresh-wedding use GlobalValues#verona-iris-senator use Input#actor-minus-multi use GlobalStateType#yoga-quick-jasmine @@ -102,9 +103,8 @@ import RGBCommit#printer-window-alpine use XChainSecretSeal#alex-griffin-left use Valencies#light-letter-comet use Redeemed#mile-lady-perfect - use AssignBlindSealTxPtr#alamo-dallas-caesar + use Transition#economy-ethnic-audio use Metadata#member-nobody-imitate - use TransitionBundle#final-numeric-berlin import Std#ralph-blue-lucky use AlphaCaps#picnic-soprano-aurora @@ -157,17 +157,17 @@ data AssignIface : stateTy StrictTypes.SemId? , required Std.Bool , multiple Std.Bool -@mnemonic(monaco-pilot-nitro) +@mnemonic(prague-peru-under) data ClientBundleOpretProof : mpcProof CommitVerify.MerkleProof , dbcProof BPCore.OpretProof , bundle RGBCommit.TransitionBundle -@mnemonic(lithium-shrink-actor) +@mnemonic(baron-liberal-burger) data ClientBundleTapretProof : mpcProof CommitVerify.MerkleProof , dbcProof BPCore.TapretProof , bundle RGBCommit.TransitionBundle -@mnemonic(center-saddle-annual) +@mnemonic(jordan-episode-duet) data Consignmentfalse : version ContainerVer , transfer Std.Bool , terminals {RGBCommit.BundleId -> RGBCommit.XChainSecretSeal} @@ -182,7 +182,7 @@ data Consignmentfalse : version ContainerVer , attachments {RGBCommit.AttachId -> [Byte ^ ..0xffffff]} , signatures {ContentId -> ^ ..0xff ContentSigs} -@mnemonic(permit-simon-summer) +@mnemonic(gustav-people-message) data Consignmenttrue : version ContainerVer , transfer Std.Bool , terminals {RGBCommit.BundleId -> RGBCommit.XChainSecretSeal} diff --git a/stl/RGBStorage@0.11.0.sta b/stl/RGBStorage@0.11.0.sta index 6b324b0b..f87233bf 100644 --- a/stl/RGBStorage@0.11.0.sta +++ b/stl/RGBStorage@0.11.0.sta @@ -1,24 +1,24 @@ -----BEGIN STRICT TYPE LIB----- -Id: stl:lnl6QOG0-EYfOLKP-MHdEyA3-$cyUNuc-F3XmU!W-0glc1M0#alaska-phone-bagel +Id: stl:dYzM3Ct9-SJ8PljY-C!6hB6y-VlWvDE7-DAtNg3y-zanf6hE#media-fresh-cadet Name: RGBStorage Dependencies: + RGBLogic#leonid-melody-quick, StrictTypes#century-comrade-chess, BPCore#austin-story-retro, AluVM#congo-archive-folio, CommitVerify#miller-pancake-elastic, - RGBCommit#printer-window-alpine, - RGBStd#chemist-enjoy-sound, + RGBCommit#trident-rover-tape, Std#ralph-blue-lucky, - RGBLogic#ohio-electra-dilemma, + RGBStd#mango-inside-shelf, Bitcoin#signal-color-cipher -Check-SHA256: 3b654f8a5eb432f7f3c40cabf94f95336a3e9973df24330917273e0b228f8e88 +Check-SHA256: 9253c34c5b44ddbc699161987833ea989bcdcd22aa105c8cf57fbdc138fdbcb6 -3Q|WxQ*>`~VP|CtMe3tp+xFv-0Xp&G?S=|}9rRaeU`~uMrbA>C`}q*r3sZD*X=8L$d2nTORuk6O)Q5AK -bFW;JEQ>MoHhG*Mzd(pEtONi$rOUxc20~CnZ*pZ~a5aA+<>R2XhQO_4{AcS-HH^7AVzASV8M4NYxyCjH -L2PwaO?m?z-)Viz@~C%8KNS}Z0aQ3s^SOqbBwN-D{wl@OCJaMwZEb0ER%LQ&W_hoT#`k1y;WQvCHXeDD -EB)y-4aXJJr*xW72o5QK9=-`uM?ynyZEb0E$ib$G)8#G2g~}h6>clrIl2GyM={OOtBk4fW8*%zb22w{t -Q*>m?EFN!zncXl9K5w2;FV{y1jDTJCC^p$-mHEbO0#qjhQ*>nKQ=pGEdKZ=MPb)<*m$;LvDR$csb;@mC -=QtLlJD!;cQb$5eZ)a&^^=uPjBlbC`N(qzPM@Gr{imSMTSY5T*7C#t%#3&jH2SRCdV{d702?arHbyiIV +3Q|WxQ*>`~VP|CtE%Dq(^gpz7jp7pJ!qRo6KcERC_=qjv!(mxp;l`5z2vSEvOmAmtV@2wtU)%QMkO4aJ +;_ZeCe;xE!X<$x_Fs4If6Z`oP*$Y#2a%p39RC#b^b5;}9*VKn|nRBmPlPrrd^EP>$AHP6|FsuXsI;G3O +NCrYsLvM0rVsJHoA?4$swuZp1Wc+9AOf`(TIbyKWjTy4WkGaM+1wm|eR!w>X9p7nv%krpqN4E?M+l67UG^w8*<_XZ#%uyqCj(P-WZerAG%@R7@(N8Kc{}IJy8K~t5|i6P +)~xSaq-}XN{034-LQ`~P^=uPjBlbC`N(qzPM@Gr{imSMTSY5T*7C#t%#3&jH2SRCdV{d702?arHbyiIV 01^bJwgM1*ibOBDT%6aZ|SrJerP1pIOD57`7Ol|-ogQ6Pjg~y>s-v>!^VNPLfWv4Jz0xkJm$nc4y MWR2J-cc#Q6SofWC)gp7L6!Sc3I$AQVo7AP4Jk3r!|EoW{Zi$060oMN(jLzPuNboiNpoRS @@ -55,39 +55,39 @@ Wo1rpWM%K_6AuO0fiYoI|8ZKC9(55{UNs2(LOhfb*8wh)9?K3=Wpib6c4cHjd30rSH2#7XN#A(BKKz&v rHo-i1kG~VoNp!e_~i}U4@G!%Wo~n6Z*Eg#Xk~3-1ACLTJsO2B2U!6ncg?mz@CdC==Kxq?gSEg)z2E{| 2tsvkWNc+gWE3Slj!?y>j|MdwWnpYo -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 +L349yXKr&sY-w&}Q)OXnRCrKyaV?} +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 -5w0WYK++p=`bayqMEp^75#kD_Tqj3Vr!KR7RO -I1#QR=|IvOar#K!YERg2%AQl=6Lc4y4BuUum=K}#_8Itcm>%s+B6*|$00000000300000000007XJu|> -b7gY?3IeZ<#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=@LlEJ-@Z0;0Ob-P{Wzd?2rs)M&&=&l*}G -;Jw22Ix+&UjmGz6Zs9Z_D>fc^lq>z|G!4fU)2DQrPzVkwe;&TExal5h{0lRojI;wCRUm@0B`|@HB98P_ -oAgZ&Vm^rg00000000300000000005b9HcVYyb)Z$ib$G)8#G2g~}h6>clrIl2GyM={OOtBk4fW8*%zb -2AHk4+Bm{3x%H=p>4!*u&nOI1#QR=|IvO -ar#JOJ=2M>OG#EL&$!Mwbxg)RqK0VQ|Mwn6X+ -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 -OI1#QR=|IvOar#K&)D=(>(T2L(qY0=?N$ib$G -)8#G2g~}h6>clrIl2GyM={OOtBk4fW8*%zbh8PemXlG!~;@e)_O3H?xO^a~KWeI~0jp}x-Dk@(^00000 -00000|Nj60000002u)>eQ*>c;Wd;HXcWHEPWpi_7a{vkguZ_m{WNzU!AS*T=d6X;t=`;<;71O75notN1 -DSsZmiECIT&Bl;lSX#$ms8AQN7m&qYX% -7Na|!nR2^A$QV;yG0%+u`Lqfm#|FpRuujhTP8r)T_J?np;Q#;t000000RR90{{R30010DnZgg^CV{~%> -3IeZ<#`k1y;WQvCHXeDDEB)y-4aXJJr*xW72o5QK9=@LlEJ-@Z0;0Ob-P{Wzd?2rs)M&&=&l*}G;Jw22 -Ix+#PeJ!|9#Bo%!^4)q3npZX#!goq#B@MRnCBuc8L!b@-0000000030000000000 +xyCjU1gEwF5PXV6FZDLo1#Vec_~kix7WfVQ#Sd|CM9$^_0000000030{{R3000004b7^OD015)#3lcOj +>tON(T2L(qY0=?N-3t;l +G3#LR3QZq*JLk)~{9$tvliNbptnXW-ZFx5Qh8PemXlG!~;@e)_O3H?xO^a~KWeI~0jp}x-Dk@(^00000 +00000|Nj60000002u)>eQ*>c;Wd;HXcWHEPWpi_7a{vkgdp?5NXDLVVImIB-z9!%DK7l%`-}aulY!amx +HJkmciECIT&Bl;lSX#$ms8AQN7m&qY<-*c+r9YqvBlw6d-@{>9 +U*X1+0dl)S$QV;yG0%+u`Lqfm#|FpRuujhTP8r)T_J?np;Q#;t000000RR90{{R30010DnZgg^CV{~%> +3IcmRg4$;(NAWquAkw}j-|{|zI;-FIp1Euir581u{j8q|EJ-@Z0;0Ob-P{Wzd?2rs)M&&=&l*}G;Jw22 +Ix+!#bL(f8`U$>X>B)Y_u0zsDWJXxNV$=kC)4@UGUHf+c0000000030000000000 -----END STRICT TYPE LIB----- diff --git a/stl/RGBStorage@0.11.0.stl b/stl/RGBStorage@0.11.0.stl index 88c58d859b8d57018d666676535185568e82aae5..314dabd9b729ebe90683305cd9be550b05c02b5e 100644 GIT binary patch delta 2550 zcmdlSwK>X^E6Cj`xFo+QF+G)2_v0P+FZNrCdmjlsJ#?vbsr>>@nZ znUMpi)+awbGkGG&B|L-xXtB?=@rjD_*ClPt2jQH`iKZ@@$>)-`2}EJt3Tf-90rgwK%g_)8t;# z<7EZAKFqJLIIPKRE>WTzA=DN!t>HSZN`Tid-|@1-I}p>`;LQK!>7bnfB2qw`|4}!qjt3_lLA`v*p;` zcdAb|ty+4dKY~zbVLY*CfNwuRdyDlzih7 z^=r-v-Q&}zmFSwR-~Dj0Fos`&ZkoWap0uf0p?a#4=JLx=w=DhT`up|iBNJs_MX2so zW>#I;uzH1vR7hn(Y6?VmF=|k47B#WI=b8NdQcNq0*6Ycudk#!#T4w#fX#VY2g2pM+ z6gXWgN>cNRCtC}IS)Hl4!!G-y{m3=t@BJd7c8#oe6s2|=YVOg${X6pa|5|@Z9M)u} zY@R5P#Hjs9qu4v^m0CcDCr{_>`@F5|*iOILm+qOOCt>CzCw@?u3lSibHH4xzZx&)> z)=m_f$g6iKfK6ytX;hWQx-)uZ$71+DEPd&_Sf=jXLuV!~$DEw}aXoSYM3MF-@R2`h?|Gnm|<$u-$lo(RPa@;Zb~wC7it{6?OOutI4; zg~?_LRt|)6Afa%ayg@-rfsi4Se<>&uc2Xa&!sKX0Q^E>2C=y}XM@4tSCVf;?P-G$) z;h;d>sia1Xaf(Wugw0#6p)ff~*^sb#Ad4?66Or2T1r?MTh_E?MPIK}?6+OZ>H^>76 zhG4WBs9F(@`z}>Q!ir9-S`&5@FgWT7hAyERf&mKtLuuCH(t?5<1}=iWWdl|Qw(`pSOBK)I- z!ekyzdBUc>0hS8cnkIx5?$_)htjJD)m~_2L>muPuo~=!UH}7bB5Ox$OzzDUnCchL? zn7mYnh~Nk25<|wC;@9cZesS)LdwH_%_&VoH9w}}S`;xA(R9`;m_&D}=IeIPt0O(bv ARR910 delta 2510 zcmdlSwKwAxVPsw{|qM&UiS2;!d?@JTjWI1aq=1jFUs?#RQ-0}iNxJZt z2OHS*l*z1&Dw@xO7xbG}iBEm!ukC6ueaGZgnq{{IN>Am+J+}~BY&~x#2T-j~etKr| z<^V=3P6auq%Q?2T-Os+gYtdr&wO{#bqj5E-yo>ygx!d-6MQ;zEJda0GLH=Nbn|;%4 zJ*|>?k5?*6nLb{{|HM~Oao|MVvW!oqJ;+Ixb@mtrdQ@)QYvbFB&#+Ils;kdhh zFP&UB%_;D0yGgq!v*hIYJYviNB}J3FxOA;_yIF$-H*p!nUO4)WY2EvPpKGVsiYwpf zk_`}i)%S4z4#|+pg47hp;^NHoyke)E%)FG~)Wn>Sip-SBBHYnht`kK~tk`naiSC)2 z|4c})Rp$;v$ud4qq0Bi~nRn`JEah~qC`rvL&dkr7oX`Do@^+rpo9FOuVpLo7K52dV ztJ~ol7tG$K@a&$S4%g?Yzn9;%^XYzAtM%*j3fAC~#FEs>oB7r2H|}^Tm-UC+cwx^L zX4z1MrcJ5_jr~e}UqWVo@#Rml>tuIN%}XuLEZ*vn7U+B_Usu;4!EE{ec9{(Z*0Dhj zWvh%{x$JJ!dnzXk@dSz=wjS(J{xpNyJHHU&cIcygSa6JbRMMk9*u2#m3X_wR4GEhEviPzx5h-kypn@_35jMxkX-;0KqDR=~26 z5R6g-RV%{r-leKYSkY-!Yr>8K21h-?&?Qv1F+jn8D9u`2T2PR~z(vrvY%|twzcu-& znjB%@JP}oxtgNn0*hj$h=Sa{;gi5{1=hfv1TLsKC4un!Vp{i$co`x)8n^tQO5#b*t z6eja%$`dy20 ^ ..0xffffff {RGBCommit.Opout ^ ..0xffffff}} -@mnemonic(dolby-mammal-pogo) +@mnemonic(fire-domingo-monaco) data MemContractState : schemaId RGBCommit.SchemaId , contractId RGBCommit.ContractId , global {RGBCommit.GlobalStateType -> ^ ..0xff MemGlobalState} @@ -213,7 +213,7 @@ data MemIndex : opBundleIndex {RGBCommit.OpId -> ^ ..0xffffff RGBCommit , contractIndex {RGBCommit.ContractId -> ^ ..0xff ContractIndex} , terminalIndex {RGBCommit.XChainSecretSeal -> ^ ..0xffffff {RGBCommit.Opout ^ ..0xff}} -@mnemonic(alfonso-office-suzuki) +@mnemonic(summer-sardine-disney) data MemStash : schemata {RGBCommit.SchemaId -> ^ ..0xff RGBStd.SchemaIfaces} , ifaces {RGBStd.IfaceId -> ^ ..0xff RGBStd.Iface} , geneses {RGBCommit.ContractId -> ^ ..0xff RGBCommit.Genesis} diff --git a/stl/Transfer.vesper b/stl/Transfer.vesper index cc718eeb..08cfaa9f 100644 --- a/stl/Transfer.vesper +++ b/stl/Transfer.vesper @@ -65,7 +65,7 @@ Consignmenttrue rec liquid bytes len=32 wrapped aka=SecretSeal tag=1 state rec State reserved bytes len=1 aka=ReservedBytes1 - value bytes len=0..MAX16 aka=StateData + data bytes len=0..MAX16 aka=StateData some bytes len=32 option wrapped aka=AttachId tag=1 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=1 @@ -82,7 +82,7 @@ Consignmenttrue rec blinding is U64 state rec State reserved bytes len=1 aka=ReservedBytes1 - value bytes len=0..MAX16 aka=StateData + data bytes len=0..MAX16 aka=StateData some bytes len=32 option wrapped aka=AttachId tag=1 lock bytes len=2 aka=ReservedBytes2 valencies set len=0..MAX8 aka=Valencies @@ -111,7 +111,7 @@ Consignmenttrue rec liquid bytes len=32 wrapped aka=SecretSeal tag=1 state rec State reserved bytes len=1 aka=ReservedBytes1 - value bytes len=0..MAX16 aka=StateData + data bytes len=0..MAX16 aka=StateData some bytes len=32 option wrapped aka=AttachId tag=1 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=1 @@ -128,7 +128,7 @@ Consignmenttrue rec blinding is U64 state rec State reserved bytes len=1 aka=ReservedBytes1 - value bytes len=0..MAX16 aka=StateData + data bytes len=0..MAX16 aka=StateData some bytes len=32 option wrapped aka=AttachId tag=1 lock bytes len=2 aka=ReservedBytes2 redeemed map len=0..MAX8 aka=Redeemed @@ -188,7 +188,7 @@ Consignmenttrue rec liquid bytes len=32 wrapped aka=SecretSeal tag=1 state rec State reserved bytes len=1 aka=ReservedBytes1 - value bytes len=0..MAX16 aka=StateData + data bytes len=0..MAX16 aka=StateData some bytes len=32 option wrapped aka=AttachId tag=1 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=1 @@ -209,7 +209,7 @@ Consignmenttrue rec blinding is U64 state rec State reserved bytes len=1 aka=ReservedBytes1 - value bytes len=0..MAX16 aka=StateData + data bytes len=0..MAX16 aka=StateData some bytes len=32 option wrapped aka=AttachId tag=1 lock bytes len=2 aka=ReservedBytes2 valencies set len=0..MAX8 aka=Valencies @@ -259,7 +259,7 @@ Consignmenttrue rec liquid bytes len=32 wrapped aka=SecretSeal tag=1 state rec State reserved bytes len=1 aka=ReservedBytes1 - value bytes len=0..MAX16 aka=StateData + data bytes len=0..MAX16 aka=StateData some bytes len=32 option wrapped aka=AttachId tag=1 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=1 @@ -280,7 +280,7 @@ Consignmenttrue rec blinding is U64 state rec State reserved bytes len=1 aka=ReservedBytes1 - value bytes len=0..MAX16 aka=StateData + data bytes len=0..MAX16 aka=StateData some bytes len=32 option wrapped aka=AttachId tag=1 lock bytes len=2 aka=ReservedBytes2 valencies set len=0..MAX8 aka=Valencies @@ -335,7 +335,7 @@ Consignmenttrue rec liquid bytes len=32 wrapped aka=SecretSeal tag=1 state rec State reserved bytes len=1 aka=ReservedBytes1 - value bytes len=0..MAX16 aka=StateData + data bytes len=0..MAX16 aka=StateData some bytes len=32 option wrapped aka=AttachId tag=1 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=1 @@ -356,7 +356,7 @@ Consignmenttrue rec blinding is U64 state rec State reserved bytes len=1 aka=ReservedBytes1 - value bytes len=0..MAX16 aka=StateData + data bytes len=0..MAX16 aka=StateData some bytes len=32 option wrapped aka=AttachId tag=1 lock bytes len=2 aka=ReservedBytes2 valencies set len=0..MAX8 aka=Valencies @@ -406,7 +406,7 @@ Consignmenttrue rec liquid bytes len=32 wrapped aka=SecretSeal tag=1 state rec State reserved bytes len=1 aka=ReservedBytes1 - value bytes len=0..MAX16 aka=StateData + data bytes len=0..MAX16 aka=StateData some bytes len=32 option wrapped aka=AttachId tag=1 lock bytes len=2 aka=ReservedBytes2 revealed rec tag=1 @@ -427,7 +427,7 @@ Consignmenttrue rec blinding is U64 state rec State reserved bytes len=1 aka=ReservedBytes1 - value bytes len=0..MAX16 aka=StateData + data bytes len=0..MAX16 aka=StateData some bytes len=32 option wrapped aka=AttachId tag=1 lock bytes len=2 aka=ReservedBytes2 valencies set len=0..MAX8 aka=Valencies From 1a1ad23a0ee94e6b9ea02a3568bc5742f95a105c Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 17 Oct 2024 15:09:08 +0200 Subject: [PATCH 09/16] further invoice and interface state improvements --- Cargo.lock | 10 +-- invoice/Cargo.toml | 1 - invoice/src/builder.rs | 111 ++++------------------------ invoice/src/invoice.rs | 32 +------- invoice/src/lib.rs | 3 +- invoice/src/parse.rs | 155 ++++++++++++++------------------------- src/interface/builder.rs | 149 +++++++++++++++++++++++++------------ src/persistence/stock.rs | 25 +++---- 8 files changed, 190 insertions(+), 296 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 80e12cd3..2420f764 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -149,12 +149,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "base58" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" - [[package]] name = "base64" version = "0.22.1" @@ -674,11 +668,12 @@ dependencies = [ [[package]] name = "rgb-core" version = "0.11.0-beta.9" -source = "git+https://github.com/RGB-WG/rgb-core?branch=feat/fungible-nonconf#75424505e4f24df90d9ee1d284c4ee25103c185b" +source = "git+https://github.com/RGB-WG/rgb-core?branch=feat/fungible-nonconf#b59f1ca4c13c62ce53152f7f4c34094e435a1be4" dependencies = [ "aluvm", "amplify", "baid64", + "base64", "bp-core", "chrono", "commit_verify", @@ -696,7 +691,6 @@ version = "0.11.0-beta.9" dependencies = [ "amplify", "baid64", - "base58", "bp-core", "bp-invoice", "fluent-uri", diff --git a/invoice/Cargo.toml b/invoice/Cargo.toml index ff70bc69..60607596 100644 --- a/invoice/Cargo.toml +++ b/invoice/Cargo.toml @@ -17,7 +17,6 @@ name = "rgbinvoice" [dependencies] amplify = { workspace = true } -base58 = "0.2.0" baid64 = { workspace = true } strict_encoding = { workspace = true } bp-core = { workspace = true } diff --git a/invoice/src/builder.rs b/invoice/src/builder.rs index 1805ee9e..9d84fb61 100644 --- a/invoice/src/builder.rs +++ b/invoice/src/builder.rs @@ -21,11 +21,10 @@ use std::str::FromStr; -use rgb::{AttachId, ContractId, State, StateData}; -use strict_encoding::{FieldName, StrictSerialize, TypeName}; +use rgb::{ContractId, StateData}; +use strict_encoding::{FieldName, SerializeError, StrictSerialize, TypeName}; -use crate::invoice::{Beneficiary, InvoiceState, RgbInvoice, RgbTransport, XChainNet}; -use crate::TransportParseError; +use crate::{Beneficiary, RgbInvoice, RgbTransport, TransportParseError, XChainNet}; #[derive(Clone, Eq, PartialEq, Debug)] pub struct RgbInvoiceBuilder(RgbInvoice); @@ -40,7 +39,7 @@ impl RgbInvoiceBuilder { operation: None, assignment: None, beneficiary: beneficiary.into(), - owned_state: InvoiceState::Any, + state: None, expiry: None, unknown_query: none!(), }) @@ -72,106 +71,26 @@ impl RgbInvoiceBuilder { self } - /// Set the invoiced state, which includes both state data and an optional attachment - /// information. - /// - /// # Panics - /// - /// If any state information or attachment requirements are already present in the invoice. - /// - /// # See also - /// - /// - [`Self::add_state_data`], adding just state data information, not affecting attachment - /// requirements; - /// - [`Self::serialize_state_data`], for adding state data by serializing them from a state - /// object; - /// - [`Self::add_attachment`], for adding attachment requirement to an existing invoiced state - /// information. - pub fn set_state(mut self, state: State) -> Self { - if !self.0.owned_state.is_any() { - panic!("invoice already has state information"); - } - self.0.owned_state = InvoiceState::Specific(state); - self - } - /// Add state data to the invoice. /// - /// NB: This keeps existing attachment requirements. - /// - /// # Panics - /// - /// If the invoice already have any state information (excluding attachment requirements). - /// - /// # See also - /// - /// - [`Self::set_state`], for redefining the whole of the invoiced state, including attachment - /// requirements; - /// - [`Self::serialize_state_data`], for adding state data by serializing them from a state - /// object; - /// - [`Self::add_attachment`], for adding attachment requirement to an existing invoiced state - /// information. - pub fn add_state_data(mut self, data: StateData) -> Self { - self.0.owned_state = match self.0.owned_state { - InvoiceState::Any => InvoiceState::Specific(State::from(data)), - InvoiceState::Specific(_) => panic!("invoice already has state information"), - InvoiceState::Attach(attach_id) => InvoiceState::Specific(State::with(data, attach_id)), - }; + /// See also [`Self::serialize_state_data`], which adds state data by serializing them from a + /// state object. + pub fn set_state(mut self, data: StateData) -> Self { + self.0.state = Some(data); self } /// Add state data to the invoice by strict-serializing the provided object. /// - /// NB: This keeps existing attachment requirements. - /// /// Use the function carefully, since the common pitfall here is to perform double serialization /// of an already serialized data type, like `SmallBlob`. This produces an invalid state object - /// which can't be properly parsed later. - /// - /// # Panics - /// - /// If the invoice already has any state information (excluding attachment requirements). - /// - /// # See also - /// - /// - [`Self::set_state`], for redefining the whole of the invoiced state, including attachment - /// requirements; - /// - [`Self::add_state_data`], adding just state data information, not affecting attachment - /// requirements; - /// - [`Self::add_attachment`], for adding attachment requirement to an existing invoiced state - /// information. - pub fn serialize_state_data(mut self, data: impl StrictSerialize) -> Self { - self.0.owned_state = InvoiceState::Specific(State::from_serialized(data)); - self - } - - /// Add attachment requirements to an invoice, keeping the rest of the invoice state information - /// unchanged. - /// - /// # Panics - /// - /// If the invoice already has attachment requirements defined. - /// - /// # See also - /// - /// - [`Self::set_state`], for redefining the whole of the invoiced state, including attachment - /// requirements; - /// - [`Self::add_state_data`], adding just state data information, not affecting attachment - /// requirements; - /// - [`Self::serialize_state_data`], for adding state data by serializing them from a state - /// object; - pub fn add_attachment(mut self, attach_id: AttachId) -> Result { - self.0.owned_state = match self.0.owned_state { - InvoiceState::Any => InvoiceState::Attach(attach_id), - InvoiceState::Attach(_) - | InvoiceState::Specific(State { - attach: Some(_), .. - }) => panic!("invoice already has attachment requirements"), - InvoiceState::Specific(mut state) => { - state.attach = Some(attach_id); - InvoiceState::Specific(state) - } - }; + /// which can't be properly parsed later. See also [`Self::set_state`], which sets state data + /// directly with no serialization. + pub fn serialize_state_data( + mut self, + data: &impl StrictSerialize, + ) -> Result { + self.0.state = Some(StateData::from_serialized(data)?); Ok(self) } diff --git a/invoice/src/invoice.rs b/invoice/src/invoice.rs index f48f5b75..41f1720d 100644 --- a/invoice/src/invoice.rs +++ b/invoice/src/invoice.rs @@ -24,7 +24,7 @@ use bp::seals::txout::CloseMethod; use bp::{InvalidPubkey, OutputPk, PubkeyHash, ScriptHash, WPubkeyHash, WScriptHash}; use indexmap::IndexMap; use invoice::{AddressNetwork, AddressPayload, Network}; -use rgb::{AttachId, ContractId, Layer1, SecretSeal, State}; +use rgb::{ContractId, Layer1, SecretSeal, StateData}; use strict_encoding::{FieldName, TypeName}; #[derive(Clone, Eq, PartialEq, Hash, Debug)] @@ -37,33 +37,6 @@ pub enum RgbTransport { UnspecifiedMeans, } -#[derive(Clone, Eq, PartialEq, Hash, Debug)] -pub enum InvoiceState { - Any, - Specific(State), - Attach(AttachId), -} - -impl InvoiceState { - pub fn is_any(&self) -> bool { matches!(self, InvoiceState::Any) } - - pub fn state(&self) -> Option<&State> { - match self { - InvoiceState::Any => None, - InvoiceState::Specific(s) => Some(s), - InvoiceState::Attach(_) => None, - } - } - - pub fn attach_id(&self) -> Option { - match self { - InvoiceState::Any => None, - InvoiceState::Specific(s) => s.attach, - InvoiceState::Attach(id) => Some(*id), - } - } -} - #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Display)] #[non_exhaustive] pub enum ChainNet { @@ -237,9 +210,10 @@ pub struct RgbInvoice { pub operation: Option, pub assignment: Option, pub beneficiary: XChainNet, - pub owned_state: InvoiceState, + pub state: Option, /// UTC unix timestamp pub expiry: Option, + // Attachment requirements should go here pub unknown_query: IndexMap, } diff --git a/invoice/src/lib.rs b/invoice/src/lib.rs index d2820bc8..9ffe2999 100644 --- a/invoice/src/lib.rs +++ b/invoice/src/lib.rs @@ -37,6 +37,5 @@ pub use builder::RgbInvoiceBuilder; pub use parse::{InvoiceParseError, TransportParseError}; pub use crate::invoice::{ - Beneficiary, ChainNet, InvoiceState, Pay2Vout, Pay2VoutError, RgbInvoice, RgbTransport, - XChainNet, + Beneficiary, ChainNet, Pay2Vout, Pay2VoutError, RgbInvoice, RgbTransport, XChainNet, }; diff --git a/invoice/src/parse.rs b/invoice/src/parse.rs index 49a49dca..3ae6b546 100644 --- a/invoice/src/parse.rs +++ b/invoice/src/parse.rs @@ -24,21 +24,16 @@ use std::io::{Cursor, Write}; use std::num::ParseIntError; use std::str::FromStr; -use amplify::confinement::{self, SmallBlob}; -use amplify::Wrapper; use baid64::{Baid64ParseError, DisplayBaid64, FromBaid64Str}; -use base58::{FromBase58, ToBase58}; use fluent_uri::enc::EStr; use fluent_uri::Uri; use indexmap::IndexMap; use invoice::{AddressPayload, UnknownNetwork}; use percent_encoding::{utf8_percent_encode, AsciiSet, CONTROLS}; -use rgb::{ContractId, SecretSeal, State, StateData}; +use rgb::{ContractId, SecretSeal, StateData, StateParseError}; use strict_encoding::{InvalidRString, TypeName}; -use crate::invoice::{ - Beneficiary, ChainNet, InvoiceState, Pay2Vout, RgbInvoice, RgbTransport, XChainNet, -}; +use crate::invoice::{Beneficiary, ChainNet, Pay2Vout, RgbInvoice, RgbTransport, XChainNet}; const OMITTED: &str = "~"; const EXPIRY: &str = "expiry"; @@ -68,22 +63,6 @@ pub enum TransportParseError { InvalidTransportHost(String), } -#[derive(Debug, Display, Error, From)] -#[display(doc_comments)] -pub enum InvoiceStateError { - #[from] - /// invalid invoice state Base58 encoding. - Base58(base58::FromBase58Error), - - #[from] - /// invoice state size exceeded. - Len(confinement::Error), - - #[from] - /// invalid invoice state encoding - {0} - Deserialize(strict_encoding::DeserializeError), -} - #[derive(Debug, Display, Error, From)] #[display(doc_comments)] pub enum InvoiceParseError { @@ -112,7 +91,7 @@ pub enum InvoiceParseError { #[from] #[display(inner)] - InvalidState(InvoiceStateError), + InvalidState(StateParseError), /// no invoice transport has been provided. NoTransport, @@ -177,30 +156,6 @@ impl RgbInvoice { } } -impl Display for InvoiceState { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - match self { - InvoiceState::Any => Ok(()), - InvoiceState::Specific(state) => f.write_str(&state.data.to_base58()), - // TODO: Support attachment through invoice params - InvoiceState::Attach(_) => Ok(()), - } - } -} - -impl FromStr for InvoiceState { - type Err = InvoiceStateError; - fn from_str(s: &str) -> Result { - if s.is_empty() { - return Ok(InvoiceState::Any); - } - let data = s.from_base58()?; - let data = SmallBlob::try_from(data)?; - let data = StateData::from_inner(data); - Ok(InvoiceState::Specific(State::from(data))) - } -} - impl Display for RgbTransport { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { @@ -337,7 +292,6 @@ impl FromStr for XChainNet { impl Display for RgbInvoice { fn fmt(&self, f: &mut Formatter) -> fmt::Result { // TODO: Support attachment through invoice params - let amt = self.owned_state.to_string(); if let Some(contract) = self.contract { let id = if f.alternate() { contract.to_string().replace('-', "") @@ -359,8 +313,8 @@ impl Display for RgbInvoice { if let Some(ref assignment_name) = self.assignment { write!(f, "{assignment_name}/")?; } - if !amt.is_empty() { - write!(f, "{amt}+")?; + if let Some(state) = self.state.as_ref() { + write!(f, "{state}+")?; } let beneficiary = if f.alternate() { self.beneficiary.to_string().replace('-', "") @@ -442,9 +396,9 @@ impl FromStr for RgbInvoice { .split_once('+') .map(|(a, b)| (Some(a), Some(b))) .unwrap_or((Some(assignment.as_str()), None)); - let (beneficiary_str, value) = match (beneficiary, state) { - (Some(b), Some(a)) => (b, InvoiceState::from_str(a)?), - (None, Some(b)) => (b, InvoiceState::Any), + let (beneficiary_str, state) = match (beneficiary, state) { + (Some(b), Some(a)) => (b, Some(StateData::from_str(a)?)), + (None, Some(b)) => (b, None), _ => unreachable!(), }; @@ -480,7 +434,7 @@ impl FromStr for RgbInvoice { operation: None, assignment: None, beneficiary, - owned_state: value, + state, expiry, unknown_query: query_params, }) @@ -518,31 +472,22 @@ mod test { fn parse() { // rgb20/rgb25 parameters let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ - T5FhUZEHbQu4B+bc:utxob:\ + y----------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); - assert_eq!( - invoice.owned_state, - InvoiceState::Specific(State::from(StateData::from_checked(vec![ - 8, 0, 100, 0, 0, 0, 0, 0, 0, 0 - ]))) - ); + assert_eq!(invoice.state, Some(StateData::from_checked(vec![100, 0, 0, 0, 0, 0, 0, 0]))); assert_eq!(invoice.to_string(), invoice_str); - assert_eq!(format!("{invoice:#}"), invoice_str.replace('-', "")); // rgb21 parameters let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB21/\ - 5QsfkEcyanohXadePHZ+bc:utxob:\ + -p----p---------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); assert_eq!( - invoice.owned_state, - InvoiceState::Specific(State::from(StateData::from_checked(vec![ - 12, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 - ]))) + invoice.state, + Some(StateData::from_checked(vec![1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0])) ); assert_eq!(invoice.to_string(), invoice_str); - assert_eq!(format!("{invoice:#}"), invoice_str.replace('-', "")); // no amount let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/bc:utxob:\ @@ -584,47 +529,51 @@ mod test { Err(InvoiceParseError::InvalidContractId(c)) if c == invalid_contract_id)); // with expiration - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ - zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?\ - expiry=1682086371"; + let invoice_str = + "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/y----------+bc:utxob:\ + zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?expiry=1682086371"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); assert_eq!(invoice.to_string(), invoice_str); // bad expiration - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + y----------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?expiry=six"; let result = RgbInvoice::from_str(invoice_str); assert!(matches!(result, Err(InvoiceParseError::InvalidExpiration(_)))); // with bad query parameter - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + y----------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?expiry"; let result = RgbInvoice::from_str(invoice_str); assert!(matches!(result, Err(InvoiceParseError::InvalidQueryParam(_)))); // with an unknown query parameter - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + y----------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?unknown=new"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); assert_eq!(invoice.to_string(), invoice_str); // with two unknown query parameters - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ - zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?unknown=new&\ - another=new"; + let invoice_str = + "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/y----------+bc:utxob:\ + zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?unknown=new&another=new"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); assert_eq!(invoice.to_string(), invoice_str); // with expiration and an unknown query parameter - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ - zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?\ - expiry=1682086371&unknown=new"; + let invoice_str = + "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/y----------+bc:utxob:\ + zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?expiry=1682086371&unknown=new"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); assert_eq!(invoice.to_string(), invoice_str); // with an unknown query parameter containing percent-encoded text - let invoice_base = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:\ - utxob:zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?"; + let invoice_base = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + y----------+bc:utxob:\ + zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?"; let query_key_encoded = ":@-%20%23"; let query_key_decoded = ":@- #"; let query_val_encoded = "?/.%26%3D"; @@ -652,26 +601,30 @@ mod test { assert!(matches!(result, Err(InvoiceParseError::InvalidScheme(_)))); // empty transport endpoint specification - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + y----------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints="; let result = RgbInvoice::from_str(invoice_str); assert!(matches!(result, Err(InvoiceParseError::InvalidQueryParam(_)))); // invalid transport endpoint specification - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + y----------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=bad"; let result = RgbInvoice::from_str(invoice_str); assert!(matches!(result, Err(InvoiceParseError::InvalidQueryParam(_)))); // invalid transport variant - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + y----------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=rpca:/\ /host.example.com"; let result = RgbInvoice::from_str(invoice_str); assert!(matches!(result, Err(InvoiceParseError::InvalidQueryParam(_)))); // rgb-rpc variant - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + y----------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=rpc://\ host.example.com"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); @@ -682,7 +635,8 @@ mod test { assert_eq!(invoice.to_string(), invoice_str); // rgb-rpc variant, host containing authentication, "-" characters and port - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + y----------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=rpcs:/\ /user:pass@host-1.ex-ample.com:1234"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); @@ -693,7 +647,8 @@ mod test { assert_eq!(invoice.to_string(), invoice_str); // rgb-rpc variant, IPv6 host - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + y----------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=rpcs:/\ /%5B2001:db8::1%5D:1234"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); @@ -704,29 +659,30 @@ mod test { assert_eq!(invoice.to_string(), invoice_str); // rgb-rpc variant with missing host - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + y----------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=rpc://"; let result = RgbInvoice::from_str(invoice_str); assert!(matches!(result, Err(InvoiceParseError::InvalidQueryParam(_)))); // rgb-rpc variant with invalid separator - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ - zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=rpc/\ - host.example.com"; + let invoice_str = + "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/y----------+bc:utxob:\ + zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=rpc/host.example.com"; let result = RgbInvoice::from_str(invoice_str); assert!(matches!(result, Err(InvoiceParseError::InvalidQueryParam(_)))); // rgb-rpc variant with invalid transport host specification - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ - zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=rpc://\ - ho]t"; + let invoice_str = + "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/y----------+bc:utxob:\ + zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=rpc://ho]t"; let result = RgbInvoice::from_str(invoice_str); assert!(matches!(result, Err(InvoiceParseError::Uri(_)))); // rgb+http variant let invoice_str = "rgb:\ 11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ - BF+bc:utxob:zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=https://\ + y----------+bc:utxob:zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=https://\ host.example.com"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); let transports = vec![RgbTransport::RestHttp { @@ -737,7 +693,8 @@ mod test { assert_eq!(invoice.to_string(), invoice_str); // rgb+ws variant - let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/BF+bc:utxob:\ + let invoice_str = "rgb:11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ + y----------+bc:utxob:\ zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=wss://\ host.example.com"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); @@ -753,7 +710,7 @@ mod test { // multiple transports let invoice_str = "rgb:\ 11Fa!$Dk-rUWXhy8-7H35qXm-pLGGLOo-txBWUgj-tbOaSbI/RGB20/\ - BF+bc:utxob:zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=rpcs://\ + y----------+bc:utxob:zlVS28Rb-amM5lih-ONXGACC-IUWD0Y$-0JXcnWZ-MQn8VEI-B39!F?endpoints=rpcs://\ host1.example.com,http://host2.example.com,ws://host3.example.com"; let invoice = RgbInvoice::from_str(invoice_str).unwrap(); let transports = vec![ diff --git a/src/interface/builder.rs b/src/interface/builder.rs index e794dad5..5f444a82 100644 --- a/src/interface/builder.rs +++ b/src/interface/builder.rs @@ -27,13 +27,14 @@ use amplify::confinement::{self, Confined, SmallOrdSet, TinyOrdMap}; use chrono::Utc; use rgb::validation::Scripts; use rgb::{ - validation, AltLayer1, AltLayer1Set, AssignmentType, Assignments, ContractId, ExposedSeal, - Genesis, GenesisSeal, GlobalState, GraphSeal, Identity, Input, Layer1, MetadataError, Opout, - Schema, State, Transition, TransitionType, TypedAssigns, XChain, XOutpoint, + validation, AltLayer1, AltLayer1Set, AssignmentType, Assignments, AttachId, ContractId, + ExposedSeal, Genesis, GenesisSeal, GlobalState, GraphSeal, Identity, Input, Layer1, + MetadataError, Opout, Schema, State, StateData, Transition, TransitionType, TypedAssigns, + XChain, XOutpoint, }; use rgbcore::{GlobalStateSchema, GlobalStateType, MetaType, Metadata, ValencyType}; use strict_encoding::{FieldName, SerializeError, StrictSerialize}; -use strict_types::{decode, SemId, TypeSystem}; +use strict_types::{decode, typify, SemId, StrictVal, TypeSystem}; use crate::containers::{BuilderSeal, ContainerVer, Contract, ValidConsignment}; use crate::interface::resolver::DumbResolver; @@ -59,15 +60,12 @@ pub enum BuilderError { /// assignment `{0}` is not known to the schema. AssignmentNotFound(FieldName), + /// valency `{0}` is not known to the schema. + ValencyNotFound(FieldName), + /// transition `{0}` is not known to the schema. TransitionNotFound(FieldName), - /// unknown owned state name `{0}`. - InvalidStateField(FieldName), - - /// state `{0}` provided to the builder has invalid type. - InvalidStateType(AssignmentType), - /// interface doesn't specify default operation name, thus an explicit /// operation type must be provided with `set_operation_type` method. NoOperationSubtype, @@ -90,6 +88,10 @@ pub enum BuilderError { #[display(inner)] Reify(decode::Error), + #[from] + #[display(inner)] + Typify(typify::Error), + #[from] #[display(inner)] Confinement(confinement::Error), @@ -179,23 +181,28 @@ impl ContractBuilder { } #[inline] - pub fn global_type(&self, name: &FieldName) -> Option { + pub fn meta_type(&self, name: impl Into) -> Result { + self.builder.meta_type(name) + } + + #[inline] + pub fn global_type(&self, name: impl Into) -> Result { self.builder.global_type(name) } #[inline] - pub fn valency_type(&self, name: &FieldName) -> Option { + pub fn valency_type(&self, name: impl Into) -> Result { self.builder.valency_type(name) } + #[inline] + pub fn meta_name(&self, type_id: MetaType) -> &FieldName { self.builder.meta_name(type_id) } + #[inline] pub fn valency_name(&self, type_id: ValencyType) -> &FieldName { self.builder.valency_name(type_id) } - #[inline] - pub fn meta_name(&self, type_id: MetaType) -> &FieldName { self.builder.meta_name(type_id) } - #[inline] pub fn add_metadata( mut self, @@ -232,11 +239,27 @@ impl ContractBuilder { mut self, name: impl Into, seal: impl Into>, - value: impl StrictSerialize, + state: StrictVal, + attach: Option, ) -> Result { let seal = seal.into(); self.check_layer1(seal.layer1())?; - self.builder = self.builder.add_owned_state(name, seal, value)?; + self.builder = self.builder.add_owned_state(name, seal, state, attach)?; + Ok(self) + } + + pub fn serialize_owned_state( + mut self, + name: impl Into, + seal: impl Into>, + value: &impl StrictSerialize, + attach: Option, + ) -> Result { + let seal = seal.into(); + self.check_layer1(seal.layer1())?; + self.builder = self + .builder + .serialize_owned_state(name, seal, value, attach)?; Ok(self) } @@ -419,17 +442,20 @@ impl TransitionBuilder { } #[inline] - pub fn assignments_type(&self, name: &FieldName) -> Option { + pub fn assignments_type( + &self, + name: impl Into, + ) -> Result { self.builder.assignments_type(name) } #[inline] - pub fn global_type(&self, name: &FieldName) -> Option { + pub fn global_type(&self, name: impl Into) -> Result { self.builder.global_type(name) } #[inline] - pub fn valency_type(&self, name: &FieldName) -> Option { + pub fn valency_type(&self, name: impl Into) -> Result { self.builder.valency_type(name) } @@ -440,8 +466,9 @@ impl TransitionBuilder { pub fn meta_name(&self, type_id: MetaType) -> &FieldName { self.builder.meta_name(type_id) } - /// NB: Doesn't process the state with VM - pub fn add_owned_state_raw( + // TODO: We won't need this once we will have Blank Transition builder + /// NB: This does not process the state with VM + pub fn add_owned_state_blank( mut self, type_id: AssignmentType, seal: impl Into>, @@ -546,22 +573,36 @@ impl OperationBuilder { .expect("internal inconsistency") } - fn assignments_type(&self, name: &FieldName) -> Option { - self.iimpl.assignments_type(name) + fn assignments_type(&self, name: impl Into) -> Result { + let name = name.into(); + self.iimpl + .assignments_type(&name) + .ok_or(BuilderError::AssignmentNotFound(name)) } - fn meta_type(&self, name: &FieldName) -> Option { self.iimpl.meta_type(name) } + fn meta_type(&self, name: impl Into) -> Result { + let name = name.into(); + self.iimpl + .meta_type(&name) + .ok_or(BuilderError::MetadataNotFound(name)) + } fn meta_name(&self, ty: MetaType) -> &FieldName { self.iimpl.meta_name(ty).expect("internal inconsistency") } - fn global_type(&self, name: &FieldName) -> Option { - self.iimpl.global_type(name) + fn global_type(&self, name: impl Into) -> Result { + let name = name.into(); + self.iimpl + .global_type(&name) + .ok_or(BuilderError::GlobalNotFound(name)) } - fn valency_type(&self, name: &FieldName) -> Option { - self.iimpl.valency_type(name) + fn valency_type(&self, name: impl Into) -> Result { + let name = name.into(); + self.iimpl + .valency_type(&name) + .ok_or(BuilderError::ValencyNotFound(name)) } fn valency_name(&self, ty: ValencyType) -> &FieldName { @@ -589,13 +630,8 @@ impl OperationBuilder { name: impl Into, value: impl StrictSerialize, ) -> Result { - let name = name.into(); + let type_id = self.meta_type(name)?; let serialized = value.to_strict_serialized::<{ u16::MAX as usize }>()?; - - let Some(type_id) = self.meta_type(&name) else { - return Err(BuilderError::MetadataNotFound(name)); - }; - let sem_id = self.meta_schema(type_id); self.types.strict_deserialize_type(*sem_id, &serialized)?; self.meta.add_value(type_id, serialized.into())?; @@ -607,13 +643,9 @@ impl OperationBuilder { name: impl Into, value: impl StrictSerialize, ) -> Result { - let name = name.into(); + let type_id = self.global_type(name)?; let serialized = value.to_strict_serialized::<{ u16::MAX as usize }>()?; - // Check value matches type requirements - let Some(type_id) = self.global_type(&name) else { - return Err(BuilderError::GlobalNotFound(name)); - }; let sem_id = self.global_schema(type_id).sem_id; self.types.strict_deserialize_type(sem_id, &serialized)?; @@ -645,15 +677,40 @@ impl OperationBuilder { self, name: impl Into, seal: impl Into>, - value: impl StrictSerialize, + value: StrictVal, + attach: Option, ) -> Result { - let name = name.into(); + let type_id = self.assignments_type(name)?; - let type_id = self - .assignments_type(&name) - .ok_or(BuilderError::AssignmentNotFound(name))?; + let types = self.type_system(); + let sem_id = self + .schema + .owned_types + .get(&type_id) + .expect("schema-interface inconsistence") + .sem_id; + let value = types.typify(value, sem_id)?; + let data = types + .strict_serialize_type::<{ confinement::U16 }>(&value)? + .to_strict_serialized()?; + + let mut state = State::from(StateData::from(data)); + state.attach = attach; + self.add_owned_state_raw(type_id, seal, state) + } + + fn serialize_owned_state( + self, + name: impl Into, + seal: impl Into>, + value: &impl StrictSerialize, + attach: Option, + ) -> Result { + let type_id = self.assignments_type(name)?; - self.add_owned_state_raw(type_id, seal, State::from_serialized(value)) + let mut state = State::from_serialized(value)?; + state.attach = attach; + self.add_owned_state_raw(type_id, seal, state) } fn complete(self) -> (Schema, Iface, IfaceImpl, GlobalState, Assignments, TypeSystem) { diff --git a/src/persistence/stock.rs b/src/persistence/stock.rs index 273af067..2793c156 100644 --- a/src/persistence/stock.rs +++ b/src/persistence/stock.rs @@ -885,7 +885,7 @@ impl Stock { #[allow(clippy::result_large_err)] pub fn compose( &self, - invoice: &RgbInvoice, + invoice: RgbInvoice, prev_outputs: impl IntoIterator>, method: CloseMethod, beneficiary_vout: Option>, @@ -908,7 +908,7 @@ impl Stock { #[allow(clippy::too_many_arguments, clippy::result_large_err)] pub fn compose_deterministic( &self, - invoice: &RgbInvoice, + invoice: RgbInvoice, prev_outputs: impl IntoIterator>, method: CloseMethod, beneficiary_vout: Option>, @@ -917,11 +917,8 @@ impl Stock { seal_blinder: impl Fn(ContractId, AssignmentType) -> u64, ) -> Result> { let layer1 = invoice.layer1(); - let invoice_state = invoice - .owned_state - .state() - .ok_or(ComposeError::NoInvoiceState)? - .clone(); + let state_data = invoice.state.ok_or(ComposeError::NoInvoiceState)?; + let state = rgb::State::from(state_data); // TODO: Take account attachements when they will be supported by invoices let prev_outputs = prev_outputs .into_iter() .map(|o| o.into()) @@ -970,9 +967,7 @@ impl Stock { .or_else(|| main_builder.default_assignment().ok()) .ok_or(BuilderError::NoDefaultAssignment)? .clone(); - let assignment_id = main_builder - .assignments_type(&assignment_name) - .ok_or(BuilderError::InvalidStateField(assignment_name.clone()))?; + let assignment_id = main_builder.assignments_type(assignment_name)?; // If there are inputs which are using different seal closing method from our // wallet (and thus main state transition) we need to put them aside and @@ -1019,9 +1014,9 @@ impl Stock { if opout.ty != assignment_id { let seal = output_for_assignment(contract_id, opout.ty)?; if output.method() == method { - main_builder = main_builder.add_owned_state_raw(opout.ty, seal, state)?; + main_builder = main_builder.add_owned_state_blank(opout.ty, seal, state)?; } else { - alt_builder = alt_builder.add_owned_state_raw(opout.ty, seal, state)?; + alt_builder = alt_builder.add_owned_state_blank(opout.ty, seal, state)?; } } } @@ -1029,7 +1024,7 @@ impl Stock { // Add payments to beneficiary let (builder, partial_state) = - main_builder.fulfill_owned_state(assignment_id, beneficiary, invoice_state)?; + main_builder.fulfill_owned_state(assignment_id, beneficiary, state)?; main_builder = builder; if let Some(partial_state) = partial_state { let (builder, remaining_state) = @@ -1080,12 +1075,12 @@ impl Stock { Method::TapretFirst => { blank_builder_tapret = blank_builder_tapret .add_input(opout, state.clone())? - .add_owned_state_raw(opout.ty, seal, state)? + .add_owned_state_blank(opout.ty, seal, state)? } Method::OpretFirst => { blank_builder_opret = blank_builder_opret .add_input(opout, state.clone())? - .add_owned_state_raw(opout.ty, seal, state)? + .add_owned_state_blank(opout.ty, seal, state)? } } } From bc455d70d168deb56551ad67885c498f6f27d2b4 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 17 Oct 2024 16:52:57 +0200 Subject: [PATCH 10/16] iface: use updated state serialization APIs --- Cargo.lock | 5 +- Cargo.toml | 1 + src/interface/builder.rs | 195 +++++++++++++++++++++++++++----------- src/interface/contract.rs | 8 +- 4 files changed, 145 insertions(+), 64 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2420f764..60158c23 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -668,7 +668,7 @@ dependencies = [ [[package]] name = "rgb-core" version = "0.11.0-beta.9" -source = "git+https://github.com/RGB-WG/rgb-core?branch=feat/fungible-nonconf#b59f1ca4c13c62ce53152f7f4c34094e435a1be4" +source = "git+https://github.com/RGB-WG/rgb-core?branch=feat/fungible-nonconf#e92e5b176886b3f04d8cfbb41714ab8f7d0b8046" dependencies = [ "aluvm", "amplify", @@ -906,8 +906,7 @@ dependencies = [ [[package]] name = "strict_types" version = "2.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3188d65ee78a90da3545df762a1363b5b4f9c3b845f182a18fc40ae991c235ce" +source = "git+https://github.com/strict-types/strict-types?branch=develop#729a4f86d25dfcea15ed15bbeb1e027473401c58" dependencies = [ "amplify", "ascii-armor", diff --git a/Cargo.toml b/Cargo.toml index e4200e51..3837c078 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -101,6 +101,7 @@ features = ["all"] [patch.crates-io] commit_verify = { git = "https://github.com/LNP-BP/client_side_validation", branch = "develop" } single_use_seals = { git = "https://github.com/LNP-BP/client_side_validation", branch = "develop" } +strict_types = { git = "https://github.com/strict-types/strict-types", branch = "develop" } aluvm = { git = "https://github.com/AluVM/rust-aluvm", branch = "develop" } bp-consensus = { git = "https://github.com/BP-WG/bp-core", branch = "develop" } bp-dbc = { git = "https://github.com/BP-WG/bp-core", branch = "develop" } diff --git a/src/interface/builder.rs b/src/interface/builder.rs index 5f444a82..4905aca1 100644 --- a/src/interface/builder.rs +++ b/src/interface/builder.rs @@ -28,11 +28,10 @@ use chrono::Utc; use rgb::validation::Scripts; use rgb::{ validation, AltLayer1, AltLayer1Set, AssignmentType, Assignments, AttachId, ContractId, - ExposedSeal, Genesis, GenesisSeal, GlobalState, GraphSeal, Identity, Input, Layer1, - MetadataError, Opout, Schema, State, StateData, Transition, TransitionType, TypedAssigns, - XChain, XOutpoint, + ExposedSeal, Genesis, GenesisSeal, GlobalState, GlobalStateSchema, GlobalStateType, GraphSeal, + Identity, Input, Layer1, MetaType, Metadata, MetadataError, Opout, Schema, State, StateData, + Transition, TransitionType, TypedAssigns, ValencyType, XChain, XOutpoint, STATE_DATA_MAX_LEN, }; -use rgbcore::{GlobalStateSchema, GlobalStateType, MetaType, Metadata, ValencyType}; use strict_encoding::{FieldName, SerializeError, StrictSerialize}; use strict_types::{decode, typify, SemId, StrictVal, TypeSystem}; @@ -203,26 +202,44 @@ impl ContractBuilder { self.builder.valency_name(type_id) } - #[inline] pub fn add_metadata( mut self, name: impl Into, - value: impl StrictSerialize, + value: StrictVal, ) -> Result { self.builder = self.builder.add_metadata(name, value)?; Ok(self) } #[inline] + pub fn serialize_metadata( + mut self, + name: impl Into, + value: &impl StrictSerialize, + ) -> Result { + self.builder = self.builder.serialize_metadata(name, value)?; + Ok(self) + } + pub fn add_global_state( mut self, name: impl Into, - value: impl StrictSerialize, + value: StrictVal, ) -> Result { self.builder = self.builder.add_global_state(name, value)?; Ok(self) } + #[inline] + pub fn serialize_global_state( + mut self, + name: impl Into, + value: &impl StrictSerialize, + ) -> Result { + self.builder = self.builder.serialize_global_state(name, value)?; + Ok(self) + } + pub fn add_owned_state_raw( mut self, type_id: AssignmentType, @@ -400,39 +417,31 @@ impl TransitionBuilder { pub fn transition_type(&self) -> TransitionType { self.transition_type } - pub fn set_nonce(mut self, nonce: u64) -> Self { - self.nonce = nonce; - self + #[inline] + pub fn global_type(&self, name: impl Into) -> Result { + self.builder.global_type(name) } #[inline] - pub fn add_metadata( - mut self, + pub fn assignments_type( + &self, name: impl Into, - value: impl StrictSerialize, - ) -> Result { - self.builder = self.builder.add_metadata(name, value)?; - Ok(self) + ) -> Result { + self.builder.assignments_type(name) } #[inline] - pub fn add_global_state( - mut self, - name: impl Into, - value: impl StrictSerialize, - ) -> Result { - self.builder = self.builder.add_global_state(name, value)?; - Ok(self) + pub fn valency_type(&self, name: impl Into) -> Result { + self.builder.valency_type(name) } - pub fn add_input(mut self, opout: Opout, state: State) -> Result { - if let Some(calc) = &mut self.calc { - calc.reg_input(opout.ty, &state)?; - } - self.inputs.insert(Input::with(opout), state)?; - Ok(self) + #[inline] + pub fn valency_name(&self, type_id: ValencyType) -> &FieldName { + self.builder.valency_name(type_id) } + pub fn meta_name(&self, type_id: MetaType) -> &FieldName { self.builder.meta_name(type_id) } + pub fn default_assignment(&self) -> Result<&FieldName, BuilderError> { self.builder .transition_iface(self.transition_type) @@ -441,31 +450,57 @@ impl TransitionBuilder { .ok_or(BuilderError::NoDefaultAssignment) } - #[inline] - pub fn assignments_type( - &self, + pub fn set_nonce(mut self, nonce: u64) -> Self { + self.nonce = nonce; + self + } + + pub fn add_input(mut self, opout: Opout, state: State) -> Result { + if let Some(calc) = &mut self.calc { + calc.reg_input(opout.ty, &state)?; + } + self.inputs.insert(Input::with(opout), state)?; + Ok(self) + } + + pub fn add_metadata( + mut self, name: impl Into, - ) -> Result { - self.builder.assignments_type(name) + value: StrictVal, + ) -> Result { + self.builder = self.builder.add_metadata(name, value)?; + Ok(self) } #[inline] - pub fn global_type(&self, name: impl Into) -> Result { - self.builder.global_type(name) + pub fn serialize_metadata( + mut self, + name: impl Into, + value: &impl StrictSerialize, + ) -> Result { + self.builder = self.builder.serialize_metadata(name, value)?; + Ok(self) } - #[inline] - pub fn valency_type(&self, name: impl Into) -> Result { - self.builder.valency_type(name) + pub fn add_global_state( + mut self, + name: impl Into, + value: StrictVal, + ) -> Result { + self.builder = self.builder.add_global_state(name, value)?; + Ok(self) } #[inline] - pub fn valency_name(&self, type_id: ValencyType) -> &FieldName { - self.builder.valency_name(type_id) + pub fn serialize_global_state( + mut self, + name: impl Into, + value: &impl StrictSerialize, + ) -> Result { + self.builder = self.builder.serialize_global_state(name, value)?; + Ok(self) } - pub fn meta_name(&self, type_id: MetaType) -> &FieldName { self.builder.meta_name(type_id) } - // TODO: We won't need this once we will have Blank Transition builder /// NB: This does not process the state with VM pub fn add_owned_state_blank( @@ -610,8 +645,9 @@ impl OperationBuilder { } #[inline] - fn meta_schema(&self, type_id: MetaType) -> &SemId { - self.schema + fn meta_schema(&self, type_id: MetaType) -> SemId { + *self + .schema .meta_types .get(&type_id) .expect("schema should match interface: must be checked by the constructor") @@ -625,29 +661,78 @@ impl OperationBuilder { .expect("schema should match interface: must be checked by the constructor") } - pub fn add_metadata( + fn add_metadata( mut self, name: impl Into, - value: impl StrictSerialize, + value: StrictVal, + ) -> Result { + let type_id = self.meta_type(name)?; + + let types = self.type_system(); + let sem_id = *self + .schema + .meta_types + .get(&type_id) + .expect("schema-interface inconsistency"); + let value = types.typify(value, sem_id)?; + let data = types.strict_serialize_value::(&value)?; + + self.meta.add_value(type_id, data.into())?; + Ok(self) + } + + fn serialize_metadata( + mut self, + name: impl Into, + value: &impl StrictSerialize, ) -> Result { let type_id = self.meta_type(name)?; let serialized = value.to_strict_serialized::<{ u16::MAX as usize }>()?; let sem_id = self.meta_schema(type_id); - self.types.strict_deserialize_type(*sem_id, &serialized)?; + + #[cfg(debug_assertions)] + self.types + .strict_deserialize_type(sem_id, &serialized) + .expect("failed deserialization"); + self.meta.add_value(type_id, serialized.into())?; Ok(self) } - pub fn add_global_state( + fn add_global_state( mut self, name: impl Into, - value: impl StrictSerialize, + value: StrictVal, + ) -> Result { + let type_id = self.global_type(name)?; + + let types = self.type_system(); + let sem_id = self + .schema + .global_types + .get(&type_id) + .expect("schema-interface inconsistency") + .sem_id; + let value = types.typify(value, sem_id)?; + let data = types.strict_serialize_value::(&value)?; + + self.global.add_state(type_id, data.into())?; + Ok(self) + } + + fn serialize_global_state( + mut self, + name: impl Into, + value: &impl StrictSerialize, ) -> Result { let type_id = self.global_type(name)?; let serialized = value.to_strict_serialized::<{ u16::MAX as usize }>()?; - // Check value matches type requirements let sem_id = self.global_schema(type_id).sem_id; - self.types.strict_deserialize_type(sem_id, &serialized)?; + + #[cfg(debug_assertions)] + self.types + .strict_deserialize_type(sem_id, &serialized) + .expect("failed deserialization"); self.global.add_state(type_id, serialized.into())?; @@ -687,12 +772,10 @@ impl OperationBuilder { .schema .owned_types .get(&type_id) - .expect("schema-interface inconsistence") + .expect("schema-interface inconsistency") .sem_id; let value = types.typify(value, sem_id)?; - let data = types - .strict_serialize_type::<{ confinement::U16 }>(&value)? - .to_strict_serialized()?; + let data = types.strict_serialize_value::(&value)?; let mut state = State::from(StateData::from(data)); state.attach = attach; diff --git a/src/interface/contract.rs b/src/interface/contract.rs index 075fafb1..2f92e710 100644 --- a/src/interface/contract.rs +++ b/src/interface/contract.rs @@ -22,13 +22,12 @@ use std::borrow::Borrow; use std::collections::{BTreeSet, HashMap, HashSet}; -use amplify::confinement; use rgb::validation::Scripts; use rgb::{ AssignmentType, AttachId, ContractId, OpId, Opout, Schema, State, StateData, XOutputSeal, - XWitnessId, + XWitnessId, STATE_DATA_MAX_LEN, }; -use strict_encoding::{FieldName, SerializeError, StrictSerialize}; +use strict_encoding::{FieldName, SerializeError}; use strict_types::{typify, SemId, StrictVal, TypeSystem}; use crate::contract::{Allocation, WitnessInfo}; @@ -189,8 +188,7 @@ impl ContractIface { let t = self.types.typify(value, self.assignment_sem_id(ty))?; let value = self .types - .strict_serialize_type::<{ confinement::U16 }>(&t)? - .to_strict_serialized()?; + .strict_serialize_value::(&t)?; Ok(value.into()) } From 0bc16ef093a99b16c61f09a5e82ca9eb594d9511 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 17 Oct 2024 18:47:26 +0200 Subject: [PATCH 11/16] iface: improve AssignIface APIs --- src/interface/iface.rs | 57 +++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/src/interface/iface.rs b/src/interface/iface.rs index 684cfc1c..84dfec26 100644 --- a/src/interface/iface.rs +++ b/src/interface/iface.rs @@ -208,25 +208,58 @@ pub struct AssignIface { } impl AssignIface { - pub fn public(state_ty: Option, attach: Option, req: Req) -> Self { + pub fn optional() -> Self { AssignIface { - state_ty, - attach, - public: true, - required: req.is_required(), - multiple: req.is_multiple(), + state_ty: None, + attach: None, + public: false, + required: false, + multiple: false, } } - - pub fn private(state_ty: Option, attach: Option, req: Req) -> Self { + pub fn required() -> Self { AssignIface { - state_ty, - attach, + state_ty: None, + attach: None, public: false, - required: req.is_required(), - multiple: req.is_multiple(), + required: true, + multiple: false, + } + } + pub fn none_or_many() -> Self { + AssignIface { + state_ty: None, + attach: None, + public: false, + required: false, + multiple: true, } } + pub fn one_or_many() -> Self { + AssignIface { + state_ty: None, + attach: None, + public: false, + required: true, + multiple: true, + } + } + pub fn public(mut self) -> Self { + self.public = true; + self + } + pub fn rights(mut self) -> Self { + self.state_ty = Some(SemId::default()); + self + } + pub fn typed(mut self, sem_id: SemId) -> Self { + self.state_ty = Some(sem_id); + self + } + pub fn attachments(mut self, require: bool) -> Self { + self.attach = Some(require); + self + } } pub type ArgMap = TinyOrdMap; From 9240917a44e4ba5a3e44da5acac3a0ad9c1498df Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 17 Oct 2024 19:12:31 +0200 Subject: [PATCH 12/16] iface: add add_rights convenience method to builder --- Cargo.lock | 2 +- src/interface/builder.rs | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 60158c23..040ef4f6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -668,7 +668,7 @@ dependencies = [ [[package]] name = "rgb-core" version = "0.11.0-beta.9" -source = "git+https://github.com/RGB-WG/rgb-core?branch=feat/fungible-nonconf#e92e5b176886b3f04d8cfbb41714ab8f7d0b8046" +source = "git+https://github.com/RGB-WG/rgb-core?branch=feat/fungible-nonconf#9c6f3fee4ac573380c0ed8658d644fc5a7cfc533" dependencies = [ "aluvm", "amplify", diff --git a/src/interface/builder.rs b/src/interface/builder.rs index 4905aca1..76eff309 100644 --- a/src/interface/builder.rs +++ b/src/interface/builder.rs @@ -252,6 +252,16 @@ impl ContractBuilder { Ok(self) } + pub fn add_rights( + mut self, + name: impl Into, + seal: impl Into>, + attach: Option, + ) -> Result { + self.builder = self.builder.add_rights(name, seal, attach)?; + Ok(self) + } + pub fn add_owned_state( mut self, name: impl Into, @@ -513,6 +523,16 @@ impl TransitionBuilder { Ok(self) } + pub fn add_rights( + mut self, + name: impl Into, + seal: impl Into>, + attach: Option, + ) -> Result { + self.builder = self.builder.add_rights(name, seal, attach)?; + Ok(self) + } + pub fn fulfill_owned_state( mut self, type_id: AssignmentType, @@ -758,6 +778,18 @@ impl OperationBuilder { Ok(self) } + fn add_rights( + self, + name: impl Into, + seal: impl Into>, + attach: Option, + ) -> Result { + let type_id = self.assignments_type(name)?; + let mut state = State::default(); + state.attach = attach; + self.add_owned_state_raw(type_id, seal, state) + } + fn add_owned_state( self, name: impl Into, From 0bf8c97606d081b65a6d74f21f854c997246bf8d Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 17 Oct 2024 20:25:51 +0200 Subject: [PATCH 13/16] iface: add ContractIface::outputs_typed method --- src/interface/contract.rs | 61 +++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/src/interface/contract.rs b/src/interface/contract.rs index 2f92e710..37d18fd1 100644 --- a/src/interface/contract.rs +++ b/src/interface/contract.rs @@ -22,12 +22,14 @@ use std::borrow::Borrow; use std::collections::{BTreeSet, HashMap, HashSet}; +use amplify::confinement::SmallBlob; +use amplify::Wrapper; use rgb::validation::Scripts; use rgb::{ AssignmentType, AttachId, ContractId, OpId, Opout, Schema, State, StateData, XOutputSeal, XWitnessId, STATE_DATA_MAX_LEN, }; -use strict_encoding::{FieldName, SerializeError}; +use strict_encoding::{FieldName, SerializeError, StrictDeserialize}; use strict_types::{typify, SemId, StrictVal, TypeSystem}; use crate::contract::{Allocation, WitnessInfo}; @@ -58,14 +60,27 @@ pub enum ContractError { derive(Serialize, Deserialize), serde(crate = "serde_crate", rename_all = "camelCase") )] -pub struct Output { +pub struct Output { pub opout: Opout, pub seal: XOutputSeal, - pub state: StrictVal, + pub state: T, pub attach_id: Option, pub witness: Option, } +impl From for Output { + fn from(a: Allocation) -> Self { + Output { + opout: a.opout, + seal: a.seal, + state: T::from_strict_serialized(a.state.data.to_inner()) + .expect("data in stash are not valid"), + attach_id: a.state.attach, + witness: a.witness, + } + } +} + #[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Display)] #[cfg_attr( feature = "serde", @@ -205,8 +220,7 @@ impl ContractIface { /// # Panics /// - /// If data are corrupted and contract schema doesn't match interface - /// implementations. + /// If data are corrupted and contract schema doesn't match interface implementations. pub fn global( &self, name: impl Into, @@ -227,12 +241,34 @@ impl ContractIface { .expect("schema doesn't match interface") .map(|data| { self.types - .strict_deserialize_type(global_schema.sem_id, data.borrow().as_slice()) + .strict_deserialize_type(global_schema.sem_id, data.borrow()) .expect("unvalidated contract data in stash") .unbox() })) } + /// # Panics + /// + /// If data are corrupted and contract schema doesn't match interface implementations. + pub fn global_typed( + &self, + name: impl Into, + ) -> Result + '_, ContractError> { + let name = name.into(); + let type_id = self + .iface + .global_type(&name) + .ok_or(ContractError::FieldNameUnknown(name))?; + Ok(self + .state + .global(type_id) + .expect("schema doesn't match interface") + .map(|data| { + let data = SmallBlob::from_slice_checked(data.borrow()); + T::from_strict_serialized(data).expect("unvalidated contract data in stash") + })) + } + pub fn allocations<'c>( &'c self, filter: impl AssignmentsFilter + 'c, @@ -286,6 +322,19 @@ impl ContractIface { .map(|a| self.allocation_to_output(a))) } + pub fn outputs_typed<'c, T: StrictDeserialize + 'c>( + &'c self, + name: impl Into, + filter: impl AssignmentsFilter + 'c, + ) -> Result> + 'c, ContractError> { + let type_id = self.assignment_type(name)?; + Ok(self + .allocations(filter) + .filter(move |a| a.opout.ty == type_id) + .cloned() + .map(Output::from)) + } + pub fn history( &self, filter_outpoints: impl AssignmentsFilter, From 50a76079864c35fc8229bb861f17ad8c6e45f566 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Thu, 17 Oct 2024 20:25:51 +0200 Subject: [PATCH 14/16] chore: remove outdated IfaceStd.con --- stl/IfaceStd.con | 252 ----------------------------------------------- 1 file changed, 252 deletions(-) delete mode 100644 stl/IfaceStd.con diff --git a/stl/IfaceStd.con b/stl/IfaceStd.con deleted file mode 100644 index 37380a20..00000000 --- a/stl/IfaceStd.con +++ /dev/null @@ -1,252 +0,0 @@ -@version(1) -@timestamp(1711405444) -interface NamedAsset - global spec: RGBContract.AssetSpec - global terms: RGBContract.AssetTerms - - genesis: abstract - globals: spec, terms - - -@version(1) -@timestamp(1711405444) -interface RenameableAsset - - public updateRight: Rights - - genesis: override - assigns: updateRight - - transition rename: required, final - globals: spec - assigns: updateRight(?) - default: updateRight - inputs: updateRight - - -@version(1) -@timestamp(1711405444) -interface FungibleAsset - global issuedSupply: RGBContract.Amount - - owned assetOwner(*): Zk64 - - error nonEqualAmounts - "the sum of spent assets doesn't equal to the sum of assets in outputs" - error supplyMismatch - "supply specified as a global parameter doesn't match the issued supply allocated to the asset owners" - - genesis: override - errors: insufficientReserves, invalidProof, supplyMismatch - globals: issuedSupply - assigns: assetOwner(*) - - transition transfer: required, default, abstract - errors: nonEqualAmounts - assigns: assetOwner(+) - default: assetOwner - inputs: assetOwner(+) - - -@version(1) -@timestamp(1711405444) -interface FixedAsset - - owned assetOwner(+): Zk64 - - genesis: override - errors: insufficientReserves, invalidProof, supplyMismatch - assigns: assetOwner(+) - - -@version(1) -@timestamp(1711405444) -interface BurnableAsset - global burnedSupply(*): RGBContract.Amount - - public burnRight(+): Rights - - error insufficientCoverage - "the claimed amount of burned assets is not covered by the assets in the operation inputs" - - genesis: override - assigns: burnRight(+) - - transition burn: required, final - errors: insufficientCoverage, invalidProof, supplyMismatch - meta: RGBContract.BurnMeta - globals: burnedSupply - assigns: burnRight(*) - inputs: burnRight - - -@version(1) -@timestamp(1711405444) -interface InflatableAsset - global issuedSupply(+): RGBContract.Amount - - public inflationAllowance(*): Zk64 - - error issueExceedsAllowance - "you try to issue more assets than allowed by the contract terms" - - genesis: override - assigns: inflationAllowance(+) - - transition issue: required, abstract - errors: issueExceedsAllowance, supplyMismatch - globals: issuedSupply - assigns: assetOwner(*), inflationAllowance(*) - default: assetOwner - inputs: inflationAllowance(+) - - -@version(1) -@timestamp(1711405444) -interface ReplaceableAsset - global burnedSupply(*): RGBContract.Amount - global replacedSupply(*): RGBContract.Amount - - public burnEpoch(+): Rights - public burnRight(*): Rights - - error insufficientCoverage - "the claimed amount of burned assets is not covered by the assets in the operation inputs" - - genesis: override - assigns: burnEpoch - - transition burn: required, final - errors: insufficientCoverage, invalidProof, supplyMismatch - meta: RGBContract.BurnMeta - globals: burnedSupply - assigns: burnRight(?) - inputs: burnRight - - transition openEpoch: required, final - assigns: burnEpoch(?), burnRight - default: burnRight - inputs: burnEpoch - - transition replace: required, final - errors: insufficientCoverage, invalidProof, nonEqualAmounts, supplyMismatch - meta: RGBContract.BurnMeta - globals: replacedSupply - assigns: assetOwner(*), burnRight(?) - default: assetOwner - inputs: burnRight - - -@version(1) -@timestamp(1711405444) -interface ReservableAsset - - error insufficientReserves - "reserve is insufficient to cover the issued assets" - error invalidProof - "the provided proof is invalid" - - genesis: override - errors: insufficientReserves, invalidProof - meta: RGBContract.IssueMeta - - transition issue: override - errors: insufficientReserves, invalidProof - meta: RGBContract.IssueMeta - default: assetOwner - inputs: - - -@version(1) -@timestamp(1711405444) -interface NonFungibleToken - global attachmentTypes(*): RGB21.AttachmentType - global tokens(*): RGB21.TokenData - - owned assetOwner(*): RGB21.Allocation - - error fractionOverflow - "the amount of fractional token in outputs exceeds 1" - error invalidAttachmentType - "attachment has a type which is not allowed for the token" - error nonEqualValues - "the sum of spent token fractions doesn't equal to the sum of token fractions in outputs" - error nonFractionalToken - "attempt to transfer a fraction of non-fractionable token" - - genesis: override - errors: fractionOverflow, invalidAttachmentType - globals: attachmentTypes(*), tokens(*) - assigns: assetOwner(*) - - transition transfer: required, default, final - errors: fractionOverflow, nonEqualValues, nonFractionalToken - assigns: assetOwner(+) - default: assetOwner - inputs: assetOwner(+) - - -@version(1) -@timestamp(1711405444) -interface EngravableNft - global engravings(*): RGB21.EngravingData - - error nonEngravableToken - "attempt to engrave on a token which prohibit engraving" - - genesis: override - - transition engrave: required, final - errors: fractionOverflow, nonEngravableToken, nonEqualValues, nonFractionalToken - globals: engravings - assigns: assetOwner(+) - default: assetOwner - inputs: assetOwner(+) - - -@version(1) -@timestamp(1711405444) -interface UniqueNft - global attachmentTypes: RGB21.AttachmentType - global tokens: RGB21.TokenData - - owned assetOwner(+): RGB21.Allocation - - genesis: override - globals: attachmentTypes, tokens - assigns: assetOwner(+) - - -@version(1) -@timestamp(1711405444) -interface LimitedNft - global attachmentTypes(+): RGB21.AttachmentType - global tokens(+): RGB21.TokenData - - owned assetOwner(+): RGB21.Allocation - - genesis: override - globals: attachmentTypes(+), tokens(+) - assigns: assetOwner(+) - - -@version(1) -@timestamp(1711405444) -interface IssuableNft - - public inflationAllowance(+): RGB21.ItemsCount - - error issueExceedsAllowance - "you try to issue more assets than allowed by the contract terms" - - genesis: override - assigns: inflationAllowance(+) - - transition issue: required, abstract - errors: fractionOverflow, insufficientReserves, invalidAttachmentType, invalidProof, issueExceedsAllowance - globals: attachmentTypes(*), tokens(*) - assigns: assetOwner(*), inflationAllowance(*) - default: assetOwner - inputs: inflationAllowance(+) - - From ee649c6f71edd66175c158fe6d47bf154129933c Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 19 Oct 2024 11:01:37 +0200 Subject: [PATCH 15/16] chore: update aluvm --- Cargo.lock | 18 +++++++++--------- src/interface/builder.rs | 2 +- src/interface/calc.rs | 10 ++++------ src/interface/contract.rs | 2 +- src/interface/iimpl.rs | 2 +- 5 files changed, 16 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 040ef4f6..e5000e05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5,7 +5,7 @@ version = 3 [[package]] name = "aluvm" version = "0.11.0-beta.9" -source = "git+https://github.com/AluVM/rust-aluvm?branch=develop#7adf61dbe4a3b39834bc3d665800024d66658e9c" +source = "git+https://github.com/AluVM/rust-aluvm?branch=develop#bedd86c160bab2398c07901728fd06b6bab13ddc" dependencies = [ "amplify", "ascii-armor", @@ -540,9 +540,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "log" @@ -619,9 +619,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.88" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "7c3a7fc5db1e57d5a779a352c8cdb57b29aa4c40cc69c3a68a7fedc815fbf2f9" dependencies = [ "unicode-ident", ] @@ -668,7 +668,7 @@ dependencies = [ [[package]] name = "rgb-core" version = "0.11.0-beta.9" -source = "git+https://github.com/RGB-WG/rgb-core?branch=feat/fungible-nonconf#9c6f3fee4ac573380c0ed8658d644fc5a7cfc533" +source = "git+https://github.com/RGB-WG/rgb-core?branch=feat/fungible-nonconf#78ee97123665b5da312336f52d56485153af1673" dependencies = [ "aluvm", "amplify", @@ -810,9 +810,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.131" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "67d42a0bd4ac281beff598909bb56a86acaf979b84483e1c79c10dcaf98f8cf3" dependencies = [ "itoa", "memchr", @@ -906,7 +906,7 @@ dependencies = [ [[package]] name = "strict_types" version = "2.7.1" -source = "git+https://github.com/strict-types/strict-types?branch=develop#729a4f86d25dfcea15ed15bbeb1e027473401c58" +source = "git+https://github.com/strict-types/strict-types?branch=develop#9a2041a9b1988b17608564725d47b39f442e5062" dependencies = [ "amplify", "ascii-armor", diff --git a/src/interface/builder.rs b/src/interface/builder.rs index 76eff309..5b2f08b4 100644 --- a/src/interface/builder.rs +++ b/src/interface/builder.rs @@ -631,7 +631,7 @@ impl OperationBuilder { fn assignments_type(&self, name: impl Into) -> Result { let name = name.into(); self.iimpl - .assignments_type(&name) + .assignment_type(&name) .ok_or(BuilderError::AssignmentNotFound(name)) } diff --git a/src/interface/calc.rs b/src/interface/calc.rs index 2932f775..077b2fd5 100644 --- a/src/interface/calc.rs +++ b/src/interface/calc.rs @@ -21,7 +21,7 @@ use aluvm::data::ByteStr; use aluvm::library::{LibId, LibSite}; -use aluvm::reg::{Reg16, Reg32, RegA, RegR, RegS}; +use aluvm::reg::{Reg16, Reg32, RegA, RegR}; use amplify::num::{u256, u4}; use amplify::{ByteArray, Wrapper}; use rgb::validation::Scripts; @@ -91,7 +91,7 @@ impl StateCalc { fn run(&mut self, site: LibSite) -> Result<(), String> { if !self.vm.exec(site, |id| self.scripts.get(&id), &()) { - if let Some(err) = self.vm.registers.get_s(RegS::from(15)).cloned() { + if let Some(err) = self.vm.registers.s16(15).cloned() { return Err(err.to_string()); } } @@ -104,9 +104,7 @@ impl StateCalc { .set_n(RegA::A16, Reg32::Reg0, Some(ty.to_inner())); assert_eq!(state.reserved, none!()); self.vm.registers.set_n(RegA::A8, Reg32::Reg0, Some(0u8)); - self.vm - .registers - .set_s(RegS::from(0), Some(ByteStr::with(&state.data))); + self.vm.registers.set_s16(0, ByteStr::with(&state.data)); self.vm.registers.set_n( RegR::R256, Reg32::Reg0, @@ -119,7 +117,7 @@ impl StateCalc { ty: AssignmentType, idx: Reg16, ) -> Result, StateCalcError> { - let Some(data) = self.vm.registers.get_s(RegS::from(u4::from(idx))) else { + let Some(data) = self.vm.registers.s16(u4::from(idx)) else { return Ok(None); }; let reserved = self diff --git a/src/interface/contract.rs b/src/interface/contract.rs index 37d18fd1..e027b43c 100644 --- a/src/interface/contract.rs +++ b/src/interface/contract.rs @@ -157,7 +157,7 @@ impl ContractIface { fn assignment_type(&self, name: impl Into) -> Result { let name = name.into(); self.iface - .assignments_type(&name) + .assignment_type(&name) .ok_or(ContractError::FieldNameUnknown(name)) } diff --git a/src/interface/iimpl.rs b/src/interface/iimpl.rs index 69f9eb76..5644aa36 100644 --- a/src/interface/iimpl.rs +++ b/src/interface/iimpl.rs @@ -256,7 +256,7 @@ impl IfaceImpl { .map(|nt| nt.id) } - pub fn assignments_type(&self, name: &FieldName) -> Option { + pub fn assignment_type(&self, name: &FieldName) -> Option { self.assignments .iter() .find(|nt| &nt.name == name) From 355b9516c3c3bfe69208d33ecea7fed0acb20d17 Mon Sep 17 00:00:00 2001 From: Dr Maxim Orlovsky Date: Sat, 19 Oct 2024 11:06:06 +0200 Subject: [PATCH 16/16] containers: add Suppl::with deterministic constructor --- Cargo.lock | 4 ++-- src/containers/suppl.rs | 13 +++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e5000e05..a3fdd9ee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -307,9 +307,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "cc" -version = "1.1.30" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "shlex", ] diff --git a/src/containers/suppl.rs b/src/containers/suppl.rs index 5da0ea8b..a98aa3ed 100644 --- a/src/containers/suppl.rs +++ b/src/containers/suppl.rs @@ -221,6 +221,19 @@ impl Supplement { } } + pub fn with( + content: impl Into, + creator: impl Into, + timestamp: i64, + ) -> Self { + Supplement { + content_id: content.into(), + timestamp, + creator: creator.into(), + annotations: none!(), + } + } + pub fn get_default_opt( &self, sub: SupplSub,