コード例 #1
0
def hash_key_pairs_for_conditions_dict(
    conditions_dict: Dict[ConditionOpcode, List[ConditionVarPair]], coin_name: bytes32
) -> List[BLSSignature.PkMessagePair]:
    pairs: List[BLSSignature.PkMessagePair] = []
    for cvp in conditions_dict.get(ConditionOpcode.AGG_SIG, []):
        # TODO: check types
        # assert len(_) == 3
        blspubkey: BLSPublicKey = BLSPublicKey(cvp.var1)
        message: bytes32 = bytes32(blspy.Util.hash256(cvp.var2))
        pairs.append(BLSSignature.PkMessagePair(blspubkey, message))
    for cvp in conditions_dict.get(ConditionOpcode.AGG_SIG_ME, []):
        aggsigme_blspubkey: BLSPublicKey = BLSPublicKey(cvp.var1)
        aggsigme_message: bytes32 = bytes32(blspy.Util.hash256(cvp.var2 + coin_name))
        pairs.append(BLSSignature.PkMessagePair(aggsigme_blspubkey, aggsigme_message))
    return pairs
コード例 #2
0
    def sign_transaction(self, spends: List[Tuple[Program, CoinSolution]]):
        sigs = []
        solution: Program
        puzzle: Program
        for puzzle, solution in spends:  # type: ignore # noqa
            pubkey, secretkey = self.get_keys(solution.coin.puzzle_hash)
            secretkey = BLSPrivateKey(secretkey)
            code_ = [puzzle, solution.solution]
            sexp = Program.to(code_)
            err, con, cost = conditions_for_solution(sexp)
            if not con:
                return
            conditions_dict = conditions_by_opcode(con)

            for _ in hash_key_pairs_for_conditions_dict(
                    conditions_dict, bytes(solution.coin)):
                signature = secretkey.sign(_.message_hash)
                sigs.append(signature)
        aggsig = BLSSignature.aggregate(sigs)
        solution_list: List[CoinSolution] = [
            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
コード例 #3
0
ファイル: key_tool.py プロジェクト: exodusnet/Exodus
 def signature_for_solution(self, solution, coin_name):
     signatures = []
     conditions = conditions_for_solution(solution)
     assert conditions[1] is not None
     conditions_dict = conditions_by_opcode(conditions[1])
     for _ in hash_key_pairs_for_conditions_dict(conditions_dict, coin_name):
         signature = self.sign(_)
         signatures.append(signature)
     return BLSSignature.aggregate(signatures)
コード例 #4
0
ファイル: cc_wallet_puzzles.py プロジェクト: spring3th/Exodus
def cc_generate_eve_spend(coin: Coin, full_puzzle: Program):
    solution = cc_make_eve_solution(coin.parent_coin_info, coin.puzzle_hash,
                                    coin.amount)
    list_of_solutions = [
        CoinSolution(
            coin,
            clvm.to_sexp_f([full_puzzle, solution]),
        )
    ]
    aggsig = BLSSignature.aggregate([])
    spend_bundle = SpendBundle(list_of_solutions, aggsig)
    return spend_bundle
コード例 #5
0
ファイル: rl_wallet.py プロジェクト: starlure/chia-blockchain
    async def sign_clawback_transaction(self,
                                        spends: List[Tuple[Program,
                                                           CoinSolution]],
                                        clawback_pubkey):
        sigs = []
        for puzzle, solution in spends:
            pubkey, secretkey = await self.get_keys_pk(clawback_pubkey)
            signature = secretkey.sign(Program(solution.solution).get_hash())
            sigs.append(signature)
        aggsig = BLSSignature.aggregate(sigs)
        solution_list = []
        for puzzle, coin_solution in spends:
            solution_list.append(
                CoinSolution(coin_solution.coin,
                             clvm.to_sexp_f([puzzle, coin_solution.solution])))

        spend_bundle = SpendBundle(solution_list, aggsig)
        return spend_bundle
コード例 #6
0
    async def create_spend_bundle_relative_chia(
        self, chia_amount: int, exclude: List[Coin]
    ):
        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)

        if utxos is None:
            return None

        # 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
        sigs: List[BLSSignature] = []
        for coin in utxos:
            pubkey, secretkey = await self.wallet_state_manager.get_keys(
                coin.puzzle_hash
            )
            puzzle = self.puzzle_for_pk(bytes(pubkey))
            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
            else:
                solution = self.make_solution(consumed=[output_created.name()])
            list_of_solutions.append(
                CoinSolution(coin, clvm.to_sexp_f([puzzle, solution]))
            )
            new_sigs = await self.get_sigs_for_innerpuz_with_innersol(puzzle, solution)
            sigs = sigs + new_sigs

        aggsig = BLSSignature.aggregate(sigs)
        spend_bundle = SpendBundle(list_of_solutions, aggsig)
        return spend_bundle
コード例 #7
0
    async def sign_transaction(
        self, spends: List[Tuple[Program, CoinSolution]]
    ) -> Optional[SpendBundle]:
        signatures = []
        for puzzle, solution in spends:
            # Get keys
            keys = await self.wallet_state_manager.get_keys(solution.coin.puzzle_hash)
            if not keys:
                self.log.error(
                    f"Sign transaction failed, No Keys for puzzlehash {solution.coin.puzzle_hash}"
                )
                return None

            pubkey, secretkey = keys
            secretkey = BLSPrivateKey(secretkey)
            code_ = [puzzle, solution.solution]
            sexp = clvm.to_sexp_f(code_)

            # Get AGGSIG conditions
            err, con, cost = conditions_for_solution(sexp)
            if err or not con:
                self.log.error(f"Sign transcation failed, con:{con}, error: {err}")
                return None

            conditions_dict = conditions_by_opcode(con)

            # Create signature
            for pk_message in hash_key_pairs_for_conditions_dict(
                conditions_dict, bytes(solution.coin)
            ):
                signature = secretkey.sign(pk_message.message_hash)
                signatures.append(signature)

        # Aggregate signatures
        aggsig = BLSSignature.aggregate(signatures)
        solution_list: List[CoinSolution] = [
            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
ファイル: coinbase.py プロジェクト: spring3th/Exodus
def signature_for_coinbase(coin: Coin, pool_private_key: blspy.PrivateKey):
    message_hash = blspy.Util.hash256(bytes(coin))
    return BLSSignature(bytes(pool_private_key.sign_prepend_prehashed(message_hash)))
コード例 #9
0
    async def respond_to_offer(self,
                               file_path: Path) -> Tuple[bool, Optional[str]]:
        has_wallets = await self.maybe_create_wallets_for_offer(file_path)
        if not has_wallets:
            return False, "Unknown Error"
        trade_offer_hex = file_path.read_text()
        trade_offer = SpendBundle.from_bytes(bytes.fromhex(trade_offer_hex))

        coinsols = []  # [] of CoinSolutions
        cc_coinsol_outamounts: Dict[bytes32, List[Tuple[Any, int]]] = dict()
        # Used for generating auditor solution, key is colour
        auditees: Dict[bytes32, List[Tuple[bytes32, bytes32, Any,
                                           int]]] = dict()
        aggsig = trade_offer.aggregated_signature
        cc_discrepancies: Dict[bytes32, int] = dict()
        chia_discrepancy = None
        wallets: Dict[bytes32, Any] = dict()  # colour to wallet dict

        for coinsol in trade_offer.coin_solutions:
            puzzle = coinsol.solution.first()
            solution = coinsol.solution.rest().first()

            # work out the deficits between coin amount and expected output for each
            if cc_wallet_puzzles.check_is_cc_puzzle(puzzle):
                parent_info = binutils.disassemble(
                    solution.rest().first()).split(" ")

                if len(parent_info) > 1:
                    # Calculate output amounts
                    colour = cc_wallet_puzzles.get_genesis_from_puzzle(
                        binutils.disassemble(puzzle))
                    if colour not in wallets:
                        wallets[
                            colour] = await self.wallet_state_manager.get_wallet_for_colour(
                                colour)
                    unspent = await self.wallet_state_manager.get_spendable_coins_for_wallet(
                        wallets[colour].wallet_info.id)
                    if coinsol.coin in [record.coin for record in unspent]:
                        return False, "can't respond to own offer"
                    innerpuzzlereveal = solution.rest().rest().rest().first()
                    innersol = solution.rest().rest().rest().rest().first()
                    out_amount = cc_wallet_puzzles.get_output_amount_for_puzzle_and_solution(
                        innerpuzzlereveal, innersol)

                    if colour in cc_discrepancies:
                        cc_discrepancies[
                            colour] += coinsol.coin.amount - out_amount
                    else:
                        cc_discrepancies[
                            colour] = coinsol.coin.amount - out_amount
                    # Store coinsol and output amount for later
                    if colour in cc_coinsol_outamounts:
                        cc_coinsol_outamounts[colour].append(
                            (coinsol, out_amount))
                    else:
                        cc_coinsol_outamounts[colour] = [(coinsol, out_amount)]

                    # auditees should be (primary_input, innerpuzhash, coin_amount, output_amount)
                    if colour in auditees:
                        auditees[colour].append((
                            coinsol.coin.parent_coin_info,
                            Program(innerpuzzlereveal).get_tree_hash(),
                            coinsol.coin.amount,
                            out_amount,
                        ))
                    else:
                        auditees[colour] = [(
                            coinsol.coin.parent_coin_info,
                            Program(innerpuzzlereveal).get_tree_hash(),
                            coinsol.coin.amount,
                            out_amount,
                        )]
                else:
                    coinsols.append(coinsol)
            else:
                # standard chia coin
                unspent = await self.wallet_state_manager.get_spendable_coins_for_wallet(
                    1)
                if coinsol.coin in [record.coin for record in unspent]:
                    return False, "can't respond to own offer"
                if chia_discrepancy is None:
                    chia_discrepancy = cc_wallet_puzzles.get_output_discrepancy_for_puzzle_and_solution(
                        coinsol.coin, puzzle, solution)
                else:
                    chia_discrepancy += cc_wallet_puzzles.get_output_discrepancy_for_puzzle_and_solution(
                        coinsol.coin, puzzle, solution)
                coinsols.append(coinsol)

        chia_spend_bundle: Optional[SpendBundle] = None
        if chia_discrepancy is not None:
            chia_spend_bundle = await self.wallet_state_manager.main_wallet.create_spend_bundle_relative_chia(
                chia_discrepancy, [])

        zero_spend_list: List[SpendBundle] = []
        # create coloured coin
        self.log.info(cc_discrepancies)
        for colour in cc_discrepancies.keys():
            if cc_discrepancies[colour] < 0:
                my_cc_spends = await wallets[colour].select_coins(
                    abs(cc_discrepancies[colour]))
            else:
                if chia_spend_bundle is None:
                    to_exclude: List = []
                else:
                    to_exclude = chia_spend_bundle.removals()
                my_cc_spends = await wallets[colour].select_coins(0)
                if my_cc_spends is None or my_cc_spends == set():
                    zero_spend_bundle: SpendBundle = await wallets[
                        colour].generate_zero_val_coin(False, to_exclude)
                    if zero_spend_bundle is None:
                        return (
                            False,
                            "unable to generate zero value coin, check you have chia available",
                        )
                    zero_spend_list.append(zero_spend_bundle)

                    additions = zero_spend_bundle.additions()
                    removals = zero_spend_bundle.removals()
                    my_cc_spends = set()
                    for add in additions:
                        if add not in removals and add.amount == 0:
                            my_cc_spends.add(add)

            if my_cc_spends == set() or my_cc_spends is None:
                return False, "insufficient funds"

            auditor = my_cc_spends.pop()
            auditor_inner_puzzle = await self.get_inner_puzzle_for_puzzle_hash(
                auditor.puzzle_hash)
            assert auditor_inner_puzzle is not None
            inner_hash = auditor_inner_puzzle.get_tree_hash()

            auditor_info = (
                auditor.parent_coin_info,
                inner_hash,
                auditor.amount,
            )
            auditor_formatted = (
                f"(0x{auditor.parent_coin_info} 0x{inner_hash} {auditor.amount})"
            )
            core = cc_wallet_puzzles.cc_make_core(colour)
            parent_info = await wallets[colour].get_parent_for_coin(auditor)

            for coloured_coin in my_cc_spends:
                inner_solution = self.wallet_state_manager.main_wallet.make_solution(
                    consumed=[auditor.name()])
                sig = await wallets[
                    colour].get_sigs_for_innerpuz_with_innersol(
                        await self.get_inner_puzzle_for_puzzle_hash(
                            coloured_coin.puzzle_hash),
                        inner_solution,
                    )
                aggsig = BLSSignature.aggregate(
                    [BLSSignature.aggregate(sig), aggsig])
                inner_puzzle = await self.get_inner_puzzle_for_puzzle_hash(
                    coloured_coin.puzzle_hash)
                assert inner_puzzle is not None
                # auditees should be (primary_input, innerpuzhash, coin_amount, output_amount)
                auditees[colour].append((
                    coloured_coin.parent_coin_info,
                    inner_puzzle.get_tree_hash(),
                    coloured_coin.amount,
                    0,
                ))

                solution = cc_wallet_puzzles.cc_make_solution(
                    core,
                    (
                        parent_info.parent_name,
                        parent_info.inner_puzzle_hash,
                        parent_info.amount,
                    ),
                    coloured_coin.amount,
                    binutils.disassemble(inner_puzzle),
                    binutils.disassemble(inner_solution),
                    auditor_info,
                    None,
                )
                coin_spend = CoinSolution(
                    coloured_coin,
                    clvm.to_sexp_f([
                        cc_wallet_puzzles.cc_make_puzzle(
                            inner_puzzle.get_tree_hash(),
                            core,
                        ),
                        solution,
                    ]),
                )
                coinsols.append(coin_spend)

                ephemeral = cc_wallet_puzzles.create_spend_for_ephemeral(
                    coloured_coin, auditor, 0)
                coinsols.append(ephemeral)

                auditor = cc_wallet_puzzles.create_spend_for_auditor(
                    auditor, coloured_coin)
                coinsols.append(auditor)

            # Tweak the offer's solution to include the new auditor
            for cc_coinsol_out in cc_coinsol_outamounts[colour]:
                cc_coinsol = cc_coinsol_out[0]
                offer_sol = binutils.disassemble(cc_coinsol.solution)
                # auditor is (primary_input, innerpuzzlehash, amount)
                offer_sol = offer_sol.replace(
                    "))) ()) () ()))", f"))) ()) {auditor_formatted} ()))")
                new_coinsol = CoinSolution(cc_coinsol.coin,
                                           binutils.assemble(offer_sol))
                coinsols.append(new_coinsol)

                eph = cc_wallet_puzzles.create_spend_for_ephemeral(
                    cc_coinsol.coin, auditor, cc_coinsol_out[1])
                coinsols.append(eph)

                aud = cc_wallet_puzzles.create_spend_for_auditor(
                    auditor, cc_coinsol.coin)
                coinsols.append(aud)

            # Finish the auditor CoinSolution with new information
            newinnerpuzhash = await wallets[colour].get_new_inner_hash()
            outputamount = (sum([c.amount for c in my_cc_spends]) +
                            cc_discrepancies[colour] + auditor.amount)
            innersol = self.wallet_state_manager.main_wallet.make_solution(
                primaries=[{
                    "puzzlehash": newinnerpuzhash,
                    "amount": outputamount
                }])
            parent_info = await wallets[colour].get_parent_for_coin(auditor)

            auditees[colour].append((
                auditor.parent_coin_info,
                auditor_inner_puzzle.get_tree_hash(),
                auditor.amount,
                outputamount,
            ))

            sig = await wallets[colour].get_sigs(auditor_inner_puzzle,
                                                 innersol)
            aggsig = BLSSignature.aggregate(
                [BLSSignature.aggregate(sig), aggsig])

            solution = cc_wallet_puzzles.cc_make_solution(
                core,
                (
                    parent_info.parent_name,
                    parent_info.inner_puzzle_hash,
                    parent_info.amount,
                ),
                auditor.amount,
                binutils.disassemble(auditor_inner_puzzle),
                binutils.disassemble(innersol),
                auditor_info,
                auditees[colour],
            )

            cs = CoinSolution(
                auditor,
                clvm.to_sexp_f([
                    cc_wallet_puzzles.cc_make_puzzle(
                        auditor_inner_puzzle.get_tree_hash(), core),
                    solution,
                ]),
            )
            coinsols.append(cs)

            cs_eph = create_spend_for_ephemeral(auditor, auditor, outputamount)
            coinsols.append(cs_eph)

            cs_aud = create_spend_for_auditor(auditor, auditor)
            coinsols.append(cs_aud)

        spend_bundle = SpendBundle(coinsols, aggsig)
        my_tx_records = []

        if zero_spend_list is not None:
            zero_spend_list.append(spend_bundle)
            spend_bundle = SpendBundle.aggregate(zero_spend_list)

        # Add transaction history hor this trade
        if chia_spend_bundle is not None:
            spend_bundle = SpendBundle.aggregate(
                [spend_bundle, chia_spend_bundle])
            if chia_discrepancy < 0:
                tx_record = TransactionRecord(
                    confirmed_at_index=uint32(0),
                    created_at_time=uint64(int(time.time())),
                    to_puzzle_hash=token_bytes(),
                    amount=uint64(abs(chia_discrepancy)),
                    fee_amount=uint64(0),
                    incoming=False,
                    confirmed=False,
                    sent=uint32(10),
                    spend_bundle=chia_spend_bundle,
                    additions=chia_spend_bundle.additions(),
                    removals=chia_spend_bundle.removals(),
                    wallet_id=uint32(1),
                    sent_to=[],
                )
            else:
                tx_record = TransactionRecord(
                    confirmed_at_index=uint32(0),
                    created_at_time=uint64(int(time.time())),
                    to_puzzle_hash=token_bytes(),
                    amount=uint64(abs(chia_discrepancy)),
                    fee_amount=uint64(0),
                    incoming=True,
                    confirmed=False,
                    sent=uint32(10),
                    spend_bundle=chia_spend_bundle,
                    additions=chia_spend_bundle.additions(),
                    removals=chia_spend_bundle.removals(),
                    wallet_id=uint32(1),
                    sent_to=[],
                )
            my_tx_records.append(tx_record)

        for colour, amount in cc_discrepancies.items():
            wallet = wallets[colour]
            if chia_discrepancy > 0:
                tx_record = TransactionRecord(
                    confirmed_at_index=uint32(0),
                    created_at_time=uint64(int(time.time())),
                    to_puzzle_hash=token_bytes(),
                    amount=uint64(abs(amount)),
                    fee_amount=uint64(0),
                    incoming=False,
                    confirmed=False,
                    sent=uint32(10),
                    spend_bundle=spend_bundle,
                    additions=spend_bundle.additions(),
                    removals=spend_bundle.removals(),
                    wallet_id=wallet.wallet_info.id,
                    sent_to=[],
                )
            else:
                tx_record = TransactionRecord(
                    confirmed_at_index=uint32(0),
                    created_at_time=uint64(int(time.time())),
                    to_puzzle_hash=token_bytes(),
                    amount=uint64(abs(amount)),
                    fee_amount=uint64(0),
                    incoming=True,
                    confirmed=False,
                    sent=uint32(10),
                    spend_bundle=spend_bundle,
                    additions=spend_bundle.additions(),
                    removals=spend_bundle.removals(),
                    wallet_id=wallet.wallet_info.id,
                    sent_to=[],
                )
            my_tx_records.append(tx_record)

        tx_record = TransactionRecord(
            confirmed_at_index=uint32(0),
            created_at_time=uint64(int(time.time())),
            to_puzzle_hash=token_bytes(),
            amount=uint64(0),
            fee_amount=uint64(0),
            incoming=False,
            confirmed=False,
            sent=uint32(0),
            spend_bundle=spend_bundle,
            additions=spend_bundle.additions(),
            removals=spend_bundle.removals(),
            wallet_id=uint32(0),
            sent_to=[],
        )

        await self.wallet_state_manager.add_pending_transaction(tx_record)
        for tx in my_tx_records:
            await self.wallet_state_manager.add_transaction(tx)

        return True, None
コード例 #10
0
ファイル: benchmark_cost.py プロジェクト: exodusnet/Exodus
    clvm_cost = 0
    for i in range(0, 1000):
        cost_run, sexp = run_program(puzzles[i], solutions[i])
        clvm_cost += cost_run

    puzzle_end = time.time()
    puzzle_time = puzzle_end - puzzle_start
    print(f"Puzzle_time is: {puzzle_time}")
    print(f"Puzzle cost sum is: {clvm_cost}")

    private_key = BLSPrivateKey(
        extended_secret_key.private_child(0).get_private_key())
    public_key = private_key.public_key()
    message = token_bytes()
    signature = private_key.sign(message)
    pk_message_pair = BLSSignature.PkMessagePair(public_key, message)

    # Run AggSig 1000 times
    agg_sig_start = time.time()
    agg_sig_cost = 0
    for i in range(0, 1000):
        valid = signature.validate([pk_message_pair])
        agg_sig_cost += 20
    agg_sig_end = time.time()
    agg_sig_time = agg_sig_end - agg_sig_start
    print(f"Aggsig Cost: {agg_sig_cost}")
    print(f"Aggsig time is: {agg_sig_time}")

    # clvm_should_cost = agg_sig_cost * puzzle_time / agg_sig_time
    clvm_should_cost = (agg_sig_cost * puzzle_time) / agg_sig_time
    print(f"Puzzle should cost: {clvm_should_cost}")
コード例 #11
0
ファイル: cc_wallet.py プロジェクト: spring3th/Exodus
    async def create_spend_bundle_relative_amount(
        self, cc_amount, zero_coin: Coin = None
    ):
        # 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[BLSSignature] = []
        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()
            innerpuz: Program = await self.inner_puzzle_for_cc_puzzle(coin.puzzle_hash)

            parent_info = await self.get_parent_for_coin(coin)
            assert parent_info is not None
            assert self.cc_info.my_core is not None
            # Use coin info to create solution and add coin and solution to list of CoinSolutions
            solution = cc_wallet_puzzles.cc_make_solution(
                self.cc_info.my_core,
                (
                    parent_info.parent_name,
                    parent_info.inner_puzzle_hash,
                    parent_info.amount,
                ),
                coin.amount,
                binutils.disassemble(innerpuz),
                binutils.disassemble(innersol),
                None,
                None,
            )
            list_of_solutions.append(
                CoinSolution(
                    coin,
                    clvm.to_sexp_f(
                        [
                            cc_wallet_puzzles.cc_make_puzzle(
                                innerpuz.get_tree_hash(), self.cc_info.my_core
                            ),
                            solution,
                        ]
                    ),
                )
            )
            sigs = sigs + await self.get_sigs(innerpuz, innersol)

        aggsig = BLSSignature.aggregate(sigs)
        spend_bundle = SpendBundle(list_of_solutions, aggsig)
        return spend_bundle
コード例 #12
0
ファイル: cc_wallet.py プロジェクト: spring3th/Exodus
    async def cc_spend(
        self, amount: uint64, to_address: bytes32
    ) -> Optional[SpendBundle]:
        sigs: List[BLSSignature] = []

        # Get coins and calculate amount of change required
        selected_coins: Optional[Set[Coin]] = await self.select_coins(amount)
        if selected_coins is None:
            return None

        total_amount = sum([x.amount for x in selected_coins])
        change = total_amount - amount

        # first coin becomes the auditor special case
        auditor = selected_coins.pop()
        puzzle_hash = auditor.puzzle_hash
        inner_puzzle: Program = await self.inner_puzzle_for_cc_puzzle(puzzle_hash)

        auditor_info = (
            auditor.parent_coin_info,
            inner_puzzle.get_tree_hash(),
            auditor.amount,
        )
        list_of_solutions = []

        # auditees should be (primary_input, innerpuzhash, coin_amount, output_amount)
        auditees = [
            (
                auditor.parent_coin_info,
                inner_puzzle.get_tree_hash(),
                auditor.amount,
                total_amount,
            )
        ]
        for coin in selected_coins:
            coin_inner_puzzle: Program = await self.inner_puzzle_for_cc_puzzle(
                coin.puzzle_hash
            )
            auditees.append(
                (coin.parent_coin_info, coin_inner_puzzle[coin], coin.amount, 0,)
            )

        primaries = [{"puzzlehash": to_address, "amount": amount}]
        if change > 0:
            changepuzzlehash = await self.get_new_inner_hash()
            primaries.append({"puzzlehash": changepuzzlehash, "amount": change})

        innersol = self.standard_wallet.make_solution(primaries=primaries)
        sigs = sigs + await self.get_sigs(inner_puzzle, innersol)
        parent_info = await self.get_parent_for_coin(auditor)
        assert parent_info is not None
        assert self.cc_info.my_core is not None

        solution = cc_wallet_puzzles.cc_make_solution(
            self.cc_info.my_core,
            (
                parent_info.parent_name,
                parent_info.inner_puzzle_hash,
                parent_info.amount,
            ),
            auditor.amount,
            binutils.disassemble(inner_puzzle),
            binutils.disassemble(innersol),
            auditor_info,
            auditees,
            False,
        )

        main_coin_solution = CoinSolution(
            auditor,
            clvm.to_sexp_f(
                [
                    cc_wallet_puzzles.cc_make_puzzle(
                        inner_puzzle.get_tree_hash(), self.cc_info.my_core,
                    ),
                    solution,
                ]
            ),
        )
        list_of_solutions.append(main_coin_solution)
        # main = SpendBundle([main_coin_solution], ZERO96)

        ephemeral_coin_solution = create_spend_for_ephemeral(
            auditor, auditor, total_amount
        )
        list_of_solutions.append(ephemeral_coin_solution)
        # eph = SpendBundle([ephemeral_coin_solution], ZERO96)

        auditor_coin_colution = create_spend_for_auditor(auditor, auditor)
        list_of_solutions.append(auditor_coin_colution)
        # aud = SpendBundle([auditor_coin_colution], ZERO96)

        # loop through remaining spends, treating them as aggregatees
        for coin in selected_coins:
            coin_inner_puzzle = await self.inner_puzzle_for_cc_puzzle(coin.puzzle_hash)
            innersol = self.standard_wallet.make_solution()
            parent_info = await self.get_parent_for_coin(coin)
            assert parent_info is not None
            sigs = sigs + await self.get_sigs(coin_inner_puzzle, innersol)

            solution = cc_wallet_puzzles.cc_make_solution(
                self.cc_info.my_core,
                (
                    parent_info.parent_name,
                    parent_info.inner_puzzle_hash,
                    parent_info.amount,
                ),
                coin.amount,
                binutils.disassemble(coin_inner_puzzle),
                binutils.disassemble(innersol),
                auditor_info,
                None,
            )
            list_of_solutions.append(
                CoinSolution(
                    coin,
                    clvm.to_sexp_f(
                        [
                            cc_wallet_puzzles.cc_make_puzzle(
                                coin_inner_puzzle.get_tree_hash(), self.cc_info.my_core,
                            ),
                            solution,
                        ]
                    ),
                )
            )
            list_of_solutions.append(create_spend_for_ephemeral(coin, auditor, 0))
            list_of_solutions.append(create_spend_for_auditor(auditor, coin))

        aggsig = BLSSignature.aggregate(sigs)
        spend_bundle = SpendBundle(list_of_solutions, aggsig)

        tx_record = TransactionRecord(
            confirmed_at_index=uint32(0),
            created_at_time=uint64(int(time.time())),
            to_puzzle_hash=to_address,
            amount=uint64(amount),
            fee_amount=uint64(0),
            incoming=False,
            confirmed=False,
            sent=uint32(0),
            spend_bundle=spend_bundle,
            additions=spend_bundle.additions(),
            removals=spend_bundle.removals(),
            wallet_id=self.wallet_info.id,
            sent_to=[],
        )
        await self.wallet_state_manager.add_pending_transaction(tx_record)

        return spend_bundle
コード例 #13
0
ファイル: rl_wallet.py プロジェクト: starlure/chia-blockchain
    async def rl_generate_signed_aggregation_transaction(
            self, rl_info: RLInfo, consolidating_coin: Coin, rl_parent: Coin,
            rl_coin: Coin):
        if (rl_info.limit is None or rl_info.interval is None
                or 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

        list_of_coinsolutions = []

        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,
            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 = secretkey.sign(solution.get_hash())
        list_of_coinsolutions.append(
            CoinSolution(self.rl_coin_record.coin,
                         clvm.to_sexp_f([puzzle, solution])))

        # 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,
        )
        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_record.coin, puzzle.get_hash(), uint64(0)),
                clvm.to_sexp_f([puzzle, solution]),
            ))

        aggsig = BLSSignature.aggregate([signature])

        return SpendBundle(list_of_coinsolutions, aggsig)
コード例 #14
0
ファイル: BLSPrivateKey.py プロジェクト: exodusnet/Exodus
 def sign(self, message_hash: bytes32) -> BLSSignature:
     return BLSSignature(bytes(
         self.pk.sign_prepend_prehashed(message_hash)))