def generate_unsigned_transaction(self, amount, newpuzzlehash): if self.temp_balance < amount: return None # TODO: Should we throw a proper error here, or just return None? utxos = self.select_coins(amount) spends = [] output_created = False spend_value = sum([coin.amount for coin in utxos]) change = spend_value - amount for coin in utxos: puzzle_hash = coin.puzzle_hash pubkey, secretkey = self.get_keys(puzzle_hash) puzzle = puzzle_for_pk(pubkey) if output_created is False: primaries = [{'puzzlehash': newpuzzlehash, 'amount': amount}] if change > 0: changepuzzlehash = self.get_new_puzzlehash() primaries.append( {'puzzlehash': changepuzzlehash, 'amount': change}) # add change coin into temp_utxo set self.temp_utxos.add(Coin(coin, changepuzzlehash, change)) self.temp_balance += change solution = self.make_solution(primaries=primaries) output_created = True else: solution = self.make_solution(consumed=[coin.name()]) spends.append((puzzle, CoinSolution(coin, solution))) return spends
def test_p2_delegated_puzzle_simple(self): payments, conditions = default_payments_and_conditions() pk = public_key_bytes_for_index(1) puzzle_program = p2_delegated_puzzle.puzzle_for_pk(pk) puzzle_hash = ProgramHash(puzzle_program) solution = p2_delegated_puzzle.solution_for_conditions( puzzle_program, conditions) run_test(puzzle_hash, solution, payments)
def as_make_puzzle(self, as_pubkey_sender, as_pubkey_receiver, as_amount, as_timelock_block, as_secret_hash): as_pubkey_sender_cl = f"0x{as_pubkey_sender.hex()}" as_pubkey_receiver_cl = f"0x{as_pubkey_receiver.hex()}" as_payout_puzzlehash_receiver = ProgramHash( puzzle_for_pk(as_pubkey_receiver)) as_payout_puzzlehash_sender = ProgramHash( puzzle_for_pk(as_pubkey_sender)) payout_receiver = f"(c (q 0x{ConditionOpcode.CREATE_COIN.hex()}) (c (q 0x{as_payout_puzzlehash_receiver.hex()}) (c (q {as_amount}) (q ()))))" payout_sender = f"(c (q 0x{ConditionOpcode.CREATE_COIN.hex()}) (c (q 0x{as_payout_puzzlehash_sender.hex()}) (c (q {as_amount}) (q ()))))" aggsig_receiver = f"(c (q 0x{ConditionOpcode.AGG_SIG.hex()}) (c (q {as_pubkey_receiver_cl}) (c (sha256tree (a)) (q ()))))" aggsig_sender = f"(c (q 0x{ConditionOpcode.AGG_SIG.hex()}) (c (q {as_pubkey_sender_cl}) (c (sha256tree (a)) (q ()))))" receiver_puz = ( f"((c (i (= (sha256 (f (r (a)))) (q {as_secret_hash})) (q (c " + aggsig_receiver + " (c " + payout_receiver + " (q ())))) (q (x (q 'invalid secret')))) (a))) ) ") timelock = f"(c (q 0x{ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS.hex()}) (c (q {as_timelock_block}) (q ()))) " sender_puz = "(c " + aggsig_sender + " (c " + timelock + " (c " + payout_sender + " (q ()))))" as_puz_sender = "((c (i (= (f (a)) (q 77777)) (q " + sender_puz + ") (q (x (q 'not a valid option'))) ) (a)))" as_puz = "((c (i (= (f (a)) (q 33333)) (q " + receiver_puz + " (q " + as_puz_sender + ")) (a)))" return Program(binutils.assemble(as_puz))
def get_keys(self, hash, a_pubkey_used=None, b_pubkey_used=None): for child in reversed(range(self.next_address)): pubkey = self.extended_secret_key.public_child(child) if hash == ProgramHash(puzzle_for_pk(bytes(pubkey))): return (pubkey, self.extended_secret_key.private_child(child)) if a_pubkey_used is not None and b_pubkey_used is None: if hash == ProgramHash( ap_make_puzzle(a_pubkey_used, bytes(pubkey))): return (pubkey, self.extended_secret_key.private_child(child)) elif a_pubkey_used is None and b_pubkey_used is not None: if hash == ProgramHash( ap_make_puzzle(bytes(pubkey), b_pubkey_used)): return (pubkey, self.extended_secret_key.private_child(child))
def test_p2_delegated_puzzle_graftroot(self): payments, conditions = default_payments_and_conditions() delegated_puzzle = p2_delegated_conditions.puzzle_for_pk( public_key_bytes_for_index(8)) delegated_solution = p2_delegated_conditions.solution_for_conditions( delegated_puzzle, conditions) puzzle_program = p2_delegated_puzzle.puzzle_for_pk( public_key_bytes_for_index(1)) puzzle_hash = ProgramHash(puzzle_program) solution = p2_delegated_puzzle.solution_for_delegated_puzzle( puzzle_program, delegated_solution) run_test(puzzle_hash, solution, payments)
def get_puzzle_for_pk(self, pubkey): puzzle = puzzle_for_pk(pubkey) return puzzle
def get_new_puzzle(self): pubkey = bytes(self.get_next_public_key()) puzzle = puzzle_for_pk(pubkey) return puzzle
def puzzle_for_pk(self, pubkey): return puzzle_for_pk(pubkey)
def get_keys(self, hash): for child in range(self.next_address): pubkey = self.extended_secret_key.public_child(child) if hash == ProgramHash(puzzle_for_pk(bytes(pubkey))): return (pubkey, self.extended_secret_key.private_child(child))
def can_generate_puzzle_hash(self, hash): return any(map(lambda child: hash == ProgramHash(puzzle_for_pk( bytes(self.extended_secret_key.public_child(child)))), reversed(range(self.next_address))))