示例#1
0
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()
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()
示例#3
0
    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)
def create_spend_for_ephemeral(parent_of_e, auditor_coin, spend_amount):
    puzstring = f"(r (r (c (q 0x{auditor_coin.name()}) (c (q {spend_amount}) (q ())))))"
    puzzle = Program(binutils.assemble(puzstring))
    coin = Coin(parent_of_e.name(), puzzle.get_tree_hash(), uint64(0))
    solution = Program(binutils.assemble("()"))
    coinsol = CoinSolution(coin, Program.to([puzzle, solution]))
    return coinsol
示例#5
0
    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)
示例#6
0
 def generate_unsigned_clawback_transaction(
     self, clawback_coin: Coin, clawback_puzzle_hash: bytes32, fee
 ):
     if (
         self.rl_info.limit is None
         or self.rl_info.interval is None
         or self.rl_info.user_pubkey is None
         or self.rl_info.admin_pubkey is None
     ):
         raise ValueError("One ore more of the elements of rl_info is None")
     spends = []
     coin = clawback_coin
     if self.rl_info.rl_origin is None:
         raise ValueError("Origin not initialized")
     puzzle = rl_puzzle_for_pk(
         self.rl_info.user_pubkey,
         self.rl_info.limit,
         self.rl_info.interval,
         self.rl_info.rl_origin.name(),
         self.rl_info.admin_pubkey,
     )
     solution = make_clawback_solution(
         clawback_puzzle_hash, clawback_coin.amount, fee
     )
     spends.append((puzzle, CoinSolution(coin, solution)))
     return spends
示例#7
0
    async def rl_generate_unsigned_transaction(self, to_puzzlehash, amount):
        spends = []
        coin = self.rl_coin_record.coin
        puzzle_hash = coin.puzzle_hash
        pubkey, secretkey = await self.get_keys(puzzle_hash)
        rl_parent: Coin = await self.get_rl_parent()

        puzzle = rl_puzzle_for_pk(
            bytes(pubkey),
            self.rl_info.interval,
            self.rl_info.limit,
            self.rl_info.rl_origin.name(),
            self.rl_info.rl_clawback_pk,
        )

        solution = solution_for_rl(
            coin.parent_coin_info,
            puzzle_hash,
            coin.amount,
            to_puzzlehash,
            amount,
            rl_parent.parent_coin_info,
            rl_parent.amount,
            None,
            None,
        )

        spends.append((puzzle, CoinSolution(coin, solution)))
        return spends
示例#8
0
    async def rl_generate_unsigned_transaction(self, to_puzzlehash, amount, fee):
        spends = []
        coin = self.rl_coin_record.coin
        puzzle_hash = coin.puzzle_hash
        pubkey = self.rl_info.user_pubkey
        rl_parent: Optional[Coin] = await self._get_rl_parent()
        if rl_parent is None:
            raise ValueError("No RL parent coin")

        puzzle = rl_puzzle_for_pk(
            bytes(pubkey),
            self.rl_info.limit,
            self.rl_info.interval,
            self.rl_info.rl_origin_id,
            self.rl_info.admin_pubkey,
        )

        solution = solution_for_rl(
            coin.parent_coin_info,
            puzzle_hash,
            coin.amount,
            to_puzzlehash,
            amount,
            rl_parent.parent_coin_info,
            rl_parent.amount,
            self.rl_info.interval,
            self.rl_info.limit,
            fee,
        )

        spends.append((puzzle, CoinSolution(coin, solution)))
        return spends
示例#9
0
    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
示例#10
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)
            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 _, msg in pkm_pairs_for_conditions_dict(
                    conditions_dict, bytes(solution.coin)):
                signature = AugSchemeMPL.sign(secretkey, msg)
                sigs.append(signature)
        aggsig = AugSchemeMPL.aggregate(sigs)
        solution_list: List[CoinSolution] = [
            CoinSolution(coin_solution.coin,
                         Program.to([puzzle, coin_solution.solution]))
            for (puzzle, coin_solution) in spends
        ]
        spend_bundle = SpendBundle(solution_list, aggsig)
        return spend_bundle
def create_spend_for_auditor(parent_of_a, auditee):
    puzstring = f"(r (c (q 0x{auditee.name()}) (q ())))"
    puzzle = Program(binutils.assemble(puzstring))
    coin = Coin(parent_of_a.name(), puzzle.get_tree_hash(), uint64(0))
    solution = Program(binutils.assemble("()"))
    coinsol = CoinSolution(coin, Program.to([puzzle, solution]))
    return coinsol
    def generate_unsigned_transaction(
        self,
        amount: uint64,
        new_puzzle_hash: bytes32,
        coin: Coin,
        condition_dic: Dict[ConditionOpcode, List[ConditionVarPair]],
        fee: int = 0,
        secret_key=None,
    ) -> List[CoinSolution]:
        spends = []
        spend_value = coin.amount
        puzzle_hash = coin.puzzle_hash
        if secret_key is None:
            secret_key = self.get_private_key_for_puzzle_hash(puzzle_hash)
        pubkey = secret_key.get_g1()
        puzzle = puzzle_for_pk(bytes(pubkey))
        if ConditionOpcode.CREATE_COIN not in condition_dic:
            condition_dic[ConditionOpcode.CREATE_COIN] = []

        output = ConditionVarPair(ConditionOpcode.CREATE_COIN, [new_puzzle_hash, int_to_bytes(amount)])
        condition_dic[output.opcode].append(output)
        amount_total = sum(int_from_bytes(cvp.vars[1]) for cvp in condition_dic[ConditionOpcode.CREATE_COIN])
        change = spend_value - amount_total - fee
        if change > 0:
            change_puzzle_hash = self.get_new_puzzlehash()
            change_output = ConditionVarPair(ConditionOpcode.CREATE_COIN, [change_puzzle_hash, int_to_bytes(change)])
            condition_dic[output.opcode].append(change_output)
            solution = self.make_solution(condition_dic)
        else:
            solution = self.make_solution(condition_dic)
        puzzle_solution_pair = Program.to([puzzle, solution])

        spends.append(CoinSolution(coin, puzzle_solution_pair))
        return spends
示例#13
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
示例#14
0
    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, 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
示例#15
0
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
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,
            Program.to([full_puzzle, solution]),
        )
    ]
    aggsig = AugSchemeMPL.aggregate([])
    spend_bundle = SpendBundle(list_of_solutions, aggsig)
    return spend_bundle
示例#17
0
    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)
示例#18
0
def make_block_generator(count: int) -> SerializedProgram:
    puzzle_hash_db: Dict = dict()
    coins = [make_fake_coin(_, puzzle_hash_db) for _ in range(count)]

    coin_solutions = []
    for coin in coins:
        puzzle_reveal = puzzle_hash_db[coin.puzzle_hash]
        conditions = conditions_for_payment(coin)
        solution = solution_for_conditions(conditions)
        coin_solution = CoinSolution(coin, puzzle_reveal, solution)
        coin_solutions.append(coin_solution)

    spend_bundle = SpendBundle(coin_solutions, blspy.G2Element())
    return best_solution_program(spend_bundle)
示例#19
0
    async def generate_unsigned_transaction(
        self,
        amount: uint64,
        newpuzzlehash: bytes32,
        fee: uint64 = uint64(0),
        origin_id: bytes32 = None,
        coins: Set[Coin] = None,
    ) -> List[CoinSolution]:
        """
        Generates a unsigned transaction in form of List(Puzzle, Solutions)
        """
        if coins is None:
            coins = await self.select_coins(amount + fee)
        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 - amount - fee

        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()):
                primaries = [{"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
示例#20
0
    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
示例#21
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
示例#22
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
示例#23
0
def do_test_spend(
    puzzle_reveal: Program,
    solution: Program,
    payments: Iterable[Tuple[bytes32, int]],
    key_lookup: KeyTool,
    farm_time: CoinTimestamp = T1,
    spend_time: CoinTimestamp = T2,
) -> SpendBundle:
    """
    This method will farm a coin paid to the hash of `puzzle_reveal`, then try to spend it
    with `solution`, and verify that the created coins correspond to `payments`.

    The `key_lookup` is used to create a signed version of the `SpendBundle`, although at
    this time, signatures are not verified.
    """

    coin_db = CoinStore()

    puzzle_hash = puzzle_reveal.get_tree_hash()

    # farm it
    coin = coin_db.farm_coin(puzzle_hash, farm_time)

    # spend it
    coin_solution = CoinSolution(coin, puzzle_reveal, solution)

    spend_bundle = SpendBundle([coin_solution], G2Element())
    coin_db.update_coin_store_for_spend_bundle(spend_bundle, spend_time)

    # ensure all outputs are there
    for puzzle_hash, amount in payments:
        for coin in coin_db.coins_for_puzzle_hash(puzzle_hash):
            if coin.amount == amount:
                break
        else:
            assert 0

    # make sure we can actually sign the solution
    signatures = []
    for coin_solution in spend_bundle.coin_solutions:
        signature = key_lookup.signature_for_solution(coin_solution)
        signatures.append(signature)
    return SpendBundle(spend_bundle.coin_solutions,
                       AugSchemeMPL.aggregate(signatures))
示例#24
0
    async def rl_sign_transaction(self, spends: List[Tuple[Program, CoinSolution]]):
        sigs = []
        for puzzle, solution in spends:
            pubkey, secretkey = await self.get_keys(solution.coin.puzzle_hash)
            signature = secretkey.sign(Program(solution.solution).get_hash())
            sigs.append(signature)

        aggsig = AugSchemeMPL.aggregate(sigs)

        solution_list: List[CoinSolution] = []
        for puzzle, coin_solution in spends:
            solution_list.append(
                CoinSolution(
                    coin_solution.coin, Program.to([puzzle, coin_solution.solution])
                )
            )

        spend_bundle = SpendBundle(solution_list, aggsig)
        return spend_bundle
示例#25
0
 def generate_unsigned_clawback_transaction(self, clawback_coin: Coin,
                                            clawback_puzzle_hash: bytes32):
     if (self.rl_info.limit is None or self.rl_info.interval is None
             or self.rl_info.user_pubkey is None
             or self.rl_info.admin_pubkey is None):
         raise
     spends = []
     coin = clawback_coin
     puzzle = rl_puzzle_for_pk(
         self.rl_info.user_pubkey,
         self.rl_info.limit,
         self.rl_info.interval,
         self.rl_info.rl_origin,
         self.rl_info.admin_pubkey,
     )
     solution = make_clawback_solution(clawback_puzzle_hash,
                                       clawback_coin.amount)
     spends.append((puzzle, CoinSolution(coin, solution)))
     return spends
示例#26
0
    def generate_unsigned_transaction(
        self,
        amount,
        newpuzzlehash,
        coin: Coin,
        condition_dic: Dict[ConditionOpcode, List[ConditionVarPair]],
        fee: int = 0,
        secretkey=None,
    ):
        spends = []
        spend_value = coin.amount
        puzzle_hash = coin.puzzle_hash
        if secretkey is None:
            pubkey, secretkey = self.get_keys(puzzle_hash)
        else:
            pubkey = secretkey.get_g1()
        puzzle = puzzle_for_pk(bytes(pubkey))
        if ConditionOpcode.CREATE_COIN not in condition_dic:
            condition_dic[ConditionOpcode.CREATE_COIN] = []

        output = ConditionVarPair(
            ConditionOpcode.CREATE_COIN, newpuzzlehash, int_to_bytes(amount)
        )
        condition_dic[output.opcode].append(output)
        amount_total = sum(
            int_from_bytes(cvp.var2)
            for cvp in condition_dic[ConditionOpcode.CREATE_COIN]
        )
        change = spend_value - amount_total - fee
        if change > 0:
            changepuzzlehash = self.get_new_puzzlehash()
            change_output = ConditionVarPair(
                ConditionOpcode.CREATE_COIN, changepuzzlehash, int_to_bytes(change)
            )
            condition_dic[output.opcode].append(change_output)
            solution = self.make_solution(condition_dic)
        else:
            solution = self.make_solution(condition_dic)

        spends.append((puzzle, CoinSolution(coin, solution)))
        return spends
示例#27
0
文件: keys.py 项目: exodusnet/Exodus
def build_spend_bundle(coin, solution, keychain=DEFAULT_KEYTOOL):
    coin_solution = CoinSolution(coin, solution)
    signature = keychain.signature_for_solution(solution, bytes(coin))
    return SpendBundle([coin_solution], signature)
示例#28
0
    async def generate_signed_transaction(
        self,
        amount: uint64,
        to_address: bytes32,
        fee: uint64 = uint64(0),
        origin_id: bytes32 = None,
        coins: Set[Coin] = None,
    ) -> Optional[TransactionRecord]:
        sigs: List[G2Element] = []

        # Get coins and calculate amount of change required
        if coins is None:
            selected_coins: Optional[Set[Coin]] = await self.select_coins(
                amount)
        else:
            selected_coins = coins
        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,
            Program.to([
                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,
                    Program.to([
                        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 = AugSchemeMPL.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=[],
            trade_id=None,
        )

        return tx_record
示例#29
0
    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[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()
            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,
                    Program.to([
                        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 = AugSchemeMPL.aggregate(sigs)
        spend_bundle = SpendBundle(list_of_solutions, aggsig)
        return spend_bundle
示例#30
0
    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 Exception("One ore more of the elements of rl_info is None")

        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, Program.to([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, Program.to([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)),
                Program.to([puzzle, solution]),
            )
        )

        aggsig = AugSchemeMPL.aggregate([signature])

        return SpendBundle(list_of_coinsolutions, aggsig)