diff --git a/Cargo.lock b/Cargo.lock index 9af824f86..d5fd464bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -314,8 +314,10 @@ dependencies = [ "chia_py_streamable_macro", "criterion", "hex", + "hex-literal", "hkdf", "linked-hash-map", + "num-bigint", "pyo3", "rand", "rstest", @@ -420,29 +422,12 @@ dependencies = [ [[package]] name = "chia-puzzles" -version = "0.17.0" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b35f3772cc16bb33521f0f9dcc2e9b27e86cd5bc306fce25355f571f4388b3d" dependencies = [ - "anyhow", - "arbitrary", - "chia-bls 0.17.0", - "chia-protocol", - "chia-sha2", - "clvm-traits", - "clvm-utils", - "clvmr", "hex", "hex-literal", - "num-bigint", -] - -[[package]] -name = "chia-puzzles-fuzz" -version = "0.16.0" -dependencies = [ - "chia-puzzles", - "clvm-traits", - "clvmr", - "libfuzzer-sys", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index a6b3f662c..e94c8d930 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -111,7 +111,6 @@ chia-protocol = { path = "./crates/chia-protocol", version = "0.17.0" } chia-secp = { path = "./crates/chia-secp", version = "0.17.0" } chia-ssl = { path = "./crates/chia-ssl", version = "0.17.0" } chia-traits = { path = "./crates/chia-traits", version = "0.17.0" } -chia-puzzles = { path = "./crates/chia-puzzles", version = "0.17.0" } chia-sha2 = { path = "./crates/chia-sha2", version = "0.17.0" } clvm-traits = { path = "./crates/clvm-traits", version = "0.17.0" } clvm-utils = { path = "./crates/clvm-utils", version = "0.17.0" } @@ -122,6 +121,7 @@ chia-protocol-fuzz = { path = "./crates/chia-protocol/fuzz", version = "0.16.0" chia-puzzles-fuzz = { path = "./crates/chia-puzzles/fuzz", version = "0.16.0" } clvm-traits-fuzz = { path = "./crates/clvm-traits/fuzz", version = "0.16.0" } clvm-utils-fuzz = { path = "./crates/clvm-utils/fuzz", version = "0.16.0" } +chia-puzzles = "0.19.1" blst = { version = "0.3.12", features = ["portable"] } clvmr = "0.10.0" syn = "2.0.90" diff --git a/crates/chia-bls/Cargo.toml b/crates/chia-bls/Cargo.toml index 393f0cc55..bd1c5eeb2 100644 --- a/crates/chia-bls/Cargo.toml +++ b/crates/chia-bls/Cargo.toml @@ -26,6 +26,8 @@ hex = { workspace = true } thiserror = { workspace = true } pyo3 = { workspace = true, features = ["multiple-pymethods"], optional = true } arbitrary = { workspace = true, optional = true } +hex-literal = { workspace = true } +num-bigint = { workspace = true } linked-hash-map = "0.5.6" [dev-dependencies] diff --git a/crates/chia-puzzles/src/derive_synthetic.rs b/crates/chia-bls/src/derive_synthetic.rs similarity index 91% rename from crates/chia-puzzles/src/derive_synthetic.rs rename to crates/chia-bls/src/derive_synthetic.rs index 9e03d7b90..246e2a529 100644 --- a/crates/chia-puzzles/src/derive_synthetic.rs +++ b/crates/chia-bls/src/derive_synthetic.rs @@ -1,9 +1,18 @@ -use chia_bls::{PublicKey, SecretKey}; use chia_sha2::Sha256; use hex_literal::hex; use num_bigint::BigInt; -use crate::standard::DEFAULT_HIDDEN_PUZZLE_HASH; +use crate::{PublicKey, SecretKey}; + +/// This is the puzzle reveal of the [default hidden puzzle](https://chialisp.com/standard-transactions#default-hidden-puzzle). +pub const DEFAULT_HIDDEN_PUZZLE: [u8; 3] = hex!("ff0980"); + +/// This is the puzzle hash of the [default hidden puzzle](https://chialisp.com/standard-transactions#default-hidden-puzzle). +pub const DEFAULT_HIDDEN_PUZZLE_HASH: [u8; 32] = hex!( + " + 711d6c4e32c92e53179b199484cf8c897542bc57f2b22582799f9d657eec4699 + " +); const GROUP_ORDER_BYTES: [u8; 32] = hex!("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001"); @@ -20,7 +29,7 @@ pub trait DeriveSynthetic { where Self: Sized, { - self.derive_synthetic_hidden(&DEFAULT_HIDDEN_PUZZLE_HASH.to_bytes()) + self.derive_synthetic_hidden(&DEFAULT_HIDDEN_PUZZLE_HASH) } } @@ -60,9 +69,9 @@ fn synthetic_offset(public_key: &PublicKey, hidden_puzzle_hash: &[u8; 32]) -> Se mod tests { use super::*; - use chia_bls::{master_to_wallet_unhardened_intermediate, DerivableKey}; use hex::ToHex; - use hex_literal::hex; + + use crate::{master_to_wallet_unhardened_intermediate, DerivableKey}; #[test] fn test_synthetic_public_keys() { diff --git a/crates/chia-bls/src/lib.rs b/crates/chia-bls/src/lib.rs index 8fd08f823..a96e41bc0 100644 --- a/crates/chia-bls/src/lib.rs +++ b/crates/chia-bls/src/lib.rs @@ -2,6 +2,7 @@ mod bls_cache; mod derive_keys; +mod derive_synthetic; mod error; mod gtelement; mod public_key; @@ -13,6 +14,7 @@ mod parse_hex; pub use bls_cache::BlsCache; pub use derive_keys::*; +pub use derive_synthetic::*; pub use error::{Error, Result}; pub use gtelement::GTElement; pub use public_key::{hash_to_g1, hash_to_g1_with_dst, PublicKey}; diff --git a/crates/chia-consensus/src/fast_forward.rs b/crates/chia-consensus/src/fast_forward.rs index f3195a4c6..d5c8e22b0 100644 --- a/crates/chia-consensus/src/fast_forward.rs +++ b/crates/chia-consensus/src/fast_forward.rs @@ -1,16 +1,101 @@ use crate::error::{Error, Result}; use chia_protocol::Bytes32; use chia_protocol::Coin; -use chia_puzzles::singleton::{ - SingletonArgs, SingletonSolution, SingletonStruct, SINGLETON_TOP_LAYER_PUZZLE_HASH, -}; -use chia_puzzles::Proof; +use chia_puzzles::SINGLETON_LAUNCHER_HASH; +use chia_puzzles::SINGLETON_TOP_LAYER_V1_1_HASH; use clvm_traits::{FromClvm, ToClvm}; use clvm_utils::CurriedProgram; +use clvm_utils::ToTreeHash; use clvm_utils::TreeHash; use clvm_utils::{tree_hash, tree_hash_atom, tree_hash_pair}; use clvmr::allocator::{Allocator, NodePtr}; +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(curry)] +pub struct SingletonArgs { + pub singleton_struct: SingletonStruct, + pub inner_puzzle: I, +} + +impl SingletonArgs { + pub fn new(launcher_id: Bytes32, inner_puzzle: I) -> Self { + Self { + singleton_struct: SingletonStruct::new(launcher_id), + inner_puzzle, + } + } +} + +impl SingletonArgs { + pub fn curry_tree_hash(launcher_id: Bytes32, inner_puzzle: TreeHash) -> TreeHash { + CurriedProgram { + program: TreeHash::new(SINGLETON_TOP_LAYER_V1_1_HASH), + args: SingletonArgs { + singleton_struct: SingletonStruct::new(launcher_id), + inner_puzzle, + }, + } + .tree_hash() + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(list)] +pub struct SingletonStruct { + pub mod_hash: Bytes32, + pub launcher_id: Bytes32, + #[clvm(rest)] + pub launcher_puzzle_hash: Bytes32, +} + +impl SingletonStruct { + pub fn new(launcher_id: Bytes32) -> Self { + Self { + mod_hash: SINGLETON_TOP_LAYER_V1_1_HASH.into(), + launcher_id, + launcher_puzzle_hash: SINGLETON_LAUNCHER_HASH.into(), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(solution)] +pub struct SingletonSolution { + pub lineage_proof: Proof, + pub amount: u64, + pub inner_solution: I, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(solution)] +pub struct LauncherSolution { + pub singleton_puzzle_hash: Bytes32, + pub amount: u64, + pub key_value_list: T, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(transparent)] +pub enum Proof { + Lineage(LineageProof), + Eve(EveProof), +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(list)] +pub struct LineageProof { + pub parent_parent_coin_info: Bytes32, + pub parent_inner_puzzle_hash: Bytes32, + pub parent_amount: u64, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] +#[clvm(list)] +pub struct EveProof { + pub parent_parent_coin_info: Bytes32, + pub parent_amount: u64, +} + // TODO: replace this with a generic function to compute the hash of curried // puzzles const OP_QUOTE: u8 = 1; @@ -86,16 +171,14 @@ pub fn fast_forward_singleton( // this is the tree hash of the singleton top layer puzzle // the tree hash of singleton_top_layer_v1_1.clsp - if singleton.args.singleton_struct.mod_hash.as_ref() - != SINGLETON_TOP_LAYER_PUZZLE_HASH.to_bytes() - { + if singleton.args.singleton_struct.mod_hash.as_ref() != SINGLETON_TOP_LAYER_V1_1_HASH { return Err(Error::NotSingletonModHash); } // also make sure the actual mod-hash of this puzzle matches the // singleton_top_layer_v1_1.clsp let mod_hash = tree_hash(a, singleton.program); - if mod_hash != SINGLETON_TOP_LAYER_PUZZLE_HASH { + if mod_hash != SINGLETON_TOP_LAYER_V1_1_HASH.into() { return Err(Error::NotSingletonModHash); } diff --git a/crates/chia-puzzles/Cargo.toml b/crates/chia-puzzles/Cargo.toml deleted file mode 100644 index a93624a3f..000000000 --- a/crates/chia-puzzles/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "chia-puzzles" -version = "0.17.0" -edition = "2021" -license = "Apache-2.0" -description = "Chia primitives needed for building wallets." -authors = ["Brandon Haggstrom "] -homepage = "https://github.com/Chia-Network/chia_rs" -repository = "https://github.com/Chia-Network/chia_rs" - -[lints] -workspace = true - -[features] -arbitrary = ["dep:arbitrary", "chia-protocol/arbitrary"] - -[dependencies] -clvmr = { workspace = true } -num-bigint = { workspace = true } -hex-literal = { workspace = true } -clvm-utils = { workspace = true } -clvm-traits = { workspace = true, features = ["chia-bls"] } -chia-sha2 = { workspace = true } -chia-bls = { workspace = true } -chia-protocol = { workspace = true } -arbitrary = { workspace = true, features = ["derive"], optional = true } - -[dev-dependencies] -hex = { workspace = true } -anyhow = { workspace = true } - -[lib] -crate-type = ["rlib"] diff --git a/crates/chia-puzzles/fuzz/.gitignore b/crates/chia-puzzles/fuzz/.gitignore deleted file mode 100644 index a0925114d..000000000 --- a/crates/chia-puzzles/fuzz/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -target -corpus -artifacts diff --git a/crates/chia-puzzles/fuzz/Cargo.toml b/crates/chia-puzzles/fuzz/Cargo.toml deleted file mode 100644 index 918709e98..000000000 --- a/crates/chia-puzzles/fuzz/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "chia-puzzles-fuzz" -version = "0.16.0" -authors = ["Automatically generated"] -publish = false -edition = "2021" - -[package.metadata] -cargo-fuzz = true - -[lints] -workspace = true - -[dependencies] -libfuzzer-sys = { workspace = true } -clvmr = { workspace = true } -chia-puzzles = { workspace = true, features = ["arbitrary"] } -clvm-traits = { workspace = true } - -[[bin]] -name = "roundtrip" -path = "fuzz_targets/roundtrip.rs" -test = false -doc = false -bench = false diff --git a/crates/chia-puzzles/fuzz/fuzz_targets/roundtrip.rs b/crates/chia-puzzles/fuzz/fuzz_targets/roundtrip.rs deleted file mode 100644 index 0f44f8f72..000000000 --- a/crates/chia-puzzles/fuzz/fuzz_targets/roundtrip.rs +++ /dev/null @@ -1,26 +0,0 @@ -#![no_main] - -use std::fmt; - -use chia_puzzles::{nft::NftMetadata, Proof}; -use clvm_traits::{FromClvm, ToClvm}; -use clvmr::Allocator; -use libfuzzer_sys::arbitrary::{Arbitrary, Unstructured}; -use libfuzzer_sys::fuzz_target; - -fuzz_target!(|data: &[u8]| { - let mut u = Unstructured::new(data); - roundtrip::(&mut u); - roundtrip::(&mut u); -}); - -fn roundtrip<'a, T>(u: &mut Unstructured<'a>) -where - T: Arbitrary<'a> + ToClvm + FromClvm + PartialEq + fmt::Debug, -{ - let obj = T::arbitrary(u).unwrap(); - let mut a = Allocator::new(); - let ptr = obj.to_clvm(&mut a).unwrap(); - let obj2 = T::from_clvm(&a, ptr).unwrap(); - assert_eq!(obj, obj2); -} diff --git a/crates/chia-puzzles/src/lib.rs b/crates/chia-puzzles/src/lib.rs deleted file mode 100644 index 108b2dc7b..000000000 --- a/crates/chia-puzzles/src/lib.rs +++ /dev/null @@ -1,7 +0,0 @@ -mod derive_synthetic; -mod proof; -mod puzzles; - -pub use derive_synthetic::*; -pub use proof::*; -pub use puzzles::*; diff --git a/crates/chia-puzzles/src/proof.rs b/crates/chia-puzzles/src/proof.rs deleted file mode 100644 index e14949ec2..000000000 --- a/crates/chia-puzzles/src/proof.rs +++ /dev/null @@ -1,36 +0,0 @@ -use chia_protocol::Bytes32; -use clvm_traits::{FromClvm, ToClvm}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(transparent)] -pub enum Proof { - Lineage(LineageProof), - Eve(EveProof), -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(list)] -pub struct LineageProof { - pub parent_parent_coin_info: Bytes32, - pub parent_inner_puzzle_hash: Bytes32, - pub parent_amount: u64, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(list)] -pub struct EveProof { - pub parent_parent_coin_info: Bytes32, - pub parent_amount: u64, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(list)] -pub struct CoinProof { - pub parent_coin_info: Bytes32, - pub inner_puzzle_hash: Bytes32, - pub amount: u64, -} diff --git a/crates/chia-puzzles/src/puzzles.rs b/crates/chia-puzzles/src/puzzles.rs deleted file mode 100644 index 7ad0298af..000000000 --- a/crates/chia-puzzles/src/puzzles.rs +++ /dev/null @@ -1,17 +0,0 @@ -pub mod cat; -pub mod did; -pub mod nft; -pub mod offer; -pub mod singleton; -pub mod standard; - -#[cfg(test)] -#[macro_export] -macro_rules! assert_puzzle_hash { - ($puzzle:ident => $puzzle_hash:ident) => { - let mut a = clvmr::Allocator::new(); - let ptr = clvmr::serde::node_from_bytes(&mut a, &$puzzle).unwrap(); - let hash = clvm_utils::tree_hash(&mut a, ptr); - assert_eq!($puzzle_hash, hash); - }; -} diff --git a/crates/chia-puzzles/src/puzzles/cat.rs b/crates/chia-puzzles/src/puzzles/cat.rs deleted file mode 100644 index 598cc5ac9..000000000 --- a/crates/chia-puzzles/src/puzzles/cat.rs +++ /dev/null @@ -1,353 +0,0 @@ -use chia_bls::PublicKey; -use chia_protocol::{Bytes32, Coin}; -use clvm_traits::{FromClvm, ToClvm}; -use clvm_utils::{CurriedProgram, ToTreeHash, TreeHash}; -use hex_literal::hex; - -use crate::{CoinProof, LineageProof}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(curry)] -pub struct CatArgs { - pub mod_hash: Bytes32, - pub asset_id: Bytes32, - pub inner_puzzle: I, -} - -impl CatArgs { - pub fn new(asset_id: Bytes32, inner_puzzle: I) -> Self { - Self { - mod_hash: CAT_PUZZLE_HASH.into(), - asset_id, - inner_puzzle, - } - } -} - -impl CatArgs { - pub fn curry_tree_hash(asset_id: Bytes32, inner_puzzle: TreeHash) -> TreeHash { - CurriedProgram { - program: CAT_PUZZLE_HASH, - args: CatArgs { - mod_hash: CAT_PUZZLE_HASH.into(), - asset_id, - inner_puzzle, - }, - } - .tree_hash() - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(curry)] -pub struct EverythingWithSignatureTailArgs { - pub public_key: PublicKey, -} - -impl EverythingWithSignatureTailArgs { - pub fn new(public_key: PublicKey) -> Self { - Self { public_key } - } - - pub fn curry_tree_hash(public_key: PublicKey) -> TreeHash { - CurriedProgram { - program: EVERYTHING_WITH_SIGNATURE_TAIL_PUZZLE_HASH, - args: EverythingWithSignatureTailArgs { public_key }, - } - .tree_hash() - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(curry)] -pub struct GenesisByCoinIdTailArgs { - pub genesis_coin_id: Bytes32, -} - -impl GenesisByCoinIdTailArgs { - pub fn new(genesis_coin_id: Bytes32) -> Self { - Self { genesis_coin_id } - } - - pub fn curry_tree_hash(genesis_coin_id: Bytes32) -> TreeHash { - CurriedProgram { - program: GENESIS_BY_COIN_ID_TAIL_PUZZLE_HASH, - args: GenesisByCoinIdTailArgs { genesis_coin_id }, - } - .tree_hash() - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(solution)] -pub struct CatSolution { - pub inner_puzzle_solution: I, - pub lineage_proof: Option, - pub prev_coin_id: Bytes32, - pub this_coin_info: Coin, - pub next_coin_proof: CoinProof, - pub prev_subtotal: i64, - pub extra_delta: i64, -} - -/// This is the puzzle reveal of the [CAT2 standard](https://chialisp.com/cats) puzzle. -pub const CAT_PUZZLE: [u8; 1672] = hex!( - " - ff02ffff01ff02ff5effff04ff02ffff04ffff04ff05ffff04ffff0bff34ff05 - 80ffff04ff0bff80808080ffff04ffff02ff17ff2f80ffff04ff5fffff04ffff - 02ff2effff04ff02ffff04ff17ff80808080ffff04ffff02ff2affff04ff02ff - ff04ff82027fffff04ff82057fffff04ff820b7fff808080808080ffff04ff81 - bfffff04ff82017fffff04ff8202ffffff04ff8205ffffff04ff820bffff8080 - 8080808080808080808080ffff04ffff01ffffffff3d46ff02ff333cffff0401 - ff01ff81cb02ffffff20ff02ffff03ff05ffff01ff02ff32ffff04ff02ffff04 - ff0dffff04ffff0bff7cffff0bff34ff2480ffff0bff7cffff0bff7cffff0bff - 34ff2c80ff0980ffff0bff7cff0bffff0bff34ff8080808080ff8080808080ff - ff010b80ff0180ffff02ffff03ffff22ffff09ffff0dff0580ff2280ffff09ff - ff0dff0b80ff2280ffff15ff17ffff0181ff8080ffff01ff0bff05ff0bff1780 - ffff01ff088080ff0180ffff02ffff03ff0bffff01ff02ffff03ffff09ffff02 - ff2effff04ff02ffff04ff13ff80808080ff820b9f80ffff01ff02ff56ffff04 - ff02ffff04ffff02ff13ffff04ff5fffff04ff17ffff04ff2fffff04ff81bfff - ff04ff82017fffff04ff1bff8080808080808080ffff04ff82017fff80808080 - 80ffff01ff088080ff0180ffff01ff02ffff03ff17ffff01ff02ffff03ffff20 - ff81bf80ffff0182017fffff01ff088080ff0180ffff01ff088080ff018080ff - 0180ff04ffff04ff05ff2780ffff04ffff10ff0bff5780ff778080ffffff02ff - ff03ff05ffff01ff02ffff03ffff09ffff02ffff03ffff09ff11ff5880ffff01 - 59ff8080ff0180ffff01818f80ffff01ff02ff26ffff04ff02ffff04ff0dffff - 04ff0bffff04ffff04ff81b9ff82017980ff808080808080ffff01ff02ff7aff - ff04ff02ffff04ffff02ffff03ffff09ff11ff5880ffff01ff04ff58ffff04ff - ff02ff76ffff04ff02ffff04ff13ffff04ff29ffff04ffff0bff34ff5b80ffff - 04ff2bff80808080808080ff398080ffff01ff02ffff03ffff09ff11ff7880ff - ff01ff02ffff03ffff20ffff02ffff03ffff09ffff0121ffff0dff298080ffff - 01ff02ffff03ffff09ffff0cff29ff80ff3480ff5c80ffff01ff0101ff8080ff - 0180ff8080ff018080ffff0109ffff01ff088080ff0180ffff010980ff018080 - ff0180ffff04ffff02ffff03ffff09ff11ff5880ffff0159ff8080ff0180ffff - 04ffff02ff26ffff04ff02ffff04ff0dffff04ff0bffff04ff17ff8080808080 - 80ff80808080808080ff0180ffff01ff04ff80ffff04ff80ff17808080ff0180 - ffff02ffff03ff05ffff01ff04ff09ffff02ff56ffff04ff02ffff04ff0dffff - 04ff0bff808080808080ffff010b80ff0180ff0bff7cffff0bff34ff2880ffff - 0bff7cffff0bff7cffff0bff34ff2c80ff0580ffff0bff7cffff02ff32ffff04 - ff02ffff04ff07ffff04ffff0bff34ff3480ff8080808080ffff0bff34ff8080 - 808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04 - ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff80808080 - 80ffff01ff0bffff0101ff058080ff0180ffff04ffff04ff30ffff04ff5fff80 - 8080ffff02ff7effff04ff02ffff04ffff04ffff04ff2fff0580ffff04ff5fff - 82017f8080ffff04ffff02ff26ffff04ff02ffff04ff0bffff04ff05ffff01ff - 808080808080ffff04ff17ffff04ff81bfffff04ff82017fffff04ffff02ff2a - ffff04ff02ffff04ff8204ffffff04ffff02ff76ffff04ff02ffff04ff09ffff - 04ff820affffff04ffff0bff34ff2d80ffff04ff15ff80808080808080ffff04 - ff8216ffff808080808080ffff04ff8205ffffff04ff820bffff808080808080 - 808080808080ff02ff5affff04ff02ffff04ff5fffff04ff3bffff04ffff02ff - ff03ff17ffff01ff09ff2dffff02ff2affff04ff02ffff04ff27ffff04ffff02 - ff76ffff04ff02ffff04ff29ffff04ff57ffff04ffff0bff34ff81b980ffff04 - ff59ff80808080808080ffff04ff81b7ff80808080808080ff8080ff0180ffff - 04ff17ffff04ff05ffff04ff8202ffffff04ffff04ffff04ff78ffff04ffff0e - ff5cffff02ff2effff04ff02ffff04ffff04ff2fffff04ff82017fff808080ff - 8080808080ff808080ffff04ffff04ff20ffff04ffff0bff81bfff5cffff02ff - 2effff04ff02ffff04ffff04ff15ffff04ffff10ff82017fffff11ff8202dfff - 2b80ff8202ff80ff808080ff8080808080ff808080ff138080ff808080808080 - 80808080ff018080 - " -); - -/// This is the puzzle hash of the [CAT2 standard](https://chialisp.com/cats) puzzle. -pub const CAT_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - 37bef360ee858133b69d595a906dc45d01af50379dad515eb9518abb7c1d2a7a - " -)); - -/// This is the puzzle reveal of the [CAT2 multi-issuance TAIL](https://chialisp.com/cats#multi) puzzle. -pub const EVERYTHING_WITH_SIGNATURE_TAIL_PUZZLE: [u8; 41] = hex!( - " - ff02ffff01ff04ffff04ff02ffff04ff05ffff04ff5fff80808080ff8080ffff - 04ffff0132ff018080 - " -); - -/// This is the puzzle hash of the [CAT2 multi-issuance TAIL](https://chialisp.com/cats#multi) puzzle. -pub const EVERYTHING_WITH_SIGNATURE_TAIL_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - 1720d13250a7c16988eaf530331cefa9dd57a76b2c82236bec8bbbff91499b89 - " -)); - -/// This is the puzzle reveal of the [CAT2 single-issuance TAIL](https://chialisp.com/cats/#single) puzzle. -pub const GENESIS_BY_COIN_ID_TAIL_PUZZLE: [u8; 45] = hex!( - " - ff02ffff03ff2fffff01ff0880ffff01ff02ffff03ffff09ff2dff0280ff80ff - ff01ff088080ff018080ff0180 - " -); - -/// This is the puzzle hash of the [CAT2 single-issuance TAIL](https://chialisp.com/cats/#single) puzzle. -pub const GENESIS_BY_COIN_ID_TAIL_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - 493afb89eed93ab86741b2aa61b8f5de495d33ff9b781dfc8919e602b2afa150 - " -)); - -/// This is the puzzle reveal of the old [CAT1 standard](https://chialisp.com/cats) puzzle. -/// -/// **Warning:** -/// It is recommended not to use CAT1 for anything other than backwards compatibility (e.g. offer compression), -/// due to security issues uncovered in an audit. You can read more about the vulnerability that prompted the creation -/// of CAT2 in the [CATbleed Post Mortem](https://github.com/Chia-Network/post-mortem/blob/main/2022-08/2022-08-19-CATbleed.md). -pub const CAT_PUZZLE_V1: [u8; 1420] = hex!( - " - ff02ffff01ff02ff5effff04ff02ffff04ffff04ff05ffff04ffff0bff2cff05 - 80ffff04ff0bff80808080ffff04ffff02ff17ff2f80ffff04ff5fffff04ffff - 02ff2effff04ff02ffff04ff17ff80808080ffff04ffff0bff82027fff82057f - ff820b7f80ffff04ff81bfffff04ff82017fffff04ff8202ffffff04ff8205ff - ffff04ff820bffff80808080808080808080808080ffff04ffff01ffffffff81 - ca3dff46ff0233ffff3c04ff01ff0181cbffffff02ff02ffff03ff05ffff01ff - 02ff32ffff04ff02ffff04ff0dffff04ffff0bff22ffff0bff2cff3480ffff0b - ff22ffff0bff22ffff0bff2cff5c80ff0980ffff0bff22ff0bffff0bff2cff80 - 80808080ff8080808080ffff010b80ff0180ffff02ffff03ff0bffff01ff02ff - ff03ffff09ffff02ff2effff04ff02ffff04ff13ff80808080ff820b9f80ffff - 01ff02ff26ffff04ff02ffff04ffff02ff13ffff04ff5fffff04ff17ffff04ff - 2fffff04ff81bfffff04ff82017fffff04ff1bff8080808080808080ffff04ff - 82017fff8080808080ffff01ff088080ff0180ffff01ff02ffff03ff17ffff01 - ff02ffff03ffff20ff81bf80ffff0182017fffff01ff088080ff0180ffff01ff - 088080ff018080ff0180ffff04ffff04ff05ff2780ffff04ffff10ff0bff5780 - ff778080ff02ffff03ff05ffff01ff02ffff03ffff09ffff02ffff03ffff09ff - 11ff7880ffff0159ff8080ff0180ffff01818f80ffff01ff02ff7affff04ff02 - ffff04ff0dffff04ff0bffff04ffff04ff81b9ff82017980ff808080808080ff - ff01ff02ff5affff04ff02ffff04ffff02ffff03ffff09ff11ff7880ffff01ff - 04ff78ffff04ffff02ff36ffff04ff02ffff04ff13ffff04ff29ffff04ffff0b - ff2cff5b80ffff04ff2bff80808080808080ff398080ffff01ff02ffff03ffff - 09ff11ff2480ffff01ff04ff24ffff04ffff0bff20ff2980ff398080ffff0109 - 80ff018080ff0180ffff04ffff02ffff03ffff09ff11ff7880ffff0159ff8080 - ff0180ffff04ffff02ff7affff04ff02ffff04ff0dffff04ff0bffff04ff17ff - 808080808080ff80808080808080ff0180ffff01ff04ff80ffff04ff80ff1780 - 8080ff0180ffffff02ffff03ff05ffff01ff04ff09ffff02ff26ffff04ff02ff - ff04ff0dffff04ff0bff808080808080ffff010b80ff0180ff0bff22ffff0bff - 2cff5880ffff0bff22ffff0bff22ffff0bff2cff5c80ff0580ffff0bff22ffff - 02ff32ffff04ff02ffff04ff07ffff04ffff0bff2cff2c80ff8080808080ffff - 0bff2cff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff - 02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff - 0dff8080808080ffff01ff0bff2cff058080ff0180ffff04ffff04ff28ffff04 - ff5fff808080ffff02ff7effff04ff02ffff04ffff04ffff04ff2fff0580ffff - 04ff5fff82017f8080ffff04ffff02ff7affff04ff02ffff04ff0bffff04ff05 - ffff01ff808080808080ffff04ff17ffff04ff81bfffff04ff82017fffff04ff - ff0bff8204ffffff02ff36ffff04ff02ffff04ff09ffff04ff820affffff04ff - ff0bff2cff2d80ffff04ff15ff80808080808080ff8216ff80ffff04ff8205ff - ffff04ff820bffff808080808080808080808080ff02ff2affff04ff02ffff04 - ff5fffff04ff3bffff04ffff02ffff03ff17ffff01ff09ff2dffff0bff27ffff - 02ff36ffff04ff02ffff04ff29ffff04ff57ffff04ffff0bff2cff81b980ffff - 04ff59ff80808080808080ff81b78080ff8080ff0180ffff04ff17ffff04ff05 - ffff04ff8202ffffff04ffff04ffff04ff24ffff04ffff0bff7cff2fff82017f - 80ff808080ffff04ffff04ff30ffff04ffff0bff81bfffff0bff7cff15ffff10 - ff82017fffff11ff8202dfff2b80ff8202ff808080ff808080ff138080ff8080 - 8080808080808080ff018080 - " -); - -/// This is the puzzle hash of the old [CAT1 standard](https://chialisp.com/cats) puzzle. -/// -/// **Warning:** -/// It is recommended not to use CAT1 for anything other than backwards compatibility (e.g. offer compression), -/// due to security issues uncovered in an audit. You can read more about the vulnerability that prompted the creation -/// of CAT2 in the [CATbleed Post Mortem](https://github.com/Chia-Network/post-mortem/blob/main/2022-08/2022-08-19-CATbleed.md). -pub const CAT_PUZZLE_HASH_V1: TreeHash = TreeHash::new(hex!( - " - 72dec062874cd4d3aab892a0906688a1ae412b0109982e1797a170add88bdcdc - " -)); - -#[cfg(test)] -mod tests { - use clvm_traits::ToClvm; - use clvm_utils::tree_hash; - use clvmr::{serde::node_from_bytes, Allocator}; - - use super::*; - - use crate::{ - assert_puzzle_hash, - standard::{StandardArgs, STANDARD_PUZZLE}, - }; - - #[test] - fn puzzle_hashes() { - assert_puzzle_hash!(CAT_PUZZLE => CAT_PUZZLE_HASH); - assert_puzzle_hash!(CAT_PUZZLE_V1 => CAT_PUZZLE_HASH_V1); - assert_puzzle_hash!(EVERYTHING_WITH_SIGNATURE_TAIL_PUZZLE => EVERYTHING_WITH_SIGNATURE_TAIL_PUZZLE_HASH); - assert_puzzle_hash!(GENESIS_BY_COIN_ID_TAIL_PUZZLE => GENESIS_BY_COIN_ID_TAIL_PUZZLE_HASH); - } - - #[test] - fn curry_cat_tree_hash() { - let synthetic_key = PublicKey::default(); - let asset_id = Bytes32::new([120; 32]); - - let mut a = Allocator::new(); - let mod_ptr = node_from_bytes(&mut a, &CAT_PUZZLE).unwrap(); - let inner_mod_ptr = node_from_bytes(&mut a, &STANDARD_PUZZLE).unwrap(); - - let curried_ptr = CurriedProgram { - program: mod_ptr, - args: CatArgs::new( - asset_id, - CurriedProgram { - program: inner_mod_ptr, - args: StandardArgs::new(synthetic_key), - }, - ), - } - .to_clvm(&mut a) - .unwrap(); - - let allocated_tree_hash = hex::encode(tree_hash(&a, curried_ptr)); - - let inner_puzzle_hash = StandardArgs::curry_tree_hash(synthetic_key); - let tree_hash = hex::encode(CatArgs::curry_tree_hash(asset_id, inner_puzzle_hash)); - - assert_eq!(allocated_tree_hash, tree_hash); - } - - #[test] - fn curry_everything_with_signature() { - let public_key = PublicKey::default(); - - let mut a = Allocator::new(); - let mod_ptr = node_from_bytes(&mut a, &EVERYTHING_WITH_SIGNATURE_TAIL_PUZZLE).unwrap(); - - let curried_ptr = CurriedProgram { - program: mod_ptr, - args: EverythingWithSignatureTailArgs::new(public_key), - } - .to_clvm(&mut a) - .unwrap(); - - let allocated_tree_hash = hex::encode(tree_hash(&a, curried_ptr)); - - let tree_hash = hex::encode(EverythingWithSignatureTailArgs::curry_tree_hash(public_key)); - - assert_eq!(allocated_tree_hash, tree_hash); - } - - #[test] - fn curry_genesis_by_coin_id() { - let genesis_coin_id = Bytes32::new([120; 32]); - - let mut a = Allocator::new(); - let mod_ptr = node_from_bytes(&mut a, &GENESIS_BY_COIN_ID_TAIL_PUZZLE).unwrap(); - - let curried_ptr = CurriedProgram { - program: mod_ptr, - args: GenesisByCoinIdTailArgs::new(genesis_coin_id), - } - .to_clvm(&mut a) - .unwrap(); - - let allocated_tree_hash = hex::encode(tree_hash(&a, curried_ptr)); - - let tree_hash = hex::encode(GenesisByCoinIdTailArgs::curry_tree_hash(genesis_coin_id)); - - assert_eq!(allocated_tree_hash, tree_hash); - } -} diff --git a/crates/chia-puzzles/src/puzzles/did.rs b/crates/chia-puzzles/src/puzzles/did.rs deleted file mode 100644 index f5b5d5442..000000000 --- a/crates/chia-puzzles/src/puzzles/did.rs +++ /dev/null @@ -1,178 +0,0 @@ -use chia_bls::PublicKey; -use chia_protocol::Bytes32; -use clvm_traits::{FromClvm, ToClvm}; -use clvm_utils::{CurriedProgram, ToTreeHash, TreeHash}; -use hex_literal::hex; - -use crate::{singleton::SingletonStruct, CoinProof}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(curry)] -pub struct DidArgs { - pub inner_puzzle: I, - pub recovery_list_hash: Option, - pub num_verifications_required: u64, - pub singleton_struct: SingletonStruct, - pub metadata: M, -} - -impl DidArgs { - pub fn new( - inner_puzzle: I, - recovery_list_hash: Option, - num_verifications_required: u64, - singleton_struct: SingletonStruct, - metadata: M, - ) -> Self { - Self { - inner_puzzle, - recovery_list_hash, - num_verifications_required, - singleton_struct, - metadata, - } - } -} - -impl DidArgs { - pub fn curry_tree_hash( - inner_puzzle: TreeHash, - recovery_list_hash: Option, - num_verifications_required: u64, - singleton_struct: SingletonStruct, - metadata: TreeHash, - ) -> TreeHash { - CurriedProgram { - program: DID_INNER_PUZZLE_HASH, - args: DidArgs { - inner_puzzle, - recovery_list_hash, - num_verifications_required, - singleton_struct, - metadata, - }, - } - .tree_hash() - } -} - -#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(solution)] -#[repr(u8)] -pub enum DidSolution { - Recover(#[clvm(rest)] Box) = 0, - Spend(I) = 1, -} - -#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(solution)] -pub struct DidRecoverySolution { - pub amount: u64, - pub new_inner_puzzle_hash: Bytes32, - pub recovery_coins: Vec, - pub public_key: PublicKey, - pub recovery_list_reveal: Vec, -} - -/// This is the puzzle reveal of the [DID1 standard](https://chialisp.com/dids) puzzle. -pub const DID_INNER_PUZZLE: [u8; 1012] = hex!( - " - ff02ffff01ff02ffff03ff81bfffff01ff02ff05ff82017f80ffff01ff02ffff - 03ffff22ffff09ffff02ff7effff04ff02ffff04ff8217ffff80808080ff0b80 - ffff15ff17ff808080ffff01ff04ffff04ff28ffff04ff82017fff808080ffff - 04ffff04ff34ffff04ff8202ffffff04ff82017fffff04ffff04ff8202ffff80 - 80ff8080808080ffff04ffff04ff38ffff04ff822fffff808080ffff02ff26ff - ff04ff02ffff04ff2fffff04ff17ffff04ff8217ffffff04ff822fffffff04ff - 8202ffffff04ff8205ffffff04ff820bffffff01ff8080808080808080808080 - 808080ffff01ff088080ff018080ff0180ffff04ffff01ffffffff313dff4946 - ffff0233ff3c04ffffff0101ff02ff02ffff03ff05ffff01ff02ff3affff04ff - 02ffff04ff0dffff04ffff0bff2affff0bff22ff3c80ffff0bff2affff0bff2a - ffff0bff22ff3280ff0980ffff0bff2aff0bffff0bff22ff8080808080ff8080 - 808080ffff010b80ff0180ffffff02ffff03ff17ffff01ff02ffff03ff82013f - ffff01ff04ffff04ff30ffff04ffff0bffff0bffff02ff36ffff04ff02ffff04 - ff05ffff04ff27ffff04ff82023fffff04ff82053fffff04ff820b3fff808080 - 8080808080ffff02ff7effff04ff02ffff04ffff02ff2effff04ff02ffff04ff - 2fffff04ff5fffff04ff82017fff808080808080ff8080808080ff2f80ff8080 - 80ffff02ff26ffff04ff02ffff04ff05ffff04ff0bffff04ff37ffff04ff2fff - ff04ff5fffff04ff8201bfffff04ff82017fffff04ffff10ff8202ffffff0101 - 80ff808080808080808080808080ffff01ff02ff26ffff04ff02ffff04ff05ff - ff04ff37ffff04ff2fffff04ff5fffff04ff8201bfffff04ff82017fffff04ff - 8202ffff8080808080808080808080ff0180ffff01ff02ffff03ffff15ff8202 - ffffff11ff0bffff01018080ffff01ff04ffff04ff20ffff04ff82017fffff04 - ff5fff80808080ff8080ffff01ff088080ff018080ff0180ff0bff17ffff02ff - 5effff04ff02ffff04ff09ffff04ff2fffff04ffff02ff7effff04ff02ffff04 - ffff04ff09ffff04ff0bff1d8080ff80808080ff808080808080ff5f80ffff04 - ffff0101ffff04ffff04ff2cffff04ff05ff808080ffff04ffff04ff20ffff04 - ff17ffff04ff0bff80808080ff80808080ffff0bff2affff0bff22ff2480ffff - 0bff2affff0bff2affff0bff22ff3280ff0580ffff0bff2affff02ff3affff04 - ff02ffff04ff07ffff04ffff0bff22ff2280ff8080808080ffff0bff22ff8080 - 808080ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff7effff04ff - 02ffff04ff09ff80808080ffff02ff7effff04ff02ffff04ff0dff8080808080 - ffff01ff0bffff0101ff058080ff0180ff018080 - " -); - -/// This is the puzzle hash of the [DID1 standard](https://chialisp.com/dids) puzzle. -pub const DID_INNER_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - 33143d2bef64f14036742673afd158126b94284b4530a28c354fac202b0c910e - " -)); - -#[cfg(test)] -mod tests { - use clvm_traits::{clvm_list, match_list}; - use clvmr::{ - run_program, - serde::{node_from_bytes, node_to_bytes}, - Allocator, ChiaDialect, - }; - - use super::*; - - use crate::assert_puzzle_hash; - - #[test] - fn puzzle_hashes() { - assert_puzzle_hash!(DID_INNER_PUZZLE => DID_INNER_PUZZLE_HASH); - } - - #[test] - fn did_solution() { - let a = &mut Allocator::new(); - - let ptr = clvm_list!(1, clvm_list!(42, "test")).to_clvm(a).unwrap(); - let did_solution = DidSolution::::from_clvm(a, ptr).unwrap(); - assert_eq!( - did_solution, - DidSolution::Spend(clvm_list!(42, "test".to_string())) - ); - - let puzzle = node_from_bytes(a, &DID_INNER_PUZZLE).unwrap(); - let curried = CurriedProgram { - program: puzzle, - args: DidArgs::new(1, None, 1, SingletonStruct::new(Bytes32::default()), ()), - } - .to_clvm(a) - .unwrap(); - - let output = run_program(a, &ChiaDialect::new(0), curried, ptr, u64::MAX) - .expect("could not run did puzzle and solution"); - assert_eq!( - hex::encode(node_to_bytes(a, output.1).unwrap()), - "ff2aff847465737480" - ); - } - - #[test] - fn did_solution_roundtrip() { - let a = &mut Allocator::new(); - let did_solution = DidSolution::Spend(a.nil()); - let ptr = did_solution.to_clvm(a).unwrap(); - let roundtrip = DidSolution::from_clvm(a, ptr).unwrap(); - assert_eq!(did_solution, roundtrip); - } -} diff --git a/crates/chia-puzzles/src/puzzles/nft.rs b/crates/chia-puzzles/src/puzzles/nft.rs deleted file mode 100644 index b092e2dd1..000000000 --- a/crates/chia-puzzles/src/puzzles/nft.rs +++ /dev/null @@ -1,435 +0,0 @@ -use chia_protocol::Bytes32; -use clvm_traits::{ClvmDecoder, ClvmEncoder, FromClvm, FromClvmError, Raw, ToClvm, ToClvmError}; -use clvm_utils::{CurriedProgram, ToTreeHash, TreeHash}; -use hex_literal::hex; - -use crate::singleton::{SingletonStruct, SINGLETON_LAUNCHER_PUZZLE_HASH}; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(curry)] -pub struct NftIntermediateLauncherArgs { - pub launcher_puzzle_hash: Bytes32, - pub mint_number: usize, - pub mint_total: usize, -} - -impl NftIntermediateLauncherArgs { - pub fn new(mint_number: usize, mint_total: usize) -> Self { - Self { - launcher_puzzle_hash: SINGLETON_LAUNCHER_PUZZLE_HASH.into(), - mint_number, - mint_total, - } - } - - pub fn curry_tree_hash(mint_number: usize, mint_total: usize) -> TreeHash { - CurriedProgram { - program: NFT_INTERMEDIATE_LAUNCHER_PUZZLE_HASH, - args: NftIntermediateLauncherArgs { - launcher_puzzle_hash: SINGLETON_LAUNCHER_PUZZLE_HASH.into(), - mint_number, - mint_total, - }, - } - .tree_hash() - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(curry)] -pub struct NftStateLayerArgs { - pub mod_hash: Bytes32, - pub metadata: M, - pub metadata_updater_puzzle_hash: Bytes32, - pub inner_puzzle: I, -} - -impl NftStateLayerArgs { - pub fn new(metadata: M, inner_puzzle: I) -> Self { - Self { - mod_hash: NFT_STATE_LAYER_PUZZLE_HASH.into(), - metadata, - metadata_updater_puzzle_hash: NFT_METADATA_UPDATER_PUZZLE_HASH.into(), - inner_puzzle, - } - } -} - -impl NftStateLayerArgs { - pub fn curry_tree_hash(metadata: TreeHash, inner_puzzle: TreeHash) -> TreeHash { - CurriedProgram { - program: NFT_STATE_LAYER_PUZZLE_HASH, - args: NftStateLayerArgs { - mod_hash: NFT_STATE_LAYER_PUZZLE_HASH.into(), - metadata, - metadata_updater_puzzle_hash: NFT_METADATA_UPDATER_PUZZLE_HASH.into(), - inner_puzzle, - }, - } - .tree_hash() - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(solution)] -pub struct NftStateLayerSolution { - pub inner_solution: I, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(curry)] -pub struct NftOwnershipLayerArgs { - pub mod_hash: Bytes32, - pub current_owner: Option, - pub transfer_program: P, - pub inner_puzzle: I, -} - -impl NftOwnershipLayerArgs { - pub fn new(current_owner: Option, transfer_program: P, inner_puzzle: I) -> Self { - Self { - mod_hash: NFT_OWNERSHIP_LAYER_PUZZLE_HASH.into(), - current_owner, - transfer_program, - inner_puzzle, - } - } -} - -impl NftOwnershipLayerArgs { - pub fn curry_tree_hash( - current_owner: Option, - transfer_program: TreeHash, - inner_puzzle: TreeHash, - ) -> TreeHash { - CurriedProgram { - program: NFT_OWNERSHIP_LAYER_PUZZLE_HASH, - args: NftOwnershipLayerArgs { - mod_hash: NFT_OWNERSHIP_LAYER_PUZZLE_HASH.into(), - current_owner, - transfer_program, - inner_puzzle, - }, - } - .tree_hash() - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(solution)] -pub struct NftOwnershipLayerSolution { - pub inner_solution: I, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(curry)] -pub struct NftRoyaltyTransferPuzzleArgs { - pub singleton_struct: SingletonStruct, - pub royalty_puzzle_hash: Bytes32, - /// The royalty percentage expressed as ten-thousandths. - /// For example, 300 represents 3%. - pub royalty_ten_thousandths: u16, -} - -impl NftRoyaltyTransferPuzzleArgs { - pub fn new( - launcher_id: Bytes32, - royalty_puzzle_hash: Bytes32, - royalty_ten_thousandths: u16, - ) -> Self { - Self { - singleton_struct: SingletonStruct::new(launcher_id), - royalty_puzzle_hash, - royalty_ten_thousandths, - } - } - - pub fn curry_tree_hash( - launcher_id: Bytes32, - royalty_puzzle_hash: Bytes32, - royalty_ten_thousandths: u16, - ) -> TreeHash { - CurriedProgram { - program: NFT_ROYALTY_TRANSFER_PUZZLE_HASH, - args: NftRoyaltyTransferPuzzleArgs { - singleton_struct: SingletonStruct::new(launcher_id), - royalty_puzzle_hash, - royalty_ten_thousandths, - }, - } - .tree_hash() - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -pub struct NftMetadata { - pub edition_number: u64, - pub edition_total: u64, - pub data_uris: Vec, - pub data_hash: Option, - pub metadata_uris: Vec, - pub metadata_hash: Option, - pub license_uris: Vec, - pub license_hash: Option, -} - -impl Default for NftMetadata { - fn default() -> Self { - Self { - edition_number: 1, - edition_total: 1, - data_uris: Vec::new(), - data_hash: None, - metadata_uris: Vec::new(), - metadata_hash: None, - license_uris: Vec::new(), - license_hash: None, - } - } -} - -impl> FromClvm for NftMetadata { - fn from_clvm(decoder: &D, node: N) -> Result { - let items: Vec<(String, Raw)> = FromClvm::from_clvm(decoder, node)?; - let mut metadata = Self::default(); - - for (key, value_ptr) in items { - match key.as_str() { - "sn" => metadata.edition_number = FromClvm::from_clvm(decoder, value_ptr.0)?, - "st" => metadata.edition_total = FromClvm::from_clvm(decoder, value_ptr.0)?, - "u" => metadata.data_uris = FromClvm::from_clvm(decoder, value_ptr.0)?, - "h" => metadata.data_hash = FromClvm::from_clvm(decoder, value_ptr.0)?, - "mu" => metadata.metadata_uris = FromClvm::from_clvm(decoder, value_ptr.0)?, - "mh" => metadata.metadata_hash = FromClvm::from_clvm(decoder, value_ptr.0)?, - "lu" => metadata.license_uris = FromClvm::from_clvm(decoder, value_ptr.0)?, - "lh" => metadata.license_hash = FromClvm::from_clvm(decoder, value_ptr.0)?, - _ => (), - } - } - - Ok(metadata) - } -} - -impl> ToClvm for NftMetadata { - fn to_clvm(&self, encoder: &mut E) -> Result { - let mut items: Vec<(&str, Raw)> = Vec::new(); - - if !self.data_uris.is_empty() { - items.push(("u", Raw(self.data_uris.to_clvm(encoder)?))); - } - - if let Some(hash) = self.data_hash { - items.push(("h", Raw(hash.to_clvm(encoder)?))); - } - - if !self.metadata_uris.is_empty() { - items.push(("mu", Raw(self.metadata_uris.to_clvm(encoder)?))); - } - - if let Some(hash) = self.metadata_hash { - items.push(("mh", Raw(hash.to_clvm(encoder)?))); - } - - if !self.license_uris.is_empty() { - items.push(("lu", Raw(self.license_uris.to_clvm(encoder)?))); - } - - if let Some(hash) = self.license_hash { - items.push(("lh", Raw(hash.to_clvm(encoder)?))); - } - - items.extend(vec![ - ("sn", Raw(self.edition_number.to_clvm(encoder)?)), - ("st", Raw(self.edition_total.to_clvm(encoder)?)), - ]); - - items.to_clvm(encoder) - } -} - -/// This is the puzzle reveal of the [NFT1 state layer](https://chialisp.com/nfts) puzzle. -pub const NFT_STATE_LAYER_PUZZLE: [u8; 827] = hex!( - " - ff02ffff01ff02ff3effff04ff02ffff04ff05ffff04ffff02ff2fff5f80ffff - 04ff80ffff04ffff04ffff04ff0bffff04ff17ff808080ffff01ff808080ffff - 01ff8080808080808080ffff04ffff01ffffff0233ff04ff0101ffff02ff02ff - ff03ff05ffff01ff02ff1affff04ff02ffff04ff0dffff04ffff0bff12ffff0b - ff2cff1480ffff0bff12ffff0bff12ffff0bff2cff3c80ff0980ffff0bff12ff - 0bffff0bff2cff8080808080ff8080808080ffff010b80ff0180ffff0bff12ff - ff0bff2cff1080ffff0bff12ffff0bff12ffff0bff2cff3c80ff0580ffff0bff - 12ffff02ff1affff04ff02ffff04ff07ffff04ffff0bff2cff2c80ff80808080 - 80ffff0bff2cff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff01 - 02ffff02ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ff - ff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff02ffff03ff - 0bffff01ff02ffff03ffff09ff23ff1880ffff01ff02ffff03ffff18ff81b3ff - 2c80ffff01ff02ffff03ffff20ff1780ffff01ff02ff3effff04ff02ffff04ff - 05ffff04ff1bffff04ff33ffff04ff2fffff04ff5fff8080808080808080ffff - 01ff088080ff0180ffff01ff04ff13ffff02ff3effff04ff02ffff04ff05ffff - 04ff1bffff04ff17ffff04ff2fffff04ff5fff80808080808080808080ff0180 - ffff01ff02ffff03ffff09ff23ffff0181e880ffff01ff02ff3effff04ff02ff - ff04ff05ffff04ff1bffff04ff17ffff04ffff02ffff03ffff22ffff09ffff02 - ff2effff04ff02ffff04ff53ff80808080ff82014f80ffff20ff5f8080ffff01 - ff02ff53ffff04ff818fffff04ff82014fffff04ff81b3ff8080808080ffff01 - ff088080ff0180ffff04ff2cff8080808080808080ffff01ff04ff13ffff02ff - 3effff04ff02ffff04ff05ffff04ff1bffff04ff17ffff04ff2fffff04ff5fff - 80808080808080808080ff018080ff0180ffff01ff04ffff04ff18ffff04ffff - 02ff16ffff04ff02ffff04ff05ffff04ff27ffff04ffff0bff2cff82014f80ff - ff04ffff02ff2effff04ff02ffff04ff818fff80808080ffff04ffff0bff2cff - 0580ff8080808080808080ff378080ff81af8080ff0180ff018080 - " -); - -/// This is the puzzle hash of the [NFT1 state layer](https://chialisp.com/nfts) puzzle. -pub const NFT_STATE_LAYER_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - a04d9f57764f54a43e4030befb4d80026e870519aaa66334aef8304f5d0393c2 - " -)); - -/// This is the puzzle reveal of the [NFT1 ownership layer](https://chialisp.com/nfts) puzzle. -pub const NFT_OWNERSHIP_LAYER_PUZZLE: [u8; 1226] = hex!( - " - ff02ffff01ff02ff26ffff04ff02ffff04ff05ffff04ff17ffff04ff0bffff04 - ffff02ff2fff5f80ff80808080808080ffff04ffff01ffffff82ad4cff0233ff - ff3e04ff81f601ffffff0102ffff02ffff03ff05ffff01ff02ff2affff04ff02 - ffff04ff0dffff04ffff0bff32ffff0bff3cff3480ffff0bff32ffff0bff32ff - ff0bff3cff2280ff0980ffff0bff32ff0bffff0bff3cff8080808080ff808080 - 8080ffff010b80ff0180ff04ffff04ff38ffff04ffff02ff36ffff04ff02ffff - 04ff05ffff04ff27ffff04ffff02ff2effff04ff02ffff04ffff02ffff03ff81 - afffff0181afffff010b80ff0180ff80808080ffff04ffff0bff3cff4f80ffff - 04ffff0bff3cff0580ff8080808080808080ff378080ff82016f80ffffff02ff - 3effff04ff02ffff04ff05ffff04ff0bffff04ff17ffff04ff2fffff04ff2fff - ff01ff80ff808080808080808080ff0bff32ffff0bff3cff2880ffff0bff32ff - ff0bff32ffff0bff3cff2280ff0580ffff0bff32ffff02ff2affff04ff02ffff - 04ff07ffff04ffff0bff3cff3c80ff8080808080ffff0bff3cff8080808080ff - ff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff2effff04ff02ffff - 04ff09ff80808080ffff02ff2effff04ff02ffff04ff0dff8080808080ffff01 - ff0bffff0101ff058080ff0180ff02ffff03ff5fffff01ff02ffff03ffff09ff - 82011fff3880ffff01ff02ffff03ffff09ffff18ff82059f80ff3c80ffff01ff - 02ffff03ffff20ff81bf80ffff01ff02ff3effff04ff02ffff04ff05ffff04ff - 0bffff04ff17ffff04ff2fffff04ff81dfffff04ff82019fffff04ff82017fff - 80808080808080808080ffff01ff088080ff0180ffff01ff04ff819fffff02ff - 3effff04ff02ffff04ff05ffff04ff0bffff04ff17ffff04ff2fffff04ff81df - ffff04ff81bfffff04ff82017fff808080808080808080808080ff0180ffff01 - ff02ffff03ffff09ff82011fff2c80ffff01ff02ffff03ffff20ff82017f80ff - ff01ff04ffff04ff24ffff04ffff0eff10ffff02ff2effff04ff02ffff04ff82 - 019fff8080808080ff808080ffff02ff3effff04ff02ffff04ff05ffff04ff0b - ffff04ff17ffff04ff2fffff04ff81dfffff04ff81bfffff04ffff02ff0bffff - 04ff17ffff04ff2fffff04ff82019fff8080808080ff80808080808080808080 - 80ffff01ff088080ff0180ffff01ff02ffff03ffff09ff82011fff2480ffff01 - ff02ffff03ffff20ffff02ffff03ffff09ffff0122ffff0dff82029f8080ffff - 01ff02ffff03ffff09ffff0cff82029fff80ffff010280ff1080ffff01ff0101 - ff8080ff0180ff8080ff018080ffff01ff04ff819fffff02ff3effff04ff02ff - ff04ff05ffff04ff0bffff04ff17ffff04ff2fffff04ff81dfffff04ff81bfff - ff04ff82017fff8080808080808080808080ffff01ff088080ff0180ffff01ff - 04ff819fffff02ff3effff04ff02ffff04ff05ffff04ff0bffff04ff17ffff04 - ff2fffff04ff81dfffff04ff81bfffff04ff82017fff80808080808080808080 - 8080ff018080ff018080ff0180ffff01ff02ff3affff04ff02ffff04ff05ffff - 04ff0bffff04ff81bfffff04ffff02ffff03ff82017fffff0182017fffff01ff - 02ff0bffff04ff17ffff04ff2fffff01ff808080808080ff0180ff8080808080 - 808080ff0180ff018080 - " -); - -/// This is the puzzle hash of the [NFT1 ownership layer](https://chialisp.com/nfts) puzzle. -pub const NFT_OWNERSHIP_LAYER_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - c5abea79afaa001b5427dfa0c8cf42ca6f38f5841b78f9b3c252733eb2de2726 - " -)); - -/// This is the puzzle reveal of the [NFT1 royalty transfer](https://chialisp.com/nfts) puzzle. -pub const NFT_ROYALTY_TRANSFER_PUZZLE: [u8; 687] = hex!( - " - ff02ffff01ff02ffff03ff81bfffff01ff04ff82013fffff04ff80ffff04ffff - 02ffff03ffff22ff82013fffff20ffff09ff82013fff2f808080ffff01ff04ff - ff04ff10ffff04ffff0bffff02ff2effff04ff02ffff04ff09ffff04ff8205bf - ffff04ffff02ff3effff04ff02ffff04ffff04ff09ffff04ff82013fff1d8080 - ff80808080ff808080808080ff1580ff808080ffff02ff16ffff04ff02ffff04 - ff0bffff04ff17ffff04ff8202bfffff04ff15ff8080808080808080ffff01ff - 02ff16ffff04ff02ffff04ff0bffff04ff17ffff04ff8202bfffff04ff15ff80 - 80808080808080ff0180ff80808080ffff01ff04ff2fffff01ff80ff80808080 - ff0180ffff04ffff01ffffff3f02ff04ff0101ffff822710ff02ff02ffff03ff - 05ffff01ff02ff3affff04ff02ffff04ff0dffff04ffff0bff2affff0bff2cff - 1480ffff0bff2affff0bff2affff0bff2cff3c80ff0980ffff0bff2aff0bffff - 0bff2cff8080808080ff8080808080ffff010b80ff0180ffff02ffff03ff17ff - ff01ff04ffff04ff10ffff04ffff0bff81a7ffff02ff3effff04ff02ffff04ff - ff04ff2fffff04ffff04ff05ffff04ffff05ffff14ffff12ff47ff0b80ff1280 - 80ffff04ffff04ff05ff8080ff80808080ff808080ff8080808080ff808080ff - ff02ff16ffff04ff02ffff04ff05ffff04ff0bffff04ff37ffff04ff2fff8080 - 808080808080ff8080ff0180ffff0bff2affff0bff2cff1880ffff0bff2affff - 0bff2affff0bff2cff3c80ff0580ffff0bff2affff02ff3affff04ff02ffff04 - ff07ffff04ffff0bff2cff2c80ff8080808080ffff0bff2cff8080808080ff02 - ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff3effff04ff02ffff04ff - 09ff80808080ffff02ff3effff04ff02ffff04ff0dff8080808080ffff01ff0b - ffff0101ff058080ff0180ff018080 - " -); - -/// This is the puzzle hash of the [NFT1 royalty transfer](https://chialisp.com/nfts) puzzle. -pub const NFT_ROYALTY_TRANSFER_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - 025dee0fb1e9fa110302a7e9bfb6e381ca09618e2778b0184fa5c6b275cfce1f - " -)); - -/// This is the puzzle reveal of the [NFT1 metadata updater](https://chialisp.com/nfts) puzzle. -pub const NFT_METADATA_UPDATER_PUZZLE: [u8; 241] = hex!( - " - ff02ffff01ff04ffff04ffff02ffff03ffff22ff27ff3780ffff01ff02ffff03 - ffff21ffff09ff27ffff01826d7580ffff09ff27ffff01826c7580ffff09ff27 - ffff01758080ffff01ff02ff02ffff04ff02ffff04ff05ffff04ff27ffff04ff - 37ff808080808080ffff010580ff0180ffff010580ff0180ffff04ff0bff8080 - 80ffff01ff808080ffff04ffff01ff02ffff03ff05ffff01ff02ffff03ffff09 - ff11ff0b80ffff01ff04ffff04ff0bffff04ff17ff198080ff0d80ffff01ff04 - ff09ffff02ff02ffff04ff02ffff04ff0dffff04ff0bffff04ff17ff80808080 - 80808080ff0180ff8080ff0180ff018080 - " -); - -/// This is the puzzle hash of the [NFT1 metadata updater](https://chialisp.com/nfts) puzzle. -pub const NFT_METADATA_UPDATER_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - fe8a4b4e27a2e29a4d3fc7ce9d527adbcaccbab6ada3903ccf3ba9a769d2d78b - " -)); - -/// This is the puzzle reveal of the [NFT1 intermediate launcher](https://chialisp.com/nfts) puzzle. -pub const NFT_INTERMEDIATE_LAUNCHER_PUZZLE: [u8; 65] = hex!( - " - ff02ffff01ff04ffff04ff04ffff04ff05ffff01ff01808080ffff04ffff04ff - 06ffff04ffff0bff0bff1780ff808080ff808080ffff04ffff01ff333cff0180 - 80 - " -); - -/// This is the puzzle hash of the [NFT1 intermediate launcher](https://chialisp.com/nfts) puzzle. -pub const NFT_INTERMEDIATE_LAUNCHER_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - 7a32d2d9571d3436791c0ad3d7fcfdb9c43ace2b0f0ff13f98d29f0cc093f445 - " -)); - -#[cfg(test)] -mod tests { - use super::*; - - use crate::assert_puzzle_hash; - - #[test] - fn puzzle_hashes() { - assert_puzzle_hash!(NFT_STATE_LAYER_PUZZLE => NFT_STATE_LAYER_PUZZLE_HASH); - assert_puzzle_hash!(NFT_OWNERSHIP_LAYER_PUZZLE => NFT_OWNERSHIP_LAYER_PUZZLE_HASH); - assert_puzzle_hash!(NFT_ROYALTY_TRANSFER_PUZZLE => NFT_ROYALTY_TRANSFER_PUZZLE_HASH); - assert_puzzle_hash!(NFT_METADATA_UPDATER_PUZZLE => NFT_METADATA_UPDATER_PUZZLE_HASH); - assert_puzzle_hash!(NFT_INTERMEDIATE_LAUNCHER_PUZZLE => NFT_INTERMEDIATE_LAUNCHER_PUZZLE_HASH); - } -} diff --git a/crates/chia-puzzles/src/puzzles/offer.rs b/crates/chia-puzzles/src/puzzles/offer.rs deleted file mode 100644 index ea0be5892..000000000 --- a/crates/chia-puzzles/src/puzzles/offer.rs +++ /dev/null @@ -1,213 +0,0 @@ -use chia_protocol::{Bytes, Bytes32}; -use clvm_traits::{FromClvm, ToClvm}; -use clvm_utils::TreeHash; -use hex_literal::hex; - -#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(transparent)] -pub struct SettlementPaymentsSolution { - pub notarized_payments: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(list)] -pub struct NotarizedPayment { - pub nonce: Bytes32, - #[clvm(rest)] - pub payments: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(list)] -pub struct Payment { - pub puzzle_hash: Bytes32, - pub amount: u64, - /// The memos should usually be set to [`None`] instead of an empty list. - /// This is for compatibility with the way the reference wallet encodes offers. - #[clvm(rest)] - pub memos: Option, -} - -#[derive(Debug, Clone, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(list)] -pub struct Memos(pub Vec); - -impl Payment { - pub fn new(puzzle_hash: Bytes32, amount: u64) -> Self { - Self { - puzzle_hash, - amount, - memos: None, - } - } - - pub fn with_memos(puzzle_hash: Bytes32, amount: u64, memos: Vec) -> Self { - Self { - puzzle_hash, - amount, - memos: Some(Memos(memos)), - } - } -} - -/// This is the puzzle reveal of the [offer settlement payments](https://chialisp.com/offers) puzzle. -pub const SETTLEMENT_PAYMENTS_PUZZLE: [u8; 293] = hex!( - " - ff02ffff01ff02ff0affff04ff02ffff04ff03ff80808080ffff04ffff01ffff - 333effff02ffff03ff05ffff01ff04ffff04ff0cffff04ffff02ff1effff04ff - 02ffff04ff09ff80808080ff808080ffff02ff16ffff04ff02ffff04ff19ffff - 04ffff02ff0affff04ff02ffff04ff0dff80808080ff808080808080ff8080ff - 0180ffff02ffff03ff05ffff01ff02ffff03ffff15ff29ff8080ffff01ff04ff - ff04ff08ff0980ffff02ff16ffff04ff02ffff04ff0dffff04ff0bff80808080 - 8080ffff01ff088080ff0180ffff010b80ff0180ff02ffff03ffff07ff0580ff - ff01ff0bffff0102ffff02ff1effff04ff02ffff04ff09ff80808080ffff02ff - 1effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff01 - 80ff018080 - " -); - -/// This is the puzzle hash of the [offer settlement payments](https://chialisp.com/offers) puzzle. -pub const SETTLEMENT_PAYMENTS_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - cfbfdeed5c4ca2de3d0bf520b9cb4bb7743a359bd2e6a188d19ce7dffc21d3e7 - " -)); - -/// This is the puzzle reveal of the old [offer settlement payments](https://chialisp.com/offers) puzzle. -/// -/// **Warning:** -/// It is recommended not to use settlement payments v1 for anything other than backwards compatibility (e.g. offer compression). -pub const SETTLEMENT_PAYMENTS_PUZZLE_V1: [u8; 267] = hex!( - " - ff02ffff01ff02ff0affff04ff02ffff04ff03ff80808080ffff04ffff01ffff - 333effff02ffff03ff05ffff01ff04ffff04ff0cffff04ffff02ff1effff04ff - 02ffff04ff09ff80808080ff808080ffff02ff16ffff04ff02ffff04ff19ffff - 04ffff02ff0affff04ff02ffff04ff0dff80808080ff808080808080ff8080ff - 0180ffff02ffff03ff05ffff01ff04ffff04ff08ff0980ffff02ff16ffff04ff - 02ffff04ff0dffff04ff0bff808080808080ffff010b80ff0180ff02ffff03ff - ff07ff0580ffff01ff0bffff0102ffff02ff1effff04ff02ffff04ff09ff8080 - 8080ffff02ff1effff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101 - ff058080ff0180ff018080 - " -); - -/// This is the puzzle hash of the old [offer settlement payments](https://chialisp.com/offers) puzzle. -/// -/// **Warning:** -/// It is recommended not to use settlement payments v1 for anything other than backwards compatibility (e.g. offer compression). -pub const SETTLEMENT_PAYMENTS_PUZZLE_HASH_V1: TreeHash = TreeHash::new(hex!( - " - bae24162efbd568f89bc7a340798a6118df0189eb9e3f8697bcea27af99f8f79 - " -)); - -#[cfg(test)] -mod tests { - use clvm_utils::tree_hash; - use clvmr::{serde::node_from_bytes, Allocator}; - - use super::*; - - use crate::assert_puzzle_hash; - - #[test] - fn puzzle_hashes() { - assert_puzzle_hash!(SETTLEMENT_PAYMENTS_PUZZLE => SETTLEMENT_PAYMENTS_PUZZLE_HASH); - assert_puzzle_hash!(SETTLEMENT_PAYMENTS_PUZZLE_V1 => SETTLEMENT_PAYMENTS_PUZZLE_HASH_V1); - } - - #[test] - fn test_empty_memos() -> anyhow::Result<()> { - let mut allocator = Allocator::new(); - - /* - ((0xd951714bbcd0d0af317b3ef432472b57e7c48d3036b4491539c186ce1377cad2 - (0x2a5cbc6f5076e0517bdb1e4664b3c26e64d27178b65aaa1ae97267eee629113b 0x04a817c800 ()) - )) - */ - let expected_payment = node_from_bytes( - &mut allocator, - &hex!( - " - ffffa0d951714bbcd0d0af317b3ef432472b57e7c48d3036b4491539c186ce13 - 77cad2ffffa02a5cbc6f5076e0517bdb1e4664b3c26e64d27178b65aaa1ae972 - 67eee629113bff8504a817c800ff80808080 - " - ), - )?; - - let nonce = Bytes32::from(hex!( - "d951714bbcd0d0af317b3ef432472b57e7c48d3036b4491539c186ce1377cad2" - )); - let puzzle_hash = Bytes32::from(hex!( - "2a5cbc6f5076e0517bdb1e4664b3c26e64d27178b65aaa1ae97267eee629113b" - )); - let amount = 20_000_000_000; - let memos = Vec::new(); - - let payment = Payment::with_memos(puzzle_hash, amount, memos); - let notarized_payment = SettlementPaymentsSolution { - notarized_payments: vec![NotarizedPayment { - nonce, - payments: vec![payment], - }], - } - .to_clvm(&mut allocator)?; - - assert_eq!( - tree_hash(&allocator, notarized_payment), - tree_hash(&allocator, expected_payment) - ); - - Ok(()) - } - - #[test] - fn test_missing_memos() -> anyhow::Result<()> { - let mut allocator = Allocator::new(); - - /* - ((0xd951714bbcd0d0af317b3ef432472b57e7c48d3036b4491539c186ce1377cad2 - (0x2a5cbc6f5076e0517bdb1e4664b3c26e64d27178b65aaa1ae97267eee629113b 0x04a817c800) - )) - */ - let expected_payment = node_from_bytes( - &mut allocator, - &hex!( - " - ffffa0d951714bbcd0d0af317b3ef432472b57e7c48d3036b4491539c186ce13 - 77cad2ffffa02a5cbc6f5076e0517bdb1e4664b3c26e64d27178b65aaa1ae972 - 67eee629113bff8504a817c800808080 - " - ), - )?; - - let nonce = Bytes32::from(hex!( - "d951714bbcd0d0af317b3ef432472b57e7c48d3036b4491539c186ce1377cad2" - )); - let puzzle_hash = Bytes32::from(hex!( - "2a5cbc6f5076e0517bdb1e4664b3c26e64d27178b65aaa1ae97267eee629113b" - )); - let amount = 20_000_000_000; - - let payment = Payment::new(puzzle_hash, amount); - let notarized_payment = SettlementPaymentsSolution { - notarized_payments: vec![NotarizedPayment { - nonce, - payments: vec![payment], - }], - } - .to_clvm(&mut allocator)?; - - assert_eq!( - tree_hash(&allocator, notarized_payment), - tree_hash(&allocator, expected_payment) - ); - - Ok(()) - } -} diff --git a/crates/chia-puzzles/src/puzzles/singleton.rs b/crates/chia-puzzles/src/puzzles/singleton.rs deleted file mode 100644 index 254dd148f..000000000 --- a/crates/chia-puzzles/src/puzzles/singleton.rs +++ /dev/null @@ -1,150 +0,0 @@ -use chia_protocol::Bytes32; -use clvm_traits::{FromClvm, ToClvm}; -use clvm_utils::{CurriedProgram, ToTreeHash, TreeHash}; -use hex_literal::hex; - -use crate::Proof; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(curry)] -pub struct SingletonArgs { - pub singleton_struct: SingletonStruct, - pub inner_puzzle: I, -} - -impl SingletonArgs { - pub fn new(launcher_id: Bytes32, inner_puzzle: I) -> Self { - Self { - singleton_struct: SingletonStruct::new(launcher_id), - inner_puzzle, - } - } -} - -impl SingletonArgs { - pub fn curry_tree_hash(launcher_id: Bytes32, inner_puzzle: TreeHash) -> TreeHash { - CurriedProgram { - program: SINGLETON_TOP_LAYER_PUZZLE_HASH, - args: SingletonArgs { - singleton_struct: SingletonStruct::new(launcher_id), - inner_puzzle, - }, - } - .tree_hash() - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(list)] -pub struct SingletonStruct { - pub mod_hash: Bytes32, - pub launcher_id: Bytes32, - #[clvm(rest)] - pub launcher_puzzle_hash: Bytes32, -} - -impl SingletonStruct { - pub fn new(launcher_id: Bytes32) -> Self { - Self { - mod_hash: SINGLETON_TOP_LAYER_PUZZLE_HASH.into(), - launcher_id, - launcher_puzzle_hash: SINGLETON_LAUNCHER_PUZZLE_HASH.into(), - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(solution)] -pub struct SingletonSolution { - pub lineage_proof: Proof, - pub amount: u64, - pub inner_solution: I, -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(solution)] -pub struct LauncherSolution { - pub singleton_puzzle_hash: Bytes32, - pub amount: u64, - pub key_value_list: T, -} - -/// This is the puzzle reveal of the [singleton launcher](https://chialisp.com/singletons#launcher) puzzle. -pub const SINGLETON_LAUNCHER_PUZZLE: [u8; 175] = hex!( - " - ff02ffff01ff04ffff04ff04ffff04ff05ffff04ff0bff80808080ffff04ffff - 04ff0affff04ffff02ff0effff04ff02ffff04ffff04ff05ffff04ff0bffff04 - ff17ff80808080ff80808080ff808080ff808080ffff04ffff01ff33ff3cff02 - ffff03ffff07ff0580ffff01ff0bffff0102ffff02ff0effff04ff02ffff04ff - 09ff80808080ffff02ff0effff04ff02ffff04ff0dff8080808080ffff01ff0b - ffff0101ff058080ff0180ff018080 - " -); - -/// This is the puzzle hash of the [singleton launcher](https://chialisp.com/singletons#launcher) puzzle. -pub const SINGLETON_LAUNCHER_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - eff07522495060c066f66f32acc2a77e3a3e737aca8baea4d1a64ea4cdc13da9 - " -)); - -/// This is the puzzle reveal of the [singleton](https://chialisp.com/singletons) puzzle. -pub const SINGLETON_TOP_LAYER_PUZZLE: [u8; 967] = hex!( - " - ff02ffff01ff02ffff03ffff18ff2fff3480ffff01ff04ffff04ff20ffff04ff - 2fff808080ffff04ffff02ff3effff04ff02ffff04ff05ffff04ffff02ff2aff - ff04ff02ffff04ff27ffff04ffff02ffff03ff77ffff01ff02ff36ffff04ff02 - ffff04ff09ffff04ff57ffff04ffff02ff2effff04ff02ffff04ff05ff808080 - 80ff808080808080ffff011d80ff0180ffff04ffff02ffff03ff77ffff0181b7 - ffff015780ff0180ff808080808080ffff04ff77ff808080808080ffff02ff3a - ffff04ff02ffff04ff05ffff04ffff02ff0bff5f80ffff01ff80808080808080 - 80ffff01ff088080ff0180ffff04ffff01ffffffff4947ff0233ffff0401ff01 - 02ffffff20ff02ffff03ff05ffff01ff02ff32ffff04ff02ffff04ff0dffff04 - ffff0bff3cffff0bff34ff2480ffff0bff3cffff0bff3cffff0bff34ff2c80ff - 0980ffff0bff3cff0bffff0bff34ff8080808080ff8080808080ffff010b80ff - 0180ffff02ffff03ffff22ffff09ffff0dff0580ff2280ffff09ffff0dff0b80 - ff2280ffff15ff17ffff0181ff8080ffff01ff0bff05ff0bff1780ffff01ff08 - 8080ff0180ff02ffff03ff0bffff01ff02ffff03ffff02ff26ffff04ff02ffff - 04ff13ff80808080ffff01ff02ffff03ffff20ff1780ffff01ff02ffff03ffff - 09ff81b3ffff01818f80ffff01ff02ff3affff04ff02ffff04ff05ffff04ff1b - ffff04ff34ff808080808080ffff01ff04ffff04ff23ffff04ffff02ff36ffff - 04ff02ffff04ff09ffff04ff53ffff04ffff02ff2effff04ff02ffff04ff05ff - 80808080ff808080808080ff738080ffff02ff3affff04ff02ffff04ff05ffff - 04ff1bffff04ff34ff8080808080808080ff0180ffff01ff088080ff0180ffff - 01ff04ff13ffff02ff3affff04ff02ffff04ff05ffff04ff1bffff04ff17ff80 - 80808080808080ff0180ffff01ff02ffff03ff17ff80ffff01ff088080ff0180 - 80ff0180ffffff02ffff03ffff09ff09ff3880ffff01ff02ffff03ffff18ff2d - ffff010180ffff01ff0101ff8080ff0180ff8080ff0180ff0bff3cffff0bff34 - ff2880ffff0bff3cffff0bff3cffff0bff34ff2c80ff0580ffff0bff3cffff02 - ff32ffff04ff02ffff04ff07ffff04ffff0bff34ff3480ff8080808080ffff0b - ff34ff8080808080ffff02ffff03ffff07ff0580ffff01ff0bffff0102ffff02 - ff2effff04ff02ffff04ff09ff80808080ffff02ff2effff04ff02ffff04ff0d - ff8080808080ffff01ff0bffff0101ff058080ff0180ff02ffff03ffff21ff17 - ffff09ff0bff158080ffff01ff04ff30ffff04ff0bff808080ffff01ff088080 - ff0180ff018080 - " -); - -/// This is the puzzle hash of the [singleton](https://chialisp.com/singletons) puzzle. -pub const SINGLETON_TOP_LAYER_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - 7faa3253bfddd1e0decb0906b2dc6247bbc4cf608f58345d173adb63e8b47c9f - " -)); - -#[cfg(test)] -mod tests { - use super::*; - - use crate::assert_puzzle_hash; - - #[test] - fn puzzle_hashes() { - assert_puzzle_hash!(SINGLETON_LAUNCHER_PUZZLE => SINGLETON_LAUNCHER_PUZZLE_HASH); - assert_puzzle_hash!(SINGLETON_TOP_LAYER_PUZZLE => SINGLETON_TOP_LAYER_PUZZLE_HASH); - } -} diff --git a/crates/chia-puzzles/src/puzzles/standard.rs b/crates/chia-puzzles/src/puzzles/standard.rs deleted file mode 100644 index 9e903b6e6..000000000 --- a/crates/chia-puzzles/src/puzzles/standard.rs +++ /dev/null @@ -1,114 +0,0 @@ -use chia_bls::PublicKey; -use clvm_traits::{clvm_quote, FromClvm, ToClvm}; -use clvm_utils::{CurriedProgram, ToTreeHash, TreeHash}; -use hex_literal::hex; - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(curry)] -pub struct StandardArgs { - pub synthetic_key: PublicKey, -} - -impl StandardArgs { - pub fn new(synthetic_key: PublicKey) -> Self { - Self { synthetic_key } - } - - pub fn curry_tree_hash(synthetic_key: PublicKey) -> TreeHash { - CurriedProgram { - program: STANDARD_PUZZLE_HASH, - args: StandardArgs { synthetic_key }, - } - .tree_hash() - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq, ToClvm, FromClvm)] -#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] -#[clvm(solution)] -pub struct StandardSolution { - pub original_public_key: Option, - pub delegated_puzzle: P, - pub solution: S, -} - -impl StandardSolution<(u8, T), ()> { - /// Outputs the provided condition list directly, without using the hidden puzzle. - pub fn from_conditions(conditions: T) -> Self { - Self { - original_public_key: None, - delegated_puzzle: clvm_quote!(conditions), - solution: (), - } - } -} - -/// This is the puzzle reveal of the [standard transaction](https://chialisp.com/standard-transactions) puzzle. -pub const STANDARD_PUZZLE: [u8; 227] = hex!( - " - ff02ffff01ff02ffff03ff0bffff01ff02ffff03ffff09ff05ffff1dff0bffff - 1effff0bff0bffff02ff06ffff04ff02ffff04ff17ff8080808080808080ffff - 01ff02ff17ff2f80ffff01ff088080ff0180ffff01ff04ffff04ff04ffff04ff - 05ffff04ffff02ff06ffff04ff02ffff04ff17ff80808080ff80808080ffff02 - ff17ff2f808080ff0180ffff04ffff01ff32ff02ffff03ffff07ff0580ffff01 - ff0bffff0102ffff02ff06ffff04ff02ffff04ff09ff80808080ffff02ff06ff - ff04ff02ffff04ff0dff8080808080ffff01ff0bffff0101ff058080ff0180ff - 018080 - " -); - -/// This is the puzzle hash of the [standard transaction](https://chialisp.com/standard-transactions) puzzle. -pub const STANDARD_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - e9aaa49f45bad5c889b86ee3341550c155cfdd10c3a6757de618d20612fffd52 - " -)); - -/// This is the puzzle reveal of the [default hidden puzzle](https://chialisp.com/standard-transactions#default-hidden-puzzle). -pub const DEFAULT_HIDDEN_PUZZLE: [u8; 3] = hex!("ff0980"); - -/// This is the puzzle hash of the [default hidden puzzle](https://chialisp.com/standard-transactions#default-hidden-puzzle). -pub const DEFAULT_HIDDEN_PUZZLE_HASH: TreeHash = TreeHash::new(hex!( - " - 711d6c4e32c92e53179b199484cf8c897542bc57f2b22582799f9d657eec4699 - " -)); - -#[cfg(test)] -mod tests { - use clvm_traits::ToClvm; - use clvm_utils::tree_hash; - use clvmr::{serde::node_from_bytes, Allocator}; - - use super::*; - - use crate::assert_puzzle_hash; - - #[test] - fn puzzle_hashes() { - assert_puzzle_hash!(STANDARD_PUZZLE => STANDARD_PUZZLE_HASH); - assert_puzzle_hash!(DEFAULT_HIDDEN_PUZZLE => DEFAULT_HIDDEN_PUZZLE_HASH); - } - - #[test] - fn curry_tree_hash() { - let synthetic_key = PublicKey::default(); - - let mut a = Allocator::new(); - let mod_ptr = node_from_bytes(&mut a, &STANDARD_PUZZLE).unwrap(); - - let curried_ptr = CurriedProgram { - program: mod_ptr, - args: StandardArgs::new(synthetic_key), - } - .to_clvm(&mut a) - .unwrap(); - - let allocated_tree_hash = hex::encode(tree_hash(&a, curried_ptr)); - - let tree_hash = hex::encode(StandardArgs::curry_tree_hash(synthetic_key)); - - assert_eq!(allocated_tree_hash, tree_hash); - } -} diff --git a/crates/chia-tools/src/bin/gen-corpus.rs b/crates/chia-tools/src/bin/gen-corpus.rs index ff3ad6850..53c6e013f 100644 --- a/crates/chia-tools/src/bin/gen-corpus.rs +++ b/crates/chia-tools/src/bin/gen-corpus.rs @@ -10,7 +10,7 @@ use chia_traits::streamable::Streamable; use chia_bls::G2Element; use chia_protocol::{Bytes32, Coin, CoinSpend, Program, SpendBundle}; -use chia_puzzles::singleton::SINGLETON_TOP_LAYER_PUZZLE_HASH; +use chia_puzzles::SINGLETON_TOP_LAYER_V1_1_HASH; use clvm_traits::FromClvm; use clvm_utils::{tree_hash, CurriedProgram}; use clvmr::allocator::NodePtr; @@ -126,7 +126,7 @@ fn main() { let seen_puzzle = seen_puzzles.lock().unwrap().insert(mod_hash); let run_puzzle = args.puzzles && seen_puzzle; - let fast_forward = (mod_hash == SINGLETON_TOP_LAYER_PUZZLE_HASH.into()) + let fast_forward = (mod_hash == SINGLETON_TOP_LAYER_V1_1_HASH.into()) && seen_singletons.lock().unwrap().insert(puzzle_hash); if !run_puzzle diff --git a/crates/chia-tools/src/bin/run-spend.rs b/crates/chia-tools/src/bin/run-spend.rs index 0cdf60a9f..eae5f4a16 100644 --- a/crates/chia-tools/src/bin/run-spend.rs +++ b/crates/chia-tools/src/bin/run-spend.rs @@ -1,5 +1,8 @@ use chia_consensus::gen::conditions::Condition; -use chia_puzzles::Proof; +use chia_puzzles::CAT_PUZZLE_HASH; +use chia_puzzles::DID_INNERPUZ_HASH; +use chia_puzzles::P2_DELEGATED_PUZZLE_OR_HIDDEN_PUZZLE_HASH; +use chia_puzzles::SINGLETON_TOP_LAYER_V1_1_HASH; use chia_traits::Streamable; use clap::Parser; use clvm_traits::{FromClvm, ToClvm}; @@ -7,11 +10,6 @@ use clvm_utils::tree_hash; use clvm_utils::CurriedProgram; use clvmr::{allocator::NodePtr, Allocator}; -use chia_puzzles::cat::{CatArgs, CatSolution, CAT_PUZZLE_HASH}; -use chia_puzzles::did::{DidArgs, DidSolution, DID_INNER_PUZZLE_HASH}; -use chia_puzzles::singleton::{SingletonArgs, SingletonSolution, SINGLETON_TOP_LAYER_PUZZLE_HASH}; -use chia_puzzles::standard::{StandardArgs, StandardSolution, STANDARD_PUZZLE_HASH}; - /// Run a puzzle given a solution and print the resulting conditions #[derive(Parser, Debug)] #[command(author, version, about, long_about = None)] @@ -135,8 +133,8 @@ fn print_puzzle_info(a: &Allocator, puzzle: NodePtr, solution: NodePtr) { return; }; - match tree_hash(a, uncurried.program) { - STANDARD_PUZZLE_HASH => { + match tree_hash(a, uncurried.program).to_bytes() { + P2_DELEGATED_PUZZLE_OR_HIDDEN_PUZZLE_HASH => { println!("p2_delegated_puzzle_or_hidden_puzzle.clsp"); let Ok(uncurried) = CurriedProgram::::from_clvm(a, puzzle) else { @@ -178,7 +176,7 @@ fn print_puzzle_info(a: &Allocator, puzzle: NodePtr, solution: NodePtr) { println!("\nInner Puzzle\n"); print_puzzle_info(a, uncurried.args.inner_puzzle, sol.inner_puzzle_solution); } - DID_INNER_PUZZLE_HASH => { + DID_INNERPUZ_HASH => { println!("did_innerpuz.clsp"); let Ok(uncurried) = CurriedProgram::>::from_clvm(a, puzzle) @@ -210,7 +208,7 @@ fn print_puzzle_info(a: &Allocator, puzzle: NodePtr, solution: NodePtr) { }; print_puzzle_info(a, uncurried.args.inner_puzzle, inner_sol); } - SINGLETON_TOP_LAYER_PUZZLE_HASH => { + SINGLETON_TOP_LAYER_V1_1_HASH => { println!("singleton_top_layer_1_1.clsp"); let Ok(uncurried) = CurriedProgram::>::from_clvm(a, puzzle)