def get_output_amount_for_puzzle_and_solution(puzzle, solution): error, conditions, cost = conditions_dict_for_solution(Program.to([puzzle, solution])) total = 0 if conditions: for _ in conditions.get(ConditionOpcode.CREATE_COIN, []): total += Program.to(_.vars[1]).as_int() return total
def test_deserialization_simple_list(self): # ("hello" "friend") b = hexstr_to_bytes("ff8568656c6c6fff86667269656e6480") cost, output = DESERIALIZE_MOD.run_with_cost([b]) print(cost, output) prog = Program.to(output) assert prog == Program.from_bytes(b)
async def main(): rpc_port = 8555 self_hostname = "localhost" path = DEFAULT_ROOT_PATH config = load_config(path, "config.yaml") client = await FullNodeRpcClient.create(self_hostname, rpc_port, path, config) try: farmer_prefarm = ( await client.get_block_record_by_height(1)).reward_claims_incorporated[1] pool_prefarm = ( await client.get_block_record_by_height(1)).reward_claims_incorporated[0] pool_amounts = int(calculate_pool_reward(uint32(0)) / 2) farmer_amounts = int(calculate_base_farmer_reward(uint32(0)) / 2) print(farmer_prefarm.amount, farmer_amounts) assert farmer_amounts == farmer_prefarm.amount // 2 assert pool_amounts == pool_prefarm.amount // 2 address1 = "txch15gx26ndmacfaqlq8m0yajeggzceu7cvmaz4df0hahkukes695rss6lej7h" # Gene wallet (m/12381/8444/2/42): address2 = ( "txch1c2cguswhvmdyz9hr3q6hak2h6p9dw4rz82g4707k2xy2sarv705qcce4pn" # Mariano address (m/12381/8444/2/0) ) ph1 = decode_puzzle_hash(address1) ph2 = decode_puzzle_hash(address2) p_farmer_2 = Program.to( binutils.assemble( f"(q . ((51 0x{ph1.hex()} {farmer_amounts}) (51 0x{ph2.hex()} {farmer_amounts})))" )) p_pool_2 = Program.to( binutils.assemble( f"(q . ((51 0x{ph1.hex()} {pool_amounts}) (51 0x{ph2.hex()} {pool_amounts})))" )) p_solution = Program.to(binutils.assemble("()")) sb_farmer = SpendBundle( [CoinSolution(farmer_prefarm, p_farmer_2, p_solution)], G2Element()) sb_pool = SpendBundle( [CoinSolution(pool_prefarm, p_pool_2, p_solution)], G2Element()) print(sb_pool, sb_farmer) # res = await client.push_tx(sb_farmer) res = await client.push_tx(sb_pool) print(res) up = await client.get_coin_records_by_puzzle_hash( farmer_prefarm.puzzle_hash, True) uf = await client.get_coin_records_by_puzzle_hash( pool_prefarm.puzzle_hash, True) print(up) print(uf) finally: client.close()
def test_deserialization_large_numbers(self): # '(99999999999999999999999999999999999999999999999999999999999999999 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -99999999999999999999999999999999999999999999999999999999999999999999999999999)' # noqa b = hexstr_to_bytes( "ff9c00f316271c7fc3908a8bef464e3945ef7a253609ffffffffffffffffffb00fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1ff22ea0179500526edb610f148ec0c614155678491902d6000000000000000000180" # noqa ) # noqa cost, output = DESERIALIZE_MOD.run_with_cost([b]) print(cost, output) prog = Program.to(output) assert prog == Program.from_bytes(b)
async def main(): rpc_port = 8555 self_hostname = "localhost" path = DEFAULT_ROOT_PATH config = load_config(path, "config.yaml") client = await FullNodeRpcClient.create(self_hostname, rpc_port, path, config) try: farmer_prefarm = ( await client.get_block_record_by_height(1)).reward_claims_incorporated[1] pool_prefarm = ( await client.get_block_record_by_height(1)).reward_claims_incorporated[0] pool_amounts = int(calculate_pool_reward(uint32(0)) / 2) farmer_amounts = int(calculate_base_farmer_reward(uint32(0)) / 2) print(farmer_prefarm.amount, farmer_amounts) assert farmer_amounts == farmer_prefarm.amount // 2 assert pool_amounts == pool_prefarm.amount // 2 address1 = "txch1k50glwkdffp2mrqq64rsgjtxj4waphuf72stqayz4qqk6mj9hd4qp7lrek" # Gene wallet (m/12381/8444/2/51): address2 = "txch1430mtj60hvzyuyz4t45dyxwjdjsvphhl2fgreyry362reca4zpkszhjd3e" # farmer1 key (m/12381/8444/2/51) ph1 = decode_puzzle_hash(address1) ph2 = decode_puzzle_hash(address2) p_farmer_2 = Program.to( binutils.assemble( f"(q . ((51 0x{ph1.hex()} {farmer_amounts}) (51 0x{ph2.hex()} {farmer_amounts})))" )) p_pool_2 = Program.to( binutils.assemble( f"(q . ((51 0x{ph1.hex()} {pool_amounts}) (51 0x{ph2.hex()} {pool_amounts})))" )) p_solution = Program.to(binutils.assemble("()")) sb_farmer = SpendBundle( [CoinSolution(farmer_prefarm, p_farmer_2, p_solution)], G2Element()) sb_pool = SpendBundle( [CoinSolution(pool_prefarm, p_pool_2, p_solution)], G2Element()) print(sb_pool, sb_farmer) # res = await client.push_tx(sb_farmer) # res = await client.push_tx(sb_pool) # print(res) up = await client.get_coin_records_by_puzzle_hash( farmer_prefarm.puzzle_hash, True) uf = await client.get_coin_records_by_puzzle_hash( pool_prefarm.puzzle_hash, True) print(up) print(uf) finally: client.close()
def test_deserialization_password_coin(self): # (i (= (sha256 2) (q 0x2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824)) (c (q 51) (c 5 (c (q 100) (q ())))) (q "wrong password")) # noqa b = hexstr_to_bytes( "ff04ffff0affff0bff0280ffff01ffa02cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b98248080ffff05ffff01ff3380ffff05ff05ffff05ffff01ff6480ffff01ff8080808080ffff01ff8e77726f6e672070617373776f72648080" # noqa ) # noqa cost, output = DESERIALIZE_MOD.run_with_cost([b]) print(cost, output) prog = Program.to(output) assert prog == Program.from_bytes(b)
async def rl_generate_signed_aggregation_transaction(self, rl_info, consolidating_coin, rl_parent, rl_coin): if ( rl_info.limit is None or rl_info.interval is None or rl_info.user_pubkey is None or rl_info.admin_pubkey is None ): raise ValueError("One or more of the elements of rl_info is None") if self.rl_coin_record is None: raise ValueError("Rl coin record is None") list_of_coinsolutions = [] self.rl_coin_record = await self._get_rl_coin_record() pubkey, secretkey = await self.get_keys(self.rl_coin_record.coin.puzzle_hash) # Spend wallet coin puzzle = rl_puzzle_for_pk( rl_info.user_pubkey, rl_info.limit, rl_info.interval, rl_info.rl_origin_id, rl_info.admin_pubkey, ) solution = rl_make_solution_mode_2( rl_coin.puzzle_hash, consolidating_coin.parent_coin_info, consolidating_coin.puzzle_hash, consolidating_coin.amount, rl_coin.parent_coin_info, rl_coin.amount, rl_parent.amount, rl_parent.parent_coin_info, ) signature = AugSchemeMPL.sign(secretkey, solution.get_tree_hash()) rl_spend = CoinSolution(self.rl_coin_record.coin, Program.to([puzzle, solution])) list_of_coinsolutions.append(rl_spend) # Spend consolidating coin puzzle = rl_make_aggregation_puzzle(self.rl_coin_record.coin.puzzle_hash) solution = rl_make_aggregation_solution( consolidating_coin.name(), self.rl_coin_record.coin.parent_coin_info, self.rl_coin_record.coin.amount, ) agg_spend = CoinSolution(consolidating_coin, Program.to([puzzle, solution])) list_of_coinsolutions.append(agg_spend) aggsig = AugSchemeMPL.aggregate([signature]) return SpendBundle(list_of_coinsolutions, aggsig)
async def sign_clawback_transaction( self, spends: List[Tuple[Program, CoinSolution]], clawback_pubkey ) -> SpendBundle: sigs = [] for puzzle, solution in spends: pubkey, secretkey = await self.get_keys_pk(clawback_pubkey) signature = AugSchemeMPL.sign(secretkey, Program.to(solution.solution).get_tree_hash()) sigs.append(signature) aggsig = AugSchemeMPL.aggregate(sigs) solution_list = [] for puzzle, coin_solution in spends: solution_list.append(CoinSolution(coin_solution.coin, Program.to([puzzle, coin_solution.solution]))) return SpendBundle(solution_list, aggsig)
async def get_sigs(self, innerpuz: Program, innersol: Program, coin_name) -> List[G2Element]: puzzle_hash = innerpuz.get_tree_hash() pubkey, private = await self.wallet_state_manager.get_keys(puzzle_hash) synthetic_secret_key = calculate_synthetic_secret_key( private, DEFAULT_HIDDEN_PUZZLE_HASH) sigs: List[G2Element] = [] code_ = [innerpuz, innersol] sexp = Program.to(code_) error, conditions, cost = conditions_dict_for_solution(sexp) if conditions is not None: for _, msg in pkm_pairs_for_conditions_dict(conditions, coin_name): signature = AugSchemeMPL.sign(synthetic_secret_key, msg) sigs.append(signature) return sigs
def disassemble(sexp): """ This version of `disassemble` also disassembles condition opcodes like `ASSERT_ANNOUNCEMENT_CONSUMED`. """ kfa = dict(KEYWORD_FROM_ATOM) kfa.update((Program.to(k).as_atom(), v) for k, v in KFA.items()) return bu_disassemble(sexp, kfa)
def lineage_proof_for_cc_parent(parent_coin: Coin, parent_inner_puzzle_hash: bytes32) -> Program: return Program.to( ( 1, [parent_coin.parent_coin_info, parent_inner_puzzle_hash, parent_coin.amount], ) )
def make_puzzle(amount: int) -> int: puzzle = f"(q . ((51 0x{ph1.hex()} {amount}) (51 0x{ph2.hex()} {amount})))" # print(puzzle) puzzle_prog = Program.to(binutils.assemble(puzzle)) print("Program: ", puzzle_prog) puzzle_hash = puzzle_prog.get_tree_hash() solution = "()" prefix = "xch" print("PH", puzzle_hash) print(f"Address: {encode_puzzle_hash(puzzle_hash, prefix)}") result = puzzle_prog.run(solution) error, result_human = parse_sexp_to_conditions(result) total_chia = 0 if error: print(f"Error: {error}") else: assert result_human is not None for cvp in result_human: assert len(cvp.vars) == 2 total_chia += int_from_bytes(cvp.vars[1]) print( f"{ConditionOpcode(cvp.opcode).name}: {encode_puzzle_hash(cvp.vars[0], prefix)}," f" amount: {int_from_bytes(cvp.vars[1])}") return total_chia
def test_1(): puzzle_program_1 = puzzle_program_for_index(uint32(1)) puzzle_program_2 = puzzle_program_for_index(uint32(2)) conditions = Program.to([ make_create_coin_condition(std_hash(bytes(pp)), amount) for pp, amount in [(puzzle_program_1, 1000), (puzzle_program_2, 2000)] ]) assert conditions is not None puzzle_reveal = p2_delegated_puzzle.puzzle_reveal_for_conditions( conditions) solution = p2_delegated_puzzle.solution_for_conditions(conditions) error, output_conditions, cost = conditions_for_solution( puzzle_reveal, solution) assert error is None from pprint import pprint assert output_conditions is not None output_conditions_dict = conditions_by_opcode(output_conditions) pprint(output_conditions_dict) input_coin_info_hash = bytes([0] * 32) created_outputs_for_conditions_dict(output_conditions_dict, input_coin_info_hash) aggsigs = aggsig_in_conditions_dict(output_conditions_dict) pprint(aggsigs)
async def generate_unsigned_transaction( self, amount: uint64, newpuzzlehash: bytes32, fee: uint64 = uint64(0), origin_id: bytes32 = None, coins: Set[Coin] = None, primaries: Optional[List[Dict[str, bytes32]]] = None, ignore_max_send_amount: bool = False, ) -> List[CoinSolution]: """ Generates a unsigned transaction in form of List(Puzzle, Solutions) """ if primaries is None: total_amount = amount + fee else: primaries_amount = 0 for prim in primaries: primaries_amount += prim["amount"] total_amount = amount + fee + primaries_amount if not ignore_max_send_amount: max_send = await self.get_max_send_amount() if total_amount > max_send: raise ValueError(f"Can't send more than {max_send} in a single transaction") if coins is None: coins = await self.select_coins(total_amount) assert len(coins) > 0 self.log.info(f"coins is not None {coins}") spend_value = sum([coin.amount for coin in coins]) change = spend_value - total_amount spends: List[CoinSolution] = [] output_created = False for coin in coins: self.log.info(f"coin from coins {coin}") puzzle: Program = await self.puzzle_for_puzzle_hash(coin.puzzle_hash) # Only one coin creates outputs if not output_created and origin_id in (None, coin.name()): if primaries is None: primaries = [{"puzzlehash": newpuzzlehash, "amount": amount}] else: primaries.append({"puzzlehash": newpuzzlehash, "amount": amount}) if change > 0: changepuzzlehash = await self.get_new_puzzlehash() primaries.append({"puzzlehash": changepuzzlehash, "amount": change}) solution = self.make_solution(primaries=primaries, fee=fee) output_created = True else: solution = self.make_solution() puzzle_solution_pair = Program.to([puzzle, solution]) spends.append(CoinSolution(coin, puzzle_solution_pair)) self.log.info(f"Spends is {spends}") return spends
async def create_spend_bundle_relative_amount(self, cc_amount, zero_coin: Coin = None ) -> Optional[SpendBundle]: # If we're losing value then get coloured coins with at least that much value # If we're gaining value then our amount doesn't matter if cc_amount < 0: cc_spends = await self.select_coins(abs(cc_amount)) else: if zero_coin is None: return None cc_spends = set() cc_spends.add(zero_coin) if cc_spends is None: return None # Calculate output amount given relative difference and sum of actual values spend_value = sum([coin.amount for coin in cc_spends]) cc_amount = spend_value + cc_amount # Loop through coins and create solution for innerpuzzle list_of_solutions = [] output_created = None sigs: List[G2Element] = [] for coin in cc_spends: if output_created is None: newinnerpuzhash = await self.get_new_inner_hash() innersol = self.standard_wallet.make_solution( primaries=[{ "puzzlehash": newinnerpuzhash, "amount": cc_amount }]) output_created = coin else: innersol = self.standard_wallet.make_solution( consumed=[output_created.name()]) innerpuz: Program = await self.inner_puzzle_for_cc_puzhash( coin.puzzle_hash) sigs = sigs + await self.get_sigs(innerpuz, innersol, coin.name()) lineage_proof = await self.get_lineage_proof_for_coin(coin) puzzle_reveal = cc_puzzle_for_inner_puzzle( CC_MOD, self.cc_info.my_genesis_checker, innerpuz) # Use coin info to create solution and add coin and solution to list of CoinSolutions solution = [ innersol, coin.as_list(), lineage_proof, None, None, None, None, None, ] full_solution = Program.to([puzzle_reveal, solution]) list_of_solutions.append(CoinSolution(coin, full_solution)) aggsig = AugSchemeMPL.aggregate(sigs) return SpendBundle(list_of_solutions, aggsig)
async def test_invalid_my_puzhash(self, two_nodes): reward_ph = WALLET_A.get_new_puzzlehash() full_node_1, full_node_2, server_1, server_2 = two_nodes blocks = await full_node_1.get_all_full_blocks() start_height = blocks[-1].height if len(blocks) > 0 else -1 blocks = bt.get_consecutive_blocks( 3, block_list_input=blocks, guarantee_transaction_block=True, farmer_reward_puzzle_hash=reward_ph, pool_reward_puzzle_hash=reward_ph, ) peer = await connect_and_get_peer(server_1, server_2) for block in blocks: await full_node_1.full_node.respond_block(full_node_protocol.RespondBlock(block)) await time_out_assert(60, node_height_at_least, True, full_node_1, start_height + 3) coin = list(blocks[-1].get_included_reward_coins())[0] cvp = ConditionVarPair(ConditionOpcode.ASSERT_MY_PUZZLEHASH, [Program.to([]).get_tree_hash()]) dic = {cvp.opcode: [cvp]} spend_bundle1 = generate_test_spend_bundle(coin, dic) assert spend_bundle1 is not None tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(spend_bundle1) await full_node_1.respond_transaction(tx1, peer) sb1 = full_node_1.full_node.mempool_manager.get_spendbundle(spend_bundle1.name()) assert sb1 is None
def test_shatrees_match(self): """Checks to see that all .sha256tree files match their .hex files""" for prog_path in wallet_program_files: # load the .hex file as a program hex_filename = path_with_ext(prog_path, ".hex") clvm_hex = hex_filename.read_text() # .decode("utf8") clvm_blob = bytes.fromhex(clvm_hex) s = SerializedProgram.from_bytes(clvm_blob) p = Program.from_bytes(clvm_blob) # load the checked-in shatree existing_sha = path_with_ext( prog_path, ".hex.sha256tree").read_text().strip() self.assertEqual( s.get_tree_hash().hex(), existing_sha, msg= f"Checked-in shatree hash file does not match shatree hash of loaded SerializedProgram: {prog_path}", # noqa ) self.assertEqual( p.get_tree_hash().hex(), existing_sha, msg= f"Checked-in shatree hash file does not match shatree hash of loaded Program: {prog_path}", )
def solution_for_hidden_puzzle( hidden_public_key: G1Element, hidden_puzzle: Program, solution_to_hidden_puzzle: Program, ) -> Program: return Program.to( [hidden_public_key, hidden_puzzle, solution_to_hidden_puzzle])
def rl_make_solution_mode_2( my_puzzle_hash, consolidating_primary_input, consolidating_coin_puzzle_hash, outgoing_amount, my_primary_input, incoming_amount, parent_amount, my_parent_parent_id, ): my_puzzle_hash = hexlify(my_puzzle_hash).decode("ascii") consolidating_primary_input = hexlify(consolidating_primary_input).decode( "ascii") consolidating_coin_puzzle_hash = hexlify( consolidating_coin_puzzle_hash).decode("ascii") primary_input = hexlify(my_primary_input).decode("ascii") sol = sexp( AGGREGATION_MODE, "0x" + my_puzzle_hash, "0x" + consolidating_primary_input, "0x" + consolidating_coin_puzzle_hash, outgoing_amount, "0x" + primary_input, incoming_amount, parent_amount, "0x" + str(my_parent_parent_id), ) return Program.to(binutils.assemble(sol))
def solution_for_rl( my_parent_id: bytes32, my_puzzlehash: bytes32, my_amount: uint64, out_puzzlehash: bytes32, out_amount: uint64, my_parent_parent_id: bytes32, parent_amount: uint64, interval, limit, fee, ): """ Solution is (1 my_parent_id, my_puzzlehash, my_amount, outgoing_puzzle_hash, outgoing_amount, min_block_time, parent_parent_id, parent_amount, fee) min block time = Math.ceil((new_amount * self.interval) / self.limit) """ min_block_count = math.ceil((out_amount * interval) / limit) solution = sexp( RATE_LIMITED_MODE, "0x" + my_parent_id.hex(), "0x" + my_puzzlehash.hex(), my_amount, "0x" + out_puzzlehash.hex(), out_amount, min_block_count, "0x" + my_parent_parent_id.hex(), parent_amount, fee, ) return Program.to(binutils.assemble(solution))
def make_solution( self, condition_dic: Dict[ConditionOpcode, List[ConditionVarPair]]) -> Program: ret = [] for con_list in condition_dic.values(): for cvp in con_list: if cvp.opcode == ConditionOpcode.CREATE_COIN: ret.append( make_create_coin_condition(cvp.vars[0], cvp.vars[1])) if cvp.opcode == ConditionOpcode.CREATE_ANNOUNCEMENT: ret.append(make_create_announcement(cvp.vars[0])) if cvp.opcode == ConditionOpcode.AGG_SIG: ret.append(make_assert_aggsig_condition(cvp.vars[0])) if cvp.opcode == ConditionOpcode.ASSERT_ANNOUNCEMENT: ret.append(make_assert_announcement(cvp.vars[0])) if cvp.opcode == ConditionOpcode.ASSERT_SECONDS_NOW_EXCEEDS: ret.append( make_assert_seconds_now_exceeds_condition(cvp.vars[0])) if cvp.opcode == ConditionOpcode.ASSERT_MY_COIN_ID: ret.append(make_assert_my_coin_id_condition(cvp.vars[0])) if cvp.opcode == ConditionOpcode.ASSERT_HEIGHT_NOW_EXCEEDS: ret.append( make_assert_height_now_exceeds_condition(cvp.vars[0])) if cvp.opcode == ConditionOpcode.ASSERT_HEIGHT_AGE_EXCEEDS: ret.append( make_assert_height_age_exceeds_condition(cvp.vars[0])) if cvp.opcode == ConditionOpcode.RESERVE_FEE: ret.append(make_reserve_fee_condition(cvp.vars[0])) return solution_for_conditions(Program.to(ret))
async def create_spend_bundle_relative_chia(self, chia_amount: int, exclude: List[Coin]) -> SpendBundle: list_of_solutions = [] utxos = None # If we're losing value then get coins with at least that much value # If we're gaining value then our amount doesn't matter if chia_amount < 0: utxos = await self.select_coins(abs(chia_amount), exclude) else: utxos = await self.select_coins(0, exclude) assert len(utxos) > 0 # Calculate output amount given sum of utxos spend_value = sum([coin.amount for coin in utxos]) chia_amount = spend_value + chia_amount # Create coin solutions for each utxo output_created = None for coin in utxos: puzzle = await self.puzzle_for_puzzle_hash(coin.puzzle_hash) if output_created is None: newpuzhash = await self.get_new_puzzlehash() primaries = [{"puzzlehash": newpuzhash, "amount": chia_amount}] solution = self.make_solution(primaries=primaries) output_created = coin list_of_solutions.append(CoinSolution(coin, Program.to([puzzle, solution]))) await self.hack_populate_secret_keys_for_coin_solutions(list_of_solutions) spend_bundle = await sign_coin_solutions(list_of_solutions, self.secret_key_store.secret_key_for_public_key) return spend_bundle
def make_solution( self, condition_dic: Dict[ConditionOpcode, List[ConditionVarPair]]) -> Program: ret = [] for con_list in condition_dic.values(): for cvp in con_list: if cvp.opcode == ConditionOpcode.CREATE_COIN: ret.append( make_create_coin_condition(cvp.vars[0], cvp.vars[1])) if cvp.opcode == ConditionOpcode.CREATE_ANNOUNCEMENT: ret.append(make_create_announcement(cvp.vars[0])) if cvp.opcode == ConditionOpcode.AGG_SIG: ret.append(make_assert_aggsig_condition(cvp.vars[0])) if cvp.opcode == ConditionOpcode.ASSERT_ANNOUNCEMENT: ret.append(make_assert_announcement(cvp.vars[0])) if cvp.opcode == ConditionOpcode.ASSERT_TIME_EXCEEDS: ret.append(make_assert_time_exceeds_condition(cvp.vars[0])) if cvp.opcode == ConditionOpcode.ASSERT_MY_COIN_ID: ret.append(make_assert_my_coin_id_condition(cvp.vars[0])) if cvp.opcode == ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS: ret.append( make_assert_block_index_exceeds_condition(cvp.vars[0])) if cvp.opcode == ConditionOpcode.ASSERT_BLOCK_AGE_EXCEEDS: ret.append( make_assert_block_age_exceeds_condition(cvp.vars[0])) if cvp.opcode == ConditionOpcode.ASSERT_FEE: ret.append(make_assert_fee_condition(cvp.vars[0])) return solution_for_conditions(Program.to(ret))
def test_spend_zero_coin(mod_code: Program, coin_checker_for_farmed_coin): """ Test to spend ccs from a farmed coin to a cc genesis coin, then to N outputs, then joining back down to two outputs. """ eve_inner_puzzle = ANYONE_CAN_SPEND_PUZZLE eve_inner_puzzle_hash = eve_inner_puzzle.get_tree_hash() total_minted = 0x111 genesis_coin_checker, spend_bundle = issue_cc_from_farmed_coin( mod_code, coin_checker_for_farmed_coin, 1, eve_inner_puzzle_hash, total_minted) puzzles_for_db = [ cc_puzzle_for_inner_puzzle(mod_code, genesis_coin_checker, eve_inner_puzzle) ] add_puzzles_to_puzzle_preimage_db(puzzles_for_db) eve_cc_list = [] for _ in spend_bundle.coin_solutions: eve_cc_list.extend( spendable_cc_list_from_coin_solution(_, hash_to_puzzle_f)) assert len(eve_cc_list) == 1 eve_cc_spendable = eve_cc_list[0] # farm regular chia farmed_coin = generate_farmed_coin(2, eve_inner_puzzle_hash, amount=500) # create a zero cc from this farmed coin wrapped_cc_puzzle_hash = cc_puzzle_hash_for_inner_puzzle_hash( mod_code, genesis_coin_checker, eve_inner_puzzle_hash) solution = solution_for_pay_to_any([(wrapped_cc_puzzle_hash, 0)]) reveal_w_solution = Program.to([ANYONE_CAN_SPEND_PUZZLE, solution]) coin_solution = CoinSolution(farmed_coin, reveal_w_solution) spendable_cc_list = spendable_cc_list_from_coin_solution( coin_solution, hash_to_puzzle_f) assert len(spendable_cc_list) == 1 zero_cc_spendable = spendable_cc_list[0] # we have our zero coin # now try to spend it spendable_cc_list = [eve_cc_spendable, zero_cc_spendable] inner_solutions = [ solution_for_pay_to_any([]), solution_for_pay_to_any([(wrapped_cc_puzzle_hash, eve_cc_spendable.coin.amount)]), ] spend_bundle = spend_bundle_for_spendable_ccs(mod_code, genesis_coin_checker, spendable_cc_list, inner_solutions) debug_spend_bundle(spend_bundle)
def run_and_return_cost_time(chialisp): start = time.time() clvm_loop = "((c (q ((c (f (a)) (c (f (a)) (c (f (r (a))) (c (f (r (r (a))))" " (q ()))))))) (c (q ((c (i (f (r (a))) (q (i (q 1) ((c (f (a)) (c (f (a))" " (c (- (f (r (a))) (q 1)) (c (f (r (r (a)))) (q ()))))))" " ((c (f (r (r (a)))) (q ()))))) (q (q ()))) (a)))) (a))))" loop_program = Program.to(binutils.assemble(clvm_loop)) clvm_loop_solution = f"(1000 {chialisp})" solution_program = Program.to(binutils.assemble(clvm_loop_solution)) cost, sexp = loop_program.run_with_cost(solution_program) end = time.time() total_time = end - start return cost, total_time
def parse_sexp_to_condition( sexp: Program, ) -> Tuple[Optional[Err], Optional[ConditionVarPair]]: """ Takes a ChiaLisp sexp and returns a ConditionVarPair. If it fails, returns an Error """ if not sexp.listp(): return Err.INVALID_CONDITION, None items = sexp.as_python() if not isinstance(items[0], bytes): return Err.INVALID_CONDITION, None try: opcode = ConditionOpcode(items[0]) except ValueError: opcode = ConditionOpcode.UNKNOWN if len(items) == 3: return None, ConditionVarPair(opcode, [items[1], items[2]]) return None, ConditionVarPair(opcode, [items[1]])
def coin_solution_for_lock_coin( prev_coin: Coin, subtotal: int, coin: Coin, ) -> CoinSolution: puzzle_reveal = LOCK_INNER_PUZZLE.curry(prev_coin.as_list(), subtotal) coin = Coin(coin.name(), puzzle_reveal.get_tree_hash(), uint64(0)) coin_solution = CoinSolution(coin, puzzle_reveal, Program.to(0)) return coin_solution
def default_payments_and_conditions( initial_index: int, key_lookup: KeyTool ) -> Tuple[List[Tuple[bytes32, int]], Program]: payments = [ (throwaway_puzzle_hash(initial_index + 1, key_lookup), initial_index * 1000), (throwaway_puzzle_hash(initial_index + 2, key_lookup), (initial_index + 1) * 1000), ] conditions = Program.to([make_create_coin_condition(ph, amount) for ph, amount in payments]) return payments, conditions
def solution_with_hidden_puzzle( hidden_public_key: G1Element, hidden_puzzle: Program, solution_to_hidden_puzzle: Program, ) -> Program: synthetic_public_key = calculate_synthetic_public_key( hidden_public_key, hidden_puzzle) puzzle = puzzle_for_synthetic_public_key(synthetic_public_key) return Program.to([ puzzle, [hidden_public_key, hidden_puzzle, solution_to_hidden_puzzle] ])
def conditions_for_solution( puzzle_reveal: Program, solution: Program, ) -> Tuple[Optional[Err], Optional[List[ConditionVarPair]], uint64]: # get the standard script for a puzzle hash and feed in the solution try: cost, r = puzzle_reveal.run_with_cost(solution) error, result = parse_sexp_to_conditions(r) return error, result, uint64(cost) except Program.EvalError: return Err.SEXP_ERROR, None, uint64(0)