chia_sdk_types/
puzzle_mod.rs

1use std::borrow::Cow;
2
3use chia_puzzle_types::{
4    cat::{CatArgs, EverythingWithSignatureTailArgs, GenesisByCoinIdTailArgs},
5    did::DidArgs,
6    nft::{
7        NftIntermediateLauncherArgs, NftOwnershipLayerArgs, NftRoyaltyTransferPuzzleArgs,
8        NftStateLayerArgs,
9    },
10    singleton::SingletonArgs,
11    standard::StandardArgs,
12};
13use chia_puzzles::{
14    CAT_PUZZLE, CAT_PUZZLE_HASH, DID_INNERPUZ, DID_INNERPUZ_HASH, EVERYTHING_WITH_SIGNATURE,
15    EVERYTHING_WITH_SIGNATURE_HASH, GENESIS_BY_COIN_ID, GENESIS_BY_COIN_ID_HASH,
16    NFT_INTERMEDIATE_LAUNCHER, NFT_INTERMEDIATE_LAUNCHER_HASH, NFT_OWNERSHIP_LAYER,
17    NFT_OWNERSHIP_LAYER_HASH, NFT_OWNERSHIP_TRANSFER_PROGRAM_ONE_WAY_CLAIM_WITH_ROYALTIES,
18    NFT_OWNERSHIP_TRANSFER_PROGRAM_ONE_WAY_CLAIM_WITH_ROYALTIES_HASH, NFT_STATE_LAYER,
19    NFT_STATE_LAYER_HASH, P2_DELEGATED_PUZZLE_OR_HIDDEN_PUZZLE,
20    P2_DELEGATED_PUZZLE_OR_HIDDEN_PUZZLE_HASH, SINGLETON_TOP_LAYER_V1_1,
21    SINGLETON_TOP_LAYER_V1_1_HASH,
22};
23use clvm_traits::ToClvm;
24use clvm_utils::{CurriedProgram, TreeHash, TreeHasher};
25
26/// This trait makes it possible to get the mod hash or puzzle reveal of a puzzle.
27///
28/// There is also a utility for calculating the curried tree hash, provided the type
29/// implements [`ToTreeHash`](clvm_utils::ToTreeHash). This is much more efficient than
30/// manually allocating and hashing the puzzle and its arguments.
31///
32/// This trait should be be implemented for types that represent the curried arguments of puzzles.
33/// However, if a puzzle can't be curried (ie it has no arguments), this trait  can still be
34/// implemented on a marker struct that doesn't implement [`ToTreeHash`](clvm_utils::ToTreeHash).
35/// This will disable the [`curry_tree_hash`](Mod::curry_tree_hash) method.
36///
37/// ## Usage Example
38///
39/// We can specify the arguments of a puzzle to get its curried puzzle hash.
40///
41/// ```rust
42/// # use chia_bls::PublicKey;
43/// # use chia_puzzle_types::standard::StandardArgs;
44/// # use chia_sdk_types::Mod;
45/// let args = StandardArgs::new(PublicKey::default());
46/// let puzzle_hash = args.curry_tree_hash();
47/// ```
48pub trait Mod {
49    fn mod_reveal() -> Cow<'static, [u8]>;
50    fn mod_hash() -> TreeHash;
51
52    /// Curry the arguments into the [`Mod::mod_hash`].
53    fn curry_tree_hash(&self) -> TreeHash
54    where
55        Self: Sized + ToClvm<TreeHasher>,
56    {
57        CurriedProgram {
58            program: Self::mod_hash(),
59            args: self,
60        }
61        .to_clvm(&mut TreeHasher)
62        .unwrap()
63    }
64}
65
66impl<T> Mod for &T
67where
68    T: Mod,
69{
70    fn mod_reveal() -> Cow<'static, [u8]> {
71        T::mod_reveal()
72    }
73
74    fn mod_hash() -> TreeHash {
75        T::mod_hash()
76    }
77}
78
79impl Mod for StandardArgs {
80    fn mod_reveal() -> Cow<'static, [u8]> {
81        Cow::Borrowed(&P2_DELEGATED_PUZZLE_OR_HIDDEN_PUZZLE)
82    }
83
84    fn mod_hash() -> TreeHash {
85        TreeHash::new(P2_DELEGATED_PUZZLE_OR_HIDDEN_PUZZLE_HASH)
86    }
87}
88
89impl<I> Mod for CatArgs<I> {
90    fn mod_reveal() -> Cow<'static, [u8]> {
91        Cow::Borrowed(&CAT_PUZZLE)
92    }
93
94    fn mod_hash() -> TreeHash {
95        TreeHash::new(CAT_PUZZLE_HASH)
96    }
97}
98
99impl<I, M> Mod for DidArgs<I, M> {
100    fn mod_reveal() -> Cow<'static, [u8]> {
101        Cow::Borrowed(&DID_INNERPUZ)
102    }
103
104    fn mod_hash() -> TreeHash {
105        TreeHash::new(DID_INNERPUZ_HASH)
106    }
107}
108
109impl Mod for NftIntermediateLauncherArgs {
110    fn mod_reveal() -> Cow<'static, [u8]> {
111        Cow::Borrowed(&NFT_INTERMEDIATE_LAUNCHER)
112    }
113
114    fn mod_hash() -> TreeHash {
115        TreeHash::new(NFT_INTERMEDIATE_LAUNCHER_HASH)
116    }
117}
118
119impl Mod for NftRoyaltyTransferPuzzleArgs {
120    fn mod_reveal() -> Cow<'static, [u8]> {
121        Cow::Borrowed(&NFT_OWNERSHIP_TRANSFER_PROGRAM_ONE_WAY_CLAIM_WITH_ROYALTIES)
122    }
123
124    fn mod_hash() -> TreeHash {
125        TreeHash::new(NFT_OWNERSHIP_TRANSFER_PROGRAM_ONE_WAY_CLAIM_WITH_ROYALTIES_HASH)
126    }
127}
128
129impl<I, P> Mod for NftOwnershipLayerArgs<I, P> {
130    fn mod_reveal() -> Cow<'static, [u8]> {
131        Cow::Borrowed(&NFT_OWNERSHIP_LAYER)
132    }
133
134    fn mod_hash() -> TreeHash {
135        TreeHash::new(NFT_OWNERSHIP_LAYER_HASH)
136    }
137}
138
139impl<I, M> Mod for NftStateLayerArgs<I, M> {
140    fn mod_reveal() -> Cow<'static, [u8]> {
141        Cow::Borrowed(&NFT_STATE_LAYER)
142    }
143
144    fn mod_hash() -> TreeHash {
145        TreeHash::new(NFT_STATE_LAYER_HASH)
146    }
147}
148
149impl<I> Mod for SingletonArgs<I> {
150    fn mod_reveal() -> Cow<'static, [u8]> {
151        Cow::Borrowed(&SINGLETON_TOP_LAYER_V1_1)
152    }
153
154    fn mod_hash() -> TreeHash {
155        TreeHash::new(SINGLETON_TOP_LAYER_V1_1_HASH)
156    }
157}
158
159impl Mod for EverythingWithSignatureTailArgs {
160    fn mod_reveal() -> Cow<'static, [u8]> {
161        Cow::Borrowed(&EVERYTHING_WITH_SIGNATURE)
162    }
163
164    fn mod_hash() -> TreeHash {
165        TreeHash::new(EVERYTHING_WITH_SIGNATURE_HASH)
166    }
167}
168
169impl Mod for GenesisByCoinIdTailArgs {
170    fn mod_reveal() -> Cow<'static, [u8]> {
171        Cow::Borrowed(&GENESIS_BY_COIN_ID)
172    }
173
174    fn mod_hash() -> TreeHash {
175        TreeHash::new(GENESIS_BY_COIN_ID_HASH)
176    }
177}