export enum Condition { Remark = 1 { ...value: (Any, nil) | nil, }, AggSigParent = 43 { public_key: PublicKey, message: Bytes, }, AggSigPuzzle = 44 { public_key: PublicKey, message: Bytes, }, AggSigAmount = 45 { public_key: PublicKey, message: Bytes, }, AggSigPuzzleAmount = 46 { public_key: PublicKey, message: Bytes, }, AggSigParentAmount = 47 { public_key: PublicKey, message: Bytes, }, AggSigParentPuzzle = 48 { public_key: PublicKey, message: Bytes, }, AggSigUnsafe = 49 { public_key: PublicKey, message: Bytes, }, AggSigMe = 50 { public_key: PublicKey, message: Bytes, }, CreateCoin = 51 { puzzle_hash: Bytes32, amount: Int, ...memos: (List, nil) | nil, }, ReserveFee = 52 { amount: Int, }, CreateCoinAnnouncement = 60 { message: Bytes, }, AssertCoinAnnouncement = 61 { announcement_id: Bytes32, }, CreatePuzzleAnnouncement = 62 { message: Bytes, }, AssertPuzzleAnnouncement = 63 { announcement_id: Bytes32, }, AssertConcurrentSpend = 64 { coin_id: Bytes32, }, AssertConcurrentPuzzle = 65 { puzzle_hash: Bytes32, }, AssertMyCoinId = 70 { coin_id: Bytes32, }, AssertMyParentId = 71 { parent_coin_id: Bytes32, }, AssertMyPuzzleHash = 72 { puzzle_hash: Bytes32, }, AssertMyAmount = 73 { amount: Int, }, AssertMyBirthSeconds = 74 { seconds: Int, }, AssertMyBirthHeight = 75 { height: Int, }, AssertEphemeral = 76, AssertSecondsRelative = 80 { seconds: Int, }, AssertSecondsAbsolute = 81 { seconds: Int, }, AssertHeightRelative = 82 { height: Int, }, AssertHeightAbsolute = 83 { height: Int, }, AssertBeforeSecondsRelative = 84 { seconds: Int, }, AssertBeforeSecondsAbsolute = 85 { seconds: Int, }, AssertBeforeHeightRelative = 86 { height: Int, }, AssertBeforeHeightAbsolute = 87 { height: Int, }, Softfork = 90 { cost: Int, ...value: (Any, nil) | nil, }, } export fun concat(a: List, b: List) -> List { if a is (T, List) { return [a.first, ...concat(a.rest, b)]; } b } inline const ATOM_PREFIX: Bytes = 1 as Bytes; inline const PAIR_PREFIX: Bytes = 2 as Bytes; export fun tree_hash(value: Any) -> Bytes32 { if value is Bytes { tree_hash_atom(value) } else { tree_hash_pair(tree_hash(value.first), tree_hash(value.rest)) } } export inline fun tree_hash_atom(value: Bytes) -> Bytes32 { sha256(ATOM_PREFIX + value) } export inline fun tree_hash_pair(first: Bytes32, rest: Bytes32) -> Bytes32 { sha256(PAIR_PREFIX + first + rest) } inline const OP_Q: Bytes = 1 as Bytes; inline const OP_A: Bytes = 2 as Bytes; inline const OP_C: Bytes = 4 as Bytes; inline const OP_Q_TREE_HASH: Bytes32 = tree_hash_atom(OP_Q); inline const OP_A_TREE_HASH: Bytes32 = tree_hash_atom(OP_A); inline const OP_C_TREE_HASH: Bytes32 = tree_hash_atom(OP_C); inline const ONE_TREE_HASH: Bytes32 = tree_hash_atom(1 as Bytes); const NIL_TREE_HASH: Bytes32 = tree_hash_atom(nil); const APPLY_PREIMAGE_PREFIX: Bytes = PAIR_PREFIX + OP_A_TREE_HASH; const CONS_PREIMAGE_PREFIX: Bytes = PAIR_PREFIX + OP_C_TREE_HASH; inline fun quote_hash(value: Bytes32) -> Bytes32 { tree_hash_pair(OP_Q_TREE_HASH, value) } inline fun two_item_list_hash(first: Bytes32, rest: Bytes32) -> Bytes32 { tree_hash_pair(first, tree_hash_pair(rest, NIL_TREE_HASH)) } inline fun apply_hash(mod_hash: Bytes32, environment_hash: Bytes32) -> Bytes32 { sha256(APPLY_PREIMAGE_PREFIX + two_item_list_hash(quote_hash(mod_hash), environment_hash)) } inline fun update_hash_with_parameter( parameter_hash: Bytes32, environment_hash: Bytes32 ) -> Bytes32 { sha256(CONS_PREIMAGE_PREFIX + two_item_list_hash(quote_hash(parameter_hash), environment_hash)) } fun curried_params_hash(parameters: List) -> Bytes32 { if parameters is nil { return ONE_TREE_HASH; } update_hash_with_parameter(parameters.first, curried_params_hash(parameters.rest)) } export inline fun curry_tree_hash( mod_hash: Bytes32, ...parameters: List ) -> Bytes32 { apply_hash(mod_hash, curried_params_hash(parameters)) } export fun calculate_coin_id( parent_coin_id: Bytes, puzzle_hash: Bytes, amount: Int, ) -> Bytes32 { assert parent_coin_id is Bytes32; assert puzzle_hash is Bytes32; sha256(parent_coin_id + puzzle_hash + amount as Bytes) } export fun map(list: List, fn: fun(item: T) -> U) -> List { if list is nil { return nil; } [fn(list.first), ...map(list.rest, fn)] } export fun filter(list: List, fn: fun(item: T) -> Bool) -> List { if list is nil { return nil; } if fn(list.first) { return [list.first, ...filter(list.rest, fn)]; } filter(list.rest, fn) } export fun fold(list: List, initial: U, fn: fun(acc: U, item: T) -> U) -> U { if list is nil { return initial; } fold(list.rest, fn(initial, list.first), fn) }