Add Chialisp pretty printer to pre-commit (#15008)
* Add chialispp port to pre-commit * Lint files
This commit is contained in:
parent
a2567f45a9
commit
eab43eb800
|
@ -37,6 +37,13 @@ repos:
|
|||
entry: ./activated.py python tools/manage_clvm.py check
|
||||
language: python
|
||||
pass_filenames: false
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: chialispp
|
||||
name: Pretty print chialisp files
|
||||
entry: ./activated.py python tools/chialispp.py .
|
||||
language: python
|
||||
pass_filenames: false
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: mypy
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
|
||||
(defun decompress_cses (decompress_puzzle decompress_coin_spend_entry cses deserialize puzzle_prefix)
|
||||
(if cses
|
||||
(c (a decompress_coin_spend_entry (list deserialize decompress_puzzle puzzle_prefix (f cses)))
|
||||
(decompress_cses decompress_puzzle decompress_coin_spend_entry (r cses) deserialize puzzle_prefix ))
|
||||
()) )
|
||||
(c (a decompress_coin_spend_entry (list deserialize decompress_puzzle puzzle_prefix (f cses)))
|
||||
(decompress_cses decompress_puzzle decompress_coin_spend_entry (r cses) deserialize puzzle_prefix ))
|
||||
()) )
|
||||
|
||||
(list (decompress_cses decompress_puzzle decompress_coin_spend_entry compressed_cses deserialize (substr (f gen_list) start end)))
|
||||
(list (decompress_cses decompress_puzzle decompress_coin_spend_entry compressed_cses deserialize (substr (f gen_list) start end)))
|
||||
|
||||
)
|
||||
|
|
|
@ -92,279 +92,279 @@
|
|||
;;
|
||||
|
||||
(mod (
|
||||
MOD_HASH ;; curried into puzzle
|
||||
TAIL_PROGRAM_HASH ;; curried into puzzle
|
||||
INNER_PUZZLE ;; curried into puzzle
|
||||
inner_puzzle_solution ;; if invalid, INNER_PUZZLE will fail
|
||||
lineage_proof ;; This is the parent's coin info, used to check if the parent was a CAT. Optional if using tail_program.
|
||||
prev_coin_id ;; used in this coin's announcement, prev_coin ASSERT_COIN_ANNOUNCEMENT will fail if wrong
|
||||
this_coin_info ;; verified with ASSERT_MY_COIN_ID
|
||||
next_coin_proof ;; used to generate ASSERT_COIN_ANNOUNCEMENT
|
||||
prev_subtotal ;; included in announcement, prev_coin ASSERT_COIN_ANNOUNCEMENT will fail if wrong
|
||||
extra_delta ;; this is the "legal discrepancy" between your real delta and what you're announcing your delta is
|
||||
)
|
||||
MOD_HASH ;; curried into puzzle
|
||||
TAIL_PROGRAM_HASH ;; curried into puzzle
|
||||
INNER_PUZZLE ;; curried into puzzle
|
||||
inner_puzzle_solution ;; if invalid, INNER_PUZZLE will fail
|
||||
lineage_proof ;; This is the parent's coin info, used to check if the parent was a CAT. Optional if using tail_program.
|
||||
prev_coin_id ;; used in this coin's announcement, prev_coin ASSERT_COIN_ANNOUNCEMENT will fail if wrong
|
||||
this_coin_info ;; verified with ASSERT_MY_COIN_ID
|
||||
next_coin_proof ;; used to generate ASSERT_COIN_ANNOUNCEMENT
|
||||
prev_subtotal ;; included in announcement, prev_coin ASSERT_COIN_ANNOUNCEMENT will fail if wrong
|
||||
extra_delta ;; this is the "legal discrepancy" between your real delta and what you're announcing your delta is
|
||||
)
|
||||
|
||||
;;;;; start library code
|
||||
;;;;; start library code
|
||||
|
||||
(include condition_codes.clib)
|
||||
(include curry-and-treehash.clib)
|
||||
(include cat_truths.clib)
|
||||
(include utility_macros.clib)
|
||||
(include condition_codes.clib)
|
||||
(include curry-and-treehash.clib)
|
||||
(include cat_truths.clib)
|
||||
(include utility_macros.clib)
|
||||
|
||||
(defconstant RING_MORPH_BYTE 0xcb)
|
||||
(defconstant RING_MORPH_BYTE 0xcb)
|
||||
|
||||
|
||||
; take two lists and merge them into one
|
||||
(defun merge_list (list_a list_b)
|
||||
(if list_a
|
||||
; take two lists and merge them into one
|
||||
(defun merge_list (list_a list_b)
|
||||
(if list_a
|
||||
(c (f list_a) (merge_list (r list_a) list_b))
|
||||
list_b
|
||||
)
|
||||
)
|
||||
|
||||
; cat_mod_struct = (MOD_HASH MOD_HASH_hash GENESIS_COIN_CHECKER GENESIS_COIN_CHECKER_hash)
|
||||
|
||||
(defun-inline mod_hash_from_cat_mod_struct (cat_mod_struct) (f cat_mod_struct))
|
||||
(defun-inline mod_hash_hash_from_cat_mod_struct (cat_mod_struct) (f (r cat_mod_struct)))
|
||||
(defun-inline tail_program_hash_from_cat_mod_struct (cat_mod_struct) (f (r (r cat_mod_struct))))
|
||||
|
||||
;;;;; end library code
|
||||
|
||||
;; return the puzzle hash for a cat with the given `GENESIS_COIN_CHECKER_hash` & `INNER_PUZZLE`
|
||||
(defun-inline cat_puzzle_hash (cat_mod_struct inner_puzzle_hash)
|
||||
(puzzle-hash-of-curried-function (mod_hash_from_cat_mod_struct cat_mod_struct)
|
||||
inner_puzzle_hash
|
||||
(sha256 ONE (tail_program_hash_from_cat_mod_struct cat_mod_struct))
|
||||
(mod_hash_hash_from_cat_mod_struct cat_mod_struct)
|
||||
)
|
||||
)
|
||||
|
||||
;; assert `CREATE_COIN_ANNOUNCEMENT` doesn't contain the RING_MORPH_BYTE bytes so it cannot be used to cheat the coin ring
|
||||
|
||||
(defun-inline morph_condition (condition cat_mod_struct)
|
||||
(if (= (f condition) CREATE_COIN)
|
||||
(c CREATE_COIN
|
||||
(c (cat_puzzle_hash cat_mod_struct (f (r condition)))
|
||||
(r (r condition)))
|
||||
)
|
||||
(if (= (f condition) CREATE_COIN_ANNOUNCEMENT)
|
||||
(assert (not (and
|
||||
(= 33 (strlen (f (r condition))))
|
||||
(= (substr (f (r condition)) 0 ONE) RING_MORPH_BYTE) ; lazy eval
|
||||
))
|
||||
; then
|
||||
condition
|
||||
)
|
||||
condition
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; given a coin's parent, inner_puzzle and amount, and the cat_mod_struct, calculate the id of the coin
|
||||
(defun-inline coin_id_for_proof (coin cat_mod_struct)
|
||||
(calculate_coin_id (f coin) (cat_puzzle_hash cat_mod_struct (f (r coin))) (f (r (r coin))))
|
||||
)
|
||||
|
||||
;; utility to fetch coin amount from coin
|
||||
(defun-inline input_amount_for_coin (coin)
|
||||
(f (r (r coin)))
|
||||
)
|
||||
|
||||
;; calculate the hash of an announcement
|
||||
;; we add 0xcb so ring announcements exist in a different namespace to announcements from inner_puzzles
|
||||
(defun-inline calculate_annoucement_id (this_coin_id this_subtotal next_coin_id cat_mod_struct)
|
||||
(sha256 next_coin_id RING_MORPH_BYTE (sha256tree (list this_coin_id this_subtotal)))
|
||||
)
|
||||
|
||||
;; create the `ASSERT_COIN_ANNOUNCEMENT` condition that ensures the next coin's announcement is correct
|
||||
(defun-inline create_assert_next_announcement_condition (this_coin_id this_subtotal next_coin_id cat_mod_struct)
|
||||
(list ASSERT_COIN_ANNOUNCEMENT
|
||||
(calculate_annoucement_id this_coin_id
|
||||
this_subtotal
|
||||
next_coin_id
|
||||
cat_mod_struct
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
; cat_mod_struct = (MOD_HASH MOD_HASH_hash GENESIS_COIN_CHECKER GENESIS_COIN_CHECKER_hash)
|
||||
;; here we commit to I_{k-1} and S_k
|
||||
;; we add 0xcb so ring announcements exist in a different namespace to announcements from inner_puzzles
|
||||
(defun-inline create_announcement_condition (prev_coin_id prev_subtotal)
|
||||
(list CREATE_COIN_ANNOUNCEMENT
|
||||
(concat RING_MORPH_BYTE (sha256tree (list prev_coin_id prev_subtotal)))
|
||||
)
|
||||
)
|
||||
|
||||
(defun-inline mod_hash_from_cat_mod_struct (cat_mod_struct) (f cat_mod_struct))
|
||||
(defun-inline mod_hash_hash_from_cat_mod_struct (cat_mod_struct) (f (r cat_mod_struct)))
|
||||
(defun-inline tail_program_hash_from_cat_mod_struct (cat_mod_struct) (f (r (r cat_mod_struct))))
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;;;;; end library code
|
||||
;; this function takes a condition and returns an integer indicating
|
||||
;; the value of all output coins created with CREATE_COIN. If it's not
|
||||
;; a CREATE_COIN condition, it returns 0.
|
||||
|
||||
;; return the puzzle hash for a cat with the given `GENESIS_COIN_CHECKER_hash` & `INNER_PUZZLE`
|
||||
(defun-inline cat_puzzle_hash (cat_mod_struct inner_puzzle_hash)
|
||||
(puzzle-hash-of-curried-function (mod_hash_from_cat_mod_struct cat_mod_struct)
|
||||
inner_puzzle_hash
|
||||
(sha256 ONE (tail_program_hash_from_cat_mod_struct cat_mod_struct))
|
||||
(mod_hash_hash_from_cat_mod_struct cat_mod_struct)
|
||||
)
|
||||
)
|
||||
(defun-inline output_value_for_condition (condition)
|
||||
(if (= (f condition) CREATE_COIN)
|
||||
(f (r (r condition)))
|
||||
0
|
||||
)
|
||||
)
|
||||
|
||||
;; assert `CREATE_COIN_ANNOUNCEMENT` doesn't contain the RING_MORPH_BYTE bytes so it cannot be used to cheat the coin ring
|
||||
|
||||
(defun-inline morph_condition (condition cat_mod_struct)
|
||||
(if (= (f condition) CREATE_COIN)
|
||||
(c CREATE_COIN
|
||||
(c (cat_puzzle_hash cat_mod_struct (f (r condition)))
|
||||
(r (r condition)))
|
||||
)
|
||||
(if (= (f condition) CREATE_COIN_ANNOUNCEMENT)
|
||||
(assert (not (and
|
||||
(= 33 (strlen (f (r condition))))
|
||||
(= (substr (f (r condition)) 0 ONE) RING_MORPH_BYTE) ; lazy eval
|
||||
))
|
||||
; then
|
||||
condition
|
||||
)
|
||||
condition
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; given a coin's parent, inner_puzzle and amount, and the cat_mod_struct, calculate the id of the coin
|
||||
(defun-inline coin_id_for_proof (coin cat_mod_struct)
|
||||
(calculate_coin_id (f coin) (cat_puzzle_hash cat_mod_struct (f (r coin))) (f (r (r coin))))
|
||||
)
|
||||
|
||||
;; utility to fetch coin amount from coin
|
||||
(defun-inline input_amount_for_coin (coin)
|
||||
(f (r (r coin)))
|
||||
)
|
||||
|
||||
;; calculate the hash of an announcement
|
||||
;; we add 0xcb so ring announcements exist in a different namespace to announcements from inner_puzzles
|
||||
(defun-inline calculate_annoucement_id (this_coin_id this_subtotal next_coin_id cat_mod_struct)
|
||||
(sha256 next_coin_id RING_MORPH_BYTE (sha256tree (list this_coin_id this_subtotal)))
|
||||
)
|
||||
|
||||
;; create the `ASSERT_COIN_ANNOUNCEMENT` condition that ensures the next coin's announcement is correct
|
||||
(defun-inline create_assert_next_announcement_condition (this_coin_id this_subtotal next_coin_id cat_mod_struct)
|
||||
(list ASSERT_COIN_ANNOUNCEMENT
|
||||
(calculate_annoucement_id this_coin_id
|
||||
this_subtotal
|
||||
next_coin_id
|
||||
cat_mod_struct
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; here we commit to I_{k-1} and S_k
|
||||
;; we add 0xcb so ring announcements exist in a different namespace to announcements from inner_puzzles
|
||||
(defun-inline create_announcement_condition (prev_coin_id prev_subtotal)
|
||||
(list CREATE_COIN_ANNOUNCEMENT
|
||||
(concat RING_MORPH_BYTE (sha256tree (list prev_coin_id prev_subtotal)))
|
||||
)
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; this function takes a condition and returns an integer indicating
|
||||
;; the value of all output coins created with CREATE_COIN. If it's not
|
||||
;; a CREATE_COIN condition, it returns 0.
|
||||
|
||||
(defun-inline output_value_for_condition (condition)
|
||||
(if (= (f condition) CREATE_COIN)
|
||||
(f (r (r condition)))
|
||||
0
|
||||
)
|
||||
)
|
||||
|
||||
;; add two conditions to the list of morphed conditions:
|
||||
;; CREATE_COIN_ANNOUNCEMENT for my announcement
|
||||
;; ASSERT_COIN_ANNOUNCEMENT for the next coin's announcement
|
||||
(defun-inline generate_final_output_conditions
|
||||
(
|
||||
prev_subtotal
|
||||
this_subtotal
|
||||
morphed_conditions
|
||||
prev_coin_id
|
||||
this_coin_id
|
||||
next_coin_id
|
||||
cat_mod_struct
|
||||
)
|
||||
(c (create_announcement_condition prev_coin_id prev_subtotal)
|
||||
(c (create_assert_next_announcement_condition this_coin_id this_subtotal next_coin_id cat_mod_struct)
|
||||
morphed_conditions)
|
||||
)
|
||||
)
|
||||
;; add two conditions to the list of morphed conditions:
|
||||
;; CREATE_COIN_ANNOUNCEMENT for my announcement
|
||||
;; ASSERT_COIN_ANNOUNCEMENT for the next coin's announcement
|
||||
(defun-inline generate_final_output_conditions
|
||||
(
|
||||
prev_subtotal
|
||||
this_subtotal
|
||||
morphed_conditions
|
||||
prev_coin_id
|
||||
this_coin_id
|
||||
next_coin_id
|
||||
cat_mod_struct
|
||||
)
|
||||
(c (create_announcement_condition prev_coin_id prev_subtotal)
|
||||
(c (create_assert_next_announcement_condition this_coin_id this_subtotal next_coin_id cat_mod_struct)
|
||||
morphed_conditions)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
;; This next section of code loops through all of the conditions to do three things:
|
||||
;; 1) Look for a "magic" value of -113 and, if one exists, filter it, and take note of the tail reveal and solution
|
||||
;; 2) Morph any CREATE_COIN or CREATE_COIN_ANNOUNCEMENT conditions
|
||||
;; 3) Sum the total output amount of all of the CREATE_COINs that are output by the inner puzzle
|
||||
;;
|
||||
;; After everything return a struct in the format (morphed_conditions . (output_sum . tail_reveal_and_solution))
|
||||
;; If multiple magic conditions are specified, the later one will take precedence
|
||||
;; This next section of code loops through all of the conditions to do three things:
|
||||
;; 1) Look for a "magic" value of -113 and, if one exists, filter it, and take note of the tail reveal and solution
|
||||
;; 2) Morph any CREATE_COIN or CREATE_COIN_ANNOUNCEMENT conditions
|
||||
;; 3) Sum the total output amount of all of the CREATE_COINs that are output by the inner puzzle
|
||||
;;
|
||||
;; After everything return a struct in the format (morphed_conditions . (output_sum . tail_reveal_and_solution))
|
||||
;; If multiple magic conditions are specified, the later one will take precedence
|
||||
|
||||
(defun-inline condition_tail_reveal (condition) (f (r (r (r condition)))))
|
||||
(defun-inline condition_tail_solution (condition) (f (r (r (r (r condition))))))
|
||||
(defun-inline condition_tail_reveal (condition) (f (r (r (r condition)))))
|
||||
(defun-inline condition_tail_solution (condition) (f (r (r (r (r condition))))))
|
||||
|
||||
(defun cons_onto_first_and_add_to_second (morphed_condition output_value struct)
|
||||
(c (c morphed_condition (f struct)) (c (+ output_value (f (r struct))) (r (r struct))))
|
||||
)
|
||||
(defun cons_onto_first_and_add_to_second (morphed_condition output_value struct)
|
||||
(c (c morphed_condition (f struct)) (c (+ output_value (f (r struct))) (r (r struct))))
|
||||
)
|
||||
|
||||
(defun find_and_strip_tail_info (inner_conditions cat_mod_struct tail_reveal_and_solution)
|
||||
(if inner_conditions
|
||||
(if (= (output_value_for_condition (f inner_conditions)) -113) ; Checks this is a CREATE_COIN of value -113
|
||||
(find_and_strip_tail_info
|
||||
(r inner_conditions)
|
||||
cat_mod_struct
|
||||
(c (condition_tail_reveal (f inner_conditions)) (condition_tail_solution (f inner_conditions)))
|
||||
)
|
||||
(cons_onto_first_and_add_to_second
|
||||
(morph_condition (f inner_conditions) cat_mod_struct)
|
||||
(output_value_for_condition (f inner_conditions))
|
||||
(find_and_strip_tail_info
|
||||
(r inner_conditions)
|
||||
cat_mod_struct
|
||||
tail_reveal_and_solution
|
||||
)
|
||||
)
|
||||
(defun find_and_strip_tail_info (inner_conditions cat_mod_struct tail_reveal_and_solution)
|
||||
(if inner_conditions
|
||||
(if (= (output_value_for_condition (f inner_conditions)) -113) ; Checks this is a CREATE_COIN of value -113
|
||||
(find_and_strip_tail_info
|
||||
(r inner_conditions)
|
||||
cat_mod_struct
|
||||
(c (condition_tail_reveal (f inner_conditions)) (condition_tail_solution (f inner_conditions)))
|
||||
)
|
||||
(c () (c 0 tail_reveal_and_solution))
|
||||
)
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;; lineage checking
|
||||
|
||||
;; return true iff parent of `this_coin_info` is provably a cat
|
||||
;; A 'lineage proof' consists of (parent_parent_id parent_INNER_puzzle_hash parent_amount)
|
||||
;; We use this information to construct a coin who's puzzle has been wrapped in this MOD and verify that,
|
||||
;; once wrapped, it matches our parent coin's ID.
|
||||
(defun-inline is_parent_cat (
|
||||
cat_mod_struct
|
||||
parent_id
|
||||
lineage_proof
|
||||
)
|
||||
(= parent_id
|
||||
(calculate_coin_id (f lineage_proof)
|
||||
(cat_puzzle_hash cat_mod_struct (f (r lineage_proof)))
|
||||
(f (r (r lineage_proof)))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(defun check_lineage_or_run_tail_program
|
||||
(
|
||||
this_coin_info
|
||||
tail_reveal_and_solution
|
||||
parent_is_cat ; flag which says whether or not the parent CAT check ran and passed
|
||||
lineage_proof
|
||||
Truths
|
||||
extra_delta
|
||||
inner_conditions
|
||||
)
|
||||
(if tail_reveal_and_solution
|
||||
(assert (= (sha256tree (f tail_reveal_and_solution)) (cat_tail_program_hash_truth Truths))
|
||||
(merge_list
|
||||
(a (f tail_reveal_and_solution)
|
||||
(list
|
||||
Truths
|
||||
parent_is_cat
|
||||
lineage_proof ; Lineage proof is only guaranteed to be true if parent_is_cat
|
||||
extra_delta
|
||||
inner_conditions
|
||||
(r tail_reveal_and_solution)
|
||||
)
|
||||
(cons_onto_first_and_add_to_second
|
||||
(morph_condition (f inner_conditions) cat_mod_struct)
|
||||
(output_value_for_condition (f inner_conditions))
|
||||
(find_and_strip_tail_info
|
||||
(r inner_conditions)
|
||||
cat_mod_struct
|
||||
tail_reveal_and_solution
|
||||
)
|
||||
)
|
||||
)
|
||||
(c () (c 0 tail_reveal_and_solution))
|
||||
)
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;; lineage checking
|
||||
|
||||
;; return true iff parent of `this_coin_info` is provably a cat
|
||||
;; A 'lineage proof' consists of (parent_parent_id parent_INNER_puzzle_hash parent_amount)
|
||||
;; We use this information to construct a coin who's puzzle has been wrapped in this MOD and verify that,
|
||||
;; once wrapped, it matches our parent coin's ID.
|
||||
(defun-inline is_parent_cat (
|
||||
cat_mod_struct
|
||||
parent_id
|
||||
lineage_proof
|
||||
)
|
||||
(= parent_id
|
||||
(calculate_coin_id (f lineage_proof)
|
||||
(cat_puzzle_hash cat_mod_struct (f (r lineage_proof)))
|
||||
(f (r (r lineage_proof)))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(defun check_lineage_or_run_tail_program
|
||||
(
|
||||
this_coin_info
|
||||
tail_reveal_and_solution
|
||||
parent_is_cat ; flag which says whether or not the parent CAT check ran and passed
|
||||
lineage_proof
|
||||
Truths
|
||||
extra_delta
|
||||
inner_conditions
|
||||
)
|
||||
(if tail_reveal_and_solution
|
||||
(assert (= (sha256tree (f tail_reveal_and_solution)) (cat_tail_program_hash_truth Truths))
|
||||
(merge_list
|
||||
(a (f tail_reveal_and_solution)
|
||||
(list
|
||||
Truths
|
||||
parent_is_cat
|
||||
lineage_proof ; Lineage proof is only guaranteed to be true if parent_is_cat
|
||||
extra_delta
|
||||
inner_conditions
|
||||
(r tail_reveal_and_solution)
|
||||
)
|
||||
inner_conditions
|
||||
)
|
||||
)
|
||||
(assert parent_is_cat (not extra_delta)
|
||||
inner_conditions
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defun stager_two (
|
||||
Truths
|
||||
(inner_conditions . (output_sum . tail_reveal_and_solution))
|
||||
lineage_proof
|
||||
prev_coin_id
|
||||
this_coin_info
|
||||
next_coin_id
|
||||
prev_subtotal
|
||||
extra_delta
|
||||
)
|
||||
(check_lineage_or_run_tail_program
|
||||
this_coin_info
|
||||
tail_reveal_and_solution
|
||||
(if lineage_proof (is_parent_cat (cat_struct_truth Truths) (my_parent_cat_truth Truths) lineage_proof) ())
|
||||
lineage_proof
|
||||
Truths
|
||||
extra_delta
|
||||
(generate_final_output_conditions
|
||||
prev_subtotal
|
||||
; the expression on the next line calculates `this_subtotal` by adding the delta to `prev_subtotal`
|
||||
(+ prev_subtotal (- (input_amount_for_coin this_coin_info) output_sum) extra_delta)
|
||||
inner_conditions
|
||||
prev_coin_id
|
||||
(my_id_cat_truth Truths)
|
||||
next_coin_id
|
||||
(cat_struct_truth Truths)
|
||||
)
|
||||
)
|
||||
(assert parent_is_cat (not extra_delta)
|
||||
inner_conditions
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
; CAT TRUTHS struct is: ; CAT Truths is: ((Inner puzzle hash . (MOD hash . (MOD hash hash . TAIL hash))) . (my_id . (my_parent_info my_puzhash my_amount)))
|
||||
; create truths - this_coin_info verified true because we calculated my ID from it!
|
||||
; lineage proof is verified later by cat parent check or tail_program
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defun stager (
|
||||
cat_mod_struct
|
||||
inner_conditions
|
||||
lineage_proof
|
||||
inner_puzzle_hash
|
||||
my_id
|
||||
prev_coin_id
|
||||
this_coin_info
|
||||
next_coin_proof
|
||||
(defun stager_two (
|
||||
Truths
|
||||
(inner_conditions . (output_sum . tail_reveal_and_solution))
|
||||
lineage_proof
|
||||
prev_coin_id
|
||||
this_coin_info
|
||||
next_coin_id
|
||||
prev_subtotal
|
||||
extra_delta
|
||||
)
|
||||
(check_lineage_or_run_tail_program
|
||||
this_coin_info
|
||||
tail_reveal_and_solution
|
||||
(if lineage_proof (is_parent_cat (cat_struct_truth Truths) (my_parent_cat_truth Truths) lineage_proof) ())
|
||||
lineage_proof
|
||||
Truths
|
||||
extra_delta
|
||||
(generate_final_output_conditions
|
||||
prev_subtotal
|
||||
extra_delta
|
||||
)
|
||||
(c (list ASSERT_MY_COIN_ID my_id) (stager_two
|
||||
; the expression on the next line calculates `this_subtotal` by adding the delta to `prev_subtotal`
|
||||
(+ prev_subtotal (- (input_amount_for_coin this_coin_info) output_sum) extra_delta)
|
||||
inner_conditions
|
||||
prev_coin_id
|
||||
(my_id_cat_truth Truths)
|
||||
next_coin_id
|
||||
(cat_struct_truth Truths)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
; CAT TRUTHS struct is: ; CAT Truths is: ((Inner puzzle hash . (MOD hash . (MOD hash hash . TAIL hash))) . (my_id . (my_parent_info my_puzhash my_amount)))
|
||||
; create truths - this_coin_info verified true because we calculated my ID from it!
|
||||
; lineage proof is verified later by cat parent check or tail_program
|
||||
|
||||
(defun stager (
|
||||
cat_mod_struct
|
||||
inner_conditions
|
||||
lineage_proof
|
||||
inner_puzzle_hash
|
||||
my_id
|
||||
prev_coin_id
|
||||
this_coin_info
|
||||
next_coin_proof
|
||||
prev_subtotal
|
||||
extra_delta
|
||||
)
|
||||
(c (list ASSERT_MY_COIN_ID my_id) (stager_two
|
||||
(cat_truth_data_to_truth_struct
|
||||
inner_puzzle_hash
|
||||
cat_mod_struct
|
||||
|
@ -378,20 +378,20 @@
|
|||
(coin_id_for_proof next_coin_proof cat_mod_struct)
|
||||
prev_subtotal
|
||||
extra_delta
|
||||
))
|
||||
)
|
||||
))
|
||||
)
|
||||
|
||||
(stager
|
||||
;; calculate cat_mod_struct, inner_puzzle_hash, coin_id
|
||||
(list MOD_HASH (sha256 ONE MOD_HASH) TAIL_PROGRAM_HASH)
|
||||
(a INNER_PUZZLE inner_puzzle_solution)
|
||||
lineage_proof
|
||||
(sha256tree INNER_PUZZLE)
|
||||
(calculate_coin_id (f this_coin_info) (f (r this_coin_info)) (f (r (r this_coin_info))))
|
||||
prev_coin_id ; ID
|
||||
this_coin_info ; (parent_id puzzle_hash amount)
|
||||
next_coin_proof ; (parent_id innerpuzhash amount)
|
||||
prev_subtotal
|
||||
extra_delta
|
||||
)
|
||||
(stager
|
||||
;; calculate cat_mod_struct, inner_puzzle_hash, coin_id
|
||||
(list MOD_HASH (sha256 ONE MOD_HASH) TAIL_PROGRAM_HASH)
|
||||
(a INNER_PUZZLE inner_puzzle_solution)
|
||||
lineage_proof
|
||||
(sha256tree INNER_PUZZLE)
|
||||
(calculate_coin_id (f this_coin_info) (f (r this_coin_info)) (f (r (r this_coin_info))))
|
||||
prev_coin_id ; ID
|
||||
this_coin_info ; (parent_id puzzle_hash amount)
|
||||
next_coin_proof ; (parent_id innerpuzhash amount)
|
||||
prev_subtotal
|
||||
extra_delta
|
||||
)
|
||||
)
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
(defun sexp_from_stream (input_stream)
|
||||
(if (= (substr input_stream 0 1) CONS_BOX_MARKER)
|
||||
(cons_sexp_from_stream (sexp_from_stream (substr input_stream 1)))
|
||||
(atom_from_stream (substr input_stream 1) (substr input_stream 0 1))
|
||||
(cons_sexp_from_stream (sexp_from_stream (substr input_stream 1)))
|
||||
(atom_from_stream (substr input_stream 1) (substr input_stream 0 1))
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -33,11 +33,11 @@
|
|||
|
||||
(defun atom_from_stream (input_file input_bits)
|
||||
(if (= input_bits (quote 0x80))
|
||||
(list () input_file)
|
||||
(if (>s input_bits MAX_SINGLE_BYTE)
|
||||
(atom_from_stream_part_two (get_bitcount input_bits input_file))
|
||||
(list input_bits input_file)
|
||||
)
|
||||
(list () input_file)
|
||||
(if (>s input_bits MAX_SINGLE_BYTE)
|
||||
(atom_from_stream_part_two (get_bitcount input_bits input_file))
|
||||
(list input_bits input_file)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -49,13 +49,13 @@
|
|||
; are implemented in the clvm interpreters theselves
|
||||
(defun-inline get_bitcount (input_bits input_file)
|
||||
(if (>s input_bits MAX_TWO_BYTE)
|
||||
(if (>s input_bits MAX_THREE_BYTE)
|
||||
(x)
|
||||
;three byte length prefix
|
||||
(list (concat (logand (quote 0x1f) input_bits) (substr input_file 0 1)) (substr input_file 1))
|
||||
)
|
||||
;two byte length prefix
|
||||
(list (logand (quote 0x3f) input_bits) input_file)
|
||||
(if (>s input_bits MAX_THREE_BYTE)
|
||||
(x)
|
||||
;three byte length prefix
|
||||
(list (concat (logand (quote 0x1f) input_bits) (substr input_file 0 1)) (substr input_file 1))
|
||||
)
|
||||
;two byte length prefix
|
||||
(list (logand (quote 0x3f) input_bits) input_file)
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -1,59 +1,59 @@
|
|||
; See chia/types/condition_opcodes.py
|
||||
|
||||
(
|
||||
(defconstant AGG_SIG_UNSAFE 49)
|
||||
(defconstant AGG_SIG_ME 50)
|
||||
(defconstant AGG_SIG_UNSAFE 49)
|
||||
(defconstant AGG_SIG_ME 50)
|
||||
|
||||
; the conditions below reserve coin amounts and have to be accounted for in output totals
|
||||
; the conditions below reserve coin amounts and have to be accounted for in output totals
|
||||
|
||||
(defconstant CREATE_COIN 51)
|
||||
(defconstant RESERVE_FEE 52)
|
||||
(defconstant CREATE_COIN 51)
|
||||
(defconstant RESERVE_FEE 52)
|
||||
|
||||
; the conditions below deal with announcements, for inter-coin communication
|
||||
; the conditions below deal with announcements, for inter-coin communication
|
||||
|
||||
; coin announcements
|
||||
(defconstant CREATE_COIN_ANNOUNCEMENT 60)
|
||||
(defconstant ASSERT_COIN_ANNOUNCEMENT 61)
|
||||
; coin announcements
|
||||
(defconstant CREATE_COIN_ANNOUNCEMENT 60)
|
||||
(defconstant ASSERT_COIN_ANNOUNCEMENT 61)
|
||||
|
||||
; puzzle announcements
|
||||
(defconstant CREATE_PUZZLE_ANNOUNCEMENT 62)
|
||||
(defconstant ASSERT_PUZZLE_ANNOUNCEMENT 63)
|
||||
; puzzle announcements
|
||||
(defconstant CREATE_PUZZLE_ANNOUNCEMENT 62)
|
||||
(defconstant ASSERT_PUZZLE_ANNOUNCEMENT 63)
|
||||
|
||||
; coin-id
|
||||
(defconstant ASSERT_CONCURRENT_SPEND 64)
|
||||
; puzzle-hash
|
||||
(defconstant ASSERT_CONCURRENT_PUZZLE 65)
|
||||
; coin-id
|
||||
(defconstant ASSERT_CONCURRENT_SPEND 64)
|
||||
; puzzle-hash
|
||||
(defconstant ASSERT_CONCURRENT_PUZZLE 65)
|
||||
|
||||
; the conditions below let coins inquire about themselves
|
||||
; the conditions below let coins inquire about themselves
|
||||
|
||||
(defconstant ASSERT_MY_COIN_ID 70)
|
||||
(defconstant ASSERT_MY_PARENT_ID 71)
|
||||
(defconstant ASSERT_MY_PUZZLEHASH 72)
|
||||
(defconstant ASSERT_MY_AMOUNT 73)
|
||||
(defconstant ASSERT_MY_BIRTH_SECONDS 74)
|
||||
(defconstant ASSERT_MY_BIRTH_HEIGHT 75)
|
||||
(defconstant ASSERT_EPHEMERAL 76)
|
||||
(defconstant ASSERT_MY_COIN_ID 70)
|
||||
(defconstant ASSERT_MY_PARENT_ID 71)
|
||||
(defconstant ASSERT_MY_PUZZLEHASH 72)
|
||||
(defconstant ASSERT_MY_AMOUNT 73)
|
||||
(defconstant ASSERT_MY_BIRTH_SECONDS 74)
|
||||
(defconstant ASSERT_MY_BIRTH_HEIGHT 75)
|
||||
(defconstant ASSERT_EPHEMERAL 76)
|
||||
|
||||
; the conditions below ensure that we're "far enough" in the future
|
||||
; the conditions below ensure that we're "far enough" in the future
|
||||
|
||||
; wall-clock time
|
||||
(defconstant ASSERT_SECONDS_RELATIVE 80)
|
||||
(defconstant ASSERT_SECONDS_ABSOLUTE 81)
|
||||
; wall-clock time
|
||||
(defconstant ASSERT_SECONDS_RELATIVE 80)
|
||||
(defconstant ASSERT_SECONDS_ABSOLUTE 81)
|
||||
|
||||
; block index
|
||||
(defconstant ASSERT_HEIGHT_RELATIVE 82)
|
||||
(defconstant ASSERT_HEIGHT_ABSOLUTE 83)
|
||||
; block index
|
||||
(defconstant ASSERT_HEIGHT_RELATIVE 82)
|
||||
(defconstant ASSERT_HEIGHT_ABSOLUTE 83)
|
||||
|
||||
; the conditions below ensure that we're "not too far" in the future
|
||||
; the conditions below ensure that we're "not too far" in the future
|
||||
|
||||
; wall-clock time
|
||||
(defconstant ASSERT_BEFORE_SECONDS_RELATIVE 84)
|
||||
(defconstant ASSERT_BEFORE_SECONDS_ABSOLUTE 85)
|
||||
; wall-clock time
|
||||
(defconstant ASSERT_BEFORE_SECONDS_RELATIVE 84)
|
||||
(defconstant ASSERT_BEFORE_SECONDS_ABSOLUTE 85)
|
||||
|
||||
; block index
|
||||
(defconstant ASSERT_BEFORE_HEIGHT_RELATIVE 86)
|
||||
(defconstant ASSERT_BEFORE_HEIGHT_ABSOLUTE 87)
|
||||
; block index
|
||||
(defconstant ASSERT_BEFORE_HEIGHT_RELATIVE 86)
|
||||
(defconstant ASSERT_BEFORE_HEIGHT_ABSOLUTE 87)
|
||||
|
||||
; A condition that is always true and always ignore all arguments
|
||||
(defconstant REMARK 1)
|
||||
; A condition that is always true and always ignore all arguments
|
||||
(defconstant REMARK 1)
|
||||
)
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
; my-id is there on a discarded branch of the tree as a signal to another piece of code
|
||||
; that will be checking if a coin whose puzzle is of this form, was created or spent.
|
||||
(
|
||||
(defun-inline create-lock-puzzlehash (my-id)
|
||||
(sha256tree (list r
|
||||
(list c
|
||||
(list q
|
||||
my-id)
|
||||
(q (q ()))))))
|
||||
)
|
||||
(defun-inline create-lock-puzzlehash (my-id)
|
||||
(sha256tree (list r
|
||||
(list c
|
||||
(list q
|
||||
my-id)
|
||||
(q (q ()))))))
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(mod (LAUNCHER_PH MINT_NUMBER MINT_TOTAL)
|
||||
(include condition_codes.clib)
|
||||
(list
|
||||
(list CREATE_COIN LAUNCHER_PH 1)
|
||||
(list CREATE_COIN_ANNOUNCEMENT (sha256 MINT_NUMBER MINT_TOTAL)))
|
||||
)
|
||||
(include condition_codes.clib)
|
||||
(list
|
||||
(list CREATE_COIN LAUNCHER_PH 1)
|
||||
(list CREATE_COIN_ANNOUNCEMENT (sha256 MINT_NUMBER MINT_TOTAL)))
|
||||
)
|
||||
|
|
|
@ -23,20 +23,20 @@
|
|||
;; Note that `(c (q . P) E)` = `(c . ((q . P) . (E . 0)))`
|
||||
|
||||
(defun-inline update-hash-for-parameter-hash (parameter-hash environment-hash)
|
||||
(sha256 TWO (sha256 ONE C_KW)
|
||||
(sha256 TWO (sha256 TWO (sha256 ONE Q_KW) parameter-hash)
|
||||
(sha256 TWO environment-hash (sha256 ONE 0))))
|
||||
(sha256 TWO (sha256 ONE C_KW)
|
||||
(sha256 TWO (sha256 TWO (sha256 ONE Q_KW) parameter-hash)
|
||||
(sha256 TWO environment-hash (sha256 ONE 0))))
|
||||
)
|
||||
|
||||
;; This function recursively calls `update-hash-for-parameter-hash`, updating `environment-hash`
|
||||
;; along the way.
|
||||
|
||||
(defun build-curry-list (reversed-curry-parameter-hashes environment-hash)
|
||||
(if reversed-curry-parameter-hashes
|
||||
(build-curry-list (r reversed-curry-parameter-hashes)
|
||||
(update-hash-for-parameter-hash (f reversed-curry-parameter-hashes) environment-hash))
|
||||
environment-hash
|
||||
)
|
||||
(if reversed-curry-parameter-hashes
|
||||
(build-curry-list (r reversed-curry-parameter-hashes)
|
||||
(update-hash-for-parameter-hash (f reversed-curry-parameter-hashes) environment-hash))
|
||||
environment-hash
|
||||
)
|
||||
)
|
||||
|
||||
;; Given the tree hash `environment-hash` of an environment tree E
|
||||
|
@ -49,9 +49,9 @@
|
|||
;; Note that `(a (q . F) E)` = `(a . ((q . F) . (E . 0)))`
|
||||
|
||||
(defun-inline tree-hash-of-apply (function-hash environment-hash)
|
||||
(sha256 TWO (sha256 ONE A_KW)
|
||||
(sha256 TWO (sha256 TWO (sha256 ONE Q_KW) function-hash)
|
||||
(sha256 TWO environment-hash (sha256 ONE 0))))
|
||||
(sha256 TWO (sha256 ONE A_KW)
|
||||
(sha256 TWO (sha256 TWO (sha256 ONE Q_KW) function-hash)
|
||||
(sha256 TWO environment-hash (sha256 ONE 0))))
|
||||
)
|
||||
|
||||
;; DO NOT USE THIS FUNCTION GOING FORWARD. Having to pass the arguments in reverse order is stupid.
|
||||
|
@ -76,8 +76,8 @@
|
|||
|
||||
;; DO NOT USE
|
||||
(defun puzzle-hash-of-curried-function (function-hash . reversed-curry-parameter-hashes)
|
||||
(tree-hash-of-apply function-hash
|
||||
(build-curry-list reversed-curry-parameter-hashes (sha256 ONE ONE)))
|
||||
(tree-hash-of-apply function-hash
|
||||
(build-curry-list reversed-curry-parameter-hashes (sha256 ONE ONE)))
|
||||
)
|
||||
|
||||
(defconstant b32 32)
|
||||
|
@ -88,15 +88,15 @@
|
|||
|
||||
(defun calculate_coin_id (parent puzzlehash amount)
|
||||
(if (all (size_b32 parent) (size_b32 puzzlehash) (> amount -1))
|
||||
(sha256 parent puzzlehash amount)
|
||||
(x)
|
||||
(sha256 parent puzzlehash amount)
|
||||
(x)
|
||||
)
|
||||
)
|
||||
|
||||
; takes a lisp tree and returns the hash of it
|
||||
(defun sha256tree (TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)))
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)))
|
||||
|
||||
)
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
|
||||
(defconstant TWO 2)
|
||||
(defconstant constant_tree (
|
||||
(0x4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a . ; = `(sha256 1)`
|
||||
(0x4bf5122f344554c53bde2ebb8cd2b7e3d1600ad631c385a5d7cce23c7785459a . ; = `(sha256 1)`
|
||||
0x9dcf97a184f32623d11a73124ceb99a5709b083721e878a16d78f596718ba7b2) . ; = `(sha256 1 1)` = `(sha256 1 #q)`
|
||||
(0x02a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222 . ; = `(concat 2 (sha256 1 #a))`
|
||||
(0x02a12871fee210fb8619291eaea194581cbd2531e4b23759d225f6806923f63222 . ; = `(concat 2 (sha256 1 #a))`
|
||||
0x02a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e7298a91ce119a63400ade7c5) ; = `(concat 2 (sha256 1 #c))`
|
||||
)
|
||||
)
|
||||
|
@ -28,8 +28,8 @@
|
|||
|
||||
;; this returns the sha256 tree hash of expression F = `((q . a1) a2)`
|
||||
(defun hash_expression_F (a1 a2)
|
||||
(sha256 TWO (sha256 TWO (sha256_one_one) a1)
|
||||
(sha256 TWO a2 (sha256_one)))
|
||||
(sha256 TWO (sha256 TWO (sha256_one_one) a1)
|
||||
(sha256 TWO a2 (sha256_one)))
|
||||
)
|
||||
|
||||
;; Given the tree hash `environment_hash` of an environment tree E
|
||||
|
@ -41,7 +41,7 @@
|
|||
;; Note that `(c (q . P) E)` = `(c . ((q . P) . (E . 0)))`
|
||||
|
||||
(defun-inline update_hash_for_parameter_hash (parameter_hash environment_hash)
|
||||
(sha256 (two_sha256_one_c_kw) (hash_expression_F parameter_hash environment_hash))
|
||||
(sha256 (two_sha256_one_c_kw) (hash_expression_F parameter_hash environment_hash))
|
||||
)
|
||||
|
||||
;; Given the tree hash `environment_hash` of an environment tree E
|
||||
|
@ -54,16 +54,16 @@
|
|||
;; Note that `(a (q . M) E)` = `(a . ((q . M) . (E . 0)))`
|
||||
|
||||
(defun-inline tree_hash_of_apply (mod_hash environment_hash)
|
||||
(sha256 (two_sha256_one_a_kw) (hash_expression_F mod_hash environment_hash))
|
||||
(sha256 (two_sha256_one_a_kw) (hash_expression_F mod_hash environment_hash))
|
||||
)
|
||||
|
||||
;; This function recursively calls `update_hash_for_parameter_hash`
|
||||
|
||||
(defun calculate_hash_of_curried_parameters (curry_parameter_hashes)
|
||||
(if curry_parameter_hashes
|
||||
(update_hash_for_parameter_hash (f curry_parameter_hashes) (calculate_hash_of_curried_parameters (r curry_parameter_hashes)))
|
||||
(sha256_one_one)
|
||||
)
|
||||
(if curry_parameter_hashes
|
||||
(update_hash_for_parameter_hash (f curry_parameter_hashes) (calculate_hash_of_curried_parameters (r curry_parameter_hashes)))
|
||||
(sha256_one_one)
|
||||
)
|
||||
)
|
||||
|
||||
;; mod_hash:
|
||||
|
@ -82,8 +82,8 @@
|
|||
;; inline functions that take varargs don't seem to work, so we can't inline `curry`
|
||||
|
||||
(defun curry_hashes (mod_hash . curry_parameter_hashes)
|
||||
(tree_hash_of_apply mod_hash
|
||||
(calculate_hash_of_curried_parameters curry_parameter_hashes))
|
||||
(tree_hash_of_apply mod_hash
|
||||
(calculate_hash_of_curried_parameters curry_parameter_hashes))
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
; This is a "limitations_program" for use with cat.clsp.
|
||||
(mod (
|
||||
PUBKEY
|
||||
Truths
|
||||
parent_is_cat
|
||||
lineage_proof
|
||||
delta
|
||||
inner_conditions
|
||||
(
|
||||
delegated_puzzle
|
||||
delegated_solution
|
||||
)
|
||||
PUBKEY
|
||||
Truths
|
||||
parent_is_cat
|
||||
lineage_proof
|
||||
delta
|
||||
inner_conditions
|
||||
(
|
||||
delegated_puzzle
|
||||
delegated_solution
|
||||
)
|
||||
)
|
||||
|
||||
(include condition_codes.clib)
|
||||
(include condition_codes.clib)
|
||||
|
||||
(defun sha256tree1 (TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)))
|
||||
(defun sha256tree1 (TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)))
|
||||
|
||||
(c (list AGG_SIG_UNSAFE PUBKEY (sha256tree1 delegated_puzzle))
|
||||
(a delegated_puzzle (c Truths (c parent_is_cat (c lineage_proof (c delta (c inner_conditions delegated_solution))))))
|
||||
)
|
||||
(c (list AGG_SIG_UNSAFE PUBKEY (sha256tree1 delegated_puzzle))
|
||||
(a delegated_puzzle (c Truths (c parent_is_cat (c lineage_proof (c delta (c inner_conditions delegated_solution))))))
|
||||
)
|
||||
)
|
||||
|
|
|
@ -5,19 +5,19 @@
|
|||
|
||||
(mod
|
||||
(
|
||||
INNER_PUZZLE ; Standard P2 inner puzzle, used to record the ownership of the DID.
|
||||
RECOVERY_DID_LIST_HASH ; the list of DIDs that can send messages to you for recovery we store only the hash so that we don't have to reveal every time we make a message spend
|
||||
NUM_VERIFICATIONS_REQUIRED ; how many of the above list are required for a recovery
|
||||
SINGLETON_STRUCT ; my singleton_struct, formerly a Truth - ((SINGLETON_MOD_HASH, (LAUNCHER_ID, LAUNCHER_PUZZLE_HASH)))
|
||||
METADATA ; Customized metadata, e.g KYC info
|
||||
mode ; this indicates which spend mode we want. 0. Recovery mode 1. Run INNER_PUZZLE with p2_solution
|
||||
my_amount_or_inner_solution ; In mode 0, we use this to recover our coin and assert it is our actual amount
|
||||
; In mode 1 this is the solution of the inner P2 puzzle, only required in the create message mode and transfer mode.
|
||||
new_inner_puzhash ; In recovery mode, this will be the new wallet DID puzzle hash
|
||||
parent_innerpuzhash_amounts_for_recovery_ids ; during a recovery we need extra information about our recovery list coins
|
||||
pubkey ; this is the new pubkey used for a recovery
|
||||
recovery_list_reveal ; this is the reveal of the stored list of DIDs approved for recovery
|
||||
my_id ; my coin ID
|
||||
INNER_PUZZLE ; Standard P2 inner puzzle, used to record the ownership of the DID.
|
||||
RECOVERY_DID_LIST_HASH ; the list of DIDs that can send messages to you for recovery we store only the hash so that we don't have to reveal every time we make a message spend
|
||||
NUM_VERIFICATIONS_REQUIRED ; how many of the above list are required for a recovery
|
||||
SINGLETON_STRUCT ; my singleton_struct, formerly a Truth - ((SINGLETON_MOD_HASH, (LAUNCHER_ID, LAUNCHER_PUZZLE_HASH)))
|
||||
METADATA ; Customized metadata, e.g KYC info
|
||||
mode ; this indicates which spend mode we want. 0. Recovery mode 1. Run INNER_PUZZLE with p2_solution
|
||||
my_amount_or_inner_solution ; In mode 0, we use this to recover our coin and assert it is our actual amount
|
||||
; In mode 1 this is the solution of the inner P2 puzzle, only required in the create message mode and transfer mode.
|
||||
new_inner_puzhash ; In recovery mode, this will be the new wallet DID puzzle hash
|
||||
parent_innerpuzhash_amounts_for_recovery_ids ; during a recovery we need extra information about our recovery list coins
|
||||
pubkey ; this is the new pubkey used for a recovery
|
||||
recovery_list_reveal ; this is the reveal of the stored list of DIDs approved for recovery
|
||||
my_id ; my coin ID
|
||||
)
|
||||
;message is the new puzzle in the recovery and standard spend cases
|
||||
|
||||
|
@ -29,10 +29,10 @@
|
|||
|
||||
; takes a lisp tree and returns the hash of it
|
||||
(defun sha256tree1 (TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
; recovery message module - gets values curried in to make the puzzle
|
||||
|
@ -54,10 +54,10 @@
|
|||
; return the full puzzlehash for a singleton with the innerpuzzle curried in
|
||||
; puzzle-hash-of-curried-function is imported from curry-and-treehash.clib
|
||||
(defun-inline calculate_full_puzzle_hash (SINGLETON_STRUCT inner_puzzle_hash)
|
||||
(puzzle-hash-of-curried-function (f SINGLETON_STRUCT)
|
||||
inner_puzzle_hash
|
||||
(sha256tree1 SINGLETON_STRUCT)
|
||||
)
|
||||
(puzzle-hash-of-curried-function (f SINGLETON_STRUCT)
|
||||
inner_puzzle_hash
|
||||
(sha256tree1 SINGLETON_STRUCT)
|
||||
)
|
||||
)
|
||||
|
||||
; this loops over our identities to check list, and checks if we have been given parent information for this identity
|
||||
|
@ -66,48 +66,48 @@
|
|||
|
||||
(defun check_messages_from_identities (SINGLETON_STRUCT num_verifications_required identities my_id new_puz parent_innerpuzhash_amounts_for_recovery_ids pubkey num_verifications)
|
||||
(if identities
|
||||
(if (f parent_innerpuzhash_amounts_for_recovery_ids)
|
||||
; if we have parent information then we should create a consume coin condition
|
||||
(c
|
||||
(create_consume_message
|
||||
; create coin_id from DID
|
||||
(create_coin_ID_for_recovery
|
||||
(if (f parent_innerpuzhash_amounts_for_recovery_ids)
|
||||
; if we have parent information then we should create a consume coin condition
|
||||
(c
|
||||
(create_consume_message
|
||||
; create coin_id from DID
|
||||
(create_coin_ID_for_recovery
|
||||
SINGLETON_STRUCT
|
||||
(f identities)
|
||||
(f (f parent_innerpuzhash_amounts_for_recovery_ids))
|
||||
(f (r (f parent_innerpuzhash_amounts_for_recovery_ids)))
|
||||
(f (r (r (f parent_innerpuzhash_amounts_for_recovery_ids)))))
|
||||
my_id
|
||||
new_puz
|
||||
pubkey
|
||||
)
|
||||
(check_messages_from_identities
|
||||
SINGLETON_STRUCT
|
||||
num_verifications_required
|
||||
(r identities)
|
||||
my_id
|
||||
new_puz
|
||||
(r parent_innerpuzhash_amounts_for_recovery_ids)
|
||||
pubkey
|
||||
(+ num_verifications 1)
|
||||
)
|
||||
)
|
||||
; if no parent information found for this identity, move on to next in list
|
||||
(check_messages_from_identities
|
||||
SINGLETON_STRUCT
|
||||
(f identities)
|
||||
(f (f parent_innerpuzhash_amounts_for_recovery_ids))
|
||||
(f (r (f parent_innerpuzhash_amounts_for_recovery_ids)))
|
||||
(f (r (r (f parent_innerpuzhash_amounts_for_recovery_ids)))))
|
||||
my_id
|
||||
new_puz
|
||||
pubkey
|
||||
)
|
||||
(check_messages_from_identities
|
||||
SINGLETON_STRUCT
|
||||
num_verifications_required
|
||||
(r identities)
|
||||
my_id
|
||||
new_puz
|
||||
(r parent_innerpuzhash_amounts_for_recovery_ids)
|
||||
pubkey
|
||||
(+ num_verifications 1)
|
||||
)
|
||||
(r identities)
|
||||
my_id
|
||||
new_puz
|
||||
(r parent_innerpuzhash_amounts_for_recovery_ids)
|
||||
pubkey
|
||||
num_verifications
|
||||
)
|
||||
)
|
||||
; if no parent information found for this identity, move on to next in list
|
||||
(check_messages_from_identities
|
||||
SINGLETON_STRUCT
|
||||
(r identities)
|
||||
my_id
|
||||
new_puz
|
||||
(r parent_innerpuzhash_amounts_for_recovery_ids)
|
||||
pubkey
|
||||
num_verifications
|
||||
;if we're out of identites to check for, check we have enough
|
||||
(if (> num_verifications (- num_verifications_required 1))
|
||||
(list (list AGG_SIG_UNSAFE pubkey new_puz) )
|
||||
(x)
|
||||
)
|
||||
)
|
||||
;if we're out of identites to check for, check we have enough
|
||||
(if (> num_verifications (- num_verifications_required 1))
|
||||
(list (list AGG_SIG_UNSAFE pubkey new_puz) )
|
||||
(x)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -117,19 +117,19 @@
|
|||
|
||||
;MAIN
|
||||
(if mode
|
||||
; mode 1 - run INNER_PUZZLE
|
||||
(a INNER_PUZZLE my_amount_or_inner_solution)
|
||||
; mode 1 - run INNER_PUZZLE
|
||||
(a INNER_PUZZLE my_amount_or_inner_solution)
|
||||
|
||||
; mode 0 - recovery
|
||||
(if (all (= (sha256tree1 recovery_list_reveal) RECOVERY_DID_LIST_HASH) (> NUM_VERIFICATIONS_REQUIRED 0))
|
||||
(c (list ASSERT_MY_AMOUNT my_amount_or_inner_solution)
|
||||
(c (list CREATE_COIN new_inner_puzhash my_amount_or_inner_solution (list new_inner_puzhash))
|
||||
(c (list ASSERT_MY_COIN_ID my_id)
|
||||
; mode 0 - recovery
|
||||
(if (all (= (sha256tree1 recovery_list_reveal) RECOVERY_DID_LIST_HASH) (> NUM_VERIFICATIONS_REQUIRED 0))
|
||||
(c (list ASSERT_MY_AMOUNT my_amount_or_inner_solution)
|
||||
(c (list CREATE_COIN new_inner_puzhash my_amount_or_inner_solution (list new_inner_puzhash))
|
||||
(c (list ASSERT_MY_COIN_ID my_id)
|
||||
(check_messages_from_identities SINGLETON_STRUCT NUM_VERIFICATIONS_REQUIRED recovery_list_reveal my_id new_inner_puzhash parent_innerpuzhash_amounts_for_recovery_ids pubkey 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(x)
|
||||
)
|
||||
(x)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
; This is a "limitations_program" for use with cat.clsp.
|
||||
(mod (
|
||||
PUBKEY
|
||||
Truths
|
||||
parent_is_cat
|
||||
lineage_proof
|
||||
delta
|
||||
inner_conditions
|
||||
_
|
||||
)
|
||||
PUBKEY
|
||||
Truths
|
||||
parent_is_cat
|
||||
lineage_proof
|
||||
delta
|
||||
inner_conditions
|
||||
_
|
||||
)
|
||||
|
||||
(include condition_codes.clib)
|
||||
(include condition_codes.clib)
|
||||
|
||||
(list (list AGG_SIG_ME PUBKEY delta)) ; Careful with a delta of zero, the bytecode is 80 not 00
|
||||
(list (list AGG_SIG_ME PUBKEY delta)) ; Careful with a delta of zero, the bytecode is 80 not 00
|
||||
)
|
||||
|
|
|
@ -4,23 +4,23 @@
|
|||
;
|
||||
; The genesis_id is curried in, making this lineage_check program unique and giving the CAT it's uniqueness
|
||||
(mod (
|
||||
GENESIS_ID
|
||||
Truths
|
||||
parent_is_cat
|
||||
lineage_proof
|
||||
delta
|
||||
inner_conditions
|
||||
_
|
||||
)
|
||||
GENESIS_ID
|
||||
Truths
|
||||
parent_is_cat
|
||||
lineage_proof
|
||||
delta
|
||||
inner_conditions
|
||||
_
|
||||
)
|
||||
|
||||
(include cat_truths.clib)
|
||||
(include cat_truths.clib)
|
||||
|
||||
(if delta
|
||||
(x)
|
||||
(if (= (my_parent_cat_truth Truths) GENESIS_ID)
|
||||
(if delta
|
||||
(x)
|
||||
(if (= (my_parent_cat_truth Truths) GENESIS_ID)
|
||||
()
|
||||
(x)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
)
|
||||
|
|
|
@ -2,23 +2,23 @@
|
|||
;
|
||||
; This checker allows new CATs to be created if their parent has a particular puzzle hash
|
||||
(mod (
|
||||
GENESIS_PUZZLE_HASH
|
||||
Truths
|
||||
parent_is_cat
|
||||
lineage_proof
|
||||
delta
|
||||
inner_conditions
|
||||
(parent_parent_id parent_amount)
|
||||
)
|
||||
GENESIS_PUZZLE_HASH
|
||||
Truths
|
||||
parent_is_cat
|
||||
lineage_proof
|
||||
delta
|
||||
inner_conditions
|
||||
(parent_parent_id parent_amount)
|
||||
)
|
||||
|
||||
(include cat_truths.clib)
|
||||
(include cat_truths.clib)
|
||||
|
||||
; Returns nil since we don't need to add any conditions
|
||||
(if delta
|
||||
(x)
|
||||
(if (= (sha256 parent_parent_id GENESIS_PUZZLE_HASH parent_amount) (my_parent_cat_truth Truths))
|
||||
()
|
||||
(x)
|
||||
)
|
||||
)
|
||||
; Returns nil since we don't need to add any conditions
|
||||
(if delta
|
||||
(x)
|
||||
(if (= (sha256 parent_parent_id GENESIS_PUZZLE_HASH parent_amount) (my_parent_cat_truth Truths))
|
||||
()
|
||||
(x)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -16,21 +16,21 @@
|
|||
(include curry-and-treehash.clib)
|
||||
|
||||
(defmacro assert items
|
||||
(if (r items)
|
||||
(list if (f items) (c assert (r items)) (q . (x)))
|
||||
(f items)
|
||||
)
|
||||
(if (r items)
|
||||
(list if (f items) (c assert (r items)) (q . (x)))
|
||||
(f items)
|
||||
)
|
||||
)
|
||||
|
||||
(defun-inline construct_singleton (SINGLETON_STRUCT METADATA_LAYER_HASH new_metadata new_metadata_updater new_inner_puz)
|
||||
(puzzle-hash-of-curried-function (f SINGLETON_STRUCT)
|
||||
(puzzle-hash-of-curried-function METADATA_LAYER_HASH
|
||||
new_inner_puz
|
||||
(sha256tree new_metadata_updater)
|
||||
(sha256tree new_metadata)
|
||||
(sha256tree METADATA_LAYER_HASH)
|
||||
)
|
||||
(sha256tree SINGLETON_STRUCT)
|
||||
(puzzle-hash-of-curried-function METADATA_LAYER_HASH
|
||||
new_inner_puz
|
||||
(sha256tree new_metadata_updater)
|
||||
(sha256tree new_metadata)
|
||||
(sha256tree METADATA_LAYER_HASH)
|
||||
)
|
||||
(sha256tree SINGLETON_STRUCT)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -57,44 +57,44 @@
|
|||
)
|
||||
|
||||
(if SINGLETON_STRUCTS
|
||||
(assert (verify_proofs (f (f new_metadatas)) (f VALUES_TO_PROVE) (f proofs_of_inclusion))
|
||||
; then
|
||||
(loop_over_curried_params
|
||||
(r SINGLETON_STRUCTS)
|
||||
(r METADATA_LAYER_HASHES)
|
||||
(r VALUES_TO_PROVE)
|
||||
(r proofs_of_inclusion)
|
||||
(r new_metadatas)
|
||||
(r new_metadata_updaters)
|
||||
(r new_inner_puzs)
|
||||
(c
|
||||
(list
|
||||
ASSERT_PUZZLE_ANNOUNCEMENT
|
||||
(sha256
|
||||
(construct_singleton (f SINGLETON_STRUCTS) (f METADATA_LAYER_HASHES) (f new_metadatas) (f new_metadata_updaters) (f new_inner_puzs))
|
||||
'$'
|
||||
(assert (verify_proofs (f (f new_metadatas)) (f VALUES_TO_PROVE) (f proofs_of_inclusion))
|
||||
; then
|
||||
(loop_over_curried_params
|
||||
(r SINGLETON_STRUCTS)
|
||||
(r METADATA_LAYER_HASHES)
|
||||
(r VALUES_TO_PROVE)
|
||||
(r proofs_of_inclusion)
|
||||
(r new_metadatas)
|
||||
(r new_metadata_updaters)
|
||||
(r new_inner_puzs)
|
||||
(c
|
||||
(list
|
||||
ASSERT_PUZZLE_ANNOUNCEMENT
|
||||
(sha256
|
||||
(construct_singleton (f SINGLETON_STRUCTS) (f METADATA_LAYER_HASHES) (f new_metadatas) (f new_metadata_updaters) (f new_inner_puzs))
|
||||
'$'
|
||||
)
|
||||
)
|
||||
conditions
|
||||
)
|
||||
conditions
|
||||
)
|
||||
)
|
||||
)
|
||||
conditions
|
||||
conditions
|
||||
)
|
||||
)
|
||||
|
||||
(if proofs_of_inclusion
|
||||
(loop_over_curried_params
|
||||
SINGLETON_STRUCTS
|
||||
METADATA_LAYER_HASHES
|
||||
VALUES_TO_PROVE
|
||||
proofs_of_inclusion
|
||||
new_metadatas
|
||||
new_metadata_updaters
|
||||
new_inner_puzs
|
||||
(a INNER_PUZZLE inner_solution)
|
||||
)
|
||||
; You may want to run the puzzle without a raise to examine conditions so we'll make a "blessed" way to fail
|
||||
(c (list ASSERT_MY_AMOUNT -1) (a INNER_PUZZLE inner_solution))
|
||||
(loop_over_curried_params
|
||||
SINGLETON_STRUCTS
|
||||
METADATA_LAYER_HASHES
|
||||
VALUES_TO_PROVE
|
||||
proofs_of_inclusion
|
||||
new_metadatas
|
||||
new_metadata_updaters
|
||||
new_inner_puzs
|
||||
(a INNER_PUZZLE inner_solution)
|
||||
)
|
||||
; You may want to run the puzzle without a raise to examine conditions so we'll make a "blessed" way to fail
|
||||
(c (list ASSERT_MY_AMOUNT -1) (a INNER_PUZZLE inner_solution))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -2,24 +2,24 @@
|
|||
|
||||
(defun search_list_then_resume (key json_object result)
|
||||
(if result
|
||||
result
|
||||
(search_for_value_given_key key (r json_object))
|
||||
result
|
||||
(search_for_value_given_key key (r json_object))
|
||||
)
|
||||
)
|
||||
|
||||
(defun search_for_value_given_key (key json_object)
|
||||
(if json_object
|
||||
(if (l (f from_json_dict)) ; if we are hitting an unlabelled item (atom), just move on
|
||||
(if (= (f (f json_object)) key) ; if we have found our key
|
||||
(r (f json_object)) ; return the value
|
||||
(if (l (r (f json_object))) ; otherwise check if we have hit another dictionary
|
||||
(search_list_then_resume key json_object (search_for_value_given_key key (r (f json_object)))) ; check new dictionary
|
||||
(if (l (f from_json_dict)) ; if we are hitting an unlabelled item (atom), just move on
|
||||
(if (= (f (f json_object)) key) ; if we have found our key
|
||||
(r (f json_object)) ; return the value
|
||||
(if (l (r (f json_object))) ; otherwise check if we have hit another dictionary
|
||||
(search_list_then_resume key json_object (search_for_value_given_key key (r (f json_object)))) ; check new dictionary
|
||||
(search_for_value_given_key key (r json_object))
|
||||
)
|
||||
)
|
||||
(search_for_value_given_key key (r json_object))
|
||||
)
|
||||
)
|
||||
(search_for_value_given_key key (r json_object))
|
||||
)
|
||||
()
|
||||
()
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
(
|
||||
(defun simplify_merkle_proof_after_leaf (leaf_hash (bitpath . hashes_path))
|
||||
(if hashes_path
|
||||
(simplify_merkle_proof_after_leaf
|
||||
(if (logand 1 bitpath)
|
||||
(sha256 0x02 (f hashes_path) leaf_hash)
|
||||
(sha256 0x02 leaf_hash (f hashes_path))
|
||||
)
|
||||
(c (lsh bitpath -1) (r hashes_path))
|
||||
)
|
||||
leaf_hash
|
||||
)
|
||||
)
|
||||
(if hashes_path
|
||||
(simplify_merkle_proof_after_leaf
|
||||
(if (logand 1 bitpath)
|
||||
(sha256 0x02 (f hashes_path) leaf_hash)
|
||||
(sha256 0x02 leaf_hash (f hashes_path))
|
||||
)
|
||||
(c (lsh bitpath -1) (r hashes_path))
|
||||
)
|
||||
leaf_hash
|
||||
)
|
||||
)
|
||||
|
||||
(defun-inline simplify_merkle_proof (leaf proof)
|
||||
(simplify_merkle_proof_after_leaf (sha256 0x01 leaf) proof)
|
||||
)
|
||||
)
|
||||
(defun-inline simplify_merkle_proof (leaf proof)
|
||||
(simplify_merkle_proof_after_leaf (sha256 0x01 leaf) proof)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(mod (LAUNCHER_PH MINT_NUMBER MINT_TOTAL)
|
||||
(include condition_codes.clib)
|
||||
(list
|
||||
(list CREATE_COIN LAUNCHER_PH 1)
|
||||
(list CREATE_COIN_ANNOUNCEMENT (sha256 MINT_NUMBER MINT_TOTAL)))
|
||||
)
|
||||
(include condition_codes.clib)
|
||||
(list
|
||||
(list CREATE_COIN LAUNCHER_PH 1)
|
||||
(list CREATE_COIN_ANNOUNCEMENT (sha256 MINT_NUMBER MINT_TOTAL)))
|
||||
)
|
||||
|
|
|
@ -6,25 +6,25 @@
|
|||
; Add uri to a field
|
||||
(defun add_url (METADATA key new_url)
|
||||
(if METADATA
|
||||
(if (= (f (f METADATA)) key)
|
||||
(c (c key (c new_url (r (f METADATA)))) (r METADATA))
|
||||
(c (f METADATA) (add_url (r METADATA) key new_url))
|
||||
)
|
||||
()
|
||||
(if (= (f (f METADATA)) key)
|
||||
(c (c key (c new_url (r (f METADATA)))) (r METADATA))
|
||||
(c (f METADATA) (add_url (r METADATA) key new_url))
|
||||
)
|
||||
()
|
||||
)
|
||||
)
|
||||
; main
|
||||
; returns ((new_metadata new_metadata_updater_puzhash) conditions)
|
||||
(list
|
||||
(list
|
||||
(if (all key new_url)
|
||||
(if (any (= key "mu") (= key "lu") (= key "u"))
|
||||
(add_url CURRENT_METADATA key new_url)
|
||||
CURRENT_METADATA
|
||||
)
|
||||
CURRENT_METADATA
|
||||
)
|
||||
METADATA_UPDATER_PUZZLE_HASH)
|
||||
(if (all key new_url)
|
||||
(if (any (= key "mu") (= key "lu") (= key "u"))
|
||||
(add_url CURRENT_METADATA key new_url)
|
||||
CURRENT_METADATA
|
||||
)
|
||||
CURRENT_METADATA
|
||||
)
|
||||
METADATA_UPDATER_PUZZLE_HASH)
|
||||
0
|
||||
)
|
||||
)
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
; once we find 'u' we don't need to continue looping
|
||||
(defun add_url (METADATA new_url)
|
||||
(if METADATA
|
||||
(if (= (f (f METADATA)) 'u')
|
||||
(c (c 'u' (c new_url (r (f METADATA)))) (r METADATA))
|
||||
(c (f METADATA) (add_url (r METADATA) new_url))
|
||||
)
|
||||
()
|
||||
(if (= (f (f METADATA)) 'u')
|
||||
(c (c 'u' (c new_url (r (f METADATA)))) (r METADATA))
|
||||
(c (f METADATA) (add_url (r METADATA) new_url))
|
||||
)
|
||||
()
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -4,75 +4,75 @@
|
|||
TRANSFER_PROGRAM
|
||||
INNER_PUZZLE
|
||||
inner_solution
|
||||
)
|
||||
)
|
||||
|
||||
(include condition_codes.clib)
|
||||
(include curry-and-treehash.clib)
|
||||
(include utility_macros.clib)
|
||||
(include condition_codes.clib)
|
||||
(include curry-and-treehash.clib)
|
||||
(include utility_macros.clib)
|
||||
|
||||
(defconstant NEW_OWNER_CONDITION -10)
|
||||
(defconstant ANNOUNCEMENT_PREFIX 0xad4c) ; first 2 bytes of (sha256 "Ownership Layer")
|
||||
(defconstant NEW_OWNER_CONDITION -10)
|
||||
(defconstant ANNOUNCEMENT_PREFIX 0xad4c) ; first 2 bytes of (sha256 "Ownership Layer")
|
||||
|
||||
(defun-inline nft_ownership_layer_puzzle_hash (NFT_OWNERSHIP_LAYER_MOD_HASH new_owner TRANSFER_PROGRAM inner_puzzle_hash)
|
||||
(puzzle-hash-of-curried-function NFT_OWNERSHIP_LAYER_MOD_HASH
|
||||
inner_puzzle_hash
|
||||
(sha256tree TRANSFER_PROGRAM)
|
||||
(sha256 ONE new_owner)
|
||||
(sha256 ONE NFT_OWNERSHIP_LAYER_MOD_HASH)
|
||||
)
|
||||
)
|
||||
(defun-inline nft_ownership_layer_puzzle_hash (NFT_OWNERSHIP_LAYER_MOD_HASH new_owner TRANSFER_PROGRAM inner_puzzle_hash)
|
||||
(puzzle-hash-of-curried-function NFT_OWNERSHIP_LAYER_MOD_HASH
|
||||
inner_puzzle_hash
|
||||
(sha256tree TRANSFER_PROGRAM)
|
||||
(sha256 ONE new_owner)
|
||||
(sha256 ONE NFT_OWNERSHIP_LAYER_MOD_HASH)
|
||||
)
|
||||
)
|
||||
|
||||
(defun construct_end_conditions (NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM odd_args (new_owner new_tp conditions))
|
||||
(c
|
||||
(c
|
||||
CREATE_COIN
|
||||
(c
|
||||
(nft_ownership_layer_puzzle_hash NFT_OWNERSHIP_LAYER_MOD_HASH new_owner (if new_tp new_tp TRANSFER_PROGRAM) (f odd_args))
|
||||
(r odd_args)
|
||||
)
|
||||
(defun construct_end_conditions (NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM odd_args (new_owner new_tp conditions))
|
||||
(c
|
||||
(c
|
||||
CREATE_COIN
|
||||
(c
|
||||
(nft_ownership_layer_puzzle_hash NFT_OWNERSHIP_LAYER_MOD_HASH new_owner (if new_tp new_tp TRANSFER_PROGRAM) (f odd_args))
|
||||
(r odd_args)
|
||||
)
|
||||
conditions
|
||||
)
|
||||
)
|
||||
)
|
||||
conditions
|
||||
)
|
||||
)
|
||||
|
||||
(defun wrap_odd_create_coins (NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM CURRENT_OWNER all_conditions conditions odd_args tp_output)
|
||||
(if conditions
|
||||
(if (= (f (f conditions)) CREATE_COIN)
|
||||
(if (= (logand (f (r (r (f conditions))))) ONE)
|
||||
(assert (not odd_args)
|
||||
; then
|
||||
(wrap_odd_create_coins NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM CURRENT_OWNER all_conditions (r conditions) (r (f conditions)) tp_output)
|
||||
)
|
||||
(c (f conditions) (wrap_odd_create_coins NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM CURRENT_OWNER all_conditions (r conditions) odd_args tp_output))
|
||||
)
|
||||
(if (= (f (f conditions)) NEW_OWNER_CONDITION)
|
||||
(assert (not tp_output)
|
||||
(c
|
||||
(list CREATE_PUZZLE_ANNOUNCEMENT (concat ANNOUNCEMENT_PREFIX (sha256tree (r (f conditions)))))
|
||||
(wrap_odd_create_coins NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM CURRENT_OWNER all_conditions (r conditions) odd_args (a TRANSFER_PROGRAM (list CURRENT_OWNER all_conditions (r (f conditions)))))
|
||||
)
|
||||
)
|
||||
(if (= (f (f conditions)) CREATE_PUZZLE_ANNOUNCEMENT)
|
||||
(assert (not (and
|
||||
(= 34 (strlen (f (r (f conditions)))))
|
||||
(= (substr (f (r (f conditions))) 0 2) ANNOUNCEMENT_PREFIX) ; lazy eval
|
||||
))
|
||||
(defun wrap_odd_create_coins (NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM CURRENT_OWNER all_conditions conditions odd_args tp_output)
|
||||
(if conditions
|
||||
(if (= (f (f conditions)) CREATE_COIN)
|
||||
(if (= (logand (f (r (r (f conditions))))) ONE)
|
||||
(assert (not odd_args)
|
||||
; then
|
||||
(c (f conditions) (wrap_odd_create_coins NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM CURRENT_OWNER all_conditions (r conditions) odd_args tp_output))
|
||||
(wrap_odd_create_coins NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM CURRENT_OWNER all_conditions (r conditions) (r (f conditions)) tp_output)
|
||||
)
|
||||
(c (f conditions) (wrap_odd_create_coins NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM CURRENT_OWNER all_conditions (r conditions) odd_args tp_output))
|
||||
)
|
||||
)
|
||||
)
|
||||
; odd_args is guaranteed to not be nil or else we'll have a path into atom error
|
||||
(construct_end_conditions NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM odd_args
|
||||
(if (= (f (f conditions)) NEW_OWNER_CONDITION)
|
||||
(assert (not tp_output)
|
||||
(c
|
||||
(list CREATE_PUZZLE_ANNOUNCEMENT (concat ANNOUNCEMENT_PREFIX (sha256tree (r (f conditions)))))
|
||||
(wrap_odd_create_coins NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM CURRENT_OWNER all_conditions (r conditions) odd_args (a TRANSFER_PROGRAM (list CURRENT_OWNER all_conditions (r (f conditions)))))
|
||||
)
|
||||
)
|
||||
(if (= (f (f conditions)) CREATE_PUZZLE_ANNOUNCEMENT)
|
||||
(assert (not (and
|
||||
(= 34 (strlen (f (r (f conditions)))))
|
||||
(= (substr (f (r (f conditions))) 0 2) ANNOUNCEMENT_PREFIX) ; lazy eval
|
||||
))
|
||||
; then
|
||||
(c (f conditions) (wrap_odd_create_coins NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM CURRENT_OWNER all_conditions (r conditions) odd_args tp_output))
|
||||
)
|
||||
(c (f conditions) (wrap_odd_create_coins NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM CURRENT_OWNER all_conditions (r conditions) odd_args tp_output))
|
||||
)
|
||||
)
|
||||
)
|
||||
; odd_args is guaranteed to not be nil or else we'll have a path into atom error
|
||||
(construct_end_conditions NFT_OWNERSHIP_LAYER_MOD_HASH TRANSFER_PROGRAM odd_args
|
||||
(if tp_output
|
||||
tp_output
|
||||
(a TRANSFER_PROGRAM (list CURRENT_OWNER all_conditions ()))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(defun main (
|
||||
NFT_OWNERSHIP_LAYER_MOD_HASH
|
||||
|
|
|
@ -18,36 +18,36 @@
|
|||
;; return the full puzzlehash for a singleton with the innerpuzzle curried in
|
||||
; puzzle-hash-of-curried-function is imported from curry-and-treehash.clib
|
||||
(defun-inline calculate_full_puzzle_hash (SINGLETON_STRUCT inner_puzzle_hash)
|
||||
(puzzle-hash-of-curried-function (f SINGLETON_STRUCT)
|
||||
inner_puzzle_hash
|
||||
(sha256tree SINGLETON_STRUCT)
|
||||
)
|
||||
(puzzle-hash-of-curried-function (f SINGLETON_STRUCT)
|
||||
inner_puzzle_hash
|
||||
(sha256tree SINGLETON_STRUCT)
|
||||
)
|
||||
)
|
||||
|
||||
; Given a singleton ID, generate the singleton struct
|
||||
(defun-inline get_singleton_struct (SINGLETON_STRUCT singleton_id)
|
||||
(c (f SINGLETON_STRUCT) (c singleton_id (r (r SINGLETON_STRUCT))))
|
||||
(c (f SINGLETON_STRUCT) (c singleton_id (r (r SINGLETON_STRUCT))))
|
||||
)
|
||||
|
||||
(defun-inline calculate_percentage (amount percentage)
|
||||
(f (divmod (* amount percentage) TEN_THOUSAND))
|
||||
(f (divmod (* amount percentage) TEN_THOUSAND))
|
||||
)
|
||||
|
||||
; Loop of the trade prices list and either assert a puzzle announcement or generate xch
|
||||
(defun parse_trade_prices_list (ROYALTY_ADDRESS TRADE_PRICE_PERCENTAGE trade_prices_list my_nft_id)
|
||||
(if trade_prices_list
|
||||
(c
|
||||
(list
|
||||
ASSERT_PUZZLE_ANNOUNCEMENT
|
||||
(sha256
|
||||
(f (r (f trade_prices_list)))
|
||||
(sha256tree (c my_nft_id (list (list ROYALTY_ADDRESS (calculate_percentage (f (f trade_prices_list)) TRADE_PRICE_PERCENTAGE) (list ROYALTY_ADDRESS)))))
|
||||
)
|
||||
)
|
||||
(parse_trade_prices_list ROYALTY_ADDRESS TRADE_PRICE_PERCENTAGE (r trade_prices_list) my_nft_id)
|
||||
(if trade_prices_list
|
||||
(c
|
||||
(list
|
||||
ASSERT_PUZZLE_ANNOUNCEMENT
|
||||
(sha256
|
||||
(f (r (f trade_prices_list)))
|
||||
(sha256tree (c my_nft_id (list (list ROYALTY_ADDRESS (calculate_percentage (f (f trade_prices_list)) TRADE_PRICE_PERCENTAGE) (list ROYALTY_ADDRESS)))))
|
||||
)
|
||||
)
|
||||
()
|
||||
)
|
||||
(parse_trade_prices_list ROYALTY_ADDRESS TRADE_PRICE_PERCENTAGE (r trade_prices_list) my_nft_id)
|
||||
)
|
||||
()
|
||||
)
|
||||
)
|
||||
|
||||
; main
|
||||
|
@ -58,17 +58,17 @@
|
|||
(f solution)
|
||||
0
|
||||
(if (all (f solution) (not (= (f solution) Current_Owner)))
|
||||
(c
|
||||
(list
|
||||
ASSERT_PUZZLE_ANNOUNCEMENT
|
||||
(sha256
|
||||
(calculate_full_puzzle_hash (get_singleton_struct SINGLETON_STRUCT (f solution)) (f (r (r solution))))
|
||||
(f (r SINGLETON_STRUCT))
|
||||
(c
|
||||
(list
|
||||
ASSERT_PUZZLE_ANNOUNCEMENT
|
||||
(sha256
|
||||
(calculate_full_puzzle_hash (get_singleton_struct SINGLETON_STRUCT (f solution)) (f (r (r solution))))
|
||||
(f (r SINGLETON_STRUCT))
|
||||
)
|
||||
)
|
||||
(parse_trade_prices_list ROYALTY_ADDRESS TRADE_PRICE_PERCENTAGE (f (r solution)) (f (r SINGLETON_STRUCT)))
|
||||
)
|
||||
(parse_trade_prices_list ROYALTY_ADDRESS TRADE_PRICE_PERCENTAGE (f (r solution)) (f (r SINGLETON_STRUCT)))
|
||||
)
|
||||
(parse_trade_prices_list ROYALTY_ADDRESS TRADE_PRICE_PERCENTAGE (f (r solution)) (f (r SINGLETON_STRUCT)))
|
||||
)
|
||||
)
|
||||
(list Current_Owner () ())
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
|
||||
(defun-inline nft_state_layer_puzzle_hash (NFT_STATE_LAYER_MOD_HASH METADATA METADATA_UPDATER_PUZZLE_HASH inner_puzzle_hash)
|
||||
(puzzle-hash-of-curried-function NFT_STATE_LAYER_MOD_HASH
|
||||
inner_puzzle_hash
|
||||
(sha256 ONE METADATA_UPDATER_PUZZLE_HASH)
|
||||
(sha256tree METADATA)
|
||||
(sha256 ONE NFT_STATE_LAYER_MOD_HASH)
|
||||
inner_puzzle_hash
|
||||
(sha256 ONE METADATA_UPDATER_PUZZLE_HASH)
|
||||
(sha256tree METADATA)
|
||||
(sha256 ONE NFT_STATE_LAYER_MOD_HASH)
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -25,29 +25,29 @@
|
|||
; new_metadata_info is ((METADATA METADATA_UPDATER_PUZZLE_HASH) conditions)
|
||||
(defun wrap_odd_create_coins (NFT_STATE_LAYER_MOD_HASH conditions odd_coin_params new_metadata_info metadata_seen)
|
||||
(if conditions
|
||||
(if (= (f (f conditions)) CREATE_COIN)
|
||||
(if (logand (f (r (r (f conditions)))) ONE)
|
||||
(assert (not odd_coin_params)
|
||||
(wrap_odd_create_coins NFT_STATE_LAYER_MOD_HASH (r conditions) (r (f conditions)) new_metadata_info metadata_seen)
|
||||
)
|
||||
(c (f conditions) (wrap_odd_create_coins NFT_STATE_LAYER_MOD_HASH (r conditions) odd_coin_params new_metadata_info metadata_seen))
|
||||
)
|
||||
(if (= (f (f conditions)) -24)
|
||||
(wrap_odd_create_coins NFT_STATE_LAYER_MOD_HASH (r conditions) odd_coin_params
|
||||
(assert (all
|
||||
(= (sha256tree (f (r (f conditions)))) (f (r (f new_metadata_info))))
|
||||
(not metadata_seen)
|
||||
)
|
||||
(if (= (f (f conditions)) CREATE_COIN)
|
||||
(if (logand (f (r (r (f conditions)))) ONE)
|
||||
(assert (not odd_coin_params)
|
||||
(wrap_odd_create_coins NFT_STATE_LAYER_MOD_HASH (r conditions) (r (f conditions)) new_metadata_info metadata_seen)
|
||||
)
|
||||
(c (f conditions) (wrap_odd_create_coins NFT_STATE_LAYER_MOD_HASH (r conditions) odd_coin_params new_metadata_info metadata_seen))
|
||||
)
|
||||
(if (= (f (f conditions)) -24)
|
||||
(wrap_odd_create_coins NFT_STATE_LAYER_MOD_HASH (r conditions) odd_coin_params
|
||||
(assert (all
|
||||
(= (sha256tree (f (r (f conditions)))) (f (r (f new_metadata_info))))
|
||||
(not metadata_seen)
|
||||
)
|
||||
; then
|
||||
(a (f (r (f conditions))) (list (f (f new_metadata_info)) (f (r (f new_metadata_info))) (f (r (r (f conditions))))))
|
||||
)
|
||||
ONE ; the metadata update has been seen now
|
||||
)
|
||||
ONE ; the metadata update has been seen now
|
||||
)
|
||||
(c (f conditions) (wrap_odd_create_coins NFT_STATE_LAYER_MOD_HASH (r conditions) odd_coin_params new_metadata_info metadata_seen))
|
||||
)
|
||||
)
|
||||
(c
|
||||
(c CREATE_COIN
|
||||
(c (f conditions) (wrap_odd_create_coins NFT_STATE_LAYER_MOD_HASH (r conditions) odd_coin_params new_metadata_info metadata_seen))
|
||||
)
|
||||
)
|
||||
(c
|
||||
(c CREATE_COIN
|
||||
(c
|
||||
(nft_state_layer_puzzle_hash
|
||||
NFT_STATE_LAYER_MOD_HASH
|
||||
|
@ -57,9 +57,9 @@
|
|||
)
|
||||
(r odd_coin_params)
|
||||
)
|
||||
)
|
||||
(f (r new_metadata_info)) ; metadata_updater conditions
|
||||
)
|
||||
(f (r new_metadata_info)) ; metadata_updater conditions
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
@ -4,4 +4,4 @@
|
|||
)
|
||||
(include condition_codes.clib)
|
||||
(list (list CREATE_COIN TARGET AMOUNT) (list CREATE_COIN_ANNOUNCEMENT ()))
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
(mod (conditions)
|
||||
(qq (q . (unquote conditions)))
|
||||
(qq (q . (unquote conditions)))
|
||||
)
|
||||
|
|
|
@ -6,11 +6,11 @@
|
|||
;; hash a tree
|
||||
;; This is used to calculate a puzzle hash given a puzzle program.
|
||||
(defun sha256tree1
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
(c (list AGG_SIG_ME public_key (sha256tree1 conditions)) conditions)
|
||||
|
|
|
@ -7,13 +7,13 @@
|
|||
;; hash a tree
|
||||
;; This is used to calculate a puzzle hash given a puzzle program.
|
||||
(defun sha256tree1
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
(c (list AGG_SIG_ME public_key (sha256tree1 delegated_puzzle))
|
||||
(a delegated_puzzle delegated_puzzle_solution))
|
||||
(a delegated_puzzle delegated_puzzle_solution))
|
||||
)
|
||||
|
|
|
@ -23,69 +23,69 @@
|
|||
|
||||
|
||||
(mod
|
||||
; A puzzle should commit to `SYNTHETIC_PUBLIC_KEY`
|
||||
;
|
||||
; The solution should pass in 0 for `original_public_key` if it wants to use
|
||||
; an arbitrary `delegated_puzzle` (and `solution`) signed by the
|
||||
; `SYNTHETIC_PUBLIC_KEY` (whose corresponding private key can be calculated
|
||||
; if you know the private key for `original_public_key`)
|
||||
;
|
||||
; Or you can solve the hidden puzzle by revealing the `original_public_key`,
|
||||
; the hidden puzzle in `delegated_puzzle`, and a solution to the hidden puzzle.
|
||||
; A puzzle should commit to `SYNTHETIC_PUBLIC_KEY`
|
||||
;
|
||||
; The solution should pass in 0 for `original_public_key` if it wants to use
|
||||
; an arbitrary `delegated_puzzle` (and `solution`) signed by the
|
||||
; `SYNTHETIC_PUBLIC_KEY` (whose corresponding private key can be calculated
|
||||
; if you know the private key for `original_public_key`)
|
||||
;
|
||||
; Or you can solve the hidden puzzle by revealing the `original_public_key`,
|
||||
; the hidden puzzle in `delegated_puzzle`, and a solution to the hidden puzzle.
|
||||
|
||||
(SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle solution)
|
||||
(SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle solution)
|
||||
|
||||
; "assert" is a macro that wraps repeated instances of "if"
|
||||
; usage: (assert A0 A1 ... An R)
|
||||
; all of A0, A1, ... An must evaluate to non-null, or an exception is raised
|
||||
; return the value of R (if we get that far)
|
||||
; "assert" is a macro that wraps repeated instances of "if"
|
||||
; usage: (assert A0 A1 ... An R)
|
||||
; all of A0, A1, ... An must evaluate to non-null, or an exception is raised
|
||||
; return the value of R (if we get that far)
|
||||
|
||||
(defmacro assert items
|
||||
(if (r items)
|
||||
(list if (f items) (c assert (r items)) (q . (x)))
|
||||
(f items)
|
||||
(defmacro assert items
|
||||
(if (r items)
|
||||
(list if (f items) (c assert (r items)) (q . (x)))
|
||||
(f items)
|
||||
)
|
||||
)
|
||||
|
||||
(include condition_codes.clib)
|
||||
|
||||
;; hash a tree
|
||||
;; This is used to calculate a puzzle hash given a puzzle program.
|
||||
(defun sha256tree1
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
; "is_hidden_puzzle_correct" returns true iff the hidden puzzle is correctly encoded
|
||||
|
||||
(defun-inline is_hidden_puzzle_correct (SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle)
|
||||
(=
|
||||
SYNTHETIC_PUBLIC_KEY
|
||||
(point_add
|
||||
original_public_key
|
||||
(pubkey_for_exp (sha256 original_public_key (sha256tree1 delegated_puzzle)))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
; "possibly_prepend_aggsig" is the main entry point
|
||||
|
||||
(defun-inline possibly_prepend_aggsig (SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle conditions)
|
||||
(if original_public_key
|
||||
(assert
|
||||
(is_hidden_puzzle_correct SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle)
|
||||
conditions
|
||||
)
|
||||
(c (list AGG_SIG_ME SYNTHETIC_PUBLIC_KEY (sha256tree1 delegated_puzzle)) conditions)
|
||||
)
|
||||
)
|
||||
|
||||
(include condition_codes.clib)
|
||||
; main entry point
|
||||
|
||||
;; hash a tree
|
||||
;; This is used to calculate a puzzle hash given a puzzle program.
|
||||
(defun sha256tree1
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
; "is_hidden_puzzle_correct" returns true iff the hidden puzzle is correctly encoded
|
||||
|
||||
(defun-inline is_hidden_puzzle_correct (SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle)
|
||||
(=
|
||||
SYNTHETIC_PUBLIC_KEY
|
||||
(point_add
|
||||
original_public_key
|
||||
(pubkey_for_exp (sha256 original_public_key (sha256tree1 delegated_puzzle)))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
; "possibly_prepend_aggsig" is the main entry point
|
||||
|
||||
(defun-inline possibly_prepend_aggsig (SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle conditions)
|
||||
(if original_public_key
|
||||
(assert
|
||||
(is_hidden_puzzle_correct SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle)
|
||||
conditions
|
||||
)
|
||||
(c (list AGG_SIG_ME SYNTHETIC_PUBLIC_KEY (sha256tree1 delegated_puzzle)) conditions)
|
||||
)
|
||||
)
|
||||
|
||||
; main entry point
|
||||
|
||||
(possibly_prepend_aggsig
|
||||
SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle
|
||||
(a delegated_puzzle solution))
|
||||
(possibly_prepend_aggsig
|
||||
SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle
|
||||
(a delegated_puzzle solution))
|
||||
)
|
||||
|
|
|
@ -18,91 +18,91 @@
|
|||
|
||||
|
||||
(mod
|
||||
(M public_key_list selectors delegated_puzzle solution)
|
||||
(M public_key_list selectors delegated_puzzle solution)
|
||||
|
||||
(include condition_codes.clib)
|
||||
(include condition_codes.clib)
|
||||
|
||||
;; hash a tree
|
||||
;; This is used to calculate a puzzle hash given a puzzle program.
|
||||
(defun sha256tree1
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
;; hash a tree
|
||||
;; This is used to calculate a puzzle hash given a puzzle program.
|
||||
(defun sha256tree1
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
; "assert" is a macro that wraps repeated instances of "if"
|
||||
; usage: (assert A0 A1 ... An R)
|
||||
; all of A0, A1, ... An must evaluate to non-null, or an exception is raised
|
||||
; return the value of R (if we get that far)
|
||||
; "assert" is a macro that wraps repeated instances of "if"
|
||||
; usage: (assert A0 A1 ... An R)
|
||||
; all of A0, A1, ... An must evaluate to non-null, or an exception is raised
|
||||
; return the value of R (if we get that far)
|
||||
|
||||
(defmacro assert items
|
||||
(if (r items)
|
||||
(list if (f items) (c assert (r items)) (q . (x)))
|
||||
(f items)
|
||||
(defmacro assert items
|
||||
(if (r items)
|
||||
(list if (f items) (c assert (r items)) (q . (x)))
|
||||
(f items)
|
||||
)
|
||||
)
|
||||
|
||||
; add_aggsig returns a list of conditions. It includes M AGG_SIG conditions
|
||||
; corresponding to the given list of public keys (with the given hash)
|
||||
; plus the conditions that come out of the delegated puzzle.
|
||||
;
|
||||
; hash is the hash of delegated_puzzle.
|
||||
; Yes it's redundant since we include the delegated_puzzle itself,
|
||||
; but we don't want to recalculate the hash multiple times as its expensive to do so
|
||||
|
||||
(defun add_aggsig (public_key_list hash delegated_puzzle solution)
|
||||
(if public_key_list
|
||||
(c (list AGG_SIG_UNSAFE (f public_key_list) hash)
|
||||
(add_aggsig (r public_key_list) hash delegated_puzzle solution)
|
||||
)
|
||||
(a delegated_puzzle solution)
|
||||
)
|
||||
)
|
||||
|
||||
; add_aggsig returns a list of conditions. It includes M AGG_SIG conditions
|
||||
; corresponding to the given list of public keys (with the given hash)
|
||||
; plus the conditions that come out of the delegated puzzle.
|
||||
;
|
||||
; hash is the hash of delegated_puzzle.
|
||||
; Yes it's redundant since we include the delegated_puzzle itself,
|
||||
; but we don't want to recalculate the hash multiple times as its expensive to do so
|
||||
; choose_keys takes a list of selectors and the N public keys and
|
||||
; returns a list of the M public keys chosen by the selectors
|
||||
|
||||
(defun add_aggsig (public_key_list hash delegated_puzzle solution)
|
||||
(if public_key_list
|
||||
(c (list AGG_SIG_UNSAFE (f public_key_list) hash)
|
||||
(add_aggsig (r public_key_list) hash delegated_puzzle solution)
|
||||
)
|
||||
(a delegated_puzzle solution)
|
||||
(defun choose_keys (selectors public_key_list)
|
||||
(if selectors
|
||||
(if (f selectors)
|
||||
(c (f public_key_list) (choose_keys (r selectors) (r public_key_list)))
|
||||
(choose_keys (r selectors) (r public_key_list)))
|
||||
()
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
; count the number of non-0 values in the list of selectors and return it as an integer
|
||||
|
||||
(defun count_selectors (selectors)
|
||||
(if selectors
|
||||
(+
|
||||
(count_selectors (r selectors))
|
||||
(if (f selectors) 1 0)
|
||||
)
|
||||
0
|
||||
)
|
||||
)
|
||||
|
||||
; choose_keys takes a list of selectors and the N public keys and
|
||||
; returns a list of the M public keys chosen by the selectors
|
||||
; "solve_puzzle" is the main entry point
|
||||
|
||||
(defun choose_keys (selectors public_key_list)
|
||||
(if selectors
|
||||
(if (f selectors)
|
||||
(c (f public_key_list) (choose_keys (r selectors) (r public_key_list)))
|
||||
(choose_keys (r selectors) (r public_key_list)))
|
||||
()
|
||||
)
|
||||
(defun-inline solve_puzzle (M public_key_list selectors delegated_puzzle solution)
|
||||
; make sure we have exactly M selectors
|
||||
(assert (= M (count_selectors selectors))
|
||||
; return the AGG_SIG conditions plus the conditions from the delegated_puzzle
|
||||
(add_aggsig (choose_keys selectors public_key_list)
|
||||
(sha256tree1 delegated_puzzle)
|
||||
delegated_puzzle
|
||||
solution)
|
||||
)
|
||||
)
|
||||
|
||||
; main entry point
|
||||
|
||||
; count the number of non-0 values in the list of selectors and return it as an integer
|
||||
|
||||
(defun count_selectors (selectors)
|
||||
(if selectors
|
||||
(+
|
||||
(count_selectors (r selectors))
|
||||
(if (f selectors) 1 0)
|
||||
)
|
||||
0
|
||||
)
|
||||
)
|
||||
|
||||
; "solve_puzzle" is the main entry point
|
||||
|
||||
(defun-inline solve_puzzle (M public_key_list selectors delegated_puzzle solution)
|
||||
; make sure we have exactly M selectors
|
||||
(assert (= M (count_selectors selectors))
|
||||
; return the AGG_SIG conditions plus the conditions from the delegated_puzzle
|
||||
(add_aggsig (choose_keys selectors public_key_list)
|
||||
(sha256tree1 delegated_puzzle)
|
||||
delegated_puzzle
|
||||
solution)
|
||||
)
|
||||
)
|
||||
|
||||
; main entry point
|
||||
|
||||
(solve_puzzle
|
||||
M public_key_list
|
||||
selectors delegated_puzzle solution
|
||||
)
|
||||
(solve_puzzle
|
||||
M public_key_list
|
||||
selectors delegated_puzzle solution
|
||||
)
|
||||
)
|
||||
|
|
|
@ -16,4 +16,4 @@
|
|||
)
|
||||
(a parent_inner_puz parent_solution)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
;; hash a tree
|
||||
;; This is used to calculate a puzzle hash given a puzzle program.
|
||||
(defun sha256tree1
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
(if (= inner_puzzle_hash (sha256tree1 inner_puzzle))
|
||||
(a inner_puzzle inner_puzzle_solution)
|
||||
(x)
|
||||
(a inner_puzzle inner_puzzle_solution)
|
||||
(x)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -12,17 +12,17 @@
|
|||
;; return the full puzzlehash for a singleton with the innerpuzzle curried in
|
||||
; puzzle-hash-of-curried-function is imported from curry-and-treehash.clib
|
||||
(defun-inline calculate_full_puzzle_hash (SINGLETON_MOD_HASH LAUNCHER_ID LAUNCHER_PUZZLE_HASH inner_puzzle_hash)
|
||||
(puzzle-hash-of-curried-function SINGLETON_MOD_HASH
|
||||
inner_puzzle_hash
|
||||
(sha256tree (c SINGLETON_MOD_HASH (c LAUNCHER_ID LAUNCHER_PUZZLE_HASH)))
|
||||
)
|
||||
(puzzle-hash-of-curried-function SINGLETON_MOD_HASH
|
||||
inner_puzzle_hash
|
||||
(sha256tree (c SINGLETON_MOD_HASH (c LAUNCHER_ID LAUNCHER_PUZZLE_HASH)))
|
||||
)
|
||||
)
|
||||
|
||||
(defun-inline claim_rewards (SINGLETON_MOD_HASH LAUNCHER_ID LAUNCHER_PUZZLE_HASH singleton_inner_puzzle_hash my_id)
|
||||
(list
|
||||
(list ASSERT_PUZZLE_ANNOUNCEMENT (sha256 (calculate_full_puzzle_hash SINGLETON_MOD_HASH LAUNCHER_ID LAUNCHER_PUZZLE_HASH singleton_inner_puzzle_hash) my_id))
|
||||
(list CREATE_COIN_ANNOUNCEMENT '$')
|
||||
(list ASSERT_MY_COIN_ID my_id))
|
||||
(list ASSERT_PUZZLE_ANNOUNCEMENT (sha256 (calculate_full_puzzle_hash SINGLETON_MOD_HASH LAUNCHER_ID LAUNCHER_PUZZLE_HASH singleton_inner_puzzle_hash) my_id))
|
||||
(list CREATE_COIN_ANNOUNCEMENT '$')
|
||||
(list ASSERT_MY_COIN_ID my_id))
|
||||
)
|
||||
|
||||
; main
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
; DELAYED_PUZZLE_HASH is the puzzle hash of the delayed puzzle
|
||||
; if my_id is passed in as () then this signals that we are trying to do a delayed spend case
|
||||
; p1's meaning changes depending upon which case we're using
|
||||
; if we are paying to singleton then p1 is singleton_inner_puzzle_hash
|
||||
; if we are running the delayed case then p1 is the amount to output
|
||||
; if we are paying to singleton then p1 is singleton_inner_puzzle_hash
|
||||
; if we are running the delayed case then p1 is the amount to output
|
||||
|
||||
(include condition_codes.clib)
|
||||
(include curry-and-treehash.clib)
|
||||
|
@ -29,22 +29,22 @@
|
|||
;; return the full puzzlehash for a singleton with the innerpuzzle curried in
|
||||
; puzzle-hash-of-curried-function is imported from curry-and-treehash.clib
|
||||
(defun-inline calculate_full_puzzle_hash (SINGLETON_MOD_HASH LAUNCHER_ID LAUNCHER_PUZZLE_HASH inner_puzzle_hash)
|
||||
(puzzle-hash-of-curried-function SINGLETON_MOD_HASH
|
||||
inner_puzzle_hash
|
||||
(sha256tree (c SINGLETON_MOD_HASH (c LAUNCHER_ID LAUNCHER_PUZZLE_HASH)))
|
||||
)
|
||||
(puzzle-hash-of-curried-function SINGLETON_MOD_HASH
|
||||
inner_puzzle_hash
|
||||
(sha256tree (c SINGLETON_MOD_HASH (c LAUNCHER_ID LAUNCHER_PUZZLE_HASH)))
|
||||
)
|
||||
)
|
||||
|
||||
(defun-inline claim_rewards (SINGLETON_MOD_HASH LAUNCHER_ID LAUNCHER_PUZZLE_HASH singleton_inner_puzzle_hash my_id)
|
||||
(list
|
||||
(list ASSERT_PUZZLE_ANNOUNCEMENT (sha256 (calculate_full_puzzle_hash SINGLETON_MOD_HASH LAUNCHER_ID LAUNCHER_PUZZLE_HASH singleton_inner_puzzle_hash) my_id))
|
||||
(list CREATE_COIN_ANNOUNCEMENT '$')
|
||||
(list ASSERT_MY_COIN_ID my_id))
|
||||
(list ASSERT_PUZZLE_ANNOUNCEMENT (sha256 (calculate_full_puzzle_hash SINGLETON_MOD_HASH LAUNCHER_ID LAUNCHER_PUZZLE_HASH singleton_inner_puzzle_hash) my_id))
|
||||
(list CREATE_COIN_ANNOUNCEMENT '$')
|
||||
(list ASSERT_MY_COIN_ID my_id))
|
||||
)
|
||||
|
||||
; main
|
||||
(if my_id
|
||||
(claim_rewards SINGLETON_MOD_HASH LAUNCHER_ID LAUNCHER_PUZZLE_HASH p1 my_id)
|
||||
(delayed_spend SECONDS_DELAY DELAYED_PUZZLE_HASH p1)
|
||||
(claim_rewards SINGLETON_MOD_HASH LAUNCHER_ID LAUNCHER_PUZZLE_HASH p1 my_id)
|
||||
(delayed_spend SECONDS_DELAY DELAYED_PUZZLE_HASH p1)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
(mod (POOL_PUZZLE_HASH
|
||||
P2_SINGLETON_PUZZLE_HASH
|
||||
OWNER_PUBKEY
|
||||
POOL_REWARD_PREFIX
|
||||
WAITINGROOM_PUZHASH
|
||||
Truths
|
||||
p1
|
||||
pool_reward_height
|
||||
)
|
||||
P2_SINGLETON_PUZZLE_HASH
|
||||
OWNER_PUBKEY
|
||||
POOL_REWARD_PREFIX
|
||||
WAITINGROOM_PUZHASH
|
||||
Truths
|
||||
p1
|
||||
pool_reward_height
|
||||
)
|
||||
|
||||
|
||||
; POOL_PUZZLE_HASH is commitment to the pool's puzzle hash
|
||||
|
@ -30,10 +30,10 @@
|
|||
|
||||
; takes a lisp tree and returns the hash of it
|
||||
(defun sha256tree (TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
(defun-inline calculate_pool_reward (pool_reward_height P2_SINGLETON_PUZZLE_HASH POOL_REWARD_PREFIX pool_reward_amount)
|
||||
|
@ -42,29 +42,29 @@
|
|||
|
||||
(defun absorb_pool_reward (POOL_PUZZLE_HASH my_inner_puzzle_hash my_amount pool_reward_amount pool_reward_id)
|
||||
(list
|
||||
(list CREATE_COIN my_inner_puzzle_hash my_amount)
|
||||
(list CREATE_COIN POOL_PUZZLE_HASH pool_reward_amount)
|
||||
(list CREATE_PUZZLE_ANNOUNCEMENT pool_reward_id)
|
||||
(list ASSERT_COIN_ANNOUNCEMENT (sha256 pool_reward_id '$'))
|
||||
(list CREATE_COIN my_inner_puzzle_hash my_amount)
|
||||
(list CREATE_COIN POOL_PUZZLE_HASH pool_reward_amount)
|
||||
(list CREATE_PUZZLE_ANNOUNCEMENT pool_reward_id)
|
||||
(list ASSERT_COIN_ANNOUNCEMENT (sha256 pool_reward_id '$'))
|
||||
)
|
||||
)
|
||||
|
||||
(defun-inline travel_to_waitingroom (OWNER_PUBKEY WAITINGROOM_PUZHASH my_amount extra_data)
|
||||
(list (list AGG_SIG_ME OWNER_PUBKEY (sha256tree extra_data))
|
||||
(list CREATE_COIN WAITINGROOM_PUZHASH my_amount)
|
||||
(list CREATE_COIN WAITINGROOM_PUZHASH my_amount)
|
||||
)
|
||||
)
|
||||
|
||||
; main
|
||||
|
||||
(if pool_reward_height
|
||||
(absorb_pool_reward POOL_PUZZLE_HASH
|
||||
(my_inner_puzzle_hash_truth Truths)
|
||||
(my_amount_truth Truths)
|
||||
p1
|
||||
(calculate_pool_reward pool_reward_height P2_SINGLETON_PUZZLE_HASH POOL_REWARD_PREFIX p1)
|
||||
)
|
||||
(travel_to_waitingroom OWNER_PUBKEY WAITINGROOM_PUZHASH (my_amount_truth Truths) p1)
|
||||
)
|
||||
(absorb_pool_reward POOL_PUZZLE_HASH
|
||||
(my_inner_puzzle_hash_truth Truths)
|
||||
(my_amount_truth Truths)
|
||||
p1
|
||||
(calculate_pool_reward pool_reward_height P2_SINGLETON_PUZZLE_HASH POOL_REWARD_PREFIX p1)
|
||||
)
|
||||
(travel_to_waitingroom OWNER_PUBKEY WAITINGROOM_PUZHASH (my_amount_truth Truths) p1)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
(mod (POOL_PUZZLE_HASH
|
||||
P2_SINGLETON_PUZZLE_HASH
|
||||
OWNER_PUBKEY
|
||||
POOL_REWARD_PREFIX
|
||||
RELATIVE_LOCK_HEIGHT
|
||||
Truths
|
||||
spend_type
|
||||
p1
|
||||
p2
|
||||
)
|
||||
P2_SINGLETON_PUZZLE_HASH
|
||||
OWNER_PUBKEY
|
||||
POOL_REWARD_PREFIX
|
||||
RELATIVE_LOCK_HEIGHT
|
||||
Truths
|
||||
spend_type
|
||||
p1
|
||||
p2
|
||||
)
|
||||
|
||||
; POOL_PUZZLE_HASH is commitment to the pool's puzzle hash
|
||||
; P2_SINGLETON_PUZZLE_HASH is the puzzlehash for your pay_to_singleton puzzle
|
||||
|
@ -17,21 +17,21 @@
|
|||
|
||||
; spend_type is: 0 for absorbing money, 1 to escape
|
||||
; if spend_type is 0
|
||||
; p1 is pool_reward_amount - the value of the coin reward - this is passed in so that this puzzle will still work after halvenings
|
||||
; p2 is pool_reward_height - the block height that the reward was generated at. This is used to calculate the coin ID.
|
||||
; p1 is pool_reward_amount - the value of the coin reward - this is passed in so that this puzzle will still work after halvenings
|
||||
; p2 is pool_reward_height - the block height that the reward was generated at. This is used to calculate the coin ID.
|
||||
; if spend_type is 1
|
||||
; p1 is extra_data key_value_list - signed extra data that the wallet may want to publicly announce for syncing purposes
|
||||
; p2 is destination_puzhash - the location that the escape spend wants to create itself to
|
||||
; p1 is extra_data key_value_list - signed extra data that the wallet may want to publicly announce for syncing purposes
|
||||
; p2 is destination_puzhash - the location that the escape spend wants to create itself to
|
||||
|
||||
(include condition_codes.clib)
|
||||
(include singleton_truths.clib)
|
||||
|
||||
; takes a lisp tree and returns the hash of it
|
||||
(defun sha256tree (TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
(defun-inline calculate_pool_reward (pool_reward_height P2_SINGLETON_PUZZLE_HASH POOL_REWARD_PREFIX pool_reward_amount)
|
||||
|
@ -40,30 +40,30 @@
|
|||
|
||||
(defun absorb_pool_reward (POOL_PUZZLE_HASH my_inner_puzzle_hash my_amount pool_reward_amount pool_reward_id)
|
||||
(list
|
||||
(list CREATE_COIN my_inner_puzzle_hash my_amount)
|
||||
(list CREATE_COIN POOL_PUZZLE_HASH pool_reward_amount)
|
||||
(list CREATE_PUZZLE_ANNOUNCEMENT pool_reward_id)
|
||||
(list ASSERT_COIN_ANNOUNCEMENT (sha256 pool_reward_id '$'))
|
||||
(list CREATE_COIN my_inner_puzzle_hash my_amount)
|
||||
(list CREATE_COIN POOL_PUZZLE_HASH pool_reward_amount)
|
||||
(list CREATE_PUZZLE_ANNOUNCEMENT pool_reward_id)
|
||||
(list ASSERT_COIN_ANNOUNCEMENT (sha256 pool_reward_id '$'))
|
||||
)
|
||||
)
|
||||
|
||||
(defun-inline travel_spend (RELATIVE_LOCK_HEIGHT new_puzzle_hash my_amount extra_data)
|
||||
(list (list ASSERT_HEIGHT_RELATIVE RELATIVE_LOCK_HEIGHT)
|
||||
(list CREATE_COIN new_puzzle_hash my_amount)
|
||||
(list AGG_SIG_ME OWNER_PUBKEY (sha256tree (list new_puzzle_hash extra_data)))
|
||||
(list CREATE_COIN new_puzzle_hash my_amount)
|
||||
(list AGG_SIG_ME OWNER_PUBKEY (sha256tree (list new_puzzle_hash extra_data)))
|
||||
)
|
||||
)
|
||||
|
||||
; main
|
||||
|
||||
(if spend_type
|
||||
(travel_spend RELATIVE_LOCK_HEIGHT p2 (my_amount_truth Truths) p1)
|
||||
(absorb_pool_reward POOL_PUZZLE_HASH
|
||||
(my_inner_puzzle_hash_truth Truths)
|
||||
(my_amount_truth Truths)
|
||||
p1
|
||||
(calculate_pool_reward p2 P2_SINGLETON_PUZZLE_HASH POOL_REWARD_PREFIX p1)
|
||||
)
|
||||
(travel_spend RELATIVE_LOCK_HEIGHT p2 (my_amount_truth Truths) p1)
|
||||
(absorb_pool_reward POOL_PUZZLE_HASH
|
||||
(my_inner_puzzle_hash_truth Truths)
|
||||
(my_amount_truth Truths)
|
||||
p1
|
||||
(calculate_pool_reward p2 P2_SINGLETON_PUZZLE_HASH POOL_REWARD_PREFIX p1)
|
||||
)
|
||||
)
|
||||
|
||||
)
|
||||
|
|
|
@ -1,37 +1,37 @@
|
|||
(mod (block_decompresser_program (historical_blocks_tree))
|
||||
|
||||
(defconstant local_deserialize_mod
|
||||
;; this monstrosity is the assembly output of `chialisp_deserialisation.clsp`
|
||||
;; it's pasted in here because the compiler doesn't yet support nested `mod`
|
||||
;; my apologies -- RK
|
||||
(defconstant local_deserialize_mod
|
||||
;; this monstrosity is the assembly output of `chialisp_deserialisation.clsp`
|
||||
;; it's pasted in here because the compiler doesn't yet support nested `mod`
|
||||
;; my apologies -- RK
|
||||
|
||||
(a (q 5 (a 62 (c 2 (c 5 ()))))
|
||||
(c (q ((-1 . 127) -33 . -65) ((a (i (= 11 (q . -128)) (q 4 () (c 5 ())) (q 2 (i (>s 11 24) (q 2 26 (c 2 (c (a (i (>s 11 28) (q 2 (i (>s 11 20) (q 8) (q 4 (concat (logand (q . 31) 11) (substr 5 () (q . 1))) (c (substr 5 (q . 1)) ()))) 1) (q 4 (logand (q . 63) 11) (c 5 ()))) 1) ()))) (q 4 11 (c 5 ()))) 1)) 1) 4 (substr 21 () 9) (c (substr 21 9) ())) (c (c 5 19) (c 43 ())) (a 22 (c 2 (c 9 (c (a 62 (c 2 (c 21 ()))) ())))) 2 (i (= (substr 5 () (q . 1)) 16) (q 2 46 (c 2 (c (a 62 (c 2 (c (substr 5 (q . 1)) ()))) ()))) (q 2 18 (c 2 (c (substr 5 (q . 1)) (c (substr 5 () (q . 1)) ()))))) 1)
|
||||
1))
|
||||
(a (q 5 (a 62 (c 2 (c 5 ()))))
|
||||
(c (q ((-1 . 127) -33 . -65) ((a (i (= 11 (q . -128)) (q 4 () (c 5 ())) (q 2 (i (>s 11 24) (q 2 26 (c 2 (c (a (i (>s 11 28) (q 2 (i (>s 11 20) (q 8) (q 4 (concat (logand (q . 31) 11) (substr 5 () (q . 1))) (c (substr 5 (q . 1)) ()))) 1) (q 4 (logand (q . 63) 11) (c 5 ()))) 1) ()))) (q 4 11 (c 5 ()))) 1)) 1) 4 (substr 21 () 9) (c (substr 21 9) ())) (c (c 5 19) (c 43 ())) (a 22 (c 2 (c 9 (c (a 62 (c 2 (c 21 ()))) ())))) 2 (i (= (substr 5 () (q . 1)) 16) (q 2 46 (c 2 (c (a 62 (c 2 (c (substr 5 (q . 1)) ()))) ()))) (q 2 18 (c 2 (c (substr 5 (q . 1)) (c (substr 5 () (q . 1)) ()))))) 1)
|
||||
1))
|
||||
)
|
||||
|
||||
(defun sha256tree
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
(defun sha256tree
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
(defun process_coin_spend ((parent puzzle amount solution . spend_level_extras))
|
||||
(c parent (c (sha256tree puzzle) (c amount (c (a puzzle solution) spend_level_extras))))
|
||||
)
|
||||
|
||||
(defun recurse (coin_spends)
|
||||
(if coin_spends
|
||||
(c (process_coin_spend (f coin_spends)) (recurse (r coin_spends)))
|
||||
0
|
||||
)
|
||||
)
|
||||
|
||||
(defun process_coin_spend ((parent puzzle amount solution . spend_level_extras))
|
||||
(c parent (c (sha256tree puzzle) (c amount (c (a puzzle solution) spend_level_extras))))
|
||||
)
|
||||
(defun process-decompressor ((coin_spends . block-level-extras))
|
||||
(c (recurse coin_spends) block-level-extras)
|
||||
)
|
||||
|
||||
(defun recurse (coin_spends)
|
||||
(if coin_spends
|
||||
(c (process_coin_spend (f coin_spends)) (recurse (r coin_spends)))
|
||||
0
|
||||
)
|
||||
)
|
||||
|
||||
(defun process-decompressor ((coin_spends . block-level-extras))
|
||||
(c (recurse coin_spends) block-level-extras)
|
||||
)
|
||||
|
||||
(process-decompressor (a block_decompresser_program (list local_deserialize_mod historical_blocks_tree))))
|
||||
(process-decompressor (a block_decompresser_program (list local_deserialize_mod historical_blocks_tree))))
|
||||
)
|
||||
|
|
|
@ -4,31 +4,31 @@
|
|||
; simplify the consensus rules
|
||||
(mod (block_decompresser_program (historical_blocks_tree))
|
||||
|
||||
(defconstant null ()
|
||||
)
|
||||
(defconstant null ()
|
||||
)
|
||||
|
||||
(defun sha256tree
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
(defun sha256tree
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
(defun process_coin_spend ((parent puzzle amount solution . spend_level_extras))
|
||||
(c parent (c (sha256tree puzzle) (c amount (c (a puzzle solution) spend_level_extras))))
|
||||
(defun process_coin_spend ((parent puzzle amount solution . spend_level_extras))
|
||||
(c parent (c (sha256tree puzzle) (c amount (c (a puzzle solution) spend_level_extras))))
|
||||
)
|
||||
|
||||
(defun recurse (coin_spends)
|
||||
(if coin_spends
|
||||
(c (process_coin_spend (f coin_spends)) (recurse (r coin_spends)))
|
||||
0
|
||||
)
|
||||
)
|
||||
|
||||
(defun recurse (coin_spends)
|
||||
(if coin_spends
|
||||
(c (process_coin_spend (f coin_spends)) (recurse (r coin_spends)))
|
||||
0
|
||||
)
|
||||
)
|
||||
(defun process-decompressor ((coin_spends . block-level-extras))
|
||||
(c (recurse coin_spends) block-level-extras)
|
||||
)
|
||||
|
||||
(defun process-decompressor ((coin_spends . block-level-extras))
|
||||
(c (recurse coin_spends) block-level-extras)
|
||||
)
|
||||
|
||||
(process-decompressor (a block_decompresser_program (list null historical_blocks_tree))))
|
||||
(process-decompressor (a block_decompresser_program (list null historical_blocks_tree))))
|
||||
)
|
||||
|
|
|
@ -10,10 +10,10 @@
|
|||
(include utility_macros.clib)
|
||||
|
||||
(defun sha256tree (TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
(defun create_coins_for_payment (payment_params so_far)
|
||||
|
@ -27,8 +27,8 @@
|
|||
)
|
||||
|
||||
(defun-inline create_announcement_for_payment (notarized_payment)
|
||||
(list CREATE_PUZZLE_ANNOUNCEMENT
|
||||
(sha256tree notarized_payment))
|
||||
(list CREATE_PUZZLE_ANNOUNCEMENT
|
||||
(sha256tree notarized_payment))
|
||||
)
|
||||
|
||||
(defun-inline augment_condition_list (notarized_payment so_far)
|
||||
|
@ -46,4 +46,4 @@
|
|||
)
|
||||
|
||||
(construct_condition_list notarized_payments)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
(include condition_codes.clib)
|
||||
|
||||
(defun sha256tree (TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
(defun create_coins_for_payment (payment_params so_far)
|
||||
|
@ -23,8 +23,8 @@
|
|||
)
|
||||
|
||||
(defun-inline create_announcement_for_payment (notarized_payment)
|
||||
(list CREATE_PUZZLE_ANNOUNCEMENT
|
||||
(sha256tree notarized_payment))
|
||||
(list CREATE_PUZZLE_ANNOUNCEMENT
|
||||
(sha256tree notarized_payment))
|
||||
)
|
||||
|
||||
(defun-inline augment_condition_list (notarized_payment so_far)
|
||||
|
@ -42,4 +42,4 @@
|
|||
)
|
||||
|
||||
(construct_condition_list notarized_payments)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
(
|
||||
;; hash a tree
|
||||
;; This is used to calculate a puzzle hash given a puzzle program.
|
||||
(defun sha256tree
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
;; hash a tree
|
||||
;; This is used to calculate a puzzle hash given a puzzle program.
|
||||
(defun sha256tree
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,15 +1,15 @@
|
|||
(
|
||||
mod (program)
|
||||
mod (program)
|
||||
|
||||
;; hash a tree
|
||||
;; This is used to calculate a puzzle hash given a puzzle program.
|
||||
(defun sha256tree
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
;; hash a tree
|
||||
;; This is used to calculate a puzzle hash given a puzzle program.
|
||||
(defun sha256tree
|
||||
(TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree (f TREE)) (sha256tree (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
(sha256tree program)
|
||||
)
|
||||
(sha256tree program)
|
||||
)
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
|
||||
; takes a lisp tree and returns the hash of it
|
||||
(defun sha256tree1 (TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
; main
|
||||
(list (list CREATE_COIN singleton_full_puzzle_hash amount)
|
||||
(list CREATE_COIN_ANNOUNCEMENT (sha256tree1 (list singleton_full_puzzle_hash amount key_value_list))))
|
||||
(list CREATE_COIN_ANNOUNCEMENT (sha256tree1 (list singleton_full_puzzle_hash amount key_value_list))))
|
||||
)
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
(mod (SINGLETON_STRUCT INNER_PUZZLE lineage_proof my_amount inner_solution)
|
||||
|
||||
;; SINGLETON_STRUCT = (MOD_HASH . (LAUNCHER_ID . LAUNCHER_PUZZLE_HASH))
|
||||
;; SINGLETON_STRUCT = (MOD_HASH . (LAUNCHER_ID . LAUNCHER_PUZZLE_HASH))
|
||||
|
||||
; SINGLETON_STRUCT, INNER_PUZZLE are curried in by the wallet
|
||||
; SINGLETON_STRUCT, INNER_PUZZLE are curried in by the wallet
|
||||
|
||||
; EXAMPLE SOLUTION '(0xfadeddab 0xdeadbeef 1 (0xdeadbeef 200) 50 ((51 0xfadeddab 100) (60 "trash") (51 deadbeef 0)))'
|
||||
; EXAMPLE SOLUTION '(0xfadeddab 0xdeadbeef 1 (0xdeadbeef 200) 50 ((51 0xfadeddab 100) (60 "trash") (51 deadbeef 0)))'
|
||||
|
||||
|
||||
; This puzzle is a wrapper around an inner smart puzzle which guarantees uniqueness.
|
||||
; It takes its singleton identity from a coin with a launcher puzzle which guarantees that it is unique.
|
||||
; This puzzle is a wrapper around an inner smart puzzle which guarantees uniqueness.
|
||||
; It takes its singleton identity from a coin with a launcher puzzle which guarantees that it is unique.
|
||||
|
||||
(include condition_codes.clib)
|
||||
(include curry-and-treehash.clib)
|
||||
|
@ -16,10 +16,10 @@
|
|||
|
||||
; takes a lisp tree and returns the hash of it
|
||||
(defun sha256tree1 (TREE)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
(if (l TREE)
|
||||
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
|
||||
(sha256 1 TREE)
|
||||
)
|
||||
)
|
||||
|
||||
; "assert" is a macro that wraps repeated instances of "if"
|
||||
|
@ -41,17 +41,17 @@
|
|||
;; return the full puzzlehash for a singleton with the innerpuzzle curried in
|
||||
; puzzle-hash-of-curried-function is imported from curry-and-treehash.clib
|
||||
(defun-inline calculate_full_puzzle_hash (SINGLETON_STRUCT inner_puzzle_hash)
|
||||
(puzzle-hash-of-curried-function (mod_hash_for_singleton_struct SINGLETON_STRUCT)
|
||||
inner_puzzle_hash
|
||||
(sha256tree1 SINGLETON_STRUCT)
|
||||
)
|
||||
(puzzle-hash-of-curried-function (mod_hash_for_singleton_struct SINGLETON_STRUCT)
|
||||
inner_puzzle_hash
|
||||
(sha256tree1 SINGLETON_STRUCT)
|
||||
)
|
||||
)
|
||||
|
||||
; assembles information from the solution to create our own full ID including asserting our parent is a singleton
|
||||
(defun create_my_ID (SINGLETON_STRUCT full_puzzle_hash parent_parent parent_inner_puzzle_hash parent_amount my_amount)
|
||||
(sha256 (sha256 parent_parent (calculate_full_puzzle_hash SINGLETON_STRUCT parent_inner_puzzle_hash) parent_amount)
|
||||
full_puzzle_hash
|
||||
my_amount)
|
||||
full_puzzle_hash
|
||||
my_amount)
|
||||
)
|
||||
|
||||
;; take a boolean and a non-empty list of conditions
|
||||
|
@ -60,8 +60,8 @@
|
|||
;; pretty sneaky, eh?
|
||||
(defun strip_first_condition_if (boolean condition_list)
|
||||
(if boolean
|
||||
(r condition_list)
|
||||
condition_list
|
||||
(r condition_list)
|
||||
condition_list
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -80,8 +80,8 @@
|
|||
;; Returns a (bool . bool)
|
||||
(defun odd_cons_m113 (output_amount)
|
||||
(c
|
||||
(= (logand output_amount 1) 1) ;; is it odd?
|
||||
(= output_amount -113) ;; is it the escape value?
|
||||
(= (logand output_amount 1) 1) ;; is it odd?
|
||||
(= output_amount -113) ;; is it the escape value?
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -97,29 +97,29 @@
|
|||
(defun check_and_morph_conditions_for_singleton (SINGLETON_STRUCT conditions has_odd_output_been_found)
|
||||
(if conditions
|
||||
(morph_next_condition SINGLETON_STRUCT conditions has_odd_output_been_found (odd_cons_m113 (created_coin_value_or_0 (f conditions))))
|
||||
(if has_odd_output_been_found
|
||||
0
|
||||
(x) ;; no odd output found
|
||||
)
|
||||
(if has_odd_output_been_found
|
||||
0
|
||||
(x) ;; no odd output found
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; a continuation of `check_and_morph_conditions_for_singleton` with booleans `is_output_odd` and `is_output_m113`
|
||||
;; precalculated
|
||||
(defun morph_next_condition (SINGLETON_STRUCT conditions has_odd_output_been_found (is_output_odd . is_output_m113))
|
||||
(assert
|
||||
(not (all is_output_odd has_odd_output_been_found))
|
||||
(strip_first_condition_if
|
||||
is_output_m113
|
||||
(c (if is_output_odd
|
||||
(morph_condition (f conditions) SINGLETON_STRUCT)
|
||||
(f conditions)
|
||||
)
|
||||
(check_and_morph_conditions_for_singleton SINGLETON_STRUCT (r conditions) (any is_output_odd has_odd_output_been_found))
|
||||
)
|
||||
;; a continuation of `check_and_morph_conditions_for_singleton` with booleans `is_output_odd` and `is_output_m113`
|
||||
;; precalculated
|
||||
(defun morph_next_condition (SINGLETON_STRUCT conditions has_odd_output_been_found (is_output_odd . is_output_m113))
|
||||
(assert
|
||||
(not (all is_output_odd has_odd_output_been_found))
|
||||
(strip_first_condition_if
|
||||
is_output_m113
|
||||
(c (if is_output_odd
|
||||
(morph_condition (f conditions) SINGLETON_STRUCT)
|
||||
(f conditions)
|
||||
)
|
||||
(check_and_morph_conditions_for_singleton SINGLETON_STRUCT (r conditions) (any is_output_odd has_odd_output_been_found))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
; this final stager asserts our ID
|
||||
; it also runs the innerpuz with the innersolution with the "truths" added
|
||||
|
@ -171,7 +171,7 @@
|
|||
; if our value is not an odd amount then we are invalid
|
||||
; this calculates my_innerpuzhash and passes all values to stager_one
|
||||
(if (logand my_amount 1)
|
||||
(stager_one SINGLETON_STRUCT lineage_proof (sha256tree1 INNER_PUZZLE) my_amount INNER_PUZZLE inner_solution)
|
||||
(x)
|
||||
(stager_one SINGLETON_STRUCT lineage_proof (sha256tree1 INNER_PUZZLE) my_amount INNER_PUZZLE inner_solution)
|
||||
(x)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
(mod (SINGLETON_STRUCT INNER_PUZZLE lineage_proof my_amount inner_solution)
|
||||
|
||||
;; SINGLETON_STRUCT = (MOD_HASH . (LAUNCHER_ID . LAUNCHER_PUZZLE_HASH))
|
||||
;; SINGLETON_STRUCT = (MOD_HASH . (LAUNCHER_ID . LAUNCHER_PUZZLE_HASH))
|
||||
|
||||
; SINGLETON_STRUCT, INNER_PUZZLE are curried in by the wallet
|
||||
; SINGLETON_STRUCT, INNER_PUZZLE are curried in by the wallet
|
||||
|
||||
; EXAMPLE SOLUTION '(0xfadeddab 0xdeadbeef 1 (0xdeadbeef 200) 50 ((51 0xfadeddab 100) (60 "trash") (51 deadbeef 0)))'
|
||||
; EXAMPLE SOLUTION '(0xfadeddab 0xdeadbeef 1 (0xdeadbeef 200) 50 ((51 0xfadeddab 100) (60 "trash") (51 deadbeef 0)))'
|
||||
|
||||
|
||||
; This puzzle is a wrapper around an inner smart puzzle which guarantees uniqueness.
|
||||
; It takes its singleton identity from a coin with a launcher puzzle which guarantees that it is unique.
|
||||
; This puzzle is a wrapper around an inner smart puzzle which guarantees uniqueness.
|
||||
; It takes its singleton identity from a coin with a launcher puzzle which guarantees that it is unique.
|
||||
|
||||
(include condition_codes.clib)
|
||||
(include curry-and-treehash.clib) ; also imports the constant ONE == 1
|
||||
|
@ -22,10 +22,10 @@
|
|||
;; return the full puzzlehash for a singleton with the innerpuzzle curried in
|
||||
; puzzle-hash-of-curried-function is imported from curry-and-treehash.clib
|
||||
(defun-inline calculate_full_puzzle_hash (SINGLETON_STRUCT inner_puzzle_hash)
|
||||
(puzzle-hash-of-curried-function (mod_hash_for_singleton_struct SINGLETON_STRUCT)
|
||||
inner_puzzle_hash
|
||||
(sha256tree SINGLETON_STRUCT)
|
||||
)
|
||||
(puzzle-hash-of-curried-function (mod_hash_for_singleton_struct SINGLETON_STRUCT)
|
||||
inner_puzzle_hash
|
||||
(sha256tree SINGLETON_STRUCT)
|
||||
)
|
||||
)
|
||||
|
||||
(defun-inline morph_condition (condition SINGLETON_STRUCT)
|
||||
|
@ -63,16 +63,16 @@
|
|||
)
|
||||
(assert has_odd_output_been_found ())
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
; assert that either the lineage proof is for a parent singleton, or, if it's for the launcher, verify it matched our launcher ID
|
||||
; then return a condition asserting it actually is our parent ID
|
||||
(defun verify_lineage_proof (SINGLETON_STRUCT parent_id is_not_launcher)
|
||||
; assert that either the lineage proof is for a parent singleton, or, if it's for the launcher, verify it matched our launcher ID
|
||||
; then return a condition asserting it actually is our parent ID
|
||||
(defun verify_lineage_proof (SINGLETON_STRUCT parent_id is_not_launcher)
|
||||
(assert (any is_not_launcher (= parent_id (launcher_id_for_singleton_struct SINGLETON_STRUCT)))
|
||||
; then
|
||||
(list ASSERT_MY_PARENT_ID parent_id)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
; main
|
||||
|
||||
|
@ -89,12 +89,12 @@
|
|||
(calculate_coin_id
|
||||
(parent_info_for_lineage_proof lineage_proof)
|
||||
(if (is_not_eve_proof lineage_proof) ; The PH calculation changes based on the lineage proof
|
||||
(calculate_full_puzzle_hash SINGLETON_STRUCT (puzzle_hash_for_lineage_proof lineage_proof)) ; wrap the innerpuz in a singleton
|
||||
(launcher_puzzle_hash_for_singleton_struct SINGLETON_STRUCT) ; Use the static launcher puzzle hash
|
||||
(calculate_full_puzzle_hash SINGLETON_STRUCT (puzzle_hash_for_lineage_proof lineage_proof)) ; wrap the innerpuz in a singleton
|
||||
(launcher_puzzle_hash_for_singleton_struct SINGLETON_STRUCT) ; Use the static launcher puzzle hash
|
||||
)
|
||||
(if (is_not_eve_proof lineage_proof) ; The position of "amount" changes based on the type on lineage proof
|
||||
(amount_for_lineage_proof lineage_proof)
|
||||
(amount_for_eve_proof lineage_proof)
|
||||
(amount_for_lineage_proof lineage_proof)
|
||||
(amount_for_eve_proof lineage_proof)
|
||||
)
|
||||
)
|
||||
(is_not_eve_proof lineage_proof)
|
||||
|
|
|
@ -18,4 +18,4 @@
|
|||
(defun-inline is_not_eve_proof (lineage_proof) (r (r lineage_proof)))
|
||||
(defun-inline parent_info_for_eve_proof (lineage_proof) (f lineage_proof))
|
||||
(defun-inline amount_for_eve_proof (lineage_proof) (f (r lineage_proof)))
|
||||
)
|
||||
)
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
(defun decompress_cses (decompress_puzzle decompress_coin_spend_entry cses deserialize puzzle_prefix)
|
||||
(if cses
|
||||
(c (a decompress_coin_spend_entry (list deserialize decompress_puzzle puzzle_prefix (f cses)))
|
||||
(decompress_cses decompress_puzzle decompress_coin_spend_entry (r cses) deserialize puzzle_prefix ))
|
||||
()) )
|
||||
(c (a decompress_coin_spend_entry (list deserialize decompress_puzzle puzzle_prefix (f cses)))
|
||||
(decompress_cses decompress_puzzle decompress_coin_spend_entry (r cses) deserialize puzzle_prefix ))
|
||||
()) )
|
||||
|
||||
(defun join_gen_args (generators start1 end1 start2 end2)
|
||||
(concat
|
||||
|
|
|
@ -3,18 +3,18 @@
|
|||
; all items in the list are required to be non-nil
|
||||
; except for the final item which is returned
|
||||
(defmacro assert items
|
||||
(if (r items)
|
||||
(list if (f items) (c assert (r items)) (q . (x)))
|
||||
(f items)
|
||||
)
|
||||
(if (r items)
|
||||
(list if (f items) (c assert (r items)) (q . (x)))
|
||||
(f items)
|
||||
)
|
||||
)
|
||||
|
||||
(defmacro and ARGS
|
||||
(if ARGS
|
||||
(qq (if (unquote (f ARGS))
|
||||
(unquote (c and (r ARGS)))
|
||||
()
|
||||
))
|
||||
1)
|
||||
)
|
||||
(if ARGS
|
||||
(qq (if (unquote (f ARGS))
|
||||
(unquote (c and (r ARGS)))
|
||||
()
|
||||
))
|
||||
1)
|
||||
)
|
||||
)
|
||||
|
|
|
@ -0,0 +1,356 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
|
||||
# A simple class for separating a line into code and comment
|
||||
class Line:
|
||||
def __init__(self, code: List[bytes], comment: Optional[List[bytes]]):
|
||||
self.code = code
|
||||
self.comment = comment
|
||||
|
||||
|
||||
# Remove all whitespace from the beginning of a byte array
|
||||
def trim_ascii_start(line: List[bytes]) -> List[bytes]:
|
||||
first_non_ws: int = 0
|
||||
got_one: bool = False
|
||||
|
||||
for i, ch in enumerate(line):
|
||||
if not (ch.decode("ascii").isspace()):
|
||||
got_one = True
|
||||
first_non_ws = i
|
||||
break
|
||||
|
||||
if not got_one:
|
||||
return []
|
||||
else:
|
||||
return line[first_non_ws:]
|
||||
|
||||
|
||||
# Remove all whitespace from the end of a byte array
|
||||
def trim_ascii_end(line: List[bytes]) -> List[bytes]:
|
||||
last_non_ws: int = 0
|
||||
got_one: bool = False
|
||||
|
||||
for i, ch in enumerate(line):
|
||||
if (not ch.decode("ascii").isspace()) and ch[0] <= 127:
|
||||
got_one = True
|
||||
last_non_ws = i
|
||||
|
||||
if not got_one:
|
||||
return []
|
||||
else:
|
||||
return line[0 : last_non_ws + 1]
|
||||
|
||||
|
||||
class Formatter:
|
||||
def __init__(self) -> None:
|
||||
self.start_paren_level: int = 0
|
||||
self.paren_level: int = 0
|
||||
self.out_col: int = 0 # The colum we are at while outputting a line
|
||||
self.cur_line: int = 0
|
||||
self.line: List[bytes] = []
|
||||
self.comment: Optional[List[bytes]] = None
|
||||
self.lines: List[List[bytes]] = []
|
||||
self.work_lines: List[Line] = []
|
||||
self.getting_form_name: int = 0
|
||||
self.got_form_on_line: int = 0
|
||||
self.form_name: List[bytes] = []
|
||||
self.reset_form_indent: bool = False
|
||||
# self.def_started = False
|
||||
self.result_line: List[bytes] = []
|
||||
# self.definition_starts = []
|
||||
# self.extra_def_lines = []
|
||||
self.indent_stack: List[int] = []
|
||||
self.result: List[List[bytes]] = []
|
||||
self.config: Dict[str, Any] = {
|
||||
"gnu_comment_conventions": False,
|
||||
}
|
||||
|
||||
# Add a character of source, breaking the source into lines as we go
|
||||
def run_char(self, ch: bytes) -> None:
|
||||
if ch == b"\n":
|
||||
self.finish_line()
|
||||
else:
|
||||
self.line.append(ch)
|
||||
|
||||
# Process a single character and add it to the final result
|
||||
def output_char(self, ch: bytes) -> None:
|
||||
if ch == b"\n":
|
||||
self.work_lines.append(Line(self.result_line, self.comment))
|
||||
self.result_line = []
|
||||
self.comment = None
|
||||
self.out_col = 0
|
||||
else:
|
||||
self.result_line.append(ch)
|
||||
self.out_col += 1
|
||||
|
||||
# Process a line and add it to the work_lines array
|
||||
def output_line(self) -> None:
|
||||
line_indent = self.get_cur_indent()
|
||||
max_paren_level = self.paren_level
|
||||
self.start_paren_level = self.paren_level
|
||||
starting_indent_len = len(self.indent_stack)
|
||||
|
||||
if not self.line:
|
||||
self.output_char(b"\n")
|
||||
return
|
||||
|
||||
# Get a line from the unprocessed lines
|
||||
line = trim_ascii_end(self.line)
|
||||
line = trim_ascii_start(line)
|
||||
self.line.clear()
|
||||
|
||||
# Some variables to be aware of whether or not we're in a string literal
|
||||
in_string = None
|
||||
string_bs = False # bs == backslash
|
||||
|
||||
# Some variables to be aware of whether or not we're in a comment
|
||||
semis = 0 # number of semi colons starting a comment
|
||||
semi_off = 0 # the column where the comment starts
|
||||
comment = [] # The comment byte array
|
||||
|
||||
# Main loop to format the line
|
||||
for i, ch in enumerate(line):
|
||||
# Track the form name
|
||||
if self.getting_form_name > 0:
|
||||
self.reset_form_indent = False
|
||||
if self.getting_form_name == 1 and not (ch == b" "):
|
||||
self.getting_form_name = 2
|
||||
self.form_name.append(ch)
|
||||
elif self.getting_form_name == 2 and ch in (b" ", b"(", b")"):
|
||||
self.getting_form_name = 0
|
||||
self.got_form_on_line = self.cur_line
|
||||
else:
|
||||
self.form_name.append(ch)
|
||||
|
||||
# if self.start_paren_level == 1 and not self.def_started:
|
||||
# self.def_started = True
|
||||
# self.definition_starts.append(len(self.work_lines))
|
||||
|
||||
# Special indentation rules for `if`
|
||||
should_reset_indent = (
|
||||
self.getting_form_name == 0
|
||||
and self.form_name == [b"i", b"f"]
|
||||
and not (ch == b" ")
|
||||
and not self.reset_form_indent
|
||||
)
|
||||
|
||||
# Be sure to not format string literals as code
|
||||
if string_bs:
|
||||
string_bs = False
|
||||
continue
|
||||
if in_string is not None:
|
||||
if ch == b"\\":
|
||||
string_bs = True
|
||||
if ch == in_string:
|
||||
in_string = None
|
||||
continue
|
||||
|
||||
if semis == 0:
|
||||
# We've entered a string, stop processing
|
||||
if ch == b"'" or ch == b'"':
|
||||
in_string = ch
|
||||
continue
|
||||
elif ch == b"(":
|
||||
self.paren_level += 1
|
||||
if self.paren_level > max_paren_level:
|
||||
max_paren_level = self.paren_level
|
||||
|
||||
if should_reset_indent:
|
||||
self.reset_indent(line_indent + i)
|
||||
self.reset_form_indent = True
|
||||
self.indent_paren()
|
||||
|
||||
self.form_name.clear()
|
||||
self.got_form_on_line = 0
|
||||
self.getting_form_name = 1
|
||||
continue
|
||||
elif ch == b")":
|
||||
indentation_diff: int = (self.indent_stack[-1] if len(self.indent_stack) > 0 else 0) - (
|
||||
self.indent_stack[-2] if len(self.indent_stack) > 1 else 0
|
||||
)
|
||||
self.retire_indent()
|
||||
if self.paren_level <= self.start_paren_level:
|
||||
line_indent -= indentation_diff
|
||||
self.paren_level -= 1
|
||||
continue
|
||||
elif should_reset_indent:
|
||||
self.reset_indent(line_indent + i)
|
||||
self.reset_form_indent = True
|
||||
|
||||
if ch == b";":
|
||||
if semis == 0:
|
||||
semi_off = i
|
||||
semis += 1
|
||||
elif semis > 0:
|
||||
comment = line[i:]
|
||||
line = trim_ascii_end(line[:semi_off])
|
||||
break
|
||||
|
||||
if semis + semi_off == len(line):
|
||||
line = trim_ascii_end(line[:semi_off])
|
||||
|
||||
line = trim_ascii_end(line)
|
||||
|
||||
if semis == 1 and not line and self.config["gnu_comment_conventions"]:
|
||||
semis = 0
|
||||
self.comment = comment
|
||||
comment = []
|
||||
else:
|
||||
self.comment = None
|
||||
|
||||
if semis > 0:
|
||||
if semis < 3 or not self.config["gnu_comment_conventions"]:
|
||||
self.indent(line_indent)
|
||||
if line and not self.config["gnu_comment_conventions"]:
|
||||
for co in line:
|
||||
self.output_char(co)
|
||||
self.output_char(b" ")
|
||||
self.output_char(b" ")
|
||||
for _i in range(semis):
|
||||
self.output_char(b";")
|
||||
for co in comment:
|
||||
self.output_char(co)
|
||||
if line and self.config["gnu_comment_conventions"]:
|
||||
# Code after comment in this scenario
|
||||
self.output_char(b"\n")
|
||||
self.indent(line_indent)
|
||||
for co in line:
|
||||
self.output_char(co)
|
||||
elif line != []:
|
||||
self.indent(line_indent)
|
||||
for co in line:
|
||||
self.output_char(co)
|
||||
|
||||
self.output_char(b"\n")
|
||||
|
||||
# We never want the next line to be more indented than us + 1 unit
|
||||
if len(self.indent_stack) > starting_indent_len + 1:
|
||||
for i in range(starting_indent_len + 1, len(self.indent_stack)):
|
||||
self.indent_stack[i] = self.indent_stack[starting_indent_len + 1]
|
||||
|
||||
# if max_paren_level > 1 and self.paren_level == 1:
|
||||
# self.def_started = False
|
||||
# self.extra_def_lines.append(len(self.work_lines))
|
||||
|
||||
# Add our current line to our lines array and reset the line
|
||||
def finish_line(self) -> None:
|
||||
self.lines.append(self.line.copy())
|
||||
self.line.clear()
|
||||
self.comment = None
|
||||
|
||||
def finish(self) -> None:
|
||||
if self.line:
|
||||
self.finish_line()
|
||||
|
||||
for i in range(len(self.lines)):
|
||||
self.line = self.lines[i]
|
||||
self.cur_line = i
|
||||
self.output_line()
|
||||
|
||||
next_handle_line = 0
|
||||
for i in range(len(self.work_lines)):
|
||||
if i < next_handle_line:
|
||||
continue
|
||||
|
||||
# Find the max comment spacing needed and output the group.
|
||||
# Skip if already handled.
|
||||
comment = self.work_lines[i].comment
|
||||
if comment is not None:
|
||||
comment_offset = len(self.work_lines[i].code)
|
||||
comments = [comment]
|
||||
for j in range(i + 1, len(self.lines)):
|
||||
comment = self.work_lines[j].comment
|
||||
if comment is not None:
|
||||
comments.append(comment)
|
||||
comment_offset = max(comment_offset, len(self.work_lines[j].code))
|
||||
else:
|
||||
next_handle_line = j
|
||||
break
|
||||
|
||||
for j, comment in enumerate(comments):
|
||||
line = self.work_lines[i + j].code.copy()
|
||||
while len(line) < comment_offset:
|
||||
line.append(b" ")
|
||||
line.append(b" ")
|
||||
line.append(b";")
|
||||
line += comment[:]
|
||||
self.result.append(line)
|
||||
else:
|
||||
self.result.append(self.work_lines[i].code.copy())
|
||||
|
||||
# el_idx = 0
|
||||
# inserted = 0
|
||||
#
|
||||
# for ds in self.definition_starts[0:len(self.definition_starts)]:
|
||||
# while el_idx < len(self.extra_def_lines) and self.extra_def_lines[el_idx] < ds:
|
||||
# el_idx += 1
|
||||
#
|
||||
# if el_idx >= len(self.extra_def_lines):
|
||||
# break
|
||||
#
|
||||
# el = self.extra_def_lines[el_idx]
|
||||
# if el <= ds + 1:
|
||||
# insert_at = el + inserted
|
||||
# self.result.insert(insert_at, [])
|
||||
# inserted += 1
|
||||
|
||||
# We maintain a stack of indentation levels
|
||||
# The following functions maintain that stack
|
||||
def indent(self, cur_indent: int) -> None:
|
||||
while self.out_col < cur_indent:
|
||||
self.output_char(b" ")
|
||||
|
||||
def get_cur_indent(self) -> int:
|
||||
if self.indent_stack:
|
||||
return self.indent_stack[-1]
|
||||
else:
|
||||
return 0
|
||||
|
||||
def reset_indent(self, i: int) -> None:
|
||||
if self.indent_stack:
|
||||
self.indent_stack[-1] = i
|
||||
|
||||
def indent_paren(self) -> None:
|
||||
current_indent = self.indent_stack[-1] if self.indent_stack else 0
|
||||
self.indent_stack.append(current_indent + 2)
|
||||
|
||||
def retire_indent(self) -> None:
|
||||
if self.indent_stack:
|
||||
self.indent_stack.pop()
|
||||
|
||||
|
||||
def concat_byte_array(bs: List[bytes]) -> bytes:
|
||||
return b"".join(bs)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
for arg in sys.argv[1:]:
|
||||
path = Path(arg)
|
||||
if path.is_dir():
|
||||
all_paths = [*path.rglob("*.clsp"), *path.rglob("*.clib")]
|
||||
else:
|
||||
all_paths = [path]
|
||||
|
||||
for filename in all_paths:
|
||||
with open(filename, "rb") as f:
|
||||
filedata = f.read()
|
||||
|
||||
formatter = Formatter()
|
||||
|
||||
for ch in filedata:
|
||||
formatter.run_char(bytes([ch]))
|
||||
|
||||
formatter.finish()
|
||||
|
||||
with open(filename, "wb") as f:
|
||||
for i, line in enumerate(formatter.result):
|
||||
f.write(concat_byte_array(line))
|
||||
f.write(b"\n")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in New Issue