コード例 #1
0
    def test_version_bytes(self):
        xprv_headers_b58 = {
            'standard':    'tprv',
        }
        xpub_headers_b58 = {
            'standard':    'tpub',
        }
        for xtype, xkey_header_bytes in constants.net.XPRV_HEADERS.items():
            xkey_header_bytes = bfh("%08x" % xkey_header_bytes)
            xkey_bytes = xkey_header_bytes + bytes([0] * 74)
            xkey_b58 = EncodeBase58Check(xkey_bytes)
            self.assertTrue(xkey_b58.startswith(xprv_headers_b58[xtype]))

            xkey_bytes = xkey_header_bytes + bytes([255] * 74)
            xkey_b58 = EncodeBase58Check(xkey_bytes)
            self.assertTrue(xkey_b58.startswith(xprv_headers_b58[xtype]))

        for xtype, xkey_header_bytes in constants.net.XPUB_HEADERS.items():
            xkey_header_bytes = bfh("%08x" % xkey_header_bytes)
            xkey_bytes = xkey_header_bytes + bytes([0] * 74)
            xkey_b58 = EncodeBase58Check(xkey_bytes)
            self.assertTrue(xkey_b58.startswith(xpub_headers_b58[xtype]))

            xkey_bytes = xkey_header_bytes + bytes([255] * 74)
            xkey_b58 = EncodeBase58Check(xkey_bytes)
            self.assertTrue(xkey_b58.startswith(xpub_headers_b58[xtype]))
コード例 #2
0
 def parse_script(self, x):
     script = ''
     for word in x.split():
         if word[0:3] == 'OP_':
             opcode_int = opcodes[word]
             assert opcode_int < 256  # opcode is single-byte
             script += bitcoin.int_to_hex(opcode_int)
         else:
             bfh(word)  # to test it is hex data
             script += push_script(word)
     return script
コード例 #3
0
    def test_verify(self):
        announce = MasternodeAnnounce.deserialize(raw_announce)
        message = announce.serialize_for_sig()

        pk = bitcoin.public_key_to_p2pkh(bfh(announce.collateral_key))
        self.assertTrue(announce.verify())

        raw = '7ca6564432d0e0920b811887e1f9077a92924c83564e6ea8ea874fc8843ccd2b0000000000ffffffff00000000000000000000ffffc0a801014e1f410411e2638aeb4584ff2e027b6ee20e05655ff05583185b1d87188185d6955534fe02ad35caabb5e6e9ce8747ba73fdccccd2369feb9a6f2b0bdee93378e7c8f1c0410411e2638aeb4584ff2e027b6ee20e05655ff05583185b1d87188185d6955534fe02ad35caabb5e6e9ce8747ba73fdccccd2369feb9a6f2b0bdee93378e7c8f1c0411bab132617d8e6a0e3b5434c91a5a64ff13a9cfadc6c178a47b87691f13a26e7440c08660e488ddf927bba1bf04c1ec196370452a30fd3381ea8ba27d627f9d4468be80e5700000000d71101007ca6564432d0e0920b811887e1f9077a92924c83564e6ea8ea874fc8843ccd2b0000000000ffffffffd75eb4fa0cb71dd2e99d7b242784a5601c5c86d7c1cf0362a3391575070000008be80e5700000000411b6d5985008e0821c936fafc192f31963141ae2fab837e84bb9f12422711c1952d5750f9a781c89117a6f4576edc1149a1bf211e7151c5c88cf3252e2d83cb154a0000000000000000'
        announce = MasternodeAnnounce.deserialize(raw)
        msg = announce.serialize_for_sig()

        pk = bitcoin.public_key_to_p2pkh(bfh(announce.collateral_key))
        self.assertTrue(announce.verify(pk))
コード例 #4
0
    def test_create_and_sign(self):
        collateral_pub = '038ae57bd0fa5b45640e771614ec571c7326a2266c78bb444f1971c85188411ba1'  # 1Feczj12KEioQTrXhd4zUUdmijxzwXfdcE
        delegate_pub = '02526201c87c1b4630aabbd04572eec3e2545e442503e57e60880fafcc1f684dbc'  # 1NLwcP3gVQPZHUdjKVrU9J4v4jRSYsB4Dj
        protocol_version = 70103

        ip = '0.0.0.0'
        port = 20000
        addr = NetworkAddress(ip=ip, port=port)

        vin = {
            'prevout_hash': '00' * 32,
            'prevout_n': 0,
            'scriptSig': '',
            'sequence': 0xffffffff
        }

        last_ping = MasternodePing(vin=vin, block_hash='ff' * 32)

        announce = MasternodeAnnounce(vin=vin,
                                      addr=addr,
                                      collateral_key=collateral_pub,
                                      delegate_key=delegate_pub,
                                      protocol_version=protocol_version,
                                      last_ping=last_ping)

        collateral_wif = '5K4hm916sRw93k9eoSf4XfHvUmi4ZyEpfMMT7yprvWPhTCc7wcJ'
        delegate_wif = '5HsgYSCySd34BySFqo1CDaYHJVdHy1yqBXk3dGy9ABB3B4Pos3T'
        announce.last_ping.sign(delegate_wif, bfh(delegate_pub), 1461858375)
        sig = announce.sign(collateral_wif, 1461858375)

        address = '1Feczj12KEioQTrXhd4zUUdmijxzwXfdcE'
        self.assertTrue(announce.verify(address))
        self.assertTrue(
            ecc.verify_message_with_address(address, sig,
                                            announce.serialize_for_sig()))
コード例 #5
0
    def do_send(self, tx):
        def on_success(result):
            window.show_message(
                _("Your transaction was sent to the cosigning pool.") + '\n' +
                _("Open your cosigner wallet to retrieve it."))

        def on_failure(exc_info):
            e = exc_info[1]
            try:
                self.logger.error("on_failure", exc_info=exc_info)
            except OSError:
                pass
            window.show_error(
                _("Failed to send transaction to cosigning pool") + ':\n' +
                str(e))

        for window, xpub, K, _hash in self.cosigner_list:
            if not self.cosigner_can_sign(tx, xpub):
                continue
            # construct message
            raw_tx_bytes = bfh(str(tx))
            public_key = ecc.ECPubkey(K)
            message = public_key.encrypt_message(raw_tx_bytes).decode('ascii')
            # send message
            task = lambda: server.put(_hash, message)
            msg = _('Sending transaction to cosigning pool...')
            WaitingDialog(window, msg, task, on_success, on_failure)
コード例 #6
0
ファイル: revealer.py プロジェクト: terracoin/electrum-trc
 def get_noise_map(cls, versioned_seed: VersionedSeed) -> Dict[Tuple[int, int], int]:
     """Returns a map from (x,y) coordinate to pixel value 0/1, to be used as rawnoise."""
     w, h = cls.SIZE
     version  = versioned_seed.version
     hex_seed = versioned_seed.seed
     checksum = versioned_seed.checksum
     noise_map = {}
     if version == '0':
         random.seed(int(hex_seed, 16))
         for x in range(w):
             for y in range(h):
                 noise_map[(x, y)] = random.randint(0, 1)
     elif version == '1':
         prng_seed = bfh(hex_seed + version + checksum)
         drbg = DRBG(prng_seed)
         num_noise_bytes = 1929  # ~ w*h
         noise_array = bin(int.from_bytes(drbg.generate(num_noise_bytes), 'big'))[2:]
         # there's an approx 1/1024 chance that the generated number is 'too small'
         # and we would get IndexError below. easiest backwards compat fix:
         noise_array += '0' * (w * h - len(noise_array))
         i = 0
         for x in range(w):
             for y in range(h):
                 noise_map[(x, y)] = int(noise_array[i])
                 i += 1
     else:
         raise Exception(f"unexpected revealer version: {version}")
     return noise_map
コード例 #7
0
 def test_base43(self):
     tx_hex = "020000000001021cd0e96f9ca202e017ca3465e3c13373c0df3a4cdd91c1fd02ea42a1a65d2a410000000000fdffffff757da7cf8322e5063785e2d8ada74702d2648fa2add2d533ba83c52eb110df690200000000fdffffff02d07e010000000000160014b544c86eaf95e3bb3b6d2cabb12ab40fc59cad9ca086010000000000232102ce0d066fbfcf150a5a1bbc4f312cd2eb080e8d8a47e5f2ce1a63b23215e54fb5ac02483045022100a9856bf10a950810abceeabc9a86e6ba533e130686e3d7863971b9377e7c658a0220288a69ef2b958a7c2ecfa376841d4a13817ed24fa9a0e0a6b9cb48e6439794c701210324e291735f83ff8de47301b12034950b80fa4724926a34d67e413d8ff8817c53024830450221008f885978f7af746679200ed55fe2e86c1303620824721f95cc41eb7965a3dfcf02207872082ac4a3c433d41a203e6d685a459e70e551904904711626ac899238c20a0121023d4c9deae1aacf3f822dd97a28deaec7d4e4ff97be746d124a63d20e582f5b290a971600"
     tx_bytes = bfh(tx_hex)
     tx_base43 = base_encode(tx_bytes, 43)
     self.assertEqual("3E2DH7.J3PKVZJ3RCOXQVS3Y./6-WE.75DDU0K58-0N1FRL565N8ZH-DG1Z.1IGWTE5HK8F7PWH5P8+V3XGZZ6GQBPHNDE+RD8CAQVV1/6PQEMJIZTGPMIJ93B8P$QX+Y2R:TGT9QW8S89U4N2.+FUT8VG+34USI/N/JJ3CE*KLSW:REE8T5Y*9:U6515JIUR$6TODLYHSDE3B5DAF:5TF7V*VAL3G40WBOM0DO2+CFKTTM$G-SO:8U0EW:M8V:4*R9ZDX$B1IRBP9PLMDK8H801PNTFB4$HL1+/U3F61P$4N:UAO88:N5D+J:HI4YR8IM:3A7K1YZ9VMRC/47$6GGW5JEL1N690TDQ4XW+TWHD:V.1.630QK*JN/.EITVU80YS3.8LWKO:2STLWZAVHUXFHQ..NZ0:.J/FTZM.KYDXIE1VBY7/:PHZMQ$.JZQ2.XT32440X/HM+UY/7QP4I+HTD9.DUSY-8R6HDR-B8/PF2NP7I2-MRW9VPW3U9.S0LQ.*221F8KVMD5ANJXZJ8WV4UFZ4R.$-NXVE+-FAL:WFERGU+WHJTHAP",
                      tx_base43)
     self.assertEqual(tx_bytes,
                      base_decode(tx_base43, None, 43))
コード例 #8
0
 def test_base58(self):
     data_hex = '0cd394bef396200774544c58a5be0189f3ceb6a41c8da023b099ce547dd4d8071ed6ed647259fba8c26382edbf5165dfd2404e7a8885d88437db16947a116e451a5d1325e3fd075f9d370120d2ab537af69f32e74fc0ba53aaaa637752964b3ac95cfea7'
     data_bytes = bfh(data_hex)
     data_base58 = base_encode(data_bytes, 58)
     self.assertEqual("VuvZ2K5UEcXCVcogny7NH4Evd9UfeYipsTdWuU4jLDhyaESijKtrGWZTFzVZJPjaoC9jFBs3SFtarhDhQhAxkXosUD8PmUb5UXW1tafcoPiCp8jHy7Fe2CUPXAbYuMvAyrkocbe6",
                      data_base58)
     self.assertEqual(data_bytes,
                      base_decode(data_base58, None, 58))
コード例 #9
0
 def test_base58check(self):
     data_hex = '0cd394bef396200774544c58a5be0189f3ceb6a41c8da023b099ce547dd4d8071ed6ed647259fba8c26382edbf5165dfd2404e7a8885d88437db16947a116e451a5d1325e3fd075f9d370120d2ab537af69f32e74fc0ba53aaaa637752964b3ac95cfea7'
     data_bytes = bfh(data_hex)
     data_base58check = EncodeBase58Check(data_bytes)
     self.assertEqual("4GCCJsjHqFbHxWbFBvRg35cSeNLHKeNqkXqFHW87zRmz6iP1dJU9Tk2KHZkoKj45jzVsSV4ZbQ8GpPwko6V3Z7cRfux3zJhUw7TZB6Kpa8Vdya8cMuUtL5Ry3CLtMetaY42u52X7Ey6MAH",
                      data_base58check)
     self.assertEqual(data_bytes,
                      DecodeBase58Check(data_base58check))
コード例 #10
0
    def test_serialize_protocol_version_70210(self):
        announce = MasternodeAnnounce.deserialize(raw_announce_70210)
        msg = announce.serialize_for_sig()
        expected = to_bytes(''.join([
            '178.151.192.107:19999',
            '1530021571',
            bitcoin.hash_encode(
                bitcoin.hash_160(
                    bfh('0221088c51bef8c9c891b385fa1e8a78b016f01db41741aea7e43e67a7415ab7be'
                        ))),
            bitcoin.hash_encode(
                bitcoin.hash_160(
                    bfh('042379a871a10ae6bf06e756262f69d7f0ce9b8b562f223bde964db573fb7d0f1e219c246a4b3a6133c5cec136d83f4049df51321ba2cb01d676cc3982c7e24d1f'
                        ))),
            '70210',
        ]))
        print('7' * 50, expected)
        print('8' * 50, msg)

        self.assertEqual(expected, msg)
コード例 #11
0
    def deserialize_with_auxpow(data_hex: str, **kwargs):
        """Deserializes a block header given as hex string
        This makes sure that the data is always deserialised as full
        block header with AuxPoW.
        The keyword-arguments expect_trailing_data and start_position can be
        set and will be passed on to deserialize_full_header."""

        # We pass a height beyond the last checkpoint, because
        # deserialize_full_header expects checkpointed headers to be truncated
        # by ElectrumX (i.e. not contain an AuxPoW).
        return blockchain.deserialize_full_header(bfh(data_hex), constants.net.max_checkpoint() + 1, **kwargs)
コード例 #12
0
 def show_qr(self):
     text = bfh(str(self.tx))
     text = base_encode(text, base=43)
     try:
         self.main_window.show_qrcode(text, 'Transaction', parent=self)
     except qrcode.exceptions.DataOverflowError:
         self.show_error(
             _('Failed to display QR code.') + '\n' +
             _('Transaction is too large in size.'))
     except Exception as e:
         self.show_error(_('Failed to display QR code.') + '\n' + str(e))
コード例 #13
0
ファイル: trezor.py プロジェクト: terracoin/electrum-trc
    def tx_inputs(self, tx, xpub_path, for_sig=False):
        inputs = []
        for txin in tx.inputs():
            txinputtype = TxInputType()
            if txin['type'] == 'coinbase':
                prev_hash = b"\x00" * 32
                prev_index = 0xffffffff  # signed int -1
            else:
                if for_sig:
                    x_pubkeys = txin['x_pubkeys']
                    xpubs = [parse_xpubkey(x) for x in x_pubkeys]
                    multisig = self._make_multisig(txin.get('num_sig'), xpubs,
                                                   txin.get('signatures'))
                    script_type = self.get_trezor_input_script_type(
                        txin['type'])
                    txinputtype = TxInputType(script_type=script_type,
                                              multisig=multisig)
                    # find which key is mine
                    for xpub, deriv in xpubs:
                        if xpub in xpub_path:
                            xpub_n = parse_path(xpub_path[xpub])
                            txinputtype.address_n = xpub_n + deriv
                            break

                prev_hash = bfh(txin['prevout_hash'])
                prev_index = txin['prevout_n']

            if 'value' in txin:
                txinputtype.amount = txin['value']
            txinputtype.prev_hash = prev_hash
            txinputtype.prev_index = prev_index

            if txin.get('scriptSig') is not None:
                script_sig = bfh(txin['scriptSig'])
                txinputtype.script_sig = script_sig

            txinputtype.sequence = txin.get('sequence', 0xffffffff - 1)

            inputs.append(txinputtype)

        return inputs
コード例 #14
0
    def test_serialize_protocol_version_70201(self):
        raw = '08108933d948aed6a107cd01e7862ed61ef9bf14e87da0a14e8d17791e9f9c570100000000ffffffff00000000000000000000ffff7f0000014e1f210269e1abb1ffe231ea045068272a06f0fae231d11b11a54225867d89267faa4e23210269e1abb1ffe231ea045068272a06f0fae231d11b11a54225867d89267faa4e234120b8bc547ce2471125eddfdfd5af30ea1e892e750acfe2896b241097b7f21442a61da073d47c885535769bf215eb3e97eca692d868db1bfb9dee469a1ece5acb92a1945457000000003912010008108933d948aed6a107cd01e7862ed61ef9bf14e87da0a14e8d17791e9f9c570100000000ffffffffefc894d8431c1774a19aeb732ea7fc56925b740ed80486f30424109a05000000a1945457000000004120818f17742e6644359c8b9a91e56b595615bd2c593de713304435dcfd07ceb6a815559fd3b2f05f531d9b9918b22b8748491c3f36cb25e8397ff950f74030444f0000000000000000'
        announce = MasternodeAnnounce.deserialize(raw)
        announce.sig_time = 1465161129
        msg = announce.serialize_for_sig()
        expected = to_bytes(''.join([
            '127.0.0.1:19999',
            '1465161129',
            bitcoin.hash_encode(
                bitcoin.hash_160(
                    bfh('0269e1abb1ffe231ea045068272a06f0fae231d11b11a54225867d89267faa4e23'
                        ))),
            bitcoin.hash_encode(
                bitcoin.hash_160(
                    bfh('0269e1abb1ffe231ea045068272a06f0fae231d11b11a54225867d89267faa4e23'
                        ))),
            '70201',
        ]))
        print('7' * 50, expected)
        print('8' * 50, msg)

        self.assertEqual(expected, msg)
コード例 #15
0
    def test_sign_transaction(self):
        eckey1 = ecc.ECPrivkey(bfh('7e1255fddb52db1729fc3ceb21a46f95b8d9fe94cc83425e936a6c5223bb679d'))
        sig1 = eckey1.sign_transaction(bfh('5a548b12369a53faaa7e51b5081829474ebdd9c924b3a8230b69aa0be254cd94'))
        self.assertEqual(bfh('3045022100902a288b98392254cd23c0e9a49ac6d7920f171b8249a48e484b998f1874a2010220723d844826828f092cf400cb210c4fa0b8cd1b9d1a7f21590e78e022ff6476b9'), sig1)

        eckey2 = ecc.ECPrivkey(bfh('c7ce8c1462c311eec24dff9e2532ac6241e50ae57e7d1833af21942136972f23'))
        sig2 = eckey2.sign_transaction(bfh('642a2e66332f507c92bda910158dfe46fc10afbf72218764899d3af99a043fac'))
        self.assertEqual(bfh('30440220618513f4cfc87dde798ce5febae7634c23e7b9254a1eabf486be820f6a7c2c4702204fef459393a2b931f949e63ced06888f35e286e446dc46feb24b5b5f81c6ed52'), sig2)
コード例 #16
0
    def _do_test_bip32(self, seed: str, sequence):
        node = BIP32Node.from_rootseed(bfh(seed), xtype='standard')
        xprv, xpub = node.to_xprv(), node.to_xpub()
        self.assertEqual("m/", sequence[0:2])
        sequence = sequence[2:]
        for n in sequence.split('/'):
            if n[-1] != "'":
                xpub2 = BIP32Node.from_xkey(xpub).subkey_at_public_derivation(n).to_xpub()
            node = BIP32Node.from_xkey(xprv).subkey_at_private_derivation(n)
            xprv, xpub = node.to_xprv(), node.to_xpub()
            if n[-1] != "'":
                self.assertEqual(xpub, xpub2)

        return xpub, xprv
コード例 #17
0
 def electrum_tx_to_txtype(self, tx):
     t = self.types.TransactionType()
     if tx is None:
         # probably for segwit input and we don't need this prev txn
         return t
     d = deserialize(tx.raw)
     t.version = d['version']
     t.lock_time = d['lockTime']
     inputs = self.tx_inputs(tx)
     t.inputs.extend(inputs)
     for vout in d['outputs']:
         o = t.bin_outputs.add()
         o.amount = vout['value']
         o.script_pubkey = bfh(vout['scriptPubKey'])
     return t
コード例 #18
0
ファイル: trezor.py プロジェクト: terracoin/electrum-trc
    def _make_multisig(self, m, xpubs, signatures=None):
        if len(xpubs) == 1:
            return None

        pubkeys = [self._make_node_path(xpub, deriv) for xpub, deriv in xpubs]
        if signatures is None:
            signatures = [b''] * len(pubkeys)
        elif len(signatures) != len(pubkeys):
            raise RuntimeError('Mismatched number of signatures')
        else:
            signatures = [bfh(x)[:-1] if x else b'' for x in signatures]

        return MultisigRedeemScriptType(pubkeys=pubkeys,
                                        signatures=signatures,
                                        m=m)
コード例 #19
0
ファイル: trezor.py プロジェクト: terracoin/electrum-trc
 def electrum_tx_to_txtype(self, tx, xpub_path):
     t = TransactionType()
     if tx is None:
         # probably for segwit input and we don't need this prev txn
         return t
     d = deserialize(tx.raw)
     t.version = d['version']
     t.lock_time = d['lockTime']
     t.inputs = self.tx_inputs(tx, xpub_path)
     t.bin_outputs = [
         TxOutputBinType(amount=vout['value'],
                         script_pubkey=bfh(vout['scriptPubKey']))
         for vout in d['outputs']
     ]
     return t
コード例 #20
0
ファイル: trezor.py プロジェクト: terracoin/electrum-trc
 def sign_transaction(self, keystore, tx, prev_tx, xpub_path):
     prev_tx = {
         bfh(txhash): self.electrum_tx_to_txtype(tx, xpub_path)
         for txhash, tx in prev_tx.items()
     }
     client = self.get_client(keystore)
     inputs = self.tx_inputs(tx, xpub_path, True)
     outputs = self.tx_outputs(keystore.get_derivation(), tx)
     details = SignTx(lock_time=tx.locktime, version=tx.version)
     signatures, _ = client.sign_tx(self.get_coin_name(),
                                    inputs,
                                    outputs,
                                    details=details,
                                    prev_txes=prev_tx)
     signatures = [(bh2u(x) + '01') for x in signatures]
     tx.update_signatures(signatures)
コード例 #21
0
    def test_deserialize_auxpow_header_explicit_coinbase(self):
        header = self.deserialize_with_auxpow(header_850964)
        header_auxpow = header['auxpow']

        self.assertEqual(constants.net.AUXPOW_CHAIN_ID, header_auxpow['chain_id'])

        coinbase_tx = header_auxpow['parent_coinbase_tx']
        expected_coinbase_txid = '0d1a8b9f539f19058b85dd209b1c210ec3811275aff414ce318efd5a05f23215'
        observed_coinbase_txid = auxpow.fast_txid(coinbase_tx)

        self.assertEqual(expected_coinbase_txid, observed_coinbase_txid)

        coinbase_merkle_branch = header_auxpow['coinbase_merkle_branch']
        self.assertEqual(9, len(coinbase_merkle_branch))
        self.assertEqual('5cc9569a1f63c3377d5fec1dcbe6cb0e42ee6d52c41790129a5f521357aef3ed', coinbase_merkle_branch[0])
        self.assertEqual('cc723704b83296a3a2304ce9c216b15a22cc5a4e5ddfae390c903676dbbae86d', coinbase_merkle_branch[1])
        self.assertEqual('78016c3cfafeb7dc2b3379241caf8d42e24dc8fad683d612a10ecb4a59f7b94e', coinbase_merkle_branch[2])
        self.assertEqual('43b6fc40f8c4a422906aa6c7fe194fb066e1d7575442402f37bcce323c5e8c4e', coinbase_merkle_branch[3])
        self.assertEqual('087919fbe8714bb8ea1a9301e6bb836e0c21cf28083902c393f59d4b2f6d9d77', coinbase_merkle_branch[4])
        self.assertEqual('afe45d89727290e4a3fb76e8b34ddf89f5e49544c65d0fd1c9bbd668d9d05d9e', coinbase_merkle_branch[5])
        self.assertEqual('2aa63a2009059bd296b0713a1680c0ed40c34bcfd046475a5da7922727ee14ec', coinbase_merkle_branch[6])
        self.assertEqual('4f031ba6c7ee9e1ded1c7c2dc5ab0bb82d239aa495e5fde55c047f09c74be901', coinbase_merkle_branch[7])
        self.assertEqual('771d47c939963f4bae3c160bfc09219f6797bb26cc66039a8798ac9e277dff2f', coinbase_merkle_branch[8])

        coinbase_merkle_index = header_auxpow['coinbase_merkle_index']
        self.assertEqual(0, coinbase_merkle_index)

        chain_merkle_branch = header_auxpow['chain_merkle_branch']
        self.assertEqual(5, len(chain_merkle_branch))
        self.assertEqual('0000000000000000000000000000000000000000000000000000000000000000', chain_merkle_branch[0])
        self.assertEqual('b886cb7e4fe65c18026bbaea7e31dfc14168b54d2b83d40bff0a240b4bcccbc1', chain_merkle_branch[1])
        self.assertEqual('58acadf5f991005ecbe697139e2ad1bc8077a3534b68604ae3a68b779908e519', chain_merkle_branch[2])
        self.assertEqual('304123c8d4cbdec14e3d16e970e8b14c87c23481fcbcff54e3ea518068960ad0', chain_merkle_branch[3])
        self.assertEqual('3ed39d3d7591968f58a6568fc7a4949aa4ca52b25b695601ea912a7290b3afb3', chain_merkle_branch[4])

        chain_merkle_index = header_auxpow['chain_merkle_index']
        self.assertEqual(8, chain_merkle_index)

        expected_parent_hash = '0000000000000074a836a521b2817a65e8a4df2dfe2c2418beb895e9cc2aa5ce'
        observed_parent_hash = blockchain.hash_header(header_auxpow['parent_header'])
        self.assertEqual(expected_parent_hash, observed_parent_hash)

        expected_parent_header = blockchain.deserialize_pure_header(bfh('00000020d4b83d5e8e6aa350094371d005275044c7789c4830b7f90200000000000000005bf56206df79280717d5d01a8f996708e55661cd960bf21875f5069a3b53ecf71fc20758c440041846f4511a'), None)
        expected_parent_merkle_root = expected_parent_header['merkle_root']
        observed_parent_merkle_root = header_auxpow['parent_header']['merkle_root']
        self.assertEqual(expected_parent_merkle_root, observed_parent_merkle_root)
コード例 #22
0
    def clear_coinbase_outputs(auxpow_header: dict, fix_merkle_root=True) -> None:
        """Clears the auxpow coinbase outputs
        Set the outputs of the auxpow coinbase to an empty list.  This is
        necessary when the coinbase has been modified and needs to be
        re-serialised, since present outputs are invalid due to the
        fast_tx_deserialize optimisation."""

        auxpow_header['parent_coinbase_tx']._outputs = []

        # Clear the cached raw serialization
        auxpow_header['parent_coinbase_tx'].raw = None
        auxpow_header['parent_coinbase_tx'].raw_bytes = None

        # Re-serialize.  Note that our AuxPoW library won't do this for us,
        # because it optimizes via fast_txid.
        auxpow_header['parent_coinbase_tx'].raw_bytes = bfh(auxpow_header['parent_coinbase_tx'].serialize_to_network())

        # Correct the coinbase Merkle root.
        if fix_merkle_root:
            update_merkle_root_to_match_coinbase(auxpow_header)
コード例 #23
0
    def tx_inputs(self, tx, for_sig=False):
        inputs = []
        for txin in tx.inputs():
            txinputtype = self.types.TxInputType()
            if txin['type'] == 'coinbase':
                prev_hash = b"\x00" * 32
                prev_index = 0xffffffff  # signed int -1
            else:
                if for_sig:
                    x_pubkeys = txin['x_pubkeys']
                    if len(x_pubkeys) == 1:
                        x_pubkey = x_pubkeys[0]
                        xpub, s = parse_xpubkey(x_pubkey)
                        xpub_n = self.client_class.expand_path(
                            self.xpub_path[xpub])
                        txinputtype.address_n.extend(xpub_n + s)
                        txinputtype.script_type = self.get_keepkey_input_script_type(
                            txin['type'])
                    else:

                        def f(x_pubkey):
                            xpub, s = parse_xpubkey(x_pubkey)
                            return self._make_node_path(xpub, s)

                        pubkeys = list(map(f, x_pubkeys))
                        multisig = self.types.MultisigRedeemScriptType(
                            pubkeys=pubkeys,
                            signatures=map(lambda x: bfh(x)[:-1] if x else b'',
                                           txin.get('signatures')),
                            m=txin.get('num_sig'),
                        )
                        script_type = self.get_keepkey_input_script_type(
                            txin['type'])
                        txinputtype = self.types.TxInputType(
                            script_type=script_type, multisig=multisig)
                        # find which key is mine
                        for x_pubkey in x_pubkeys:
                            if is_xpubkey(x_pubkey):
                                xpub, s = parse_xpubkey(x_pubkey)
                                if xpub in self.xpub_path:
                                    xpub_n = self.client_class.expand_path(
                                        self.xpub_path[xpub])
                                    txinputtype.address_n.extend(xpub_n + s)
                                    break

                prev_hash = unhexlify(txin['prevout_hash'])
                prev_index = txin['prevout_n']

            if 'value' in txin:
                txinputtype.amount = txin['value']
            txinputtype.prev_hash = prev_hash
            txinputtype.prev_index = prev_index

            if txin.get('scriptSig') is not None:
                script_sig = bfh(txin['scriptSig'])
                txinputtype.script_sig = script_sig

            txinputtype.sequence = txin.get('sequence', 0xffffffff - 1)

            inputs.append(txinputtype)

        return inputs
コード例 #24
0
class TestBlockchain(SequentialTestCase):

    HEADERS = {
        'A':
        deserialize_pure_header(
            bfh("01000000000000000000000000000000000000000000000000000000000000000000000096f12836f9a4d8029fea2c89ad06be01a9aaa6f3c3160c5867b00338f9098b0fdae5494dffff7f2002000000"
                ), 0),
        'B':
        deserialize_pure_header(
            bfh("04010100d2a8d4eaa8ba68d79f1b92313b1f11ba539c3a540b1d84b9e669e1fce7a22454c5b3adce07063ce7a0c10586aaef7e57d9f1fcdbbd323b333beedfe5b1c3c7cd92153a5dffff7f2000000000"
                ), 1),
        'C':
        deserialize_pure_header(
            bfh("04010100aeb03bd6576cce945215f99080a311c26c93165d830de2a54fa58a18de533519c8160f84c8da831592362da0bfcb89d6da871b32fcd906e8198267ea9d5b526593153a5dffff7f2000000000"
                ), 2),
        'D':
        deserialize_pure_header(
            bfh("0401010084aa29cf0745a3c22c2f337934ea353dacbe9c703fd09a292fb326cf9f6312558a6c5acd18c144171edd3b3a9d2e7464a8922cb15647e70715220db6b8f0603293153a5dffff7f2000000000"
                ), 3),
        'E':
        deserialize_pure_header(
            bfh("040101005434ea5acbd422bdee0bc85f539c69e500754007238b43d16362fedfec4ce7ce3f83f1588acc9b419a4f5b3ea8f12500d30280cad34acad00cc0a7be030704fb94153a5dffff7f2000000000"
                ), 4),
        'F':
        deserialize_pure_header(
            bfh("04010100fea84de1e70b66f600cfc6662220fc1b619a77f89203c2c07f2ef33dc94ba1956ae4074f4c02a0aae2f758e2842938feb4898f9854867aacd451031bf374ec2594153a5dffff7f2000000000"
                ), 5),
        'O':
        deserialize_pure_header(
            bfh("04010100ff601cc5e3df8f0590a9be43e9e762a0416253bc665bb7867a18ecb890f94c79c4dc044802c1146f2960366c8d6de8455d7523cec2ac3d39e212f1565a8f8f1794153a5dffff7f2000000000"
                ), 6),
        'P':
        deserialize_pure_header(
            bfh("0401010046f5eee8a16352acfe929d27af9494f5738b408a4223016fb41d81a35d2cd3c75d0c56d1272b3efee929b2e4d764f37d9a12f4be9784017442e2fd13822e6534061b3a5dffff7f2000000000"
                ), 7),
        'Q':
        deserialize_pure_header(
            bfh("04010100f782fb7ef21769f2fa7e304ba9cf2d7b17537e6dee773fa48c895bf47efebbea58fc9903c96106191f932fa92b4a5a304c88f77783717f2650b5e867fd03f1b5061b3a5dffff7f2000000000"
                ), 8),
        'R':
        deserialize_pure_header(
            bfh("040101004c5d47a675e2a8af6261313494e83b7c7411222d72aa32ccbebc43ec5c74bde50445594bfe82354d4901f870dbf42ccdaf7438dcf5b88aab0bd8d814a515aaa9061b3a5dffff7f2000000000"
                ), 9),
        'S':
        deserialize_pure_header(
            bfh("040101005e0559e20e90ccd9def4fbfa36aa6762fdd43e05939cef17849a224a991e3f190b21359445699cf68d8269017e8fb577deca79ae774c6c481e33874b21d7f814061b3a5dffff7f2000000000"
                ), 10),
        'T':
        deserialize_pure_header(
            bfh("040101004b65a96d5833467f7b770c02bfbc592bc439471a9101e9fcb348e26fd10b65d4d80a86bdf598a2ecbbec1e9ba16f66fab619b2604e94e63c4489359d8b1a0c72061b3a5dffff7f2000000000"
                ), 11),
        'U':
        deserialize_pure_header(
            bfh("040101009d2857ea52e62b41159f183c3961f54b751c0e7b124e9c0abec315416cea91d27e63ce93d701645c2f79cd90b3fcee717276c6af40f0ec5d7ef1e589ba3eb4bb061b3a5dffff7f2000000000"
                ), 12),
        'G':
        deserialize_pure_header(
            bfh("04010100ff601cc5e3df8f0590a9be43e9e762a0416253bc665bb7867a18ecb890f94c79c4dc044802c1146f2960366c8d6de8455d7523cec2ac3d39e212f1565a8f8f1794153a5dffff7f2000000000"
                ), 6),
        'H':
        deserialize_pure_header(
            bfh("0401010046f5eee8a16352acfe929d27af9494f5738b408a4223016fb41d81a35d2cd3c73a82a080149e5f04dee31e89d491cdb732ca643dfb1dce355bdf628dc21e8c6494153a5dffff7f2000000000"
                ), 7),
        'I':
        deserialize_pure_header(
            bfh("04010100056e368100b10d9a715c7bdce7e31d1f8518d19b07a8aa6e6909569c5a80fec1842026f9d0a97e1d2d98da06b7f82c16cbbdf130d955bb807178986409caf3e095153a5dffff7f2000000000"
                ), 8),
        'J':
        deserialize_pure_header(
            bfh("040101002a8a5bb4242a400052282bc9bc961d353b14dc59ea56349019891784e5224f95fe81e90dc6964e6e8926ae398636793ee28d3e3245532bdf6127fcbd146c932795153a5dffff7f2000000000"
                ), 9),
        'K':
        deserialize_pure_header(
            bfh("0401010059c0544847fb33f0238b7a5eceed2ba19293c4b5c94276a273865e419c0fdcfb5679e53c102027584ed102ef69036e2862932a2fe2ccd6b79757666cb9d4e9c995153a5dffff7f2000000000"
                ), 10),
        'L':
        deserialize_pure_header(
            bfh("0401010016c08d913ef7054acef3a5cd346c848243234645df69efc7bfb90553e453c4ccc1e463e6c8c1afa8d270b45be45d1abeaac0d09ed21f0a95db606dc8a9856ba595153a5dffff7f2000000000"
                ), 11),
        'M':
        deserialize_pure_header(
            bfh("040101002a8a5bb4242a400052282bc9bc961d353b14dc59ea56349019891784e5224f95fe81e90dc6964e6e8926ae398636793ee28d3e3245532bdf6127fcbd146c932795153a5dffff7f2000000000"
                ), 9),
        'N':
        deserialize_pure_header(
            bfh("0401010059c0544847fb33f0238b7a5eceed2ba19293c4b5c94276a273865e419c0fdcfbe39f9848d61df25b2b277089ccf9eef837b8381cc5ed6749e18598da87e490d678183a5dffff7f2000000000"
                ), 10),
        'X':
        deserialize_pure_header(
            bfh("04010100f4444a20ddfab37b22dd0cb838128e437679606d20722d7c1e69bc9504445d558e891bfd831e2440ac56ce6c24b4ae1f333b46727bf513ebe125c5fa941a441d78183a5dffff7f2000000000"
                ), 11),
        'Y':
        deserialize_pure_header(
            bfh("040101008618f830e30249a314cc453d15a3a518592efc984389164af3ee504ca6de9c12bfd55d093954d7a8e56dd5b1aa60c5b53e4d4005bb7548bb5e98837d7850feac78183a5dffff7f2000000000"
                ), 12),
        'Z':
        deserialize_pure_header(
            bfh("04010100f2180d103da82c4c377b7ff2d90353f30bb14acf94de3fad271dcf5903d8ee6b066e7374b211cbe95f4f537e1e4816f55d15a410318ca8bd8542dbe540c73dd378183a5dffff7f2000000000"
                ), 13),
    }
    # tree of headers:
    #                                            - M <- N <- X <- Y <- Z
    #                                          /
    #                             - G <- H <- I <- J <- K <- L
    #                           /
    # A <- B <- C <- D <- E <- F <- O <- P <- Q <- R <- S <- T <- U

    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        constants.set_regtest()

    @classmethod
    def tearDownClass(cls):
        super().tearDownClass()
        constants.set_mainnet()

    def setUp(self):
        super().setUp()
        self.data_dir = tempfile.mkdtemp()
        make_dir(os.path.join(self.data_dir, 'forks'))
        self.config = SimpleConfig({'electrum_path': self.data_dir})
        blockchain.blockchains = {}

    def tearDown(self):
        super().tearDown()
        shutil.rmtree(self.data_dir)

    def _append_header(self, chain: Blockchain, header: dict):
        self.assertTrue(chain.can_connect(header))
        chain.save_header(header)

    def test_get_height_of_last_common_block_with_chain(self):
        blockchain.blockchains[constants.net.GENESIS] = chain_u = Blockchain(
            config=self.config,
            forkpoint=0,
            parent=None,
            forkpoint_hash=constants.net.GENESIS,
            prev_hash=None)
        open(chain_u.path(), 'w+').close()
        self._append_header(chain_u, self.HEADERS['A'])
        self._append_header(chain_u, self.HEADERS['B'])
        self._append_header(chain_u, self.HEADERS['C'])
        self._append_header(chain_u, self.HEADERS['D'])
        self._append_header(chain_u, self.HEADERS['E'])
        self._append_header(chain_u, self.HEADERS['F'])
        self._append_header(chain_u, self.HEADERS['O'])
        self._append_header(chain_u, self.HEADERS['P'])
        self._append_header(chain_u, self.HEADERS['Q'])

        chain_l = chain_u.fork(self.HEADERS['G'])
        self._append_header(chain_l, self.HEADERS['H'])
        self._append_header(chain_l, self.HEADERS['I'])
        self._append_header(chain_l, self.HEADERS['J'])
        self._append_header(chain_l, self.HEADERS['K'])
        self._append_header(chain_l, self.HEADERS['L'])

        self.assertEqual({
            chain_u: 8,
            chain_l: 5
        }, chain_u.get_parent_heights())
        self.assertEqual({chain_l: 11}, chain_l.get_parent_heights())

        chain_z = chain_l.fork(self.HEADERS['M'])
        self._append_header(chain_z, self.HEADERS['N'])
        self._append_header(chain_z, self.HEADERS['X'])
        self._append_header(chain_z, self.HEADERS['Y'])
        self._append_header(chain_z, self.HEADERS['Z'])

        self.assertEqual({
            chain_u: 8,
            chain_z: 5
        }, chain_u.get_parent_heights())
        self.assertEqual({
            chain_l: 11,
            chain_z: 8
        }, chain_l.get_parent_heights())
        self.assertEqual({chain_z: 13}, chain_z.get_parent_heights())
        self.assertEqual(
            5, chain_u.get_height_of_last_common_block_with_chain(chain_l))
        self.assertEqual(
            5, chain_l.get_height_of_last_common_block_with_chain(chain_u))
        self.assertEqual(
            5, chain_u.get_height_of_last_common_block_with_chain(chain_z))
        self.assertEqual(
            5, chain_z.get_height_of_last_common_block_with_chain(chain_u))
        self.assertEqual(
            8, chain_l.get_height_of_last_common_block_with_chain(chain_z))
        self.assertEqual(
            8, chain_z.get_height_of_last_common_block_with_chain(chain_l))

        self._append_header(chain_u, self.HEADERS['R'])
        self._append_header(chain_u, self.HEADERS['S'])
        self._append_header(chain_u, self.HEADERS['T'])
        self._append_header(chain_u, self.HEADERS['U'])

        self.assertEqual({
            chain_u: 12,
            chain_z: 5
        }, chain_u.get_parent_heights())
        self.assertEqual({
            chain_l: 11,
            chain_z: 8
        }, chain_l.get_parent_heights())
        self.assertEqual({chain_z: 13}, chain_z.get_parent_heights())
        self.assertEqual(
            5, chain_u.get_height_of_last_common_block_with_chain(chain_l))
        self.assertEqual(
            5, chain_l.get_height_of_last_common_block_with_chain(chain_u))
        self.assertEqual(
            5, chain_u.get_height_of_last_common_block_with_chain(chain_z))
        self.assertEqual(
            5, chain_z.get_height_of_last_common_block_with_chain(chain_u))
        self.assertEqual(
            8, chain_l.get_height_of_last_common_block_with_chain(chain_z))
        self.assertEqual(
            8, chain_z.get_height_of_last_common_block_with_chain(chain_l))

    def test_parents_after_forking(self):
        blockchain.blockchains[constants.net.GENESIS] = chain_u = Blockchain(
            config=self.config,
            forkpoint=0,
            parent=None,
            forkpoint_hash=constants.net.GENESIS,
            prev_hash=None)
        open(chain_u.path(), 'w+').close()
        self._append_header(chain_u, self.HEADERS['A'])
        self._append_header(chain_u, self.HEADERS['B'])
        self._append_header(chain_u, self.HEADERS['C'])
        self._append_header(chain_u, self.HEADERS['D'])
        self._append_header(chain_u, self.HEADERS['E'])
        self._append_header(chain_u, self.HEADERS['F'])
        self._append_header(chain_u, self.HEADERS['O'])
        self._append_header(chain_u, self.HEADERS['P'])
        self._append_header(chain_u, self.HEADERS['Q'])

        self.assertEqual(None, chain_u.parent)

        chain_l = chain_u.fork(self.HEADERS['G'])
        self._append_header(chain_l, self.HEADERS['H'])
        self._append_header(chain_l, self.HEADERS['I'])
        self._append_header(chain_l, self.HEADERS['J'])
        self._append_header(chain_l, self.HEADERS['K'])
        self._append_header(chain_l, self.HEADERS['L'])

        self.assertEqual(None, chain_l.parent)
        self.assertEqual(chain_l, chain_u.parent)

        chain_z = chain_l.fork(self.HEADERS['M'])
        self._append_header(chain_z, self.HEADERS['N'])
        self._append_header(chain_z, self.HEADERS['X'])
        self._append_header(chain_z, self.HEADERS['Y'])
        self._append_header(chain_z, self.HEADERS['Z'])

        self.assertEqual(chain_z, chain_u.parent)
        self.assertEqual(chain_z, chain_l.parent)
        self.assertEqual(None, chain_z.parent)

        self._append_header(chain_u, self.HEADERS['R'])
        self._append_header(chain_u, self.HEADERS['S'])
        self._append_header(chain_u, self.HEADERS['T'])
        self._append_header(chain_u, self.HEADERS['U'])

        self.assertEqual(chain_z, chain_u.parent)
        self.assertEqual(chain_z, chain_l.parent)
        self.assertEqual(None, chain_z.parent)

    def test_forking_and_swapping(self):
        blockchain.blockchains[constants.net.GENESIS] = chain_u = Blockchain(
            config=self.config,
            forkpoint=0,
            parent=None,
            forkpoint_hash=constants.net.GENESIS,
            prev_hash=None)
        open(chain_u.path(), 'w+').close()

        self._append_header(chain_u, self.HEADERS['A'])
        self._append_header(chain_u, self.HEADERS['B'])
        self._append_header(chain_u, self.HEADERS['C'])
        self._append_header(chain_u, self.HEADERS['D'])
        self._append_header(chain_u, self.HEADERS['E'])
        self._append_header(chain_u, self.HEADERS['F'])
        self._append_header(chain_u, self.HEADERS['O'])
        self._append_header(chain_u, self.HEADERS['P'])
        self._append_header(chain_u, self.HEADERS['Q'])
        self._append_header(chain_u, self.HEADERS['R'])

        chain_l = chain_u.fork(self.HEADERS['G'])
        self._append_header(chain_l, self.HEADERS['H'])
        self._append_header(chain_l, self.HEADERS['I'])
        self._append_header(chain_l, self.HEADERS['J'])

        # do checks
        self.assertEqual(2, len(blockchain.blockchains))
        self.assertEqual(1,
                         len(os.listdir(os.path.join(self.data_dir, "forks"))))
        self.assertEqual(0, chain_u.forkpoint)
        self.assertEqual(None, chain_u.parent)
        self.assertEqual(constants.net.GENESIS, chain_u._forkpoint_hash)
        self.assertEqual(None, chain_u._prev_hash)
        self.assertEqual(os.path.join(self.data_dir, "blockchain_headers"),
                         chain_u.path())
        self.assertEqual(10 * 80, os.stat(chain_u.path()).st_size)
        self.assertEqual(6, chain_l.forkpoint)
        self.assertEqual(chain_u, chain_l.parent)
        self.assertEqual(hash_header(self.HEADERS['G']),
                         chain_l._forkpoint_hash)
        self.assertEqual(hash_header(self.HEADERS['F']), chain_l._prev_hash)
        self.assertEqual(
            os.path.join(
                self.data_dir, "forks",
                "fork2_6_794cf990b8ec187a86b75b66bc536241a062e7e943bea990058fdfe3c51c60ff_c7d32c5da3811db46f0123428a408b73f59494af279d92feac5263a1e8eef546"
            ), chain_l.path())
        self.assertEqual(4 * 80, os.stat(chain_l.path()).st_size)

        self._append_header(chain_l, self.HEADERS['K'])

        # chains were swapped, do checks
        self.assertEqual(2, len(blockchain.blockchains))
        self.assertEqual(1,
                         len(os.listdir(os.path.join(self.data_dir, "forks"))))
        self.assertEqual(6, chain_u.forkpoint)
        self.assertEqual(chain_l, chain_u.parent)
        self.assertEqual(hash_header(self.HEADERS['O']),
                         chain_u._forkpoint_hash)
        self.assertEqual(hash_header(self.HEADERS['F']), chain_u._prev_hash)
        self.assertEqual(
            os.path.join(
                self.data_dir, "forks",
                "fork2_6_794cf990b8ec187a86b75b66bc536241a062e7e943bea990058fdfe3c51c60ff_c7d32c5da3811db46f0123428a408b73f59494af279d92feac5263a1e8eef546"
            ), chain_u.path())
        self.assertEqual(4 * 80, os.stat(chain_u.path()).st_size)
        self.assertEqual(0, chain_l.forkpoint)
        self.assertEqual(None, chain_l.parent)
        self.assertEqual(constants.net.GENESIS, chain_l._forkpoint_hash)
        self.assertEqual(None, chain_l._prev_hash)
        self.assertEqual(os.path.join(self.data_dir, "blockchain_headers"),
                         chain_l.path())
        self.assertEqual(11 * 80, os.stat(chain_l.path()).st_size)
        for b in (chain_u, chain_l):
            self.assertTrue(
                all([
                    b.can_connect(b.read_header(i), False)
                    for i in range(b.height())
                ]))

        self._append_header(chain_u, self.HEADERS['S'])
        self._append_header(chain_u, self.HEADERS['T'])
        self._append_header(chain_u, self.HEADERS['U'])
        self._append_header(chain_l, self.HEADERS['L'])

        chain_z = chain_l.fork(self.HEADERS['M'])
        self._append_header(chain_z, self.HEADERS['N'])
        self._append_header(chain_z, self.HEADERS['X'])
        self._append_header(chain_z, self.HEADERS['Y'])
        self._append_header(chain_z, self.HEADERS['Z'])

        # chain_z became best chain, do checks
        self.assertEqual(3, len(blockchain.blockchains))
        self.assertEqual(2,
                         len(os.listdir(os.path.join(self.data_dir, "forks"))))
        self.assertEqual(0, chain_z.forkpoint)
        self.assertEqual(None, chain_z.parent)
        self.assertEqual(constants.net.GENESIS, chain_z._forkpoint_hash)
        self.assertEqual(None, chain_z._prev_hash)
        self.assertEqual(os.path.join(self.data_dir, "blockchain_headers"),
                         chain_z.path())
        self.assertEqual(14 * 80, os.stat(chain_z.path()).st_size)
        self.assertEqual(9, chain_l.forkpoint)
        self.assertEqual(chain_z, chain_l.parent)
        self.assertEqual(hash_header(self.HEADERS['J']),
                         chain_l._forkpoint_hash)
        self.assertEqual(hash_header(self.HEADERS['I']), chain_l._prev_hash)
        self.assertEqual(
            os.path.join(
                self.data_dir, "forks",
                "fork2_9_954f22e584178919903456ea59dc143b351d96bcc92b285200402a24b45b8a2a_fbdc0f9c415e8673a27642c9b5c49392a12bedce5e7a8b23f033fb474854c059"
            ), chain_l.path())
        self.assertEqual(3 * 80, os.stat(chain_l.path()).st_size)
        self.assertEqual(6, chain_u.forkpoint)
        self.assertEqual(chain_z, chain_u.parent)
        self.assertEqual(hash_header(self.HEADERS['O']),
                         chain_u._forkpoint_hash)
        self.assertEqual(hash_header(self.HEADERS['F']), chain_u._prev_hash)
        self.assertEqual(
            os.path.join(
                self.data_dir, "forks",
                "fork2_6_794cf990b8ec187a86b75b66bc536241a062e7e943bea990058fdfe3c51c60ff_c7d32c5da3811db46f0123428a408b73f59494af279d92feac5263a1e8eef546"
            ), chain_u.path())
        self.assertEqual(7 * 80, os.stat(chain_u.path()).st_size)
        for b in (chain_u, chain_l, chain_z):
            self.assertTrue(
                all([
                    b.can_connect(b.read_header(i), False)
                    for i in range(b.height())
                ]))

        self.assertEqual(constants.net.GENESIS, chain_z.get_hash(0))
        self.assertEqual(hash_header(self.HEADERS['F']), chain_z.get_hash(5))
        self.assertEqual(hash_header(self.HEADERS['G']), chain_z.get_hash(6))
        self.assertEqual(hash_header(self.HEADERS['I']), chain_z.get_hash(8))
        self.assertEqual(hash_header(self.HEADERS['M']), chain_z.get_hash(9))
        self.assertEqual(hash_header(self.HEADERS['Z']), chain_z.get_hash(13))

    def test_doing_multiple_swaps_after_single_new_header(self):
        blockchain.blockchains[constants.net.GENESIS] = chain_u = Blockchain(
            config=self.config,
            forkpoint=0,
            parent=None,
            forkpoint_hash=constants.net.GENESIS,
            prev_hash=None)
        open(chain_u.path(), 'w+').close()

        self._append_header(chain_u, self.HEADERS['A'])
        self._append_header(chain_u, self.HEADERS['B'])
        self._append_header(chain_u, self.HEADERS['C'])
        self._append_header(chain_u, self.HEADERS['D'])
        self._append_header(chain_u, self.HEADERS['E'])
        self._append_header(chain_u, self.HEADERS['F'])
        self._append_header(chain_u, self.HEADERS['O'])
        self._append_header(chain_u, self.HEADERS['P'])
        self._append_header(chain_u, self.HEADERS['Q'])
        self._append_header(chain_u, self.HEADERS['R'])
        self._append_header(chain_u, self.HEADERS['S'])

        self.assertEqual(1, len(blockchain.blockchains))
        self.assertEqual(0,
                         len(os.listdir(os.path.join(self.data_dir, "forks"))))

        chain_l = chain_u.fork(self.HEADERS['G'])
        self._append_header(chain_l, self.HEADERS['H'])
        self._append_header(chain_l, self.HEADERS['I'])
        self._append_header(chain_l, self.HEADERS['J'])
        self._append_header(chain_l, self.HEADERS['K'])
        # now chain_u is best chain, but it's tied with chain_l

        self.assertEqual(2, len(blockchain.blockchains))
        self.assertEqual(1,
                         len(os.listdir(os.path.join(self.data_dir, "forks"))))

        chain_z = chain_l.fork(self.HEADERS['M'])
        self._append_header(chain_z, self.HEADERS['N'])
        self._append_header(chain_z, self.HEADERS['X'])

        self.assertEqual(3, len(blockchain.blockchains))
        self.assertEqual(2,
                         len(os.listdir(os.path.join(self.data_dir, "forks"))))

        # chain_z became best chain, do checks
        self.assertEqual(0, chain_z.forkpoint)
        self.assertEqual(None, chain_z.parent)
        self.assertEqual(constants.net.GENESIS, chain_z._forkpoint_hash)
        self.assertEqual(None, chain_z._prev_hash)
        self.assertEqual(os.path.join(self.data_dir, "blockchain_headers"),
                         chain_z.path())
        self.assertEqual(12 * 80, os.stat(chain_z.path()).st_size)
        self.assertEqual(9, chain_l.forkpoint)
        self.assertEqual(chain_z, chain_l.parent)
        self.assertEqual(hash_header(self.HEADERS['J']),
                         chain_l._forkpoint_hash)
        self.assertEqual(hash_header(self.HEADERS['I']), chain_l._prev_hash)
        self.assertEqual(
            os.path.join(
                self.data_dir, "forks",
                "fork2_9_954f22e584178919903456ea59dc143b351d96bcc92b285200402a24b45b8a2a_fbdc0f9c415e8673a27642c9b5c49392a12bedce5e7a8b23f033fb474854c059"
            ), chain_l.path())
        self.assertEqual(2 * 80, os.stat(chain_l.path()).st_size)
        self.assertEqual(6, chain_u.forkpoint)
        self.assertEqual(chain_z, chain_u.parent)
        self.assertEqual(hash_header(self.HEADERS['O']),
                         chain_u._forkpoint_hash)
        self.assertEqual(hash_header(self.HEADERS['F']), chain_u._prev_hash)
        self.assertEqual(
            os.path.join(
                self.data_dir, "forks",
                "fork2_6_794cf990b8ec187a86b75b66bc536241a062e7e943bea990058fdfe3c51c60ff_c7d32c5da3811db46f0123428a408b73f59494af279d92feac5263a1e8eef546"
            ), chain_u.path())
        self.assertEqual(5 * 80, os.stat(chain_u.path()).st_size)

        self.assertEqual(constants.net.GENESIS, chain_z.get_hash(0))
        self.assertEqual(hash_header(self.HEADERS['F']), chain_z.get_hash(5))
        self.assertEqual(hash_header(self.HEADERS['G']), chain_z.get_hash(6))
        self.assertEqual(hash_header(self.HEADERS['I']), chain_z.get_hash(8))
        self.assertEqual(hash_header(self.HEADERS['M']), chain_z.get_hash(9))
        self.assertEqual(hash_header(self.HEADERS['X']), chain_z.get_hash(11))

        for b in (chain_u, chain_l, chain_z):
            self.assertTrue(
                all([
                    b.can_connect(b.read_header(i), False)
                    for i in range(b.height())
                ]))
コード例 #25
0
    def data(self, index, role=Qt.DisplayRole):
        data = None
        if not index.isValid():
            return QVariant(data)
        if role not in [
                Qt.DisplayRole, Qt.EditRole, Qt.ToolTipRole, Qt.FontRole,
                Qt.BackgroundRole
        ]:
            return None

        mn = self.masternodes[index.row()]
        i = index.column()

        if i == self.ALIAS:
            data = mn.alias
        elif i == self.STATUS:
            status = self.manager.masternode_statuses.get(
                mn.get_collateral_str())
            data = masternode_status(status)
            if role == Qt.BackgroundRole:
                data = QBrush(
                    QColor(ENABLED_MASTERNODE_BG)) if data[0] else None
            # Return the long description for data widget mappers.
            elif role == Qt.EditRole:
                data = data[2]
            else:
                data = data[1]
        elif i == self.VIN:
            txid = mn.vin.get('prevout_hash', '')
            out_n = str(mn.vin.get('prevout_n', ''))
            addr = mn.vin.get('address', '')
            value = str(mn.vin.get('value', ''))
            scriptsig = mn.vin.get('scriptSig', '')
            if role == Qt.EditRole:
                data = ':'.join([txid, out_n, addr, value, scriptsig])
            elif role == Qt.FontRole:
                data = util.MONOSPACE_FONT
            else:
                if all(attr for attr in [txid, out_n, addr]):
                    data = '%s:%s' % (txid, out_n)
                else:
                    data = ''
        elif i == self.COLLATERAL:
            data = mn.collateral_key
            if role in [Qt.EditRole, Qt.DisplayRole, Qt.ToolTipRole] and data:
                data = bitcoin.public_key_to_p2pkh(bfh(data))
            elif role == Qt.FontRole:
                data = util.MONOSPACE_FONT
        elif i == self.DELEGATE:
            data = mn.delegate_key
            if role in [Qt.EditRole, Qt.DisplayRole, Qt.ToolTipRole] and data:
                data = self.manager.get_delegate_privkey(data)
            elif role == Qt.FontRole:
                data = util.MONOSPACE_FONT
        elif i == self.ADDR:
            data = ''
            if mn.addr.ip:
                data = str(mn.addr)
        elif i == self.PROTOCOL_VERSION:
            data = mn.protocol_version

        return QVariant(data)
コード例 #26
0
from electrum_trc import storage, bitcoin, keystore
from electrum_trc.transaction import Transaction
from electrum_trc.simple_config import SimpleConfig
from electrum_trc.address_synchronizer import TX_HEIGHT_UNCONFIRMED, TX_HEIGHT_UNCONF_PARENT
from electrum_trc.wallet import sweep, Multisig_Wallet, Standard_Wallet, Imported_Wallet, restore_wallet_from_text
from electrum_trc.util import bfh, bh2u
from electrum_trc.transaction import TxOutput
from electrum_trc.mnemonic import seed_type

from . import TestCaseForTestnet
from . import SequentialTestCase
from .test_bitcoin import needs_test_with_all_ecc_implementations


UNICODE_HORROR_HEX = 'e282bf20f09f988020f09f98882020202020e3818620e38191e3819fe381be20e3828fe3828b2077cda2cda2cd9d68cda16fcda2cda120ccb8cda26bccb5cd9f6eccb4cd98c7ab77ccb8cc9b73cd9820cc80cc8177cd98cda2e1b8a9ccb561d289cca1cda27420cca7cc9568cc816fccb572cd8fccb5726f7273cca120ccb6cda1cda06cc4afccb665cd9fcd9f20ccb6cd9d696ecda220cd8f74cc9568ccb7cca1cd9f6520cd9fcd9f64cc9b61cd9c72cc95cda16bcca2cca820cda168ccb465cd8f61ccb7cca2cca17274cc81cd8f20ccb4ccb7cda0c3b2ccb5ccb666ccb82075cca7cd986ec3adcc9bcd9c63cda2cd8f6fccb7cd8f64ccb8cda265cca1cd9d3fcd9e'
UNICODE_HORROR = bfh(UNICODE_HORROR_HEX).decode('utf-8')
assert UNICODE_HORROR == '₿ 😀 😈     う けたま わる w͢͢͝h͡o͢͡ ̸͢k̵͟n̴͘ǫw̸̛s͘ ̀́w͘͢ḩ̵a҉̡͢t ̧̕h́o̵r͏̵rors̡ ̶͡͠lį̶e͟͟ ̶͝in͢ ͏t̕h̷̡͟e ͟͟d̛a͜r̕͡k̢̨ ͡h̴e͏a̷̢̡rt́͏ ̴̷͠ò̵̶f̸ u̧͘ní̛͜c͢͏o̷͏d̸͢e̡͝?͞'


class WalletIntegrityHelper:

    gap_limit = 1  # make tests run faster

    @classmethod
    def check_seeded_keystore_sanity(cls, test_obj, ks):
        test_obj.assertTrue(ks.is_deterministic())
        test_obj.assertFalse(ks.is_watching_only())
        test_obj.assertFalse(ks.can_import())
        test_obj.assertTrue(ks.has_seed())

    @classmethod
コード例 #27
0
    def test_verify(self):
        announce = MasternodeAnnounce.deserialize(raw_announce_70210)
        message = announce.serialize_for_sig()

        pk = bitcoin.public_key_to_p2pkh(bfh(announce.collateral_key))
        self.assertTrue(announce.verify())
コード例 #28
0
 def test_add_number_to_script(self):
     # https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#numbers
     self.assertEqual(add_number_to_script(0), bytes([opcodes.OP_0]))
     self.assertEqual(add_number_to_script(7), bytes([opcodes.OP_7]))
     self.assertEqual(add_number_to_script(16), bytes([opcodes.OP_16]))
     self.assertEqual(add_number_to_script(-1), bytes([opcodes.OP_1NEGATE]))
     self.assertEqual(add_number_to_script(-127), bfh('01ff'))
     self.assertEqual(add_number_to_script(-2), bfh('0182'))
     self.assertEqual(add_number_to_script(17), bfh('0111'))
     self.assertEqual(add_number_to_script(127), bfh('017f'))
     self.assertEqual(add_number_to_script(-32767), bfh('02ffff'))
     self.assertEqual(add_number_to_script(-128), bfh('028080'))
     self.assertEqual(add_number_to_script(128), bfh('028000'))
     self.assertEqual(add_number_to_script(32767), bfh('02ff7f'))
     self.assertEqual(add_number_to_script(-8388607), bfh('03ffffff'))
     self.assertEqual(add_number_to_script(-32768), bfh('03008080'))
     self.assertEqual(add_number_to_script(32768), bfh('03008000'))
     self.assertEqual(add_number_to_script(8388607), bfh('03ffff7f'))
     self.assertEqual(add_number_to_script(-2147483647), bfh('04ffffffff'))
     self.assertEqual(add_number_to_script(-8388608 ), bfh('0400008080'))
     self.assertEqual(add_number_to_script(8388608), bfh('0400008000'))
     self.assertEqual(add_number_to_script(2147483647), bfh('04ffffff7f'))
コード例 #29
0
 def test_push_script(self):
     # https://github.com/bitcoin/bips/blob/master/bip-0062.mediawiki#push-operators
     self.assertEqual(push_script(''), bh2u(bytes([opcodes.OP_0])))
     self.assertEqual(push_script('07'), bh2u(bytes([opcodes.OP_7])))
     self.assertEqual(push_script('10'), bh2u(bytes([opcodes.OP_16])))
     self.assertEqual(push_script('81'), bh2u(bytes([opcodes.OP_1NEGATE])))
     self.assertEqual(push_script('11'), '0111')
     self.assertEqual(push_script(75 * '42'), '4b' + 75 * '42')
     self.assertEqual(push_script(76 * '42'), bh2u(bytes([opcodes.OP_PUSHDATA1]) + bfh('4c' + 76 * '42')))
     self.assertEqual(push_script(100 * '42'), bh2u(bytes([opcodes.OP_PUSHDATA1]) + bfh('64' + 100 * '42')))
     self.assertEqual(push_script(255 * '42'), bh2u(bytes([opcodes.OP_PUSHDATA1]) + bfh('ff' + 255 * '42')))
     self.assertEqual(push_script(256 * '42'), bh2u(bytes([opcodes.OP_PUSHDATA2]) + bfh('0001' + 256 * '42')))
     self.assertEqual(push_script(520 * '42'), bh2u(bytes([opcodes.OP_PUSHDATA2]) + bfh('0802' + 520 * '42')))
コード例 #30
0
 def test_verify_auxpow_header_explicit_coinbase(self):
     header_bytes = bfh(header_850964)
     # We can't pass the real height because it's below a checkpoint, and
     # the deserializer expects ElectrumX to strip checkpointed AuxPoW.
     header = self.deserialize_with_auxpow(header_850964)
     blockchain.Blockchain.verify_header(header, prev_hash_850964, target_850964)