diff --git a/seals/src/lib.rs b/seals/src/lib.rs index 50c2798b..ee627686 100644 --- a/seals/src/lib.rs +++ b/seals/src/lib.rs @@ -48,8 +48,3 @@ pub mod txout; mod secret; pub use secret::SecretSeal; - -/// Method for closing BP single-use-seals. -pub trait SealCloseMethod: dbc::DbcMethod {} - -impl SealCloseMethod for dbc::Method {} diff --git a/seals/src/txout/blind.rs b/seals/src/txout/blind.rs index 28974b43..dc6563f4 100644 --- a/seals/src/txout/blind.rs +++ b/seals/src/txout/blind.rs @@ -28,18 +28,17 @@ use std::str::FromStr; use amplify::hex; use bc::{Outpoint, Txid, Vout}; use commit_verify::{CommitId, Conceal}; -use dbc::MethodParseError; use rand::{thread_rng, RngCore}; use strict_encoding::{StrictDecode, StrictDumb, StrictEncode}; -use super::{CloseMethod, WitnessVoutError}; +use super::WitnessVoutError; use crate::txout::{SealTxid, TxPtr, TxoSeal}; -use crate::{SealCloseMethod, SecretSeal}; +use crate::SecretSeal; /// Seal type which can be blinded and chained with other seals. -pub type ChainBlindSeal = BlindSeal; +pub type ChainBlindSeal = BlindSeal; /// Seal type which can be blinded, but can't be chained with other seals. -pub type SingleBlindSeal = BlindSeal; +pub type SingleBlindSeal = BlindSeal; /// Revealed seal definition which may point to a witness transactions and /// contains blinding data. @@ -52,11 +51,7 @@ pub type SingleBlindSeal = BlindSeal; #[derive(CommitEncode)] #[commit_encode(strategy = strict, id = SecretSeal)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -pub struct BlindSeal { - /// Commitment to the specific seal close method [`CloseMethod`] which must - /// be used to close this seal. - pub method: M, - +pub struct BlindSeal { /// Txid of the seal definition. /// /// It may be missed in situations when ID of a transaction is not known, @@ -74,6 +69,12 @@ pub struct BlindSeal { pub blinding: u64, } +impl BlindSeal { + /// Converts revealed seal into concealed. + #[inline] + pub fn to_secret_seal(&self) -> SecretSeal { self.conceal() } +} + impl Conceal for BlindSeal { type Concealed = SecretSeal; @@ -81,38 +82,35 @@ impl Conceal for BlindSeal { fn conceal(&self) -> Self::Concealed { self.commit_id() } } -impl TryFrom<&BlindSeal> for Outpoint { +impl TryFrom<&BlindSeal> for Outpoint { type Error = WitnessVoutError; #[inline] - fn try_from(reveal: &BlindSeal) -> Result { + fn try_from(reveal: &BlindSeal) -> Result { reveal.txid.map_to_outpoint(reveal.vout).ok_or(WitnessVoutError) } } -impl TryFrom> for Outpoint { +impl TryFrom> for Outpoint { type Error = WitnessVoutError; #[inline] - fn try_from(reveal: BlindSeal) -> Result { + fn try_from(reveal: BlindSeal) -> Result { Outpoint::try_from(&reveal) } } -impl From<&BlindSeal> for Outpoint { +impl From<&BlindSeal> for Outpoint { #[inline] - fn from(reveal: &BlindSeal) -> Self { Outpoint::new(reveal.txid, reveal.vout) } + fn from(reveal: &BlindSeal) -> Self { Outpoint::new(reveal.txid, reveal.vout) } } -impl From> for Outpoint { +impl From> for Outpoint { #[inline] - fn from(reveal: BlindSeal) -> Self { Outpoint::from(&reveal) } + fn from(reveal: BlindSeal) -> Self { Outpoint::from(&reveal) } } -impl TxoSeal for BlindSeal { - #[inline] - fn method(&self) -> M { self.method } - +impl TxoSeal for BlindSeal { #[inline] fn txid(&self) -> Option { self.txid.txid() } @@ -131,66 +129,33 @@ impl TxoSeal for BlindSeal { } } -impl BlindSeal { - /// Creates new seal using TapretFirst closing method for the provided - /// outpoint. Uses `thread_rng` to initialize blinding factor. - pub fn tapret_first_rand_from(outpoint: Outpoint) -> Self { - BlindSeal::tapret_first_rand(outpoint.txid, outpoint.vout) - } - - /// Creates new seal using OpretFirst closing method for the provided - /// outpoint. Uses `thread_rng` to initialize blinding factor. - pub fn opret_first_rand_from(outpoint: Outpoint) -> Self { - BlindSeal::opret_first_rand(outpoint.txid, outpoint.vout) +impl BlindSeal { + /// Creates new seal for the provided outpoint. Uses `thread_rng` to initialize blinding + /// factor. + pub fn rand_from(outpoint: Outpoint) -> Self { + BlindSeal::new_random(outpoint.txid, outpoint.vout) } - /// Creates new seal using TapretFirst closing method for the provided - /// outpoint. Uses `thread_rng` to initialize blinding factor. - pub fn tapret_first_rand(txid: impl Into, vout: impl Into) -> Self { - BlindSeal::with_rng(CloseMethod::TapretFirst, txid, vout, &mut thread_rng()) + /// Creates new seal for the provided outpoint. Uses `thread_rng` to initialize blinding + /// factor. + pub fn new_random(txid: impl Into, vout: impl Into) -> Self { + BlindSeal::with_rng(txid, vout, &mut thread_rng()) } - /// Creates new seal using OpretFirst closing method for the provided - /// outpoint. Uses `thread_rng` to initialize blinding factor. - pub fn opret_first_rand(txid: impl Into, vout: impl Into) -> Self { - BlindSeal::with_rng(CloseMethod::OpretFirst, txid, vout, &mut thread_rng()) - } -} - -impl BlindSeal { - /// Creates new seal for the provided outpoint and seal closing method. Uses - /// `thread_rng` to initialize blinding factor. - pub fn new_random(method: M, txid: impl Into, vout: impl Into) -> Self { - BlindSeal::with_rng(method, txid, vout, &mut thread_rng()) - } - - /// Creates new seal for the provided outpoint and seal closing method. Uses - /// provided random number generator to create a new blinding factor. - pub fn with_rng( - method: M, - txid: impl Into, - vout: impl Into, - rng: &mut impl RngCore, - ) -> Self { + /// Creates new seal for the provided outpoint. Uses provided random number generator to create + /// a new blinding factor. + pub fn with_rng(txid: impl Into, vout: impl Into, rng: &mut impl RngCore) -> Self { BlindSeal { - method, txid: txid.into(), vout: vout.into(), blinding: rng.next_u64(), } } - /// Reconstructs previously defined seal pointing to a witness transaction - /// of another seal with a given method, witness transaction output number - /// and previously generated blinding factor value.. - pub fn with_blinding( - method: M, - txid: impl Into, - vout: impl Into, - blinding: u64, - ) -> Self { + /// Reconstructs previously defined seal pointing to a witness transaction of another seal with + /// a given witness transaction output number and previously generated blinding factor value. + pub fn with_blinding(txid: impl Into, vout: impl Into, blinding: u64) -> Self { BlindSeal { - method, txid: txid.into(), vout: vout.into(), blinding, @@ -198,26 +163,22 @@ impl BlindSeal { } } -impl BlindSeal { - /// Creates new seal pointing to a witness transaction of another seal. - /// Takes seal closing method and witness transaction output number as - /// arguments. Uses `thread_rng` to initialize blinding factor. +impl BlindSeal { + /// Creates new seal pointing to a witness transaction of another seal. Takes witness + /// transaction output number as argument. Uses `thread_rng` to initialize blinding factor. #[inline] - pub fn new_random_vout(method: M, vout: impl Into) -> Self { + pub fn new_random_vout(vout: impl Into) -> Self { Self { - method, blinding: thread_rng().next_u64(), txid: TxPtr::WitnessTx, vout: vout.into(), } } - /// Reconstructs previously defined seal pointing to a witness transaction - /// of another seal with a given method, witness transaction output number - /// and previously generated blinding factor value.. - pub fn with_blinded_vout(method: M, vout: impl Into, blinding: u64) -> Self { + /// Reconstructs previously defined seal pointing to a witness transaction of another seal with + /// a given witness transaction output number and previously generated blinding factor value. + pub fn with_blinded_vout(vout: impl Into, blinding: u64) -> Self { BlindSeal { - method, txid: TxPtr::WitnessTx, vout: vout.into(), blinding, @@ -225,10 +186,10 @@ impl BlindSeal { } } -impl BlindSeal { +impl BlindSeal { /// Converts `BlindSeal` into `BlindSeal`. - pub fn transmutate(self) -> BlindSeal { - BlindSeal::with_blinding(self.method, self.txid, self.vout, self.blinding) + pub fn transmutate(self) -> BlindSeal { + BlindSeal::with_blinding(self.txid, self.vout, self.blinding) } /// Converts seal into a transaction outpoint. @@ -236,10 +197,10 @@ impl BlindSeal { pub fn to_outpoint(&self) -> Outpoint { Outpoint::new(self.txid, self.vout) } } -impl BlindSeal { +impl BlindSeal { /// Converts `BlindSeal` into `BlindSeal`. - pub fn resolve(self, txid: Txid) -> BlindSeal { - BlindSeal::with_blinding(self.method, self.txid().unwrap_or(txid), self.vout, self.blinding) + pub fn resolve(self, txid: Txid) -> BlindSeal { + BlindSeal::with_blinding(self.txid().unwrap_or(txid), self.vout, self.blinding) } } @@ -248,20 +209,12 @@ impl BlindSeal { #[derive(Clone, PartialEq, Eq, Debug, Display, Error, From)] #[display(doc_comments)] pub enum ParseError { - /// single-use-seal must start with method name (e.g. 'tapret1st' etc) - MethodRequired, - /// full transaction id is required for the seal specification TxidRequired, /// blinding factor must be specified after `#` BlindingRequired, - /// wrong seal close method id - #[display(inner)] - #[from] - WrongMethod(MethodParseError), - /// unable to parse blinding value; it must be a hexadecimal string /// starting with `0x` WrongBlinding, @@ -282,22 +235,21 @@ pub enum ParseError { NonHexBlinding, } -impl FromStr for BlindSeal -where M: FromStr -{ +impl FromStr for BlindSeal { type Err = ParseError; fn from_str(s: &str) -> Result { let mut split = s.split(&[':', '#'][..]); - match (split.next(), split.next(), split.next(), split.next(), split.next()) { - (Some("~"), ..) | (Some(""), ..) => Err(ParseError::MethodRequired), - (Some(_), Some(""), ..) => Err(ParseError::TxidRequired), - (Some(_), Some(_), None, ..) if s.contains(':') => Err(ParseError::BlindingRequired), - (Some(_), Some(_), Some(_), Some(blinding), None) if !blinding.starts_with("0x") => { + if split.next() != Some("txoseal") { + return Err(ParseError::WrongStructure); + } + match (split.next(), split.next(), split.next(), split.next()) { + (Some(""), ..) => Err(ParseError::TxidRequired), + (Some(_), None, ..) if !s.contains('#') => Err(ParseError::BlindingRequired), + (Some(_), Some(_), Some(blinding), None) if !blinding.starts_with("0x") => { Err(ParseError::NonHexBlinding) } - (Some(method), Some(txid), Some(vout), Some(blinding), None) => Ok(BlindSeal { - method: method.parse()?, + (Some(txid), Some(vout), Some(blinding), None) => Ok(BlindSeal { blinding: u64::from_str_radix(blinding.trim_start_matches("0x"), 16) .map_err(|_| ParseError::WrongBlinding)?, txid: Id::from_str(txid).map_err(ParseError::WrongTxid)?, @@ -308,13 +260,11 @@ where M: FromStr } } -impl Display for BlindSeal -where - Self: TxoSeal, - M: Display, +impl Display for BlindSeal +where Self: TxoSeal { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{}:{}:{}#{:#010x}", self.method, self.txid, self.vout, self.blinding) + write!(f, "txoseal:{}:{}#{:#010x}", self.txid, self.vout, self.blinding) } } @@ -325,7 +275,6 @@ mod test { #[test] fn blind_seal_str() { let mut outpoint_reveal = BlindSeal { - method: CloseMethod::TapretFirst, blinding: 0x31bbed7e7b2d, txid: TxPtr::Txid( Txid::from_str("646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839") @@ -337,7 +286,7 @@ mod test { let s = outpoint_reveal.to_string(); assert_eq!( &s, - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:21#\ + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:21#\ 0x31bbed7e7b2d" ); // round-trip @@ -345,37 +294,28 @@ mod test { outpoint_reveal.txid = TxPtr::WitnessTx; let s = outpoint_reveal.to_string(); - assert_eq!(&s, "tapret1st:~:21#0x31bbed7e7b2d"); + assert_eq!(&s, "txoseal:~:21#0x31bbed7e7b2d"); // round-trip assert_eq!(ChainBlindSeal::from_str(&s).unwrap(), outpoint_reveal); - // wrong method - assert_eq!( - ChainBlindSeal::::from_str( - "tapret:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:0x765#\ - 0x78ca95" - ), - Err(ParseError::WrongMethod(MethodParseError(s!("tapret")))) - ); - // wrong vout value assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:0x765#\ + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:0x765#\ 0x78ca95" ), Err(ParseError::WrongVout) ); assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:i9#\ + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:i9#\ 0x78ca95" ), Err(ParseError::WrongVout) ); assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:-5#\ + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:-5#\ 0x78ca95" ), Err(ParseError::WrongVout) @@ -383,47 +323,45 @@ mod test { // wrong blinding secret value assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:5#\ - 0x78cs" + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:5#0x78cs" ), Err(ParseError::WrongBlinding) ); assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:5#\ - 78ca95" + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:5#78ca95" ), Err(ParseError::NonHexBlinding) ); assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:5#857" + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:5#857" ), Err(ParseError::NonHexBlinding) ); assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:5#-5" + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:5#-5" ), Err(ParseError::NonHexBlinding) ); // wrong txid value assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d607719dfd820551fb773e4dc8c4ed67965a8d1fae839:5#\ + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d607719dfd820551fb773e4dc8c4ed67965a8d1fae839:5#\ 0x78ca69" ), Err(ParseError::WrongTxid(hex::Error::OddLengthString(63))) ); assert_eq!( - ChainBlindSeal::::from_str("tapret1st:rvgbdg:5#0x78ca69"), + ChainBlindSeal::from_str("txoseal:rvgbdg:5#0x78ca69"), Err(ParseError::WrongTxid(hex::Error::InvalidChar(b'r'))) ); assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:10@646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:5#\ + ChainBlindSeal::from_str( + "txoseal:10@646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:5#\ 0x78ca69" ), Err(ParseError::WrongTxid(hex::Error::OddLengthString(67))) @@ -431,48 +369,45 @@ mod test { // wrong structure assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:1" + ChainBlindSeal::from_str( + "646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:1" ), Err(ParseError::WrongStructure) ); assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839#0x78ca" + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:1" ), Err(ParseError::WrongStructure) ); assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839" + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839#0x78ca" + ), + Err(ParseError::WrongStructure) + ); + assert_eq!( + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839" ), Err(ParseError::BlindingRequired) ); assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839##\ - 0x78ca" + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839##0x78ca" ), Err(ParseError::WrongVout) ); assert_eq!( - ChainBlindSeal::::from_str( - "tapret1st:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:#\ + ChainBlindSeal::from_str( + "txoseal:646ca5c1062619e2a2d60771c9dfd820551fb773e4dc8c4ed67965a8d1fae839:#\ 0x78ca95" ), Err(ParseError::WrongVout) ); assert_eq!( - ChainBlindSeal::::from_str("tapret1st:_:5#0x78ca"), + ChainBlindSeal::from_str("txoseal:_:5#0x78ca"), Err(ParseError::WrongTxid(hex::Error::OddLengthString(1))) ); - assert_eq!( - ChainBlindSeal::::from_str(":5#0x78ca"), - Err(ParseError::MethodRequired) - ); - assert_eq!( - ChainBlindSeal::::from_str("~:5#0x78ca"), - Err(ParseError::MethodRequired) - ); } } diff --git a/seals/src/txout/error.rs b/seals/src/txout/error.rs index d8f733ba..495b24e6 100644 --- a/seals/src/txout/error.rs +++ b/seals/src/txout/error.rs @@ -32,9 +32,6 @@ use bc::Outpoint; serde(crate = "serde_crate", rename_all = "camelCase") )] pub enum VerifyError { - /// seals provided for a batch verification have inconsistent close method. - InconsistentCloseMethod, - /// the provided witness transaction does not closes seal {0}. WitnessNotClosingSeal(Outpoint), diff --git a/seals/src/txout/explicit.rs b/seals/src/txout/explicit.rs index c32366e6..fefdd00d 100644 --- a/seals/src/txout/explicit.rs +++ b/seals/src/txout/explicit.rs @@ -26,11 +26,9 @@ use std::str::FromStr; use amplify::hex; use bc::{Outpoint, Txid, Vout}; -use dbc::MethodParseError; use crate::txout::seal::{SealTxid, TxPtr}; -use crate::txout::{CloseMethod, TxoSeal, WitnessVoutError}; -use crate::SealCloseMethod; +use crate::txout::{TxoSeal, WitnessVoutError}; /// Revealed seal definition which may point to a witness transactions and does /// not contain blinding data. @@ -42,11 +40,7 @@ use crate::SealCloseMethod; #[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] #[strict_type(lib = dbc::LIB_NAME_BPCORE)] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize), serde(crate = "serde_crate"))] -pub struct ExplicitSeal { - /// Commitment to the specific seal close method [`CloseMethod`] which must - /// be used to close this seal. - pub method: M, - +pub struct ExplicitSeal { /// Txid of the seal definition. /// /// It may be missed in situations when ID of a transaction is not known, @@ -59,36 +53,33 @@ pub struct ExplicitSeal { pub vout: Vout, } -impl TryFrom<&ExplicitSeal> for Outpoint { +impl TryFrom<&ExplicitSeal> for Outpoint { type Error = WitnessVoutError; #[inline] - fn try_from(reveal: &ExplicitSeal) -> Result { + fn try_from(reveal: &ExplicitSeal) -> Result { reveal.txid.map_to_outpoint(reveal.vout).ok_or(WitnessVoutError) } } -impl TryFrom> for Outpoint { +impl TryFrom> for Outpoint { type Error = WitnessVoutError; #[inline] - fn try_from(reveal: ExplicitSeal) -> Result { + fn try_from(reveal: ExplicitSeal) -> Result { Outpoint::try_from(&reveal) } } -impl From<&ExplicitSeal> for Outpoint { - fn from(seal: &ExplicitSeal) -> Self { Outpoint::new(seal.txid, seal.vout) } +impl From<&ExplicitSeal> for Outpoint { + fn from(seal: &ExplicitSeal) -> Self { Outpoint::new(seal.txid, seal.vout) } } -impl From> for Outpoint { - fn from(seal: ExplicitSeal) -> Self { Outpoint::from(&seal) } +impl From> for Outpoint { + fn from(seal: ExplicitSeal) -> Self { Outpoint::from(&seal) } } -impl TxoSeal for ExplicitSeal { - #[inline] - fn method(&self) -> M { self.method } - +impl TxoSeal for ExplicitSeal { #[inline] fn txid(&self) -> Option { self.txid.txid() } @@ -107,12 +98,11 @@ impl TxoSeal for ExplicitSeal { } } -impl ExplicitSeal { +impl ExplicitSeal { /// Constructs seal for the provided outpoint and seal closing method. #[inline] - pub fn new(method: M, outpoint: Outpoint) -> ExplicitSeal { + pub fn new(outpoint: Outpoint) -> ExplicitSeal { Self { - method, txid: Id::from(outpoint.txid), vout: outpoint.vout, } @@ -120,16 +110,15 @@ impl ExplicitSeal { /// Constructs seal. #[inline] - pub fn with(method: M, txid: Id, vout: impl Into) -> ExplicitSeal { + pub fn with(txid: Id, vout: impl Into) -> ExplicitSeal { ExplicitSeal { - method, txid, vout: vout.into(), } } } -impl ExplicitSeal { +impl ExplicitSeal { /// Converts seal into a transaction outpoint. #[inline] pub fn to_outpoint(&self) -> Outpoint { Outpoint::new(self.txid, self.vout) } @@ -140,17 +129,9 @@ impl ExplicitSeal { #[derive(Clone, PartialEq, Eq, Debug, Display, Error, From)] #[display(doc_comments)] pub enum ParseError { - /// single-use-seal must start with method name (e.g. 'tapret1st' etc) - MethodRequired, - /// full transaction id is required for the seal specification TxidRequired, - /// wrong seal close method id - #[display(inner)] - #[from] - WrongMethod(MethodParseError), - /// unable to parse transaction id value; it must be 64-character /// hexadecimal string, however {0} WrongTxid(hex::Error), @@ -163,18 +144,14 @@ pub enum ParseError { WrongStructure, } -impl FromStr for ExplicitSeal -where M: FromStr -{ +impl FromStr for ExplicitSeal { type Err = ParseError; fn from_str(s: &str) -> Result { let mut split = s.split(&[':', '#'][..]); - match (split.next(), split.next(), split.next(), split.next()) { - (Some("~"), ..) | (Some(""), ..) => Err(ParseError::MethodRequired), - (Some(_), Some(""), ..) => Err(ParseError::TxidRequired), - (Some(method), Some(txid), Some(vout), None) => Ok(ExplicitSeal { - method: method.parse()?, + match (split.next(), split.next(), split.next()) { + (Some(""), ..) => Err(ParseError::TxidRequired), + (Some(txid), Some(vout), None) => Ok(ExplicitSeal { txid: Id::from_str(txid).map_err(ParseError::WrongTxid)?, vout: vout.parse().map_err(|_| ParseError::WrongVout)?, }), @@ -183,10 +160,8 @@ where M: FromStr } } -impl Display for ExplicitSeal -where M: Display -{ +impl Display for ExplicitSeal { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!(f, "{}:{}:{}", self.method, self.txid, self.vout,) + write!(f, "{}:{}", self.txid, self.vout,) } } diff --git a/seals/src/txout/seal.rs b/seals/src/txout/seal.rs index 99016673..f933c43d 100644 --- a/seals/src/txout/seal.rs +++ b/seals/src/txout/seal.rs @@ -27,16 +27,11 @@ use amplify::hex; use bc::{Outpoint, Txid, Vout}; use strict_encoding::{StrictDecode, StrictDumb, StrictEncode}; -use crate::SealCloseMethod; - /// Method for closing single-use-seals. pub type CloseMethod = dbc::Method; /// Methods common for all transaction-output based seal types. -pub trait TxoSeal { - /// Returns method which must be used for seal closing. - fn method(&self) -> M; - +pub trait TxoSeal { /// Returns [`Txid`] part of the seal definition, if known. fn txid(&self) -> Option; diff --git a/seals/src/txout/witness.rs b/seals/src/txout/witness.rs index d2fef193..845bbb9b 100644 --- a/seals/src/txout/witness.rs +++ b/seals/src/txout/witness.rs @@ -23,16 +23,14 @@ use std::marker::PhantomData; use bc::{Tx, Txid}; use commit_verify::mpc; -use dbc::{DbcMethod, Method}; use single_use_seals::SealWitness; use crate::txout::{TxoSeal, VerifyError}; -use crate::SealCloseMethod; /// Witness of a bitcoin-based seal being closed. Includes both transaction and /// extra-transaction data. #[derive(Clone, Eq, PartialEq, Hash, Debug)] -pub struct Witness, M: DbcMethod = Method> { +pub struct Witness { /// Witness transaction: transaction which contains commitment to the /// message over which the seal is closed. pub tx: Tx, @@ -44,13 +42,13 @@ pub struct Witness, M: DbcMethod = Method> { pub proof: D, #[doc(hidden)] - pub _phantom: PhantomData, + pub _phantom: PhantomData, } -impl, M: DbcMethod> Witness { +impl Witness { /// Constructs witness from a witness transaction and extra-transaction /// proof, taken from an anchor. - pub fn with(tx: Tx, dbc: D) -> Witness { + pub fn with(tx: Tx, dbc: D) -> Witness { Witness { txid: tx.txid(), tx, @@ -60,9 +58,7 @@ impl, M: DbcMethod> Witness { } } -impl, Dbc: dbc::Proof, M: SealCloseMethod> SealWitness - for Witness -{ +impl SealWitness for Witness { type Message = mpc::Commitment; type Error = VerifyError; @@ -85,25 +81,15 @@ impl, Dbc: dbc::Proof, M: SealCloseMethod> SealWitness where Seal: 'seal, { - let mut method = None; for seal in seals { - // 1. All seals must have the same closing method - if let Some(method) = method { - if method != seal.method() { - return Err(VerifyError::InconsistentCloseMethod); - } - } else { - method = Some(seal.method()); - } - - // 2. Each seal must match tx inputs + // 1. Each seal must match tx inputs let outpoint = seal.outpoint().ok_or(VerifyError::NoWitnessTxid)?; if !self.tx.inputs.iter().any(|txin| txin.prev_output == outpoint) { return Err(VerifyError::WitnessNotClosingSeal(outpoint)); } } - // 3. Verify DBC with the giving closing method + // 2. Verify DBC with the giving closing method self.proof.verify(msg, &self.tx).map_err(VerifyError::Dbc) } } diff --git a/src/bin/bpcore-stl.rs b/src/bin/bpcore-stl.rs index c6694033..e9f41d57 100644 --- a/src/bin/bpcore-stl.rs +++ b/src/bin/bpcore-stl.rs @@ -26,7 +26,7 @@ use bc::stl::{bp_consensus_stl, bp_tx_stl}; use bp::stl::bp_core_stl; use commit_verify::stl::commit_verify_stl; use commit_verify::CommitmentLayout; -use seals::txout::{ChainBlindSeal, CloseMethod, SingleBlindSeal}; +use seals::txout::{ChainBlindSeal, SingleBlindSeal}; use strict_encoding::libname; use strict_types::stl::std_stl; use strict_types::{parse_args, SystemBuilder}; @@ -113,9 +113,9 @@ Seals vesper lexicon=types+commitments " ) .unwrap(); - let layout = SingleBlindSeal::::commitment_layout(); + let layout = SingleBlindSeal::commitment_layout(); writeln!(file, "{layout}").unwrap(); - let layout = ChainBlindSeal::::commitment_layout(); + let layout = ChainBlindSeal::commitment_layout(); writeln!(file, "{layout}").unwrap(); let tt = sys.type_tree("BPCore.BlindSealTxid").unwrap(); writeln!(file, "{tt}").unwrap(); diff --git a/src/bp.rs b/src/bp.rs deleted file mode 100644 index 7d51fbef..00000000 --- a/src/bp.rs +++ /dev/null @@ -1,114 +0,0 @@ -// Bitcoin protocol core library. -// -// 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 strict_encoding::{StrictDecode, StrictDumb, StrictEncode}; - -/// Enumeration over types related to bitcoin protocol-compatible chains. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] -#[derive(StrictType, StrictDumb, StrictEncode, StrictDecode)] -#[strict_type(lib = dbc::LIB_NAME_BPCORE, tags = custom, dumb = Self::Bitcoin(strict_dumb!()))] -#[cfg_attr( - feature = "serde", - derive(Serialize, Deserialize), - serde(crate = "serde_crate", rename_all = "camelCase") -)] -pub enum Bp -where T: StrictDumb + StrictEncode + StrictDecode -{ - /// Bitcoin blockchain-based. - /// - /// NB: The type does not distinguish mainnet from testnets. - #[strict_type(tag = 0x00)] - Bitcoin(T), - - /// Liquid blockchain-based - /// - /// NB: The type does not distinguish mainnet from testnets. - #[strict_type(tag = 0x01)] - Liquid(T), -} - -impl Bp { - /// Detects if the variant matches bitcoin blockchain. - pub fn is_bitcoin(&self) -> bool { matches!(self, Bp::Bitcoin(_)) } - /// Detects if the variant matches liquid blockchain. - pub fn is_liquid(&self) -> bool { matches!(self, Bp::Liquid(_)) } - /// Returns bitcoin blockchain variant as an optional. - pub fn as_bitcoin(&self) -> Option<&T> { - match self { - Bp::Bitcoin(t) => Some(t), - Bp::Liquid(_) => None, - } - } - /// Returns liquid blockchain variant as an optional. - pub fn as_liquid(&self) -> Option<&T> { - match self { - Bp::Bitcoin(_) => None, - Bp::Liquid(t) => Some(t), - } - } - /// Converts into bitcoin blockchain optional. - pub fn into_bitcoin(self) -> Option { - match self { - Bp::Bitcoin(t) => Some(t), - Bp::Liquid(_) => None, - } - } - /// Converts into liquid blockchain optional. - pub fn into_liquid(self) -> Option { - match self { - Bp::Bitcoin(_) => None, - Bp::Liquid(t) => Some(t), - } - } - - /// Maps the value from one internal type into another. - pub fn map(self, f: impl FnOnce(T) -> U) -> Bp { - match self { - Bp::Bitcoin(t) => Bp::Bitcoin(f(t)), - Bp::Liquid(t) => Bp::Liquid(f(t)), - } - } - - /// Maps the value from one internal type into another, covering cases which - /// may error. - pub fn try_map( - self, - f: impl FnOnce(T) -> Result, - ) -> Result, E> { - match self { - Bp::Bitcoin(t) => f(t).map(Bp::Bitcoin), - Bp::Liquid(t) => f(t).map(Bp::Liquid), - } - } - - /// Maps the value from one internal type into another, covering cases which - /// may result in an optional value. - pub fn maybe_map( - self, - f: impl FnOnce(T) -> Option, - ) -> Option> { - match self { - Bp::Bitcoin(t) => f(t).map(Bp::Bitcoin), - Bp::Liquid(t) => f(t).map(Bp::Liquid), - } - } -} diff --git a/src/lib.rs b/src/lib.rs index 7e26bcb1..0dcf90eb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,15 +50,12 @@ pub extern crate seals; #[cfg(feature = "stl")] #[macro_use] extern crate amplify; +#[cfg(feature = "stl")] #[macro_use] extern crate strict_encoding; -#[cfg(feature = "serde")] -#[macro_use] -extern crate serde_crate as serde; #[cfg(feature = "stl")] pub mod stl; -mod bp; pub use ::bc::*; #[cfg(feature = "stl")] @@ -66,4 +63,3 @@ pub use ::bc::*; pub mod bc { pub use bc::stl; } -pub use bp::Bp; diff --git a/src/stl.rs b/src/stl.rs index 10133aae..cd8d93b6 100644 --- a/src/stl.rs +++ b/src/stl.rs @@ -25,14 +25,14 @@ use bc::Txid; use commit_verify::mpc; use dbc::opret::OpretProof; use dbc::tapret::TapretProof; -use dbc::{Method, LIB_NAME_BPCORE}; +use dbc::LIB_NAME_BPCORE; use seals::txout::TxPtr; use strict_types::{CompileError, LibBuilder, TypeLib}; /// Strict types id for the library providing data types from [`dbc`] and /// [`seals`] crates. pub const LIB_ID_BPCORE: &str = - "stl:VhPW19SH-c5lzr1y-TLIsx8z-Z5nB!$Q-IgwrAQA-OqXLwUg#austin-story-retro"; + "stl:IXCrofWg-Kg2!RIk-Hzlc5GO-7tH2hNB-YeBTdmN-$HZ0tPw#symbol-tropic-grand"; fn _bp_core_stl() -> Result { LibBuilder::new(libname!(LIB_NAME_BPCORE), tiny_bset! { @@ -46,11 +46,11 @@ fn _bp_core_stl() -> Result { .transpile::>() .transpile::>() .transpile::>() - .transpile::>() - .transpile::>() + .transpile::>() + .transpile::>() .transpile::() - .transpile::>() - .transpile::>() + .transpile::>() + .transpile::>() .compile() } diff --git a/stl/BPCore@0.1.0.sta b/stl/BPCore@0.1.0.sta index 490973c9..0980632b 100644 --- a/stl/BPCore@0.1.0.sta +++ b/stl/BPCore@0.1.0.sta @@ -1,11 +1,11 @@ -----BEGIN STRICT TYPE LIB----- -Id: stl:VhPW19SH-c5lzr1y-TLIsx8z-Z5nB!$Q-IgwrAQA-OqXLwUg#austin-story-retro +Id: stl:IXCrofWg-Kg2!RIk-Hzlc5GO-7tH2hNB-YeBTdmN-$HZ0tPw#symbol-tropic-grand Name: BPCore Dependencies: CommitVerify#miller-pancake-elastic, Std#ralph-blue-lucky, Bitcoin#signal-color-cipher -Check-SHA256: ffe8ef061b2a6733287e1874f8781a637640f3c99f05eb07d25c3a0aa5ed269e +Check-SHA256: 966bc6fd6b923e8a537bad15c2ff36d2a461864324d254bfd7277317801cadd9 20~CnZ*pY=dIKHbX?@G`sCP;~6&DQwR5(-fxrUo0Th4E?M+l67UG^w8*<_XZ#%uyqCj(P-Wc6$lVk7oBr%DNv+($;q`HHK!gIHa)*%m(-e#9sm3I{@IbYpL6 @@ -19,7 +19,7 @@ HS#3Ua|L6d7%qre2Ut&TYsZfv!yd427@;7veO2zMB=| GYU;*a%*g5NMUnmT+QYFd;Umr-dgNEFCuu*?Wk)@WS(Jw`th(K{eY_63r%HmYiwmgY;R+0h0#5^R?l+2 >x*OcO&#*^E;5@PQ20HKbE5LJk_Il(3r%HmYiwmua&K>D*tNNq^HspzKK^|l-Ci`?%`u0U6ZHVlY`S(f -i`CFq2vl-qWlnEoWdl=mWB~wXSa8^mT+s=T=}Z?`J=~w8Q=GLzSfImTncuED0}GM@RW%X-8$oVkXm4^& +i`CFq2vl-qWlnEoWdl=mWB~wXSa8^mT+s=T=}Z?`J=~w8Q=GLzSfImTncuED0}GM@RW%U+8$oVkXm4^& WpZn5WkPIkV{1=va%FT-a&K>D1_B6eaAQz%Z*OJ-dIKHbX?@G`sCP;~6&DQwR5(-fxrUo0Th0tjtzV^DH$Z)O5|10COKearHwcS=7M @@ -33,31 +33,28 @@ W>jHta%FT-a&K>D1_B6eaAQz%Z*OJ-dIKHbX?@G`sCP;~6&DQwR5(-fxrUo0Th=uAF%>iaxC SnRl2&38AmXJiCw9urENI6IdcL2hGcZ*om#a%*g5RB~lyRAF#(Wpq$-Z*OJ>0tjtzV^DH$Z)O5|10COK earHwcS=7M7YzYaI8*bvhMOc?)(rkC#nUDTR`-7%D0S~qxm_HirtB!lh<{Yi-S-!KI0_27BH<@sVme~^s3=TqUX>MdwWnpYocu;h51_TCeWprq7WC1R> -5GA>8Wft0d6dj=*oo`t>c$)o5X19O9`rXu=lIsL?cxhw-vE?{96bd-L@NXK=z8qksZ{gweeRv2cdB4&6 -(-0xu1a@zAbOQBk6JjIwIj2eqliWu}$@z+_xPw?-wb>Rw7=FYk8VVufK10Q-T=FR=Q=>S+XYD&Ml#00<32Y-w&}Q)OXnRCsA*1_TCeWprq7WC1R>5GA>8Wft0d6dj=*oo`t> -c$)o5X19O9`rXu=lIsL?cxhw;^=uPjBlbC`N(qzPM@Gr{imSMTSY5T*7C#t%#3&jHqk=;7%h%D+p%U7S -;b1RT)c9`>#Kd;Rz-U=aO9W+B1a@zAbOQBk6JjIwIj2eqliWu}$@z+_xPw?-wb>Rw7=FYk8VVufK10Q- -T=FR=Q=>S+XYD&Ml#005GA>8Wft0d6dj=*oo`t>c$)o5X19O9`rXu=lIsL?cxhw-vE?{96bd-L@NXK=z8qksZ{gweeRv2c -dB4&6(-0xu1a@zAbOQBk6JjIwIj2eqliWu}$@z+_xPw?-wb>Rw7=FYk8VVufK10Q-T=FR=Q=>S+XYD&< -oK4xzy{V5hX&1W5Lv;{EcyMfKV`+3#WnpYocxhw?0|sqnbZBp60WP-?CAn^87TS9h9ibhaZ&^Bcn*B*; -w|~I;-PD|t>jZRoX=DQRY!hN5_Bp3Y36tDMM#=e#tGI($UA5U3KNx<*C>jc*fi7rMzqbp}mkbZBp60|E+faB^jIMrm?$bN~xM0`+VY -Vk7oBr%DNv+($;q`HHK!gIHa)*%m(-e#9sm3NgE`=!A)P#jpo4axu-4_As_7EzOC4+`8Vyy2R;!*#QZ1 -X=iA3Ol4ta00jX8^=uPjBlbC`N(qzPM@Gr{imSMTSY5T*7C#t%#3&jHU#!_}M0RemmT>wB!7L}MA7sFvK -#<=RP4S#T1Vv-hhTICs&5e05N37a&BR4P-_D9Y!hN5_Bp3Y36tDMM#=e#tGI($UA5U3KNx<*C>jc> -g@kugo@o29zwXDHA;ech!BqJAy+4@X(~&*rw>NkZRAF#(Wpq+$XJ~Xna$#;`Xa)idY-MJ2PH$voNMUnm -0`+VYVk7oBr%DNv+($;q`HHK!gIHa)*%m(-e#9sm3NgE`=!A)P#jpo4axu-4_As_7EzOC4+`8Vyy2R;! -*$r}OXJ~XzZ)9aiVRL8#^=uPjBlbC`N(qzPM@Gr{imSMTSY5T*7C#t%#3&jHF}tqlgo$^>um>@6G0l?p -Ft#Zz&53{9y57aQ#OZ(81yp!YbaDg&010<#bZ%vHb5wW$00035ba-iG00jX8^=uPjBlbC`N(qzPM@Gr{ -imSMTSY5T*7C#t%#3&jHqk=;7%h%D+p%U7S;b1RT)c9`>#Kd;Rz-U=aO9W+B +a&K>D0S~qxm_HirtB!lh<{Yi-S-!KI0_27BH<@sVme~^s3=TqUX>MdwWnpYocu;h51_K0icxhw-vE?{9 +6bd-L@NXK=z8qksZ{gweeRv2cdB4&6(-0xu1a@zAbOQBk6JjIwIj2eqliWu}$@z+_xPw?-wb>Rw7=FYk +8VVufK10Q-T=FR=Q=>S+XYD&Ml#00<32Y-w&}Q)OXnRCsA*1_K0i +cxhw;^=uPjBlbC`N(qzPM@Gr{imSMTSY5T*7C#t%#3&jHqk=;7%h%D+p%U7S;b1RT)c9`>#Kd;Rz-U=a +O9W+B1a@zAbOQBk6JjIwIj2eqliWu}$@z+_xPw?-wb>Rw7=FYk8VVufK10Q-T=FR=Q=>S+XYD&Ml#00Rw7=FYk8VVufK10Q-T=FR= +Q=>S+XYD&jc*fi7rMzqbqY^#a%FT-a&K>D +1pxp6018uOV{&D5Q)OXn1pxpD002NB01;GSaB^jIPH$voP+@X(Ze?-=0{{qYWoC3vZ)9Zv1pxx}Y!hN5 +_Bp3Y36tDMM#=e#tGI($UA5U3KNx<*C>jbeyRPVjiFd`Y2QhLn&64&owka*miGSR>-o?7a>3`V)336#? +Xmm_vVP*gY0Rr`G6JjIwIj2eqliWu}$@z+_xPw?-wb>Rw7=FYk8VX;m*=^-NPQ?`2v5jYd+6t@dEhY>7 +H!Y*UdZb-BpG^V_a%pF1bV71rZewTw1pxs#KVmL%Q_{#Gkvz+H9iKg9-*)mSRaq_gMnjYqO>G4aRAF#( +Wpq$sbZAg=Z*OJ>0t;|qa&&HGa!zk#WdH;M00eGtZe;)f009JZZ*64&1pxs8dtm>UaGoca9LuK7Ij+X8IutOZf|a5WdHyH3shlna%FT-a&K>D1_B9iVRUFva&K>D0TaYiQf4Q+L?w(nXY|a% +e*XOAC%4aD5B-6UFMfO2d?<6$C@F;S3|*6`1-v+nBdcqJ?FPKco9@#aB^jIQfX&sbV71rZewT$0t{?rW^_((WMxQUb7%tf +Y!hN5_Bp3Y36tDMM#=e#tGI($UA5U3KNx<*C>jbeyRPVjiFd`Y2QhLn&64&owka*miGSR>-o?7a>3`V` +a%pF1bWU$%Wk_LjXaeRw7=FYk8VWJHuIPk`cg3&=F>*1@lJ+pR +DJ{*3f84s>#k$1lf7u08cu;h51OfmFcWHEPWpi^>cmMzZ0R(h-X=DHe0Rr`G6JjIwIj2eqliWu}$@z+_ +xPw?-wb>Rw7=FYk8VaL=Li5Yl(a@n1+Ku60FILp}Zw|!7cE!MGSxid=WmW -----END STRICT TYPE LIB----- diff --git a/stl/BPCore@0.1.0.stl b/stl/BPCore@0.1.0.stl index b3ed8f82..61d143cf 100644 Binary files a/stl/BPCore@0.1.0.stl and b/stl/BPCore@0.1.0.stl differ diff --git a/stl/BPCore@0.1.0.sty b/stl/BPCore@0.1.0.sty index 08188457..046f317c 100644 --- a/stl/BPCore@0.1.0.sty +++ b/stl/BPCore@0.1.0.sty @@ -1,5 +1,5 @@ {- - Id: stl:VhPW19SH-c5lzr1y-TLIsx8z-Z5nB!$Q-IgwrAQA-OqXLwUg#austin-story-retro + Id: stl:IXCrofWg-Kg2!RIk-Hzlc5GO-7tH2hNB-YeBTdmN-$HZ0tPw#symbol-tropic-grand Name: BPCore Version: 0.1.0 Description: Bitcoin client-side-validation library @@ -52,31 +52,21 @@ data AnchorMerkleTreeOpretProof : mpcProof CommitVerify.MerkleTree, dbcProof Opr @mnemonic(europe-mister-imitate) data AnchorMerkleTreeTapretProof : mpcProof CommitVerify.MerkleTree, dbcProof TapretProof -@mnemonic(report-process-stuart) -data BlindSealTxPtr : method Method - , txid TxPtr +@mnemonic(metro-mars-canada) +data BlindSealTxPtr : txid TxPtr , vout Bitcoin.Vout , blinding U64 -@mnemonic(baby-region-proxy) -data BlindSealTxid : method Method - , txid Bitcoin.Txid +@mnemonic(halt-crash-valid) +data BlindSealTxid : txid Bitcoin.Txid , vout Bitcoin.Vout , blinding U64 -@mnemonic(meaning-extra-sherman) -data ExplicitSealTxPtr : method Method - , txid TxPtr - , vout Bitcoin.Vout - -@mnemonic(june-total-denver) -data ExplicitSealTxid : method Method - , txid Bitcoin.Txid - , vout Bitcoin.Vout - -@mnemonic(bali-boris-plasma) -data Method : opretFirst | tapretFirst +@mnemonic(velvet-neptune-bazooka) +data ExplicitSealTxPtr : txid TxPtr, vout Bitcoin.Vout +@mnemonic(chicago-europe-phantom) +data ExplicitSealTxid : txid Bitcoin.Txid, vout Bitcoin.Vout @mnemonic(good-village-flex) data OpretProof : () diff --git a/stl/Seals.vesper b/stl/Seals.vesper index f212aaef..e9edc00f 100644 --- a/stl/Seals.vesper +++ b/stl/Seals.vesper @@ -14,13 +14,11 @@ SecretSeal commitment hasher=SHA256 tagged=urn:lnp-bp:seals:secret#2024-02-03 BlindSealTxPtr serialized BlindSealTxid rec - method enum Method opretFirst=0 tapretFirst=1 txid bytes len=32 aka=Txid vout is U32 aka=Vout blinding is U64 BlindSealTxPtr rec - method enum Method opretFirst=0 tapretFirst=1 txid union TxPtr witnessTx is Unit tag=0 txid bytes len=32 wrapped aka=Txid tag=1