-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
369 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
fun main() -> Int { | ||
factorial(15) | ||
} | ||
|
||
fun factorial(num: Int) -> Int { | ||
if num > 1 { | ||
num * factorial(num - 1) | ||
} else { | ||
1 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
fun main() -> Int { | ||
fibonacci(10) | ||
} | ||
|
||
fun fibonacci(num: Int) -> Int { | ||
if num > 1 { | ||
fibonacci(num - 1) + fibonacci(num - 2) | ||
} else { | ||
num | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
fun main() -> Bytes { | ||
"Hello, world!" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
// This puzzle has not been audited or tested, and is for example purposes only. | ||
|
||
fun main( | ||
public_keys: PublicKey[], | ||
required: Int, | ||
indices: Int[], | ||
conditions: Condition[], | ||
) -> Condition[] { | ||
let message = tree_hash(conditions); | ||
let agg_sigs = check_signatures(public_keys, required, indices, 0, message); | ||
concat(agg_sigs, conditions) | ||
} | ||
|
||
fun check_signatures( | ||
public_keys: PublicKey[], | ||
required: Int, | ||
indices: Int[], | ||
pos: Int, | ||
message: Bytes, | ||
) -> Condition[] { | ||
if required == 0 { | ||
return nil; | ||
} | ||
|
||
assume !(public_keys is Nil) && !(indices is Nil); | ||
|
||
if indices.first != pos { | ||
return check_signatures(public_keys.rest, required, indices, pos + 1, message); | ||
} | ||
|
||
let agg_sig = Condition::AggSigMe { | ||
public_key: public_keys.first, | ||
message: message, | ||
}; | ||
|
||
[agg_sig, ...check_signatures(public_keys.rest, required - 1, indices.rest, pos + 1, message)] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// This puzzle has not been audited or tested, and is for example purposes only. | ||
|
||
fun main(public_key: PublicKey, conditions: Condition[]) -> Condition[] { | ||
let agg_sig = Condition::AggSigMe { | ||
public_key: public_key, | ||
message: tree_hash(conditions), | ||
}; | ||
[agg_sig, ...conditions] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// This puzzle has not been audited or tested, and is for example purposes only. | ||
|
||
fun main( | ||
synthetic_pk: PublicKey, | ||
original_pk: PublicKey?, | ||
delegated_puzzle: fun(...solution: Any) -> Condition[], | ||
delegated_solution: Any | ||
) -> Condition[] { | ||
let conditions = delegated_puzzle(...delegated_solution); | ||
let delegated_puzzle_hash = tree_hash(delegated_puzzle); | ||
|
||
if original_pk != nil { | ||
let exponent = sha256(original_pk as Bytes + delegated_puzzle_hash); | ||
let offset_pk = pubkey_for_exp(exponent); | ||
assert synthetic_pk == original_pk + offset_pk; | ||
return conditions; | ||
} | ||
|
||
let agg_sig_me = Condition::AggSigMe { | ||
public_key: synthetic_pk, | ||
message: delegated_puzzle_hash, | ||
}; | ||
|
||
[agg_sig_me, ...conditions] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// This puzzle has not been audited or tested, and is for example purposes only. | ||
|
||
// Also known as a "singleton struct". | ||
struct SingletonInfo { | ||
mod_hash: Bytes32, | ||
launcher_id: Bytes32, | ||
...launcher_puzzle_hash: Bytes32, | ||
} | ||
|
||
// Calculate the full puzzle hash for a singleton. | ||
inline fun singleton_puzzle_hash(singleton_info: SingletonInfo, inner_puzzle_hash: Bytes32) -> Bytes32 { | ||
curry_tree_hash(singleton_info.mod_hash, tree_hash(singleton_info), inner_puzzle_hash) | ||
} | ||
|
||
fun main( | ||
fusion_singleton: SingletonInfo, | ||
fusion_inner_puzzle_hash: Bytes32, | ||
fusion_coin_id: Bytes32, | ||
my_launcher_id: Bytes32, | ||
my_inner_puzzle_hash: Bytes32, | ||
my_amount: Int, | ||
p2_puzzle_hash: Bytes32, | ||
) -> Condition[] { | ||
// The NFT singleton has the same mod hash and launcher puzzle hash as the fusion singleton. | ||
let nft_singleton = SingletonInfo { | ||
mod_hash: fusion_singleton.mod_hash, | ||
launcher_id: my_launcher_id, | ||
launcher_puzzle_hash: fusion_singleton.launcher_puzzle_hash, | ||
}; | ||
|
||
// Calculate the full puzzle hashes for the NFT and fusion singletons. | ||
let fusion_puzzle_hash = singleton_puzzle_hash(fusion_singleton, fusion_inner_puzzle_hash); | ||
let nft_puzzle_hash = singleton_puzzle_hash(nft_singleton, my_inner_puzzle_hash); | ||
|
||
// Calculate the announcement message. | ||
let announcement_message = sha256(fusion_coin_id + my_launcher_id + p2_puzzle_hash); | ||
|
||
[ | ||
// Make sure that the amount in the solution is correct. | ||
Condition::AssertMyAmount { amount: my_amount }, | ||
|
||
// Prove supplied NFT coin matches the expected derived puzzle hash. | ||
Condition::AssertMyPuzzleHash { puzzle_hash: nft_puzzle_hash }, | ||
|
||
|
||
// Assert that the fusion singleton announced this NFT spend. | ||
Condition::AssertPuzzleAnnouncement { | ||
announcement_id: sha256(fusion_puzzle_hash + announcement_message), | ||
}, | ||
|
||
// Unlock the NFT to the new p2 puzzle hash, with a hint. | ||
Condition::CreateCoin { | ||
puzzle_hash: p2_puzzle_hash, | ||
amount: my_amount, | ||
memos: [p2_puzzle_hash], | ||
}, | ||
|
||
// Announce that a specific singleton is being spent to | ||
// help prevent ephemeral singleton spends from influencing. | ||
Condition::CreateCoinAnnouncement { | ||
message: announcement_message, | ||
}, | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// This puzzle has not been audited or tested, and is for example purposes only. | ||
|
||
struct Payout { | ||
puzzle_hash: Bytes32, | ||
share: Int, | ||
} | ||
|
||
fun main(payouts: Payout[], total_shares: Int, my_amount: Int) -> Condition[] { | ||
let announcement = Condition::CreateCoinAnnouncement { message: '$' }; | ||
let assert_amount = Condition::AssertMyAmount { amount: my_amount }; | ||
|
||
let conditions = calculate_amount_and_split(payouts, my_amount, total_shares, 0, my_amount); | ||
[announcement, assert_amount, ...conditions] | ||
} | ||
|
||
fun calculate_amount_and_split( | ||
payouts: Payout[], | ||
total_amount: Int, | ||
total_shares: Int, | ||
shares_sum: Int, | ||
remaining_amount: Int, | ||
) -> Condition[] { | ||
if payouts is (Payout, Payout[]) { | ||
let amount = get_amount(payouts.first, total_amount, total_shares); | ||
return split_amount_and_create_coins(payouts, amount, total_amount, total_shares, shares_sum, remaining_amount); | ||
} | ||
assert total_shares == shares_sum; | ||
[] | ||
} | ||
|
||
fun split_amount_and_create_coins( | ||
payouts: (Payout, Payout[]), | ||
this_amount: Int, | ||
total_amount: Int, | ||
total_shares: Int, | ||
shares_sum: Int, | ||
remaining_amount: Int, | ||
) -> Condition[] { | ||
let payout = payouts.first; | ||
let create_coin = Condition::CreateCoin { | ||
puzzle_hash: payout.puzzle_hash, | ||
amount: if payout.share > 0 { this_amount } else { remaining_amount }, | ||
memos: [payout.puzzle_hash], | ||
}; | ||
let rest = calculate_amount_and_split(payouts.rest, total_amount, total_shares, shares_sum + payout.share, remaining_amount - this_amount); | ||
[create_coin, ...rest] | ||
} | ||
|
||
fun get_amount(payout: Payout, total_amount: Int, total_shares: Int) -> Int { | ||
(total_amount * payout.share) / total_shares | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
// This puzzle has not been audited or tested, and is for example purposes only. | ||
|
||
struct Singleton { | ||
mod_hash: Bytes32, | ||
launcher_id: Bytes32, | ||
launcher_puzzle_hash: Bytes32, | ||
} | ||
|
||
struct LineageProof { | ||
parent_parent_coin_info: Bytes32, | ||
parent_inner_puzzle_hash: Bytes32?, | ||
parent_amount: Int, | ||
} | ||
|
||
fun singleton_puzzle_hash(singleton: Singleton, inner_puzzle_hash: Bytes32) -> Bytes32 { | ||
curry_tree_hash(singleton.mod_hash, tree_hash(singleton), inner_puzzle_hash) | ||
} | ||
|
||
fun main( | ||
singleton: Singleton, | ||
inner_puzzle: fun(...solution: Any) -> Condition[], | ||
lineage_proof: LineageProof, | ||
my_amount: Int, | ||
inner_solution: Any, | ||
) -> Condition[] { | ||
// Ensure that the amount is odd. | ||
assert my_amount & 1 == 1; | ||
|
||
// Verify the lineage proof. | ||
let is_eve = lineage_proof.parent_inner_puzzle_hash == nil; | ||
|
||
let parent_puzzle_hash = if is_eve { | ||
singleton.launcher_puzzle_hash | ||
} else { | ||
singleton_puzzle_hash(singleton, lineage_proof.parent_inner_puzzle_hash) | ||
}; | ||
|
||
let parent_coin_id = calculate_coin_id( | ||
lineage_proof.parent_parent_coin_info, | ||
parent_puzzle_hash, | ||
lineage_proof.parent_amount, | ||
); | ||
|
||
assert is_eve || parent_coin_id == singleton.launcher_id; | ||
|
||
// Run the inner puzzle. | ||
let conditions = inner_puzzle(...inner_solution); | ||
|
||
[ | ||
Condition::AssertMyAmount { amount: my_amount }, | ||
Condition::AssertMyParentId { parent_coin_id: parent_coin_id }, | ||
...morph_conditions(singleton, conditions, false), | ||
] | ||
} | ||
|
||
fun morph_conditions( | ||
singleton: Singleton, | ||
conditions: Condition[], | ||
found_singleton_output: Bool, | ||
) -> Condition[] { | ||
if conditions is Nil { | ||
// We must have a singleton output. | ||
assert found_singleton_output; | ||
return nil; | ||
} | ||
|
||
let condition = conditions.first; | ||
let rest = conditions.rest; | ||
|
||
if !(condition is Condition::CreateCoin && condition.amount & 1 == 1) { | ||
// We don't need to morph this condition. | ||
return [ | ||
condition, | ||
...morph_conditions(singleton, rest, found_singleton_output), | ||
]; | ||
} | ||
|
||
// We need to morph this odd output, but it must be the only one. | ||
assert !found_singleton_output; | ||
|
||
if condition.amount == -113 { | ||
// We are melting the singleton, so we don't need to have an output. | ||
return morph_conditions(singleton, rest, true); | ||
} | ||
|
||
// Wrap the puzzle hash in the singleton layer. | ||
let output = Condition::CreateCoin { | ||
puzzle_hash: singleton_puzzle_hash(singleton, condition.puzzle_hash), | ||
amount: condition.amount, | ||
memos: condition.memos, | ||
}; | ||
|
||
[output, ...morph_conditions(singleton, rest, true)] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters