예제 #1
0
    def test_sending_between_p2sh_1of2_and_p2wpkh_p2sh(self, mock_write):
        wallet1a = WalletIntegrityHelper.create_multisig_wallet(
            [
                keystore.from_seed('phone guilt ancient scan defy gasp off rotate approve ill word exchange', '', True),
                keystore.from_xpub('tpubD6NzVbkrYhZ4YPZ3ntVjqSCxiUUv2jikrUBU73Q3iJ7Y8iR41oYf991L5fanv7ciHjbjokdK2bjYqg1BzEUDxucU9qM5WRdBiY738wmgLP4')
            ],
            '1of2', gap_limit=2
        )
        # ^ second seed: kingdom now gift initial age right velvet exotic harbor enforce kingdom kick
        wallet2 = WalletIntegrityHelper.create_standard_wallet(
            # bip39: uniform tank success logic lesson awesome stove elegant regular desert drip device, der: m/49'/1'/0'
            keystore.from_xprv('uprv91HGbrNZTK4x8u22nbdYGzEuWPxjaHMREUi7CNhY64KsG5ZGnVM99uCa16EMSfrnaPTFxjbRdBZ2WiBkokoM8anzAy3Vpc52o88WPkitnxi'),
            gap_limit=2
        )

        # bootstrap wallet1
        funding_tx = Transaction('010000000001027e20990282eb29588375ad04936e1e991af3bc5b9c6f1ab62eca8c25becaef6a01000000171600140e6a17fadc8bafba830f3467a889f6b211d69a00fdffffff51847fd6bcbdfd1d1ea2c2d95c2d8de1e34c5f2bd9493e88a96a4e229f564e800100000017160014ecdf9fa06856f9643b1a73144bc76c24c67774a6fdffffff021e8501000000000017a91451991bfa68fbcb1e28aa0b1e060b7d24003352e38700093d000000000017a914b0b9f31bace76cdfae2c14abc03e223403d7dc4b870247304402205e19721b92c6afd70cd932acb50815a36ee32ab46a934147d62f02c13aeacf4702207289c4a4131ef86e27058ff70b6cb6bf0e8e81c6cbab6dddd7b0a9bc732960e4012103fe504411c21f7663caa0bbf28931f03fae7e0def7bc54851e0194dfb1e2c85ef02483045022100e969b65096fba4f8b24eb5bc622d2282076241621f3efe922cc2067f7a8a6be702203ec4047dd2a71b9c83eb6a0875a6d66b4d65864637576c06ed029d3d1a8654b0012102bbc8100dca67ba0297aba51296a4184d714204a5fc2eda34708360f37019a3dccfcc1300')
        funding_txid = funding_tx.txid()
        funding_output_value = 4000000
        self.assertEqual('1137c12de4ce0f5b08de8846ba14c0814351a7f0f31457c8ea51a5d4b3c891a3', funding_txid)
        wallet1a.receive_tx_callback(funding_txid, funding_tx, TX_HEIGHT_UNCONFIRMED)

        # wallet1 -> wallet2
        outputs = [(bitcoin.TYPE_ADDRESS, wallet2.get_receiving_address(), 1000000)]
        tx = wallet1a.mktx(outputs=outputs, password=None, config=self.config, fee=5000)

        self.assertTrue(tx.is_complete())
        self.assertFalse(tx.is_segwit())
        self.assertEqual(1, len(tx.inputs()))
        tx_copy = Transaction(tx.serialize())
        self.assertEqual(wallet1a.is_mine(tx.inputs()[0]['address']), wallet1a.is_mine(tx_copy.inputs()[0]['address']))
        self.assertTrue(wallet1a.is_mine(tx.inputs()[0]['address']))
        self.assertEqual(wallet1a.txin_type, tx_copy.inputs()[0]['type'])
        self.assertEqual(tx.wtxid(), tx_copy.wtxid())
        self.assertEqual('1b7e94860b9681d4e371928d40fdbd4641e991aa74f1a211f239c887047e4a2a', tx_copy.txid())

        wallet1a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
        wallet2.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)

        # wallet2 -> wallet1
        outputs = [(bitcoin.TYPE_ADDRESS, wallet1a.get_receiving_address(), 300000)]
        tx = wallet2.mktx(outputs=outputs, password=None, config=self.config, fee=5000)

        self.assertTrue(tx.is_complete())
        self.assertTrue(tx.is_segwit())
        self.assertEqual(1, len(tx.inputs()))
        tx_copy = Transaction(tx.serialize())
        self.assertEqual(wallet2.is_mine(tx.inputs()[0]['address']), wallet2.is_mine(tx_copy.inputs()[0]['address']))
        self.assertTrue(wallet2.is_mine(tx.inputs()[0]['address']))
        self.assertEqual(wallet2.txin_type, tx_copy.inputs()[0]['type'])
        self.assertEqual(tx.wtxid(), tx_copy.wtxid())
        self.assertEqual('f65edb0843ff44436dc5964fb6b298e157502b9b4a83dac6b82dd2d2a3247d0a', tx_copy.txid())

        wallet1a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
        wallet2.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)

        # wallet level checks
        self.assertEqual((0, funding_output_value - 1000000 - 5000 + 300000, 0), wallet1a.get_balance())
        self.assertEqual((0, 1000000 - 5000 - 300000, 0), wallet2.get_balance())
예제 #2
0
    def test_sending_between_p2wpkh_and_compressed_p2pkh(self, mock_write):
        wallet1 = self.create_standard_wallet_from_seed('bitter grass shiver impose acquire brush forget axis eager alone wine silver')
        wallet2 = self.create_standard_wallet_from_seed('cycle rocket west magnet parrot shuffle foot correct salt library feed song')

        # bootstrap wallet1
        funding_tx = Transaction('01000000014576dacce264c24d81887642b726f5d64aa7825b21b350c7b75a57f337da6845010000006b483045022100a3f8b6155c71a98ad9986edd6161b20d24fad99b6463c23b463856c0ee54826d02200f606017fd987696ebbe5200daedde922eee264325a184d5bbda965ba5160821012102e5c473c051dae31043c335266d0ef89c1daab2f34d885cc7706b267f3269c609ffffffff0240420f00000000001600148a28bddb7f61864bdcf58b2ad13d5aeb3abc3c42a2ddb90e000000001976a914c384950342cb6f8df55175b48586838b03130fad88ac00000000')
        funding_txid = funding_tx.txid()
        funding_output_value = 1000000
        self.assertEqual('add2535aedcbb5ba79cc2260868bb9e57f328738ca192937f2c92e0e94c19203', funding_txid)
        wallet1.receive_tx_callback(funding_txid, funding_tx, TX_HEIGHT_UNCONFIRMED)

        # wallet1 -> wallet2
        outputs = [(bitcoin.TYPE_ADDRESS, wallet2.get_receiving_address(), 250000)]
        tx = wallet1.mktx(outputs=outputs, password=None, config=self.config, fee=5000)

        self.assertTrue(tx.is_complete())
        self.assertTrue(tx.is_segwit())
        self.assertEqual(1, len(tx.inputs()))
        tx_copy = Transaction(tx.serialize())
        self.assertEqual(wallet1.is_mine(tx.inputs()[0]['address']), wallet1.is_mine(tx_copy.inputs()[0]['address']))
        self.assertTrue(wallet1.is_mine(tx.inputs()[0]['address']))
        self.assertEqual(wallet1.txin_type, tx_copy.inputs()[0]['type'])
        self.assertEqual(tx.wtxid(), tx_copy.wtxid())
        self.assertEqual('3c06ae4d9be8226a472b3e7f7c127c7e3016f525d658d26106b80b4c7e3228e2', tx_copy.txid())

        wallet1.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)  # TX_HEIGHT_UNCONF_PARENT but nvm
        wallet2.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)

        # wallet2 -> wallet1
        outputs = [(bitcoin.TYPE_ADDRESS, wallet1.get_receiving_address(), 100000)]
        tx = wallet2.mktx(outputs=outputs, password=None, config=self.config, fee=5000)

        self.assertTrue(tx.is_complete())
        self.assertFalse(tx.is_segwit())
        self.assertEqual(1, len(tx.inputs()))
        tx_copy = Transaction(tx.serialize())
        self.assertEqual(wallet2.is_mine(tx.inputs()[0]['address']), wallet2.is_mine(tx_copy.inputs()[0]['address']))
        self.assertTrue(wallet2.is_mine(tx.inputs()[0]['address']))
        self.assertEqual(wallet2.txin_type, tx_copy.inputs()[0]['type'])
        self.assertEqual(tx.wtxid(), tx_copy.wtxid())
        self.assertEqual('5f25707571eb776bdf14142f9966bf2a681906e0a79501edbb99a972c2ceb972', tx_copy.txid())

        wallet1.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
        wallet2.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)

        # wallet level checks
        self.assertEqual((0, funding_output_value - 250000 - 5000 + 100000, 0), wallet1.get_balance())
        self.assertEqual((0, 250000 - 5000 - 100000, 0), wallet2.get_balance())
예제 #3
0
 def createTransaction(self, password, destList):
     """Create a new transaction and send it to the RelayNode
        destList is a list of tuples
        Each tuples is like : (str_address, value)
        The last transaction is the rest of the wallet send to the new user address
     """
     self.checkUpdate()
     newAddr = Address()
     newAddr.encryptPrivateKey(password)
     total = sum([i[1] for i in destList])
     if total <= self.count:
         destList.append((str(newAddr), (self.count - total)))
         transac = Transaction(self.addr.public(), destList)
         self.addr.decryptPrivateKey(password)
         transac.sign(self.addr)
         debug('valid: ' + ('True' if transac.is_signed() else 'False'))
         self.addr.encryptPrivateKey(password)
         if not self.relay.submit_transaction(transac):
             return False
         self.addrList.append(newAddr)
         self.addr = newAddr
         add_address(self.user_ID, self.addr, len(self.addrList) - 1)
         return True
     else:
         return False
예제 #4
0
    def handle_request(self, request):
        try:
            request_type = request.get('type')

            if request_type not in self.no_auth_check_handlers:
                username = request.get('auth', {}).get('username')
                token = request.get('auth', {}).get('auth_token')
                if not username or not token:
                    return construct_result(400, 'Bad request')

                with Transaction() as tr:
                    try:
                        user = User.read_by_name(tr.cursor, username)
                    except ItemNotFoundError:
                        return construct_result(404, 'User not found')

                if not self.auth_handler.verify_auth_token(user.user_id, token):
                    return construct_result(403, 'Bad auth token, you should sign in')

                self.context['user_id'] = user.user_id

            return self.type_to_handler.get(request_type, lambda _: construct_result(400, 'Bad request'))(request)
        except KeyboardInterrupt:
            raise
        except Exception as e:
            logging.exception('Unhandled exception during request handling occured: {}'.format(e))
            return construct_result(500, 'Error occured')
예제 #5
0
def transfer(bc, relay, from_addr, to_addr, amount):
    f = get_address(from_addr)
    if f is None:
        exit('no address '+str(from_addr)+' in database')
    
    total = bc.get_amount_of_address(f)
    if total < amount:
        exit('not enough money for this transfer')
    
    pwd = getpass.getpass()
    while not f.decryptPrivateKey(pwd):
        print('Invalid password')
        pwd = getpass.getpass()
    
    receivers = [(to_addr, amount)]
    if total > amount:
        new = Address()
        new.encryptPrivateKey(pwd)
        db.add_address('client', new, 0)
        print('created new address '+str(new)+' to receive remaining funds')
        receivers.append((str(new), total - amount))
    t = Transaction(f, receivers)
    if relay.submit_transaction(t):
        print('transaction sent to the network')
    else:
        print('error sending transaction')
예제 #6
0
파일: spender.py 프로젝트: gustavonalle/bfs
    def create_tx(self):
        tx = Transaction(version=self.tx_version,
                         sig_hash_type=self.sig_hash_type,
                         sig_hash_type_pre_image=self.sig_hash_type_pre_image,
                         sign_style=self.sign_type)
        keys = []
        for utxo in self.utxos:
            pub_key = utxo.private_key.create_pub_key()
            keys.append(KeyPair(utxo.private_key, pub_key))
            tx_input = TransactionInput(utxo.tx_hash,
                                        utxo.index,
                                        utxo.address,
                                        get_spend_type(utxo.address),
                                        prev_amount=utxo.amount_btc,
                                        pub_key=pub_key)
            tx.add_inputs(tx_input)

        for destination in self.destinations:
            tx_output = TransactionOutput(
                btc_to_satoshis(destination.amount_btc), destination.address,
                get_spend_type(destination.address))
            tx.add_outputs(tx_output)

        signed = tx.sign(*keys)
        return signed.serialize()
예제 #7
0
    def __init__(self, seed, *args):
        self.seed = seed
        self.wallet = Wallet(utils.hash(str(self.seed)))
        self.neighbours = set()
        self.DAG = {}

        root_transaction = Transaction('0000', 'root', 25000000000)
        self.attach_transaction(root_transaction, ['root'])
예제 #8
0
def construct_follows_list_response(follows, followers_mode=False):
    res = []
    for follow in follows:
        with Transaction() as tr:
            try:
                user_id = follow.user_id if not followers_mode else follow.follower_id
                res.append(User.read_by_pk(tr.cursor, user_id).username)
            except ItemNotFoundError:
                continue
    return res
예제 #9
0
    def handle_post(self, request):
        text = request.get('text')
        if not text:
            return construct_result(400, 'Bad request')

        ts = int(time.time())

        with Transaction() as tr:
            Post(self.context['user_id'], None, text, ts).create_me(tr.cursor)

        return construct_result()
예제 #10
0
def construct_posts_list_response(posts):
    res = []
    for post in posts:
        post_dict = post.to_dict()
        with Transaction() as tr:
            try:
                post_dict['username'] = User.read_by_pk(
                    tr.cursor, post_dict.pop('user_id')).username
            except ItemNotFoundError:
                continue
        res.append(post_dict)
    return res
예제 #11
0
파일: tangle.py 프로젝트: aliteke/Tango
    def __init__(self, isgenesis=True, *args):
        # represent the "sites" containing transactions
        # self.tngl = nx.DiGraph()

        if isgenesis:
            self.DAG = OrderedDict()
            genesis_tx = Transaction('genesis_address', 'genesis_address',
                                     21000000)
            genesis_tx_key = self.attach_transaction(genesis_tx,
                                                     ['genesis_tx'])

            founding_txA = Transaction('genesis_address', 'founderA_address',
                                       7000000)
            self.attach_transaction(founding_txA, [genesis_tx_key])

            founding_txB = Transaction('genesis_address', 'founderB_address',
                                       7000000)
            self.attach_transaction(founding_txB, [genesis_tx_key])

        else:
            print "[+] Genesis tangle is already done, connect and sync from neighbours"
예제 #12
0
    def handle_follow(self, request):
        username_to_follow = request.get('username_to_follow')
        if not username_to_follow:
            return construct_result(400, 'Bad request')

        with Transaction() as tr:
            try:
                user_to_follow = User.read_by_name(tr.cursor, username_to_follow)
            except ItemNotFoundError:
                return construct_result(404, 'User not found')

            Follow(None, user_to_follow.user_id, self.context['user_id']).create_me(tr.cursor)

        return construct_result()
예제 #13
0
    def handle_get_following_users(self, request):
        username = request.get('username')
        if not username:
            return construct_result(400, 'Bad request')

        with Transaction() as tr:
            try:
                user = User.read_by_name(tr.cursor, username)
            except ItemNotFoundError:
                return construct_result(404, 'User not found')

            follows = Follow.get_following_users(tr.cursor, user.user_id)

        return construct_result(200, construct_follows_list_response(follows, followers_mode=True))
예제 #14
0
    def handle_get_user_posts(self, request):
        username = request.get('username')
        if not username:
            return construct_result(400, 'Bad request')

        with Transaction() as tr:
            try:
                user = User.read_by_name(tr.cursor, username)
            except ItemNotFoundError:
                return construct_result(404, 'User not found')

            posts = Post.get_user_posts(tr.cursor, user.user_id)

        return construct_result(200, construct_posts_list_response(posts))
예제 #15
0
    def handle_like(self, request):
        post_id = request.get('post_id')
        if not post_id:
            return construct_result(400, 'Bad request')

        with Transaction() as tr:
            try:
                post = Post.read_by_pk(tr.cursor, post_id)
            except ItemNotFoundError:
                return construct_result(404, 'Post not found')

            post.likes += 1
            post.update_me(tr.cursor)

        return construct_result()
예제 #16
0
    def handle_signin(self, request):
        username = request.get('username')
        password = request.get('password')
        if not username or not password:
            return construct_result(400, 'Bad request')

        with Transaction() as tr:
            try:
                user = User.read_by_name(tr.cursor, username)
            except ItemNotFoundError:
                return construct_result(404, 'User not found')

            if not self.auth_handler.verify_password(password, user.password_key):
                return construct_result(400, 'Bad password')

        return construct_result(200, {'auth_token': self.auth_handler.get_auth_token(user.user_id)})
예제 #17
0
    def create_new_block(self):
        """
        Create a fresh new block that contains all valid
        pending transactions.
        """
        newb = Block(self.blockchain.top().hash)
        newb.index = self.blockchain.top().index + 1

        newb.transactions.extend(self.blockchain.get_pending_transactions())

        tx = Transaction(None, txtype=TxType.COINBASE)
        tx.add_out(MINING_REWARD, self.reward_addr)
        tx.finalize()

        newb.transactions.append(tx)

        return newb
예제 #18
0
    def handle_signup(self, request):
        username = request.get('username')
        password = request.get('password')
        if not username or not password:
            return construct_result(400, 'Bad request')

        with Transaction() as tr:
            no_users = False
            try:
                user = User.read_by_name(tr.cursor, username)
            except ItemNotFoundError:
                no_users = True

            if not no_users:
                return construct_result(400, 'User already exists')

            User(None, username, self.auth_handler.get_password_key(password)).create_me(tr.cursor)

        return construct_result()
예제 #19
0
    def _test_fraudulent_tx(self, victim, blockchain):
        """
        Try transaction from somebody else's "wallet"
        """

        miner_key = generate_key()
        perpetrator = generate_key()

        utxo = blockchain.scan_unspent_transactions(victim.publickey())

        perpetrator_owns = blockchain.scan_unspent_transactions(
            perpetrator.publickey())
        self.assertEqual(len(perpetrator_owns), 0)  # Sanity check

        # Let's handcraft tx that tries to steal victim's coins.
        tx = Transaction(perpetrator)  # Sign it with random key

        utxo = blockchain.scan_unspent_transactions(
            victim.publickey())  # Get victim's utxo

        debit = sum(map(lambda x: x['value'], utxo))

        for credit in utxo:
            tx.add_in(credit['hash'], sign(perpetrator, credit['hash']),
                      victim.publickey(), credit['value'])

        tx.add_out(debit, perpetrator.publickey())

        try:
            blockchain.add(tx)
            self.fail("Should've thrown UnauthorizedTxException")
        except UnauthorizedTxException:
            pass

        miner = Miner(blockchain)
        miner.reward_addr = miner_key.publickey()
        _ = miner._mine()

        perpetrator_owns = blockchain.scan_unspent_transactions(
            perpetrator.publickey())

        # Should own nothing. This tx should've failed.
        self.assertEqual(len(perpetrator_owns), 0)
예제 #20
0
    def make_transaction(self, receiving_addr, value):
        '''
            1. Pick at least two transactions in Tangle to confirm
            2. Check picked transactions for conflict
            3. Approve non conflicting transactions
            4. Perform proof of work
            5. Send transaction to tangle 
        '''
        confirmed_transactions = self.confirm_transactions()

        if len(confirmed_transactions) >= 2:
            proof_of_work = self.proof_of_work(''.join(confirmed_transactions))
            new_transaction = Transaction(self.wallet.generate_address(),
                                          receiving_addr, value)
            new_transaction.pow = proof_of_work
            return self.attach_transaction(new_transaction,
                                           confirmed_transactions)

        return {'msg': 'transaction failed'}
예제 #21
0
    def test_pending_transactions(self):
        receiver = generate_key()

        tx = Transaction(None, txtype=TxType.COINBASE)
        tx.add_out(10, receiver.publickey())

        blockchain = Blockchain()
        blockchain.add(tx)

        pending_tx = blockchain.get_pending_transactions()

        self.assertEqual(len(filter(lambda x: tx.hash, pending_tx)), 1)

        miner = Miner(blockchain)
        miner.reward_addr = receiver.publickey()
        newb = miner._mine()

        pending_tx = blockchain.get_pending_transactions()

        self.assertEqual(len(filter(lambda x: tx.hash, pending_tx)), 0)
        self.assertEqual(len(filter(lambda x: tx.hash, newb.transactions)), 2)
예제 #22
0
    def handle_admin_info(self, request):
        with Transaction() as tr:
            try:
                user = User.read_by_pk(tr.cursor, self.context['user_id'])
            except ItemNotFoundError:
                return construct_result(404, 'User not found')

            if not user.is_admin:
                return construct_result(403, 'Access denied')

            users = User.read_all(tr.cursor)
            posts = Post.read_all(tr.cursor)
            follows = Follow.read_all(tr.cursor)

        return construct_result(
            200,
            {
                'users': [user.to_dict() for user in users],
                'posts': [post.to_dict() for post in posts],
                'folows': [follow.to_dict() for follow in follows],
            }
        )
예제 #23
0
 def test_has_debit_shown(self):
     with freeze_time("2020-01-01"):
         transaction = Transaction(debit=10000)
         result = "01/01/2020 || || 100.00 || "
         assert transaction.display() == result
예제 #24
0
 def test_has_balance_shown(self):
     with freeze_time("2020-01-01"):
         transaction = Transaction(balance=10000)
         result = "01/01/2020 || || || 100.00 "
         assert transaction.display() == result
    def test_sending_between_p2sh_2of3_and_uncompressed_p2pkh(
            self, mock_write):
        wallet1a = WalletIntegrityHelper.create_multisig_wallet(
            keystore.from_seed(
                'blast uniform dragon fiscal ensure vast young utility dinosaur abandon rookie sure',
                '', True),
            keystore.from_xpub(
                'tpubD6NzVbkrYhZ4YTPEgwk4zzr8wyo7pXGmbbVUnfYNtx6SgAMF5q3LN3Kch58P9hxGNsTmP7Dn49nnrmpE6upoRb1Xojg12FGLuLHkVpVtS44'
            ),
            keystore.from_xpub(
                'tpubD6NzVbkrYhZ4XJzYkhsCbDCcZRmDAKSD7bXi9mdCni7acVt45fxbTVZyU6jRGh29ULKTjoapkfFsSJvQHitcVKbQgzgkkYsAmaovcro7Mhf'
            ),
            gap_limit=2)
        wallet1b = WalletIntegrityHelper.create_multisig_wallet(
            keystore.from_seed(
                'cycle rocket west magnet parrot shuffle foot correct salt library feed song',
                '', True),
            keystore.from_xpub(
                'tpubD6NzVbkrYhZ4YTPEgwk4zzr8wyo7pXGmbbVUnfYNtx6SgAMF5q3LN3Kch58P9hxGNsTmP7Dn49nnrmpE6upoRb1Xojg12FGLuLHkVpVtS44'
            ),
            keystore.from_xpub(
                'tpubD6NzVbkrYhZ4YARFMEZPckrqJkw59GZD1PXtQnw14ukvWDofR7Z1HMeSCxfYEZVvg4VdZ8zGok5VxHwdrLqew5cMdQntWc5mT7mh1CSgrnX'
            ),
            gap_limit=2)
        # ^ third seed: ghost into match ivory badge robot record tackle radar elbow traffic loud
        wallet2 = self.create_standard_wallet_from_seed(
            'powerful random nobody notice nothing important anyway look away hidden message over'
        )

        # bootstrap wallet1
        funding_tx = Transaction(
            '010000000001014121f99dc02f0364d2dab3d08905ff4c36fc76c55437fd90b769c35cc18618280100000000fdffffff02d4c22d00000000001600143fd1bc5d32245850c8cb5be5b09c73ccbb9a0f75001bb7000000000017a91480c2353f6a7bc3c71e99e062655b19adb3dd2e4887024830450221008781c78df0c9d4b5ea057333195d5d76bc29494d773f14fa80e27d2f288b2c360220762531614799b6f0fb8d539b18cb5232ab4253dd4385435157b28a44ff63810d0121033de77d21926e09efd04047ae2d39dbd3fb9db446e8b7ed53e0f70f9c9478f735dac11300'
        )
        funding_txid = funding_tx.txid()
        funding_output_value = 12000000
        self.assertEqual(
            'b25cd55687c9e528c2cfd546054f35fb6741f7cf32d600f07dfecdf2e1d42071',
            funding_txid)
        wallet1a.receive_tx_callback(funding_txid, funding_tx,
                                     TX_HEIGHT_UNCONFIRMED)

        # wallet1 -> wallet2
        outputs = [(bitcoin.TYPE_ADDRESS, wallet2.get_receiving_address(),
                    370000)]
        tx = wallet1a.mktx(outputs=outputs,
                           password=None,
                           config=self.config,
                           fee=5000)
        tx = Transaction(
            tx.serialize())  # simulates moving partial txn between cosigners
        self.assertFalse(tx.is_complete())
        wallet1b.sign_transaction(tx, password=None)

        self.assertTrue(tx.is_complete())
        self.assertFalse(tx.is_segwit())
        self.assertEqual(1, len(tx.inputs()))
        tx_copy = Transaction(tx.serialize())
        self.assertEqual(wallet1a.is_mine(tx.inputs()[0]['address']),
                         wallet1a.is_mine(tx_copy.inputs()[0]['address']))
        self.assertTrue(wallet1a.is_mine(tx.inputs()[0]['address']))
        self.assertEqual(wallet1a.txin_type, tx_copy.inputs()[0]['type'])
        self.assertEqual(tx.wtxid(), tx_copy.wtxid())
        self.assertEqual(
            '26f3bdd0402e1cff19126244ebe3d32722cef0db507c7229ca8754f5e06ef25d',
            tx_copy.txid())

        wallet1a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
        wallet2.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)

        # wallet2 -> wallet1
        outputs = [(bitcoin.TYPE_ADDRESS, wallet1a.get_receiving_address(),
                    100000)]
        tx = wallet2.mktx(outputs=outputs,
                          password=None,
                          config=self.config,
                          fee=5000)

        self.assertTrue(tx.is_complete())
        self.assertFalse(tx.is_segwit())
        self.assertEqual(1, len(tx.inputs()))
        tx_copy = Transaction(tx.serialize())
        self.assertEqual(wallet2.is_mine(tx.inputs()[0]['address']),
                         wallet2.is_mine(tx_copy.inputs()[0]['address']))
        self.assertTrue(wallet2.is_mine(tx.inputs()[0]['address']))
        self.assertEqual(wallet2.txin_type, tx_copy.inputs()[0]['type'])
        self.assertEqual(tx.wtxid(), tx_copy.wtxid())
        self.assertEqual(
            'c573b3f8464a4ed40dfc79d0889a780f44e917beef7a75883b2427c2987f3e95',
            tx_copy.txid())

        wallet1a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
        wallet2.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)

        # wallet level checks
        self.assertEqual((0, funding_output_value - 370000 - 5000 + 100000, 0),
                         wallet1a.get_balance())
        self.assertEqual((0, 370000 - 5000 - 100000, 0), wallet2.get_balance())
    def test_inputs(self):
        try:
            with open(txintests_local) as f:
                testlist = json.load(f)
            print("Got script tests from %s; will not download." %
                  (txintests_local, ))
        except IOError:
            print("Couldn't get script tests from %s; downloading from %s..." %
                  (txintests_local, txintests_url))
            testlist = requests.get(txintests_url).json()

        print("Starting %d tests on SLP's input validation" % len(testlist))
        for test in testlist:
            description = test['description']

            given_validity = {}
            #should_validity = {}
            txes = {}
            for d in test['when']:
                tx = Transaction(d['tx'])
                txid = tx.txid()
                txes[txid] = tx
                if d['valid'] is True:
                    given_validity[txid] = 1
                elif d['valid'] is False:
                    given_validity[txid] = 2
                else:
                    raise ValueError(d['valid'])

            for d in test['should']:
                tx = Transaction(d['tx'])
                txid = tx.txid()
                txes[txid] = tx
                d['txid'] = txid
                #if d['valid'] is True:
                #should_validity[txid] = 1
                #elif d['valid'] is False:
                #should_validity[txid] = 2
                #else:
                #raise ValueError(d['valid'])

            for i, d in enumerate(test['should']):
                txid = d['txid']
                with self.subTest(description=description, i=i):
                    try:
                        graph, jobmgr = slp_validator_0x01.setup_job(
                            txes[txid], reset=True)
                    except slp.SlpInvalidOutputMessage:  # If output 0 is not OP_RETURN
                        self.assertEqual(d['valid'], False)
                        continue

                    def fetch_hook(txids):
                        l = []
                        for txid in txids:
                            try:
                                l.append(txes[txid])
                            except KeyError:
                                pass
                        ### Call proxy here!
                        return l

                    job = slp_validator_0x01.ValidationJob(
                        graph, [txid],
                        None,
                        fetch_hook=fetch_hook,
                        validitycache=given_validity)
                    #if txid == '8a08b78ae434de0b1a26e56ae7e78bb11b20f8240eb3d97371fd46a609df7fc3':
                    #graph.debugging = True
                    #job.debugging_graph_state = True
                    q = Queue()
                    job.add_callback(q.put)
                    jobmgr.add_job(job)
                    try:
                        q.get(timeout=3)  # unlimited timeout
                    except Empty:
                        raise RuntimeError(
                            "Timeout during validation unit test")

                    n = next(iter(job.nodes.values()))
                    if d['valid'] is True:
                        self.assertEqual(n.validity, 1)
                    elif d['valid'] is False:
                        self.assertIn(n.validity, (2, 3))
                    else:
                        raise ValueError(d['valid'])
예제 #27
0
    def test_transaction(self):

        wallet_keys = {
            'xpub6GDQf5vZmrpQvD4ixNdqHmgSZ76Uo2Cg5isBupnvZpnNbhdRhgdhq9hkfCSKRE31rGfYuXNfZ5gTamFkj1GXt6k87MD1hUn28tuvLHY71Bk':
            'L2FQCaHPwgS4CmAf6bKtbjVWDbcHv42c72by1zLEyLuDrUG22CwM',
            'xpub6GLs33TeHkrLSTJ2uxiMLnuqxCHG9iBFCwjTwyg4EvzyxUi78U1sXxxRPUQfLGNEZRT3yYKEwR39ZbUtofEgcmTLtJdSetnFiQPEwTZRW5y':
            'L1aD1WSA3UGU56sAmjfYVj1rK3fnSzWKj2wTsDTN1DpgUgPVwQCa',
            'xpub6Fc64k9RTc79yD7xErF2yKSdUraGBhGWDt1FomUFVCFg52165LZvvoGL59hebJBGtauFqNL5zMeRgPGV29sfQp6XqoiiD9E53UDatBhFZuk':
            'L25eCRYrDNVNrTZV1XZhmaZti3dVsZz3egm1R7LsPHRdpYuyLYKE'
            #            'xpub6GiSmJrVQC5q2m5cRcZvUgnGUsfeEqi3eEfUTgacnA33G8PAQnJeeMzpNAGUA9JL3goUui7BY52rVPwhmxMALkmFh5ZuwJDKrPv8ERkG3CK': 'L3jUPoR7fUwB9mwfuqqF79mHDpj5rpygQhdWntJ9ShZ9nbyRab5h'
        }

        acc = self.wallet.accounts["0"]
        redeem_script = '53210278a1a7de63493a8c8e0e7f4ebb13fd2a8144db25bb3bc2e5f44127a851a389332102ee780aa224c9fe54caff984205077b7cca08ced3188a3f3c639d83deda6b9a592103124429ddbed55593d0abea0d0d3d283eca4546e40017b2945f4666c561b494ba210312872f0aa80fa1a9bc7df77fa5be310f5441f7bfec798fe19209b04954dec8da54ae'

        coins = [{
            'address': '32SbQbBthcMzRSpCw1ifAXqWviJGH5HKUk',
            'value': 600000,
            'prevout_n': 0,
            'prevout_hash':
            '1111111111111111111111111111111111111111111111111111111111111111',
            'height': 100000,
            'coinbase': 'True'
        }]

        txin = coins[0]

        x_pubkeys = map(lambda x: bip32_public_derivation(x, "", "/0/0/0"),
                        self.wallet.master_public_keys.values())
        pubkeys = map(lambda x: deserialize_xkey(x)[4].encode('hex'),
                      x_pubkeys)

        s = ''.join(map(lambda x: int_to_hex(x, 2), (0, 0)))
        x_pubkeys = map(
            lambda x: 'ff' + DecodeBase58Check(x).encode('hex') + s, x_pubkeys)
        pubkeys, x_pubkeys = zip(*sorted(zip(pubkeys, x_pubkeys)))
        txin['pubkeys'] = list(pubkeys)
        txin['x_pubkeys'] = list(x_pubkeys)
        txin['signatures'] = [None] * len(pubkeys)
        txin['redeemScript'] = redeem_script
        txin['num_sig'] = acc.multisig_m

        outputs = [('address', '1PyXgL1qmZPuxcVi9CcguQb3v7WUvQZBud', 500000)]
        inputs = []
        tx = Transaction(inputs, outputs)
        tx.add_input(txin)
        self.wallet.sign_transaction(tx, "secret")

        #
        ins = tx.inputs_to_sign()
        keypairs = {}
        sec = None
        for innard in ins:
            # this is easier than the commented loop below
            in_xpub, _ = BIP32_Account.parse_xpubkey(innard)
            if wallet_keys.get(in_xpub):
                keypairs[innard] = wallet_keys[in_xpub]
            # ...


#            in_xpub, in_seq = BIP32_Account.parse_xpubkey(innard)
#            sec = None
#            for k, vaccount in self.wallet.accounts.items():
#                acc_v = vaccount.get_master_pubkeys()[0]
#                acc_xpub = bip32_public_derivation(acc_v, "", "/0/0")
#                if in_xpub == acc_xpub:
#                    pk = vaccount.get_private_key(in_seq, self.wallet, "secret")
#                    sec = pk[0]

#            if sec:
#                keypairs [ innard ] = sec

        if keypairs:
            tx.sign(keypairs)
        self.assertEqual(
            '0100000001111111111111111111111111111111111111111111111111111111111111111100000000fd6701004730440220774e80fda89895d8bf3ac39c38f39456d31c1e857dc1c77c000f4de6c3de15fe02207b6d13b5ba17eadeb607f3ca56f693a0b777dae668584cefec0910a8bc90869a0147304402205e80562254972f873b5b59b1cdc81e422c7a2959d8868e5a54238fbfdf6f107002200204eef593812453ae2c22334c409f9ef25523cf9619399eb2d3c249673443dc01483045022100a81e69796aa5e5ae0d8924047e3c81a8dd64dfbc791caba6728ac7820aa114da022060b85875fd58223b7c61ef45fac2567a9f76934f947e4d03d927f5b078e1fb45014c8b53210278a1a7de63493a8c8e0e7f4ebb13fd2a8144db25bb3bc2e5f44127a851a389332102ee780aa224c9fe54caff984205077b7cca08ced3188a3f3c639d83deda6b9a592103124429ddbed55593d0abea0d0d3d283eca4546e40017b2945f4666c561b494ba210312872f0aa80fa1a9bc7df77fa5be310f5441f7bfec798fe19209b04954dec8da54aeffffffff0120a10700000000001976a914fc03ab7c28d17349f084f7cadde4dafc356918d388ac00000000',
            str(tx))

        ###########
        #
        serialized_tx = str(tx)
        tx2 = Transaction.deserialize(serialized_tx,
                                      active_chain=self.wallet.active_chain)
        self.assertEquals(4, len(tx2.inputs[0]['x_pubkeys']))
        self.assertEquals(3, tx2.inputs[0]['num_sig'])
예제 #28
0
    def handle_get_user_feed(self, request):
        with Transaction() as tr:
            posts = Post.get_user_feed(tr.cursor, self.context['user_id'])

        return construct_result(200, construct_posts_list_response(posts))
    def test_sending_between_p2wsh_2of3_and_p2wsh_p2sh_2of2(self, mock_write):
        wallet1a = WalletIntegrityHelper.create_multisig_wallet(
            keystore.from_seed(
                'bitter grass shiver impose acquire brush forget axis eager alone wine silver',
                '', True),
            keystore.from_xpub(
                'Vpub5fcdcgEwTJmbmqAktuK8Kyq92fMf7sWkcP6oqAii2tG47dNbfkGEGUbfS9NuZaRywLkHE6EmUksrqo32ZL3ouLN1HTar6oRiHpDzKMAF1tf'
            ),
            keystore.from_xpub(
                'Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra'
            ),
            gap_limit=2)
        wallet1b = WalletIntegrityHelper.create_multisig_wallet(
            keystore.from_seed(
                'snow nest raise royal more walk demise rotate smooth spirit canyon gun',
                '', True),
            keystore.from_xpub(
                'Vpub5fjkKyYnvSS4wBuakWTkNvZDaBM2vQ1MeXWq368VJHNr2eT8efqhpmZ6UUkb7s2dwCXv2Vuggjdhk4vZVyiAQTwUftvff73XcUGq2NQmWra'
            ),
            keystore.from_xpub(
                'Vpub5gSKXzxK7FeKQedu2q1z9oJWxqvX72AArW3HSWpEhc8othDH8xMDu28gr7gf17sp492BuJod8Tn7anjvJrKpETwqnQqX7CS8fcYyUtedEMk'
            ),
            gap_limit=2)
        # ^ third seed: hedgehog sunset update estate number jungle amount piano friend donate upper wool
        wallet2a = WalletIntegrityHelper.create_multisig_wallet(
            # bip39: finish seminar arrange erosion sunny coil insane together pretty lunch lunch rose, der: m/1234'/1'/0', p2wsh-p2sh multisig
            keystore.from_xprv(
                'Uprv9CvELvByqm8k2dpecJVjgLMX1z5DufEjY4fBC5YvdGF5WjGCa7GVJJ2fYni1tyuF7Hw83E6W2ZBjAhaFLZv2ri3rEsubkCd5avg4EHKoDBN'
            ),
            keystore.from_xpub(
                'Upub5Qb8ik4Cnu8g97KLXKgVXHqY6tH8emQvqtBncjSKsyfTZuorPtTZgX7ovKKZHuuVGBVd1MTTBkWez1XXt2weN1sWBz6SfgRPQYEkNgz81QF'
            ),
            gap_limit=2)
        wallet2b = WalletIntegrityHelper.create_multisig_wallet(
            # bip39: square page wood spy oil story rebel give milk screen slide shuffle, der: m/1234'/1'/0', p2wsh-p2sh multisig
            keystore.from_xprv(
                'Uprv9BbnKEXJxXaNvdEsRJ9VA9toYrSeFJh5UfGBpM2iKe8Uh7UhrM9K8ioL53s8gvCoGfirHHaqpABDAE7VUNw8LNU1DMJKVoWyeNKu9XcDC19'
            ),
            keystore.from_xpub(
                'Upub5RuakRisg8h3F7u7iL2k3UJFa1uiK7xauHamzTxYBbn4PXbM7eajr6M9Q2VCr6cVGhfhqWQqxnABvtSATuVM1xzxk4nA189jJwzaMn1QX7V'
            ),
            gap_limit=2)

        # bootstrap wallet1
        funding_tx = Transaction(
            '01000000000101a41aae475d026c9255200082c7fad26dc47771275b0afba238dccda98a597bd20000000000fdffffff02400d0300000000002200203c43ac80d6e3015cf378bf6bac0c22456723d6050bef324ec641e7762440c63c9dcd410000000000160014824626055515f3ed1d2cfc9152d2e70685c71e8f02483045022100b9f39fad57d07ce1e18251424034f21f10f20e59931041b5167ae343ce973cf602200fefb727fa0ffd25b353f1bcdae2395898fe407b692c62f5885afbf52fa06f5701210301a28f68511ace43114b674371257bb599fd2c686c4b19544870b1799c954b40e9c11300'
        )
        funding_txid = funding_tx.txid()
        funding_output_value = 200000
        self.assertEqual(
            'd2bd6c9d332db8e2c50aa521cd50f963fba214645aab2f7556e061a412103e21',
            funding_txid)
        wallet1a.receive_tx_callback(funding_txid, funding_tx,
                                     TX_HEIGHT_UNCONFIRMED)

        # wallet1 -> wallet2
        outputs = [(bitcoin.TYPE_ADDRESS, wallet2a.get_receiving_address(),
                    165000)]
        tx = wallet1a.mktx(outputs=outputs,
                           password=None,
                           config=self.config,
                           fee=5000)
        tx = Transaction(
            tx.serialize())  # simulates moving partial txn between cosigners
        self.assertFalse(tx.is_complete())
        wallet1b.sign_transaction(tx, password=None)

        self.assertTrue(tx.is_complete())
        self.assertTrue(tx.is_segwit())
        self.assertEqual(1, len(tx.inputs()))
        tx_copy = Transaction(tx.serialize())
        self.assertEqual(wallet1a.is_mine(tx.inputs()[0]['address']),
                         wallet1a.is_mine(tx_copy.inputs()[0]['address']))
        self.assertTrue(wallet1a.is_mine(tx.inputs()[0]['address']))
        self.assertEqual(wallet1a.txin_type, tx_copy.inputs()[0]['type'])
        self.assertEqual(tx.wtxid(), tx_copy.wtxid())
        self.assertEqual(
            '6e9c3cd8788bdb970a124ea06136d52bc01cec4f9b1e217627d5e90ebe77d049',
            tx_copy.txid())

        wallet1a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
        wallet2a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)

        # wallet2 -> wallet1
        outputs = [(bitcoin.TYPE_ADDRESS, wallet1a.get_receiving_address(),
                    100000)]
        tx = wallet2a.mktx(outputs=outputs,
                           password=None,
                           config=self.config,
                           fee=5000)
        tx = Transaction(
            tx.serialize())  # simulates moving partial txn between cosigners
        self.assertFalse(tx.is_complete())
        wallet2b.sign_transaction(tx, password=None)

        self.assertTrue(tx.is_complete())
        self.assertTrue(tx.is_segwit())
        self.assertEqual(1, len(tx.inputs()))
        tx_copy = Transaction(tx.serialize())
        self.assertEqual(wallet2a.is_mine(tx.inputs()[0]['address']),
                         wallet2a.is_mine(tx_copy.inputs()[0]['address']))
        self.assertTrue(wallet2a.is_mine(tx.inputs()[0]['address']))
        self.assertEqual(wallet2a.txin_type, tx_copy.inputs()[0]['type'])
        self.assertEqual(tx.wtxid(), tx_copy.wtxid())
        self.assertEqual(
            '84b0dcb43022385f7a10e2710e5625a2be3cd6e390387b6100b55500d5eea8f6',
            tx_copy.txid())

        wallet1a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)
        wallet2a.receive_tx_callback(tx.txid(), tx, TX_HEIGHT_UNCONFIRMED)

        # wallet level checks
        self.assertEqual((0, funding_output_value - 165000 - 5000 + 100000, 0),
                         wallet1a.get_balance())
        self.assertEqual((0, 165000 - 5000 - 100000, 0),
                         wallet2a.get_balance())
예제 #30
0
 def test_has_date_formatted(self):
     with freeze_time("2020-01-01"):
         transaction = Transaction()
         result = "01/01/2020 || || || "
         assert transaction.display() == result