示例#1
0
    def generate_recovery_transaction(self, coins, root_public_key, secret_key,
                                      escrow_duration):
        recovery_pubkey = root_public_key.public_child(
            0).get_public_key().serialize()
        signatures = []
        coin_solutions = []
        secret_key = BLSPrivateKey(secret_key)
        for coin in coins:
            pubkey = self.find_pubkey_for_escrow_puzzle(
                coin, root_public_key, escrow_duration)
            puzzle = self.get_escrow_puzzle_with_params(
                recovery_pubkey, pubkey.serialize(), escrow_duration)

            op_create_coin = ConditionOpcode.CREATE_COIN[0]
            puzzlehash = f'0x' + str(hexbytes(self.get_new_puzzlehash()))
            solution_src = sexp(
                quote(sexp(sexp(op_create_coin, puzzlehash, coin.amount))),
                sexp(), 1)
            solution = Program(binutils.assemble(solution_src))

            puzzle_solution_list = clvm.to_sexp_f([puzzle, solution])
            coin_solution = CoinSolution(coin, puzzle_solution_list)
            coin_solutions.append(coin_solution)

            conditions_dict = conditions_by_opcode(
                conditions_for_solution(puzzle_solution_list))
            for _ in hash_key_pairs_for_conditions_dict(conditions_dict):
                signature = secret_key.sign(_.message_hash)
                signatures.append(signature)

        coin_solution_list = CoinSolutionList(coin_solutions)
        aggsig = BLSSignature.aggregate(signatures)
        spend_bundle = SpendBundle(coin_solution_list, aggsig)
        return spend_bundle
示例#2
0
 def signature_for_solution(self, solution):
     signatures = []
     conditions_dict = conditions_by_opcode(conditions_for_solution(solution))
     for _ in hash_key_pairs_for_conditions_dict(conditions_dict):
         signature = self.sign(_)
         signatures.append(signature)
     return BLSSignature.aggregate(signatures)
示例#3
0
    def ap_generate_signed_aggregation_transaction(self):
        list_of_coinsolutions = []
        if self.aggregation_coins is False:  # empty sets evaluate to false in python
            return
        consolidating_coin = self.aggregation_coins.pop()

        pubkey, secretkey = self.get_keys(
            self.temp_coin.puzzle_hash, self.a_pubkey)

        # Spend wallet coin
        puzzle = ap_make_puzzle(self.a_pubkey, bytes(pubkey))
        solution = self.ap_make_solution_mode_2(self.temp_coin.puzzle_hash, consolidating_coin.parent_coin_info,
                                                consolidating_coin.puzzle_hash, consolidating_coin.amount, self.temp_coin.parent_coin_info, self.temp_coin.amount)
        signature = secretkey.sign(ProgramHash(solution))
        list_of_coinsolutions.append(CoinSolution(
            self.temp_coin, clvm.to_sexp_f([puzzle, solution])))

        # Spend consolidating coin
        puzzle = ap_make_aggregation_puzzle(self.temp_coin.puzzle_hash)
        solution = self.ac_make_aggregation_solution(consolidating_coin.name(
        ), self.temp_coin.parent_coin_info, self.temp_coin.amount)
        list_of_coinsolutions.append(CoinSolution(
            consolidating_coin, clvm.to_sexp_f([puzzle, solution])))
        # Spend lock
        puzstring = f"(r (c (q 0x{consolidating_coin.name().hex()}) (q ())))"
        puzzle = Program(binutils.assemble(puzstring))
        solution = Program(binutils.assemble("()"))
        list_of_coinsolutions.append(CoinSolution(Coin(self.temp_coin, ProgramHash(
            puzzle), 0), clvm.to_sexp_f([puzzle, solution])))

        self.temp_coin = Coin(self.temp_coin, self.temp_coin.puzzle_hash,
                              self.temp_coin.amount + consolidating_coin.amount)
        aggsig = BLSSignature.aggregate([signature])
        solution_list = CoinSolutionList(list_of_coinsolutions)
        return SpendBundle(solution_list, aggsig)
示例#4
0
def xform_aggsig_sig_pair(pair):
    """
    Transform a pair (aggsig_pair_bytes, sig_bytes)
    to (aggsig_pair, BLSSignature).
    """
    aggsig = BLSSignature.aggsig_pair.from_bytes(pair[0])
    sig = BLSSignature.from_bytes(pair[1])
    return (aggsig, sig)
示例#5
0
 def cp_sign_transaction(self,
                         spends: (Program, [CoinSolution]),
                         approval=None):
     sigs = []
     for puzzle, solution in spends:
         pubkey, secretkey = self.get_keys(solution.coin.puzzle_hash)
         signature = secretkey.sign(ProgramHash(Program(solution.solution)))
         sigs.append(signature)
     if approval is not None:
         app = BLSSignature(approval)
         sigs.append(app)
     aggsig = BLSSignature.aggregate(sigs)
     solution_list = CoinSolutionList([
         CoinSolution(coin_solution.coin,
                      clvm.to_sexp_f([puzzle, coin_solution.solution]))
         for (puzzle, coin_solution) in spends
     ])
     spend_bundle = SpendBundle(solution_list, aggsig)
     return spend_bundle
示例#6
0
async def do_spend_coin(wallet, storage, input):
    """
    UI to spend a coin.
    """
    coins = []
    while True:
        coin_str = input("Enter hex id of coin to spend> ")
        if len(coin_str) == 0:
            break
        coin_name = bytes.fromhex(coin_str)
        preimage = await storage.hash_preimage(hash=coin_name)
        if preimage is None:
            print(f"can't find coin id {coin_name.hex()}")
            continue
        coin = Coin.from_bytes(preimage)
        coin_puzzle_hash_hex = coin.puzzle_hash.hex()
        print(f"coin puzzle hash is {coin_puzzle_hash_hex}")
        coins.append(coin)
    if len(coins) == 0:
        return
    dest_address = "14c56fdefb47e2208de54b6c609a907c522348c96e8cfb41c7a8c75f44835dd9"
    print(f"sending 1 coin to {dest_address}, rest fees")

    # create an unfinalized SpendBundle
    pst = spend_coin(wallet, coins, dest_address)
    pst_encoded = bytes(pst)
    print(pst_encoded.hex())

    # keep requesting signatures until finalized
    sigs = []
    while True:
        sig_str = input("Enter a signature> ")
        try:
            sig = BLSSignature.from_bytes(bytes.fromhex(sig_str))
        except Exception as ex:
            print("failed: %s" % ex)
            continue
        sigs.append(sig)
        sigs = list(set(sigs))
        spend_bundle, summary_list = finalize_pst(wallet, pst, sigs)
        if spend_bundle:
            break
        for summary in summary_list:
            print(
                "coin %s has %d of %d sigs"
                % (summary[0].name(), len(summary[2]), summary[3])
            )
    print("spend bundle = %s" % bytes(spend_bundle).hex())

    # optionally send to ledger sim
    r = input(f"Send to ledger sim? (y/n)> ")
    if r.lower().startswith("y"):
        r = await storage.ledger_sim().push_tx(tx=spend_bundle)
    return spend_bundle
示例#7
0
 def sign_clawback_transaction(self, spends: (Program, [CoinSolution]), clawback_pubkey):
     sigs = []
     for puzzle, solution in spends:
         pubkey, secretkey = self.get_keys_pk(clawback_pubkey)
         signature = secretkey.sign(
             ProgramHash(Program(solution.solution)))
         sigs.append(signature)
     aggsig = BLSSignature.aggregate(sigs)
     solution_list = CoinSolutionList(
         [CoinSolution(coin_solution.coin, clvm.to_sexp_f([puzzle, coin_solution.solution])) for
          (puzzle, coin_solution) in spends])
     spend_bundle = SpendBundle(solution_list, aggsig)
     return spend_bundle
示例#8
0
    def rl_generate_signed_aggregation_transaction(self):
        list_of_coinsolutions = []
        if self.aggregation_coins is False:  # empty sets evaluate to false in python
            return
        consolidating_coin = self.aggregation_coins.pop()

        pubkey, secretkey = self.get_keys(self.rl_coin.puzzle_hash)
        # Spend wallet coin
        puzzle = self.rl_puzzle_for_pk(pubkey.serialize(), self.limit,
                                       self.interval, self.rl_origin,
                                       self.rl_clawback_pk)

        if isinstance(self.rl_parent, Coin):
            solution = self.rl_make_solution_mode_2(
                self.rl_coin.puzzle_hash, consolidating_coin.parent_coin_info,
                consolidating_coin.puzzle_hash, consolidating_coin.amount,
                self.rl_coin.parent_coin_info, self.rl_coin.amount,
                self.rl_parent.amount, self.rl_parent.parent_coin_info)
        else:
            solution = self.rl_make_solution_mode_2(
                self.rl_coin.puzzle_hash, consolidating_coin.parent_coin_info,
                consolidating_coin.puzzle_hash, consolidating_coin.amount,
                self.rl_coin.parent_coin_info, self.rl_coin.amount,
                self.rl_parent["amount"], self.rl_parent["parent_coin_info"])
        signature = BLSPrivateKey(secretkey).sign(ProgramHash(solution))
        list_of_coinsolutions.append(
            CoinSolution(self.rl_coin, clvm.to_sexp_f([puzzle, solution])))

        # Spend consolidating coin
        puzzle = self.rl_make_aggregation_puzzle(self.rl_coin.puzzle_hash)
        solution = self.rl_make_aggregation_solution(
            consolidating_coin.name(), self.rl_coin.parent_coin_info,
            self.rl_coin.amount)
        list_of_coinsolutions.append(
            CoinSolution(consolidating_coin, clvm.to_sexp_f([puzzle,
                                                             solution])))
        # Spend lock
        puzstring = "(r (c (q 0x" + hexlify(
            consolidating_coin.name()).decode('ascii') + ") (q ())))"

        puzzle = Program(binutils.assemble(puzstring))
        solution = Program(binutils.assemble("()"))
        list_of_coinsolutions.append(
            CoinSolution(Coin(self.rl_coin, ProgramHash(puzzle), 0),
                         clvm.to_sexp_f([puzzle, solution])))

        aggsig = BLSSignature.aggregate([signature])
        solution_list = CoinSolutionList(list_of_coinsolutions)

        return SpendBundle(solution_list, aggsig)
示例#9
0
 def ap_sign_transaction(self, spends: (Program, [CoinSolution]), signatures_from_a):
     sigs = []
     for puzzle, solution in spends:
         pubkey, secretkey = self.get_keys(
             solution.coin.puzzle_hash, self.a_pubkey)
         signature = secretkey.sign(
             ProgramHash(Program(solution.solution)))
         sigs.append(signature)
     for s in signatures_from_a:
         sigs.append(s)
     aggsig = BLSSignature.aggregate(sigs)
     solution_list = CoinSolutionList(
         [CoinSolution(coin_solution.coin, clvm.to_sexp_f([puzzle, coin_solution.solution])) for
          (puzzle, coin_solution) in spends])
     spend_bundle = SpendBundle(solution_list, aggsig)
     return spend_bundle
示例#10
0
 def sign_transaction(self, spends: (Program, [CoinSolution])):
     sigs = []
     for puzzle, solution in spends:
         pubkey, secretkey = self.get_keys(solution.coin.puzzle_hash)
         code_ = [puzzle, solution.solution]
         sexp = clvm.to_sexp_f(code_)
         conditions_dict = conditions_by_opcode(
             conditions_for_solution(sexp))
         for _ in hash_key_pairs_for_conditions_dict(conditions_dict):
             signature = secretkey.sign(_.message_hash)
             sigs.append(signature)
     aggsig = BLSSignature.aggregate(sigs)
     solution_list = CoinSolutionList(
         [CoinSolution(coin_solution.coin, clvm.to_sexp_f([puzzle, coin_solution.solution])) for
          (puzzle, coin_solution) in spends])
     spend_bundle = SpendBundle(solution_list, aggsig)
     return spend_bundle
示例#11
0
def BLSSignature_from_string(signature):
    try:
        sig = BLSSignature(bytes.fromhex(signature))
    except Exception:
        raise Exception
    return sig
示例#12
0
def signature_for_coinbase(coin: Coin, pool_private_key: blspy.PrivateKey):
    message_hash = coin.name()
    return BLSSignature(
        pool_private_key.sign_prepend_prehashed(message_hash).serialize())
示例#13
0
 def sign(self, message_hash: bytes32) -> BLSSignature:
     return BLSSignature(self.pk.sign_prepend_prehashed(message_hash).serialize())