Пример #1
0
 async def generate_eve_spend(self, coin: Coin, full_puzzle: Program, innerpuz: Program):
     assert self.did_info.origin_coin is not None
     # innerpuz solution is (mode amount message new_puzhash)
     innersol = Program.to([1, coin.amount, [], innerpuz.get_tree_hash()])
     # full solution is (lineage_proof my_amount inner_solution)
     fullsol = Program.to(
         [
             [self.did_info.origin_coin.parent_coin_info, self.did_info.origin_coin.amount],
             coin.amount,
             innersol,
         ]
     )
     list_of_solutions = [CoinSpend(coin, full_puzzle, fullsol)]
     # sign for AGG_SIG_ME
     message = (
         Program.to([innerpuz.get_tree_hash(), coin.amount, []]).get_tree_hash()
         + coin.name()
         + self.wallet_state_manager.constants.AGG_SIG_ME_ADDITIONAL_DATA
     )
     pubkey = did_wallet_puzzles.get_pubkey_from_innerpuz(innerpuz)
     record: Optional[DerivationRecord] = await self.wallet_state_manager.puzzle_store.record_for_pubkey(pubkey)
     assert record is not None
     private = master_sk_to_wallet_sk_unhardened(self.wallet_state_manager.private_key, record.index)
     signature = AugSchemeMPL.sign(private, message)
     sigs = [signature]
     aggsig = AugSchemeMPL.aggregate(sigs)
     spend_bundle = SpendBundle(list_of_solutions, aggsig)
     return spend_bundle
Пример #2
0
 async def generate_eve_spend(self, coin: Coin, full_puzzle: Program,
                              innerpuz: Program):
     assert self.did_info.origin_coin is not None
     # innerpuz solution is (mode amount message my_id my_puzhash parent_innerpuzhash_amounts_for_recovery_ids)
     innersol = Program.to([
         0, coin.amount, coin.puzzle_hash,
         coin.name(), coin.puzzle_hash, []
     ])
     # full solution is (parent_info my_amount innersolution)
     fullsol = Program.to([
         [
             self.did_info.origin_coin.parent_coin_info,
             self.did_info.origin_coin.amount
         ],
         coin.parent_coin_info,
         coin.amount,
         innersol,
     ])
     list_of_solutions = [CoinSolution(coin, full_puzzle, fullsol)]
     # sign for AGG_SIG_ME
     message = (
         Program.to([coin.amount, coin.puzzle_hash]).get_tree_hash() +
         coin.name() +
         self.wallet_state_manager.constants.AGG_SIG_ME_ADDITIONAL_DATA)
     pubkey = did_wallet_puzzles.get_pubkey_from_innerpuz(innerpuz)
     index = await self.wallet_state_manager.puzzle_store.index_for_pubkey(
         pubkey)
     private = master_sk_to_wallet_sk(self.wallet_state_manager.private_key,
                                      index)
     signature = AugSchemeMPL.sign(private, message)
     sigs = [signature]
     aggsig = AugSchemeMPL.aggregate(sigs)
     spend_bundle = SpendBundle(list_of_solutions, aggsig)
     return spend_bundle
Пример #3
0
    async def create_spend(self, puzhash: bytes32):
        assert self.did_info.current_inner is not None
        coins = await self.select_coins(1)
        assert coins is not None
        coin = coins.pop()
        # innerpuz solution is (mode amount new_puz identity my_puz)
        innersol: Program = Program.to([0, coin.amount, puzhash, coin.name(), coin.puzzle_hash])
        # full solution is (corehash parent_info my_amount innerpuz_reveal solution)
        innerpuz: Program = self.did_info.current_inner

        full_puzzle: Program = did_wallet_puzzles.create_fullpuz(
            innerpuz,
            self.did_info.my_did,
        )
        parent_info = await self.get_parent_for_coin(coin)
        assert parent_info is not None

        fullsol = Program.to(
            [
                [
                    parent_info.parent_name,
                    parent_info.inner_puzzle_hash,
                    parent_info.amount,
                ],
                coin.amount,
                innersol,
            ]
        )
        list_of_solutions = [CoinSolution(coin, full_puzzle, fullsol)]
        # sign for AGG_SIG_ME
        message = bytes(puzhash) + bytes(coin.name())
        pubkey = did_wallet_puzzles.get_pubkey_from_innerpuz(innerpuz)
        index = await self.wallet_state_manager.puzzle_store.index_for_pubkey(pubkey)
        private = master_sk_to_wallet_sk(self.wallet_state_manager.private_key, index)
        signature = AugSchemeMPL.sign(private, message)
        # assert signature.validate([signature.PkMessagePair(pubkey, message)])
        sigs = [signature]
        aggsig = AugSchemeMPL.aggregate(sigs)
        spend_bundle = SpendBundle(list_of_solutions, aggsig)

        did_record = TransactionRecord(
            confirmed_at_height=uint32(0),
            created_at_time=uint64(int(time.time())),
            to_puzzle_hash=puzhash,
            amount=uint64(coin.amount),
            fee_amount=uint64(0),
            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,
            type=uint32(TransactionType.OUTGOING_TX.value),
            name=token_bytes(),
        )
        await self.standard_wallet.push_transaction(did_record)
        return spend_bundle
Пример #4
0
    async def create_attestment(self,
                                recovering_coin_name: bytes32,
                                newpuz: bytes32,
                                pubkey: G1Element,
                                filename=None) -> SpendBundle:
        assert self.did_info.current_inner is not None
        assert self.did_info.origin_coin is not None
        coins = await self.select_coins(1)
        assert coins is not None and coins != set()
        coin = coins.pop()
        message = did_wallet_puzzles.create_recovery_message_puzzle(
            recovering_coin_name, newpuz, pubkey)
        innermessage = message.get_tree_hash()
        # innerpuz solution is (mode amount new_puz identity my_puz)
        innersol = Program.to([
            1, coin.amount, innermessage, recovering_coin_name,
            coin.puzzle_hash
        ])
        # full solution is (corehash parent_info my_amount innerpuz_reveal solution)
        innerpuz: Program = self.did_info.current_inner
        full_puzzle: Program = did_wallet_puzzles.create_fullpuz(
            innerpuz,
            self.did_info.origin_coin.puzzle_hash,
        )
        parent_info = await self.get_parent_for_coin(coin)
        assert parent_info is not None

        fullsol = Program.to([
            [
                self.did_info.origin_coin.parent_coin_info,
                self.did_info.origin_coin.amount
            ],
            [
                parent_info.parent_name,
                parent_info.inner_puzzle_hash,
                parent_info.amount,
            ],
            coin.amount,
            innersol,
        ])
        list_of_solutions = [CoinSolution(coin, full_puzzle, fullsol)]
        message_spend = did_wallet_puzzles.create_spend_for_message(
            coin.name(), recovering_coin_name, newpuz, pubkey)

        message_spend_bundle = SpendBundle([message_spend],
                                           AugSchemeMPL.aggregate([]))
        # sign for AGG_SIG_ME
        to_sign = Program.to([coin.puzzle_hash, coin.amount,
                              innermessage]).get_tree_hash()
        message = to_sign + coin.name(
        ) + self.wallet_state_manager.constants.AGG_SIG_ME_ADDITIONAL_DATA
        pubkey = did_wallet_puzzles.get_pubkey_from_innerpuz(innerpuz)
        index = await self.wallet_state_manager.puzzle_store.index_for_pubkey(
            pubkey)
        private = master_sk_to_wallet_sk(self.wallet_state_manager.private_key,
                                         index)
        signature = AugSchemeMPL.sign(private, message)
        # assert signature.validate([signature.PkMessagePair(pubkey, message)])
        spend_bundle = SpendBundle(list_of_solutions, signature)
        did_record = TransactionRecord(
            confirmed_at_height=uint32(0),
            created_at_time=uint64(int(time.time())),
            to_puzzle_hash=coin.puzzle_hash,
            amount=uint64(coin.amount),
            fee_amount=uint64(0),
            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,
            type=uint32(TransactionType.INCOMING_TX.value),
            name=token_bytes(),
        )
        await self.standard_wallet.push_transaction(did_record)
        if filename is not None:
            f = open(filename, "w")
            f.write(self.get_my_DID())
            f.write(":")
            f.write(bytes(message_spend_bundle).hex())
            f.write(":")
            parent = coin.parent_coin_info.hex()
            innerpuzhash = self.did_info.current_inner.get_tree_hash().hex()
            amount = coin.amount
            f.write(parent)
            f.write(":")
            f.write(innerpuzhash)
            f.write(":")
            f.write(str(amount))
            f.close()
        return message_spend_bundle
Пример #5
0
    async def test_make_fake_coin(self, two_wallet_nodes):
        num_blocks = 5
        full_nodes, wallets = two_wallet_nodes
        full_node_1 = full_nodes[0]
        server_1 = full_node_1.server
        wallet_node, server_2 = wallets[0]
        wallet_node_2, server_3 = wallets[1]
        await server_2.start_client(
            PeerInfo("localhost", uint16(server_1._port)), None)
        wallet = wallet_node.wallet_state_manager.main_wallet
        wallet2 = wallet_node_2.wallet_state_manager.main_wallet
        ph = await wallet.get_new_puzzlehash()

        await server_3.start_client(
            PeerInfo("localhost", uint16(server_1._port)), None)
        for i in range(1, num_blocks):
            await full_node_1.farm_new_transaction_block(
                FarmNewBlockProtocol(ph))

        funds = sum([
            calculate_pool_reward(uint32(i)) +
            calculate_base_farmer_reward(uint32(i))
            for i in range(1, num_blocks - 1)
        ])

        await time_out_assert(15, wallet.get_confirmed_balance, funds)

        did_wallet: DIDWallet = await DIDWallet.create_new_did_wallet(
            wallet_node.wallet_state_manager, wallet, uint64(101))
        ph2 = await wallet2.get_new_puzzlehash()
        for i in range(1, num_blocks):
            await full_node_1.farm_new_transaction_block(
                FarmNewBlockProtocol(ph2))
        await time_out_assert(15, did_wallet.get_confirmed_balance, 101)
        await time_out_assert(15, did_wallet.get_unconfirmed_balance, 101)
        await time_out_assert(15, did_wallet.get_spendable_balance, 101)

        coins = await did_wallet.select_coins(1)
        coin = coins.pop()

        # copy info for later
        parent_info = await did_wallet.get_parent_for_coin(coin)
        id_puzhash = coin.puzzle_hash

        await did_wallet.create_spend(ph)
        for i in range(1, num_blocks):
            await full_node_1.farm_new_transaction_block(
                FarmNewBlockProtocol(ph))
        await time_out_assert(15, did_wallet.get_confirmed_balance, 0)
        await time_out_assert(15, did_wallet.get_unconfirmed_balance, 0)

        tx_record = await wallet.generate_signed_transaction(101, id_puzhash)
        await wallet.push_transaction(tx_record)

        for i in range(1, num_blocks):
            await full_node_1.farm_new_transaction_block(
                FarmNewBlockProtocol(ph))

        await time_out_assert(15, wallet.get_confirmed_balance, 21999999999899)
        await time_out_assert(15, wallet.get_unconfirmed_balance,
                              21999999999899)

        coins = await did_wallet.select_coins(1)
        assert len(coins) >= 1

        coin = coins.pop()

        # Write spend by hand
        # innerpuz solution is (mode amount new_puz identity my_puz)
        innersol = Program.to(
            [0, coin.amount, ph,
             coin.name(), coin.puzzle_hash])
        # full solution is (corehash parent_info my_amount innerpuz_reveal solution)
        innerpuz = did_wallet.did_info.current_inner
        full_puzzle: Program = did_wallet_puzzles.create_fullpuz(
            innerpuz,
            did_wallet.did_info.my_did,
        )
        fullsol = Program.to([
            [
                parent_info.parent_name,
                parent_info.inner_puzzle_hash,
                parent_info.amount,
            ],
            coin.amount,
            innersol,
        ])

        list_of_solutions = [CoinSolution(coin, full_puzzle, fullsol)]
        # sign for AGG_SIG_ME
        message = coin.puzzle_hash + coin.name(
        ) + did_wallet.wallet_state_manager.constants.AGG_SIG_ME_ADDITIONAL_DATA
        pubkey = did_wallet_puzzles.get_pubkey_from_innerpuz(innerpuz)
        index = await did_wallet.wallet_state_manager.puzzle_store.index_for_pubkey(
            pubkey)
        private = master_sk_to_wallet_sk(
            did_wallet.wallet_state_manager.private_key, index)
        signature = AugSchemeMPL.sign(private, message)
        sigs = [signature]
        aggsig = AugSchemeMPL.aggregate(sigs)
        spend_bundle = SpendBundle(list_of_solutions, aggsig)

        did_record = TransactionRecord(
            confirmed_at_height=uint32(0),
            created_at_time=uint64(int(time.time())),
            to_puzzle_hash=ph,
            amount=uint64(coin.amount),
            fee_amount=uint64(0),
            confirmed=False,
            sent=uint32(0),
            spend_bundle=spend_bundle,
            additions=spend_bundle.additions(),
            removals=spend_bundle.removals(),
            wallet_id=did_wallet.wallet_info.id,
            sent_to=[],
            trade_id=None,
            type=uint32(TransactionType.OUTGOING_TX.value),
            name=token_bytes(),
        )

        await did_wallet.standard_wallet.push_transaction(did_record)

        await time_out_assert(15, wallet.get_confirmed_balance, 21999999999899)
        await time_out_assert(15, wallet.get_unconfirmed_balance,
                              21999999999899)
        ph2 = Program.to(binutils.assemble("()")).get_tree_hash()
        for i in range(1, num_blocks + 3):
            await full_node_1.farm_new_block(FarmNewBlockProtocol(ph2))
        # It ends in 900 so it's not gone through
        # Assert coin ID is failing
        await time_out_assert(15, wallet.get_confirmed_balance, 23999999999899)
        await time_out_assert(15, wallet.get_unconfirmed_balance,
                              23999999999899)
Пример #6
0
    async def create_message_spend(self, messages: List[Tuple[int, bytes]], new_innerpuzhash: Optional[bytes32] = None):
        assert self.did_info.current_inner is not None
        assert self.did_info.origin_coin is not None
        coins = await self.select_coins(1)
        assert coins is not None
        coin = coins.pop()
        innerpuz: Program = self.did_info.current_inner
        if new_innerpuzhash is None:
            new_innerpuzhash = innerpuz.get_tree_hash()
        # innerpuz solution is (mode amount messages new_puz)
        innersol: Program = Program.to([1, coin.amount, messages, new_innerpuzhash])
        # full solution is (corehash parent_info my_amount innerpuz_reveal solution)

        full_puzzle: Program = did_wallet_puzzles.create_fullpuz(
            innerpuz,
            self.did_info.origin_coin.name(),
        )
        parent_info = self.get_parent_for_coin(coin)
        assert parent_info is not None
        fullsol = Program.to(
            [
                [
                    parent_info.parent_name,
                    parent_info.inner_puzzle_hash,
                    parent_info.amount,
                ],
                coin.amount,
                innersol,
            ]
        )
        list_of_solutions = [CoinSpend(coin, full_puzzle, fullsol)]
        # sign for AGG_SIG_ME
        # new_inner_puzhash amount message
        message = (
            Program.to([new_innerpuzhash, coin.amount, messages]).get_tree_hash()
            + coin.name()
            + self.wallet_state_manager.constants.AGG_SIG_ME_ADDITIONAL_DATA
        )
        pubkey = did_wallet_puzzles.get_pubkey_from_innerpuz(innerpuz)
        index = await self.wallet_state_manager.puzzle_store.index_for_pubkey(pubkey)
        private = master_sk_to_wallet_sk_unhardened(self.wallet_state_manager.private_key, index)
        signature = AugSchemeMPL.sign(private, message)
        # assert signature.validate([signature.PkMessagePair(pubkey, message)])
        sigs = [signature]
        aggsig = AugSchemeMPL.aggregate(sigs)
        spend_bundle = SpendBundle(list_of_solutions, aggsig)

        did_record = TransactionRecord(
            confirmed_at_height=uint32(0),
            created_at_time=uint64(int(time.time())),
            to_puzzle_hash=new_innerpuzhash,
            amount=uint64(coin.amount),
            fee_amount=uint64(0),
            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,
            type=uint32(TransactionType.OUTGOING_TX.value),
            name=bytes32(token_bytes()),
            memos=list(compute_memos(spend_bundle).items()),
        )
        await self.standard_wallet.push_transaction(did_record)
        return spend_bundle
Пример #7
0
    async def create_exit_spend(self, puzhash: bytes32):
        assert self.did_info.current_inner is not None
        assert self.did_info.origin_coin is not None
        coins = await self.select_coins(1)
        assert coins is not None
        coin = coins.pop()
        amount = coin.amount - 1
        # innerpuz solution is (mode amount new_puzhash)
        innersol: Program = Program.to([0, amount, puzhash])
        # full solution is (corehash parent_info my_amount innerpuz_reveal solution)
        innerpuz: Program = self.did_info.current_inner

        full_puzzle: Program = did_wallet_puzzles.create_fullpuz(
            innerpuz,
            self.did_info.origin_coin.name(),
        )
        parent_info = await self.get_parent_for_coin(coin)
        assert parent_info is not None
        fullsol = Program.to([
            [
                parent_info.parent_name,
                parent_info.inner_puzzle_hash,
                parent_info.amount,
            ],
            coin.amount,
            innersol,
        ])
        list_of_solutions = [CoinSpend(coin, full_puzzle, fullsol)]
        # sign for AGG_SIG_ME
        message = (
            Program.to([amount, puzhash]).get_tree_hash() + coin.name() +
            self.wallet_state_manager.constants.AGG_SIG_ME_ADDITIONAL_DATA)
        pubkey = did_wallet_puzzles.get_pubkey_from_innerpuz(innerpuz)
        index = await self.wallet_state_manager.puzzle_store.index_for_pubkey(
            pubkey)
        private = master_sk_to_wallet_sk(self.wallet_state_manager.private_key,
                                         index)
        signature = AugSchemeMPL.sign(private, message)
        # assert signature.validate([signature.PkMessagePair(pubkey, message)])
        sigs = [signature]
        aggsig = AugSchemeMPL.aggregate(sigs)
        spend_bundle = SpendBundle(list_of_solutions, aggsig)

        # TODO: address hint error and remove ignore
        #       error: Argument "name" to "TransactionRecord" has incompatible type "bytes"; expected "bytes32"
        #       [arg-type]
        did_record = TransactionRecord(
            confirmed_at_height=uint32(0),
            created_at_time=uint64(int(time.time())),
            to_puzzle_hash=puzhash,
            amount=uint64(coin.amount),
            fee_amount=uint64(0),
            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,
            type=uint32(TransactionType.OUTGOING_TX.value),
            name=token_bytes(),  # type: ignore[arg-type]
        )
        await self.standard_wallet.push_transaction(did_record)
        return spend_bundle