Add Chialisp pretty printer to pre-commit (#15008)

* Add chialispp port to pre-commit

* Lint files
This commit is contained in:
Matt Hauff 2023-05-09 12:46:41 -07:00 committed by GitHub
parent a2567f45a9
commit eab43eb800
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 1435 additions and 1072 deletions

View File

@ -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

View File

@ -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)))
)

View File

@ -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
)
)

View File

@ -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)
)
)

View 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)
)

View File

@ -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 ()))))))
)

View File

@ -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)))
)

View File

@ -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)))
)

View File

@ -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))
)

View File

@ -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))))))
)
)

View File

@ -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)
)
)
)

View File

@ -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
)

View File

@ -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)
)
)
)
)
)

View File

@ -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)
)
)
)

View File

@ -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))
)
)
)

View File

@ -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))
)
()
()
)
)
)

View File

@ -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)
)
)

View File

@ -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)))
)

View File

@ -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
)
)

View File

@ -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))
)
()
)
)

View File

@ -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

View File

@ -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 () ())

View File

@ -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
)
)
)

View File

@ -4,4 +4,4 @@
)
(include condition_codes.clib)
(list (list CREATE_COIN TARGET AMOUNT) (list CREATE_COIN_ANNOUNCEMENT ()))
)
)

View File

@ -1,3 +1,3 @@
(mod (conditions)
(qq (q . (unquote conditions)))
(qq (q . (unquote conditions)))
)

View File

@ -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)

View File

@ -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))
)

View File

@ -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))
)

View File

@ -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
)
)

View File

@ -16,4 +16,4 @@
)
(a parent_inner_puz parent_solution)
)
)
)

View File

@ -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)
)
)
)

View File

@ -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

View File

@ -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)
)
)

View File

@ -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)
)
)
)

View File

@ -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)
)
)
)

View File

@ -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))))
)

View File

@ -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))))
)

View File

@ -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)
)
)

View File

@ -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)
)
)

View File

@ -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)
)
)
)
)

View File

@ -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)
)

View File

@ -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))))
)

View File

@ -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)
)
)

View File

@ -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)

View File

@ -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)))
)
)

View File

@ -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

View File

@ -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)
)
)

356
tools/chialispp.py Normal file
View File

@ -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()