Exemplo n.º 1
0
def sign_tx(pks: List[str], spend_bundle: SpendBundle):
    # This field is the ADDITIONAL_DATA found in the constants
    additional_data: bytes = bytes.fromhex(
        "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb")
    puzzle_hash_to_sk: Dict[bytes32, PrivateKey] = {}

    for p in pks:
        child_sk: PrivateKey = PrivateKey.from_bytes(bytes.fromhex(p))
        # master_private_key = PrivateKey.from_bytes(
        #     bytes.fromhex(p))
        # child_sk = master_sk_to_wallet_sk(master_private_key, 242)
        child_pk: G1Element = child_sk.get_g1()
        puzzle = puzzle_for_pk(child_pk)
        puzzle_hash = puzzle.get_tree_hash()
        puzzle_hash_to_sk[puzzle_hash] = child_sk

    aggregate_signature: G2Element = G2Element()
    for coin_solution in spend_bundle.coin_solutions:
        if coin_solution.coin.puzzle_hash not in puzzle_hash_to_sk:
            return
        sk: PrivateKey = puzzle_hash_to_sk[coin_solution.coin.puzzle_hash]
        synthetic_secret_key: PrivateKey = calculate_synthetic_secret_key(
            sk, DEFAULT_HIDDEN_PUZZLE_HASH)

        err, conditions_dict, cost = conditions_dict_for_solution(
            coin_solution.puzzle_reveal, coin_solution.solution, 11000000000)

        if err or conditions_dict is None:
            print(
                f"Sign transaction failed, con:{conditions_dict}, error: {err}"
            )
            return

        pk_msgs = pkm_pairs_for_conditions_dict(
            conditions_dict, bytes(coin_solution.coin.name()), additional_data)
        assert len(pk_msgs) == 1
        _, msg = pk_msgs[0]
        signature = AugSchemeMPL.sign(synthetic_secret_key, msg)

        aggregate_signature = AugSchemeMPL.aggregate(
            [aggregate_signature, signature])

    new_spend_bundle = SpendBundle(spend_bundle.coin_solutions,
                                   aggregate_signature)
    # print(json.dumps(new_spend_bundle.to_json_dict()))
    return json.dumps(new_spend_bundle.to_json_dict())
Exemplo n.º 2
0
def round_trip(spend_bundle: SpendBundle, **kwargs):
    json_dict = spend_bundle.to_json_dict(**kwargs)

    if kwargs.get("include_legacy_keys", True):
        assert "coin_solutions" in json_dict
    else:
        assert "coin_solutions" not in json_dict

    if kwargs.get("exclude_modern_keys", True):
        assert "coin_spends" not in json_dict
    else:
        assert "coin_spends" in json_dict

    if "coin_spends" in json_dict and "coin_solutions" in json_dict:
        del json_dict["coin_solutions"]

    sb = SpendBundle.from_json_dict(json_dict)
    json_dict_2 = sb.to_json_dict()
    sb = SpendBundle.from_json_dict(json_dict_2)
    json_dict_3 = sb.to_json_dict()
    assert json_dict_2 == json_dict_3
Exemplo n.º 3
0
 async def push_tx(self, spend_bundle: SpendBundle):
     return await self.fetch("push_tx",
                             {"spend_bundle": spend_bundle.to_json_dict()})
Exemplo n.º 4
0
def sign_tx(intermediate_sk: PrivateKey, spend_bundle: SpendBundle,
            use_hardened_keys: bool):
    """
    Takes in an unsigned transaction (called a spend bundle in chia), and a 24 word mnemonic (master sk)
    and generates the aggregate BLS signature for the transaction.
    """

    # This field is the ADDITIONAL_DATA found in the constants
    additional_data: bytes = bytes.fromhex(
        "ccd5bb71183532bff220ba46c268991a3ff07eb358e8255a65c30a2dce0e5fbb")
    puzzle_hash_to_sk: Dict[bytes32, PrivateKey] = {}

    if use_hardened_keys:
        # Change this loop to scan more keys if you have more
        for i in range(5000):
            child_sk: PrivateKey = AugSchemeMPL.derive_child_sk(
                intermediate_sk, i)
            child_pk: G1Element = child_sk.get_g1()
            puzzle = puzzle_for_pk(child_pk)
            puzzle_hash = puzzle.get_tree_hash()
            puzzle_hash_to_sk[puzzle_hash] = child_sk
    else:
        # Change this loop to scan more keys if you have more
        for i in range(5000):
            child_sk: PrivateKey = AugSchemeMPL.derive_child_sk_unhardened(
                intermediate_sk, i)
            child_pk: G1Element = child_sk.get_g1()
            puzzle = puzzle_for_pk(child_pk)
            puzzle_hash = puzzle.get_tree_hash()
            puzzle_hash_to_sk[puzzle_hash] = child_sk

    aggregate_signature: G2Element = G2Element()
    for coin_solution in spend_bundle.coin_solutions:
        if coin_solution.coin.puzzle_hash not in puzzle_hash_to_sk:
            print(
                f"Puzzle hash {coin_solution.coin.puzzle_hash} not found for this key."
            )
            return
        sk: PrivateKey = puzzle_hash_to_sk[coin_solution.coin.puzzle_hash]
        synthetic_secret_key: PrivateKey = calculate_synthetic_secret_key(
            sk, DEFAULT_HIDDEN_PUZZLE_HASH)

        err, conditions_dict, cost = conditions_dict_for_solution(
            coin_solution.puzzle_reveal, coin_solution.solution, 11000000000)

        if err or conditions_dict is None:
            print(
                f"Sign transaction failed, con:{conditions_dict}, error: {err}"
            )
            return

        pk_msgs = pkm_pairs_for_conditions_dict(
            conditions_dict, bytes(coin_solution.coin.name()), additional_data)
        assert len(pk_msgs) == 1
        _, msg = pk_msgs[0]
        signature = AugSchemeMPL.sign(synthetic_secret_key, msg)

        aggregate_signature = AugSchemeMPL.aggregate(
            [aggregate_signature, signature])

    new_spend_bundle = SpendBundle(spend_bundle.coin_solutions,
                                   aggregate_signature)
    print("")
    print("Signed spend bundle JSON:\n")
    print(json.dumps(new_spend_bundle.to_json_dict()))