(mod ((VALIDATION_PROGRAM_HASH LAST_MOVE SPLIT AMOUNT TIMEOUT MAX_MOVE_SIZE MOVER_PUZZLE_HASH WAITER_PUZZLE_HASH MOD_HASH) action . args) (include *standard-cl-21*) (include assert.clinc) (include curry.clinc) (include shatree.clinc) (include condition_codes.clinc) (defconstant move 0) (defconstant accuse 1) (defconstant timeout 2) (defconst accusehash 0x8653ac175c6821561262b57d219375307faf7bdcfd347922905b6e7eee4f3216) (defun <= (A B) (not (> A B))) (defun >= (A B) (not (> B A))) (defmacro prefix_list ARGS (defun compile-list (args) (if args (if (r args) ;; We have at least 2 things left... recurse once. (qq (c (unquote (f args)) (unquote (compile-list (r args))))) ;; This is the last item, so we return it whole (improper list form). (qq (unquote (f args))) ) 0 ) ) (compile-list ARGS) ) (defun allow-only-nonzero-coins (lst remaining) (if lst (let ((hash (f (f lst))) (size (f (r (f lst))))) (allow-only-nonzero-coins (r lst) (if size (c (list CREATE_COIN hash size) remaining) remaining ) ) ) remaining ) ) (defun is-coin-created-with-new-puzzle-hash-and-amount (new_puzzle_hash AMOUNT conditions agg ) (if conditions (let ((condname (f (f conditions))) (arg1 (f (r (f conditions)))) (arg2 (f (r (r (f conditions)))))) (is-coin-created-with-new-puzzle-hash-and-amount new_puzzle_hash AMOUNT (r conditions) (if agg 1 (if (= condname CREATE_COIN) (logand (= arg1 new_puzzle_hash) (= arg2 AMOUNT)) 0 ) ) ) ) agg ) ) (if (= action timeout) (allow-only-nonzero-coins (list (list MOVER_PUZZLE_HASH SPLIT) (list WAITER_PUZZLE_HASH (- AMOUNT SPLIT)) ) (list (list ASSERT_SECONDS_RELATIVE TIMEOUT) (list CREATE_COIN_ANNOUNCEMENT 0) ) ) (if action ;; accuse (let ((grandparent_id (f args)) (parent_validation_puzzle_hash (f (r args))) (parent_everything_else_hash (f (r (r args)))) (mover_puzzle_reveal (f (r (r (r args))))) (solution (f (r (r (r (r args))))))) (let ((new_puzzle_hash (curry_hashes accusehash (shatree (list parent_validation_puzzle_hash VALIDATION_PROGRAM_HASH LAST_MOVE SPLIT AMOUNT TIMEOUT WAITER_PUZZLE_HASH MOVER_PUZZLE_HASH) ) )) (conditions (a mover_puzzle_reveal solution)) ) (assert (= MOVER_PUZZLE_HASH (shatree mover_puzzle_reveal)) (is-coin-created-with-new-puzzle-hash-and-amount new_puzzle_hash AMOUNT conditions 0 ) (prefix_list (list ASSERT_MY_PARENT_ID (sha256 grandparent_id (curry_hashes MOD_HASH (sha256 2 (sha256 1 parent_validation_puzzle_hash) parent_everything_else_hash) ) AMOUNT ) ) (list CREATE_COIN_ANNOUNCEMENT 0) conditions ) ) ) ) ;; move (let ((new_move (f args)) (new_split (f (r args))) (new_validation_program_hash (f (r (r args)))) (mover_puzzle_reveal (f (r (r (r args))))) (solution (f (r (r (r (r args))))))) (let ((new_puzzle_hash (curry_hashes MOD_HASH (shatree (list new_validation_program_hash new_move new_split AMOUNT TIMEOUT MAX_MOVE_SIZE WAITER_PUZZLE_HASH MOVER_PUZZLE_HASH MOD_HASH ) ) )) (conditions (a mover_puzzle_reveal solution)) ) (assert VALIDATION_PROGRAM_HASH (<= (strlen new_move) MAX_MOVE_SIZE) (<= new_split AMOUNT) (>= new_split 0) (logior (not new_validation_program_hash) (= 32 (strlen new_validation_program_hash))) (= MOVER_PUZZLE_HASH (shatree mover_puzzle_reveal)) (is-coin-created-with-new-puzzle-hash-and-amount new_puzzle_hash AMOUNT conditions 0 ) conditions ) ) ) ) ) )