Пример #1
0
    def test_dash_tx_sub_tx_register(self):
        tx = transaction.Transaction(SUB_TX_REGISTER)
        deser = tx.to_json()
        assert deser['version'] == 3
        assert deser['tx_type'] == 8
        extra_dict = deser['extra_payload']
        assert extra_dict == SUB_TX_REGISTER_D
        extra = tx.extra_payload
        assert (str(extra))
        assert extra.version == SUB_TX_REGISTER_D['version']
        assert extra.userName == SUB_TX_REGISTER_D['userName']
        assert len(extra.pubKey) == 48
        assert extra.pubKey == bfh(SUB_TX_REGISTER_D['pubKey'])
        assert len(extra.payloadSig) == 96
        assert extra.payloadSig == bfh(SUB_TX_REGISTER_D['payloadSig'])
        ser = tx.serialize()
        assert ser == SUB_TX_REGISTER

        assert extra.to_hex_str() == SUB_TX_REGISTER[386:]
        extra2 = ProTxBase.from_hex_str(SPEC_SUB_TX_REGISTER,
                                        SUB_TX_REGISTER[386:])
        assert extra2.version == extra.version
        assert extra2.userName == extra.userName
        assert extra2.pubKey == extra.pubKey
        assert extra2.payloadSig == extra.payloadSig
Пример #2
0
    def test_dash_tx_pro_up_rev_tx(self):
        tx = transaction.Transaction(PRO_UP_REV_TX)
        deser = tx.to_json()
        assert deser['version'] == 3
        assert deser['tx_type'] == 4
        extra_dict = deser['extra_payload']
        assert extra_dict == PRO_UP_REV_TX_D
        extra = tx.extra_payload
        assert (str(extra))
        assert extra.version == PRO_UP_REV_TX_D['version']
        assert len(extra.proTxHash) == 32
        assert extra.proTxHash == bfh(PRO_UP_REV_TX_D['proTxHash'])
        assert extra.reason == PRO_UP_REV_TX_D['reason']
        assert len(extra.inputsHash) == 32
        assert extra.inputsHash == bfh(PRO_UP_REV_TX_D['inputsHash'])
        assert len(extra.payloadSig) == 96
        assert extra.payloadSig == bfh(PRO_UP_REV_TX_D['payloadSig'])
        ser = tx.serialize()
        assert ser == PRO_UP_REV_TX

        assert extra.to_hex_str() == PRO_UP_REV_TX[384:]
        extra2 = ProTxBase.from_hex_str(SPEC_PRO_UP_REV_TX,
                                        PRO_UP_REV_TX[384:])
        assert extra2.version == extra.version
        assert extra2.proTxHash == extra.proTxHash
        assert extra2.reason == extra.reason
        assert extra2.inputsHash == extra.inputsHash
        assert extra2.payloadSig == extra.payloadSig
Пример #3
0
    def test_dash_tx_sub_tx_reset_key(self):
        tx = transaction.Transaction(SUB_TX_RESET_KEY)
        deser = tx.to_json()
        assert deser['version'] == 3
        assert deser['tx_type'] == 10
        extra_dict = deser['extra_payload']
        assert extra_dict == SUB_TX_RESET_KEY_D
        extra = tx.extra_payload
        assert (str(extra))
        assert extra.version == SUB_TX_RESET_KEY_D['version']
        assert len(extra.regTxHash) == 32
        assert extra.regTxHash == bfh(SUB_TX_RESET_KEY_D['regTxHash'])
        assert len(extra.hashPrevSubTx) == 32
        assert extra.hashPrevSubTx == bfh(SUB_TX_RESET_KEY_D['hashPrevSubTx'])
        assert extra.creditFee == SUB_TX_RESET_KEY_D['creditFee']
        assert len(extra.newPubKey) == 48
        assert extra.newPubKey == bfh(SUB_TX_RESET_KEY_D['newPubKey'])
        assert len(extra.payloadSig) == 96
        assert extra.payloadSig == bfh(SUB_TX_RESET_KEY_D['payloadSig'])
        ser = tx.serialize()
        assert ser == SUB_TX_RESET_KEY

        assert extra.to_hex_str() == SUB_TX_RESET_KEY[386:]
        extra2 = ProTxBase.from_hex_str(SPEC_SUB_TX_RESET_KEY,
                                        SUB_TX_RESET_KEY[386:])
        assert extra2.version == extra.version
        assert extra2.regTxHash == extra.regTxHash
        assert extra2.hashPrevSubTx == extra.hashPrevSubTx
        assert extra2.creditFee == extra.creditFee
        assert extra2.newPubKey == extra.newPubKey
        assert extra2.payloadSig == extra.payloadSig
Пример #4
0
 def test_dash_tx_pro_up_serv_tx(self):
     tx = transaction.Transaction(PRO_UP_SERV_TX)
     deser = tx.deserialize()
     assert deser['version'] == 3
     assert deser['tx_type'] == 2
     extra = deser['extra_payload']
     assert extra.version == 1
     assert len(extra.proTxHash) == 32
     assert extra.proTxHash == bfh(
         '3c6dca244f49f19d3f09889753ffff1fec5bb8f9f5bd5bc09dabd999da21198f')
     assert len(extra.ipAddress) == 16
     assert extra.ipAddress == bfh('00000000000000000000ffff5fb73580')
     assert extra.port == 4391
     assert extra.scriptOperatorPayout == bfh(
         '76a91421851058431a7d722e8e8dd9509e7f2b8e7042ec88ac')
     assert len(extra.inputsHash) == 32
     assert extra.inputsHash == bfh(
         'efcfe3d578914bb48c6bd71b3459d384e4237446d521c9e2c6'
         'b6fcf019b5aafc')
     assert len(extra.payloadSig) == 96
     assert extra.payloadSig == bfh(
         '99443fe14f644cfa47086e8897cf7b546a67723d4a8ec5353a82f962a96e'
         'c3cea328343b647aace2897d6eddd0b8c8ee0f2e56f6733aed2e9f0006ca'
         'afa6fc21c18a013c619d6e37af8d2f0985e3b769abc38ffa60e46c365a38'
         'd9fa0d44fd62')
     ser = tx.serialize()
     assert ser == PRO_UP_SERV_TX
Пример #5
0
 def test_dash_tx_sub_tx_reset_key(self):
     tx = transaction.Transaction(SUB_TX_RESET_KEY)
     deser = tx.deserialize()
     assert deser['version'] == 3
     assert deser['tx_type'] == 10
     extra = deser['extra_payload']
     assert extra.version == 1
     assert len(extra.regTxHash) == 32
     assert extra.regTxHash == bfh(
         'd384e42374e8abfeffffff01570b000000a40100b67ffbbd095de31ea3844675')
     assert len(extra.hashPrevSubTx) == 32
     assert extra.hashPrevSubTx == bfh(
         'af3e98e9601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b3d0')
     assert extra.creditFee == 1000
     assert len(extra.newPubKey) == 48
     assert extra.newPubKey == bfh(
         '601210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b3d0103f7'
         '61caf3e98e9601210293360bf2a2e810673')
     assert len(extra.payloadSig) == 96
     assert extra.payloadSig == bfh(
         '412bc6e8e0e358f3fb7bdbe9a667b3d0103f761caf3e98e9601210293360b'
         'f2a2e810673412bc6e8e0e358f3fb7bdbe9a667b3d0103f761caf3e98e960'
         '1210293360bf2a2e810673412bc6e8e0e358f3fb7bdbe9a667b3d0103f761'
         'cabcdefab')
     ser = tx.serialize()
     assert ser == SUB_TX_RESET_KEY
Пример #6
0
    def test_dash_tx_pro_up_serv_tx(self):
        tx = transaction.Transaction(PRO_UP_SERV_TX)
        deser = tx.to_json()
        assert deser['version'] == 3
        assert deser['tx_type'] == 2
        extra_dict = deser['extra_payload']
        assert extra_dict == PRO_UP_SERV_TX_D
        extra = tx.extra_payload
        assert (str(extra))
        assert extra.version == PRO_UP_SERV_TX_D['version']
        assert len(extra.proTxHash) == 32
        assert extra.proTxHash == bfh(PRO_UP_SERV_TX_D['proTxHash'])
        assert extra.ipAddress == PRO_UP_SERV_TX_D['ipAddress']
        assert extra.port == PRO_UP_SERV_TX_D['port']
        assert extra.scriptOperatorPayout == \
            bfh(PRO_UP_SERV_TX_D['scriptOperatorPayout'])
        assert len(extra.inputsHash) == 32
        assert extra.inputsHash == bfh(PRO_UP_SERV_TX_D['inputsHash'])
        assert len(extra.payloadSig) == 96
        assert extra.payloadSig == bfh(PRO_UP_SERV_TX_D['payloadSig'])
        ser = tx.serialize()
        assert ser == PRO_UP_SERV_TX

        assert extra.to_hex_str() == PRO_UP_SERV_TX[386:]
        extra2 = ProTxBase.from_hex_str(SPEC_PRO_UP_SERV_TX,
                                        PRO_UP_SERV_TX[386:])
        assert extra2.version == extra.version
        assert extra2.proTxHash == extra.proTxHash
        assert extra2.ipAddress == extra.ipAddress
        assert extra2.port == extra.port
        assert extra2.scriptOperatorPayout == extra.scriptOperatorPayout
        assert extra2.inputsHash == extra.inputsHash
        assert extra2.payloadSig == extra.payloadSig
Пример #7
0
    def test_dash_tx_sub_tx_close_account(self):
        tx = transaction.Transaction(SUB_TX_CLOSE_ACCOUNT)
        deser = tx.to_json()
        assert deser['version'] == 3
        assert deser['tx_type'] == 11
        extra_dict = deser['extra_payload']
        assert extra_dict == SUB_TX_CLOSE_ACCOUNT_D
        extra = tx.extra_payload
        assert (str(extra))
        assert extra.version == SUB_TX_CLOSE_ACCOUNT_D['version']
        assert len(extra.regTxHash) == 32
        assert extra.regTxHash == bfh(SUB_TX_CLOSE_ACCOUNT_D['regTxHash'])
        assert len(extra.hashPrevSubTx) == 32
        assert extra.hashPrevSubTx == \
            bfh(SUB_TX_CLOSE_ACCOUNT_D['hashPrevSubTx'])
        assert extra.creditFee == SUB_TX_CLOSE_ACCOUNT_D['creditFee']
        assert len(extra.payloadSig) == 96
        assert extra.payloadSig == bfh(SUB_TX_CLOSE_ACCOUNT_D['payloadSig'])
        ser = tx.serialize()
        assert ser == SUB_TX_CLOSE_ACCOUNT

        assert extra.to_hex_str() == SUB_TX_CLOSE_ACCOUNT[386:]
        extra2 = ProTxBase.from_hex_str(SPEC_SUB_TX_CLOSE_ACCOUNT,
                                        SUB_TX_CLOSE_ACCOUNT[386:])
        assert extra2.version == extra.version
        assert extra2.regTxHash == extra.regTxHash
        assert extra2.hashPrevSubTx == extra.hashPrevSubTx
        assert extra2.creditFee == extra.creditFee
        assert extra2.payloadSig == extra.payloadSig
Пример #8
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]))
Пример #9
0
 def parse_script(self, x):
     script = ''
     for word in x.split():
         if word[0:3] == 'OP_':
             opcode_int = opcodes[word]
             script += construct_script([opcode_int])
         else:
             bfh(word)  # to test it is hex data
             script += construct_script([word])
     return script
Пример #10
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
Пример #11
0
 def parse_output(self, x) -> bytes:
     try:
         address = self.parse_address(x)
         return bfh(bitcoin.address_to_script(address))
     except Exception:
         pass
     try:
         script = self.parse_script(x)
         return bfh(script)
     except Exception:
         pass
     raise Exception("Invalid address or script.")
Пример #12
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))
Пример #13
0
 def parse_script(self, x):
     from electrum_dash.transaction import opcodes, push_script
     script = ''
     for word in x.split():
         if word[0:3] == 'OP_':
             assert word in opcodes.lookup
             opcode_int = opcodes.lookup[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
Пример #14
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)
Пример #15
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)
Пример #16
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))
Пример #17
0
    def test_create_and_sign(self):
        collateral_pub = '038ae57bd0fa5b45640e771614ec571c7326a2266c78bb444f1971c85188411ba1'  # XahPxwmCuKjPq69hzVxP18V1eASwDWbUrn
        delegate_pub = '02526201c87c1b4630aabbd04572eec3e2545e442503e57e60880fafcc1f684dbc'  # Xx2nSdhaT7c9SREKBPAgzpkhu518XFgkgh
        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 = 'XJqCcyfnLYK4Y7ZDVjLrgPnsrq2cWMF6MX9cyhKgfMajwqrCwZaS'
        delegate_wif = 'XCbhXBc2N9q8kxqBF41rSuLWVpVVbDm7P1oPv9GxcrS9QXYBWZkB'
        announce.last_ping.sign(delegate_wif, bfh(delegate_pub), 1461858375)
        sig = announce.sign(collateral_wif, 1461858375)

        address = 'XahPxwmCuKjPq69hzVxP18V1eASwDWbUrn'
        self.assertTrue(announce.verify(address))
        self.assertTrue(
            ecc.verify_message_with_address(address, sig,
                                            announce.serialize_for_sig()))
Пример #18
0
 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
Пример #19
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)
Пример #20
0
    def test_create_and_sign(self):
        collateral_pub = '038ae57bd0fa5b45640e771614ec571c7326a2266c78bb444f1971c85188411ba1' # XahPxwmCuKjPq69hzVxP18V1eASwDWbUrn
        delegate_pub = '02526201c87c1b4630aabbd04572eec3e2545e442503e57e60880fafcc1f684dbc' # Xx2nSdhaT7c9SREKBPAgzpkhu518XFgkgh
        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 = 'XJqCcyfnLYK4Y7ZDVjLrgPnsrq2cWMF6MX9cyhKgfMajwqrCwZaS'
        delegate_wif = 'XCbhXBc2N9q8kxqBF41rSuLWVpVVbDm7P1oPv9GxcrS9QXYBWZkB'
        announce.last_ping.sign(delegate_wif, bfh(delegate_pub), 1461858375)
        sig = announce.sign(collateral_wif, 1461858375)

        address = 'XahPxwmCuKjPq69hzVxP18V1eASwDWbUrn'
        self.assertTrue(announce.verify(address))
        self.assertTrue(ecc.verify_message_with_address
                            (address, sig, announce.serialize_for_sig()))
Пример #21
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)
Пример #22
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 Exception as e:
         self.show_message(str(e))
Пример #23
0
 def f(x_pubkey):
     if is_xpubkey(x_pubkey):
         xpub, s = parse_xpubkey(x_pubkey)
     else:
         xpub = xpub_from_pubkey(0, bfh(x_pubkey))
         s = []
     return self._make_node_path(xpub, s)
Пример #24
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)
Пример #25
0
 def f(x_pubkey):
     if is_xpubkey(x_pubkey):
         xpub, s = parse_xpubkey(x_pubkey)
     else:
         xpub = xpub_from_pubkey(0, bfh(x_pubkey))
         s = []
     node = self.ckd_public.deserialize(xpub)
     return self.types.HDNodePathType(node=node, address_n=s)
Пример #26
0
    def update(self):
        raw_tx = str(self.tx)
        tx_type = tx_header_to_tx_type(bfh(raw_tx[:8]))
        if tx_type == 0:
            txid = self.tx.txid()
            tx_type, completed = self.wallet.db.get_ps_tx(txid)
        self.title = '%s %s' % (SPEC_TX_NAMES[tx_type], _('Transaction'))
        format_amount = self.app.format_amount_and_units
        tx_details = self.wallet.get_tx_info(self.tx)
        tx_mined_status = tx_details.tx_mined_status
        exp_n = tx_details.mempool_depth_bytes
        amount, fee = tx_details.amount, tx_details.fee
        self.status_str = tx_details.status
        self.description = tx_details.label
        self.can_broadcast = tx_details.can_broadcast
        self.tx_hash = tx_details.txid or ''
        islock = tx_details.islock
        timestamp = tx_mined_status.timestamp
        if not timestamp and islock:
            timestamp = islock
        if timestamp:
            self.date_label = _('Date')
            dttm = datetime.fromtimestamp(timestamp)
            self.date_str = dttm.isoformat(' ')[:-3]
        elif exp_n is not None:
            self.date_label = _('Mempool depth')
            self.date_str = _('{} from tip').format('%.2f MB'%(exp_n/1000000))
        else:
            self.date_label = ''
            self.date_str = ''

        self.can_sign = self.wallet.can_sign(self.tx)
        if amount is None:
            self.amount_str = _("Transaction unrelated to your wallet")
        elif amount > 0:
            self.is_mine = False
            self.amount_str = format_amount(amount)
        else:
            self.is_mine = True
            self.amount_str = format_amount(-amount)
        risk_of_burning_coins = (isinstance(self.tx, PartialTransaction)
                                 and self.can_sign
                                 and fee is not None
                                 and bool(self.wallet.get_warning_for_risk_of_burning_coins_as_fees(self.tx)))
        if fee is not None and not risk_of_burning_coins:
            self.fee_str = format_amount(fee)
            fee_per_kb = fee / self.tx.estimated_size() * 1000
            self.feerate_str = self.app.format_fee_rate(fee_per_kb)
        else:
            self.fee_str = _('unknown')
            self.feerate_str = _('unknown')
        self.ids.output_list.update(self.tx.outputs())

        for dict_entry in self.ids.output_list.data:
            dict_entry['color'], dict_entry['background_color'] = address_colors(self.wallet, dict_entry['address'])

        self.can_remove_tx = tx_details.can_remove
        self.update_action_button()
Пример #27
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)
Пример #28
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)
Пример #29
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))
Пример #30
0
def trezor_validate_op_return_output_and_get_data(output: TxOutput) -> bytes:
    if output.type != TYPE_SCRIPT:
        raise Exception("Unexpected output type: {}".format(output.type))
    script = bfh(output.address)
    if not (script[0] == opcodes.OP_RETURN and
            script[1] == len(script) - 2 and script[1] <= 75):
        raise Exception(_("Only OP_RETURN scripts, with one constant push, are supported."))
    if output.value != 0:
        raise Exception(_("Amount for OP_RETURN output must be zero."))
    return script[2:]
Пример #31
0
    def test_get_address_from_output_script(self):
        # the inverse of this test is in test_bitcoin: test_address_to_script
        addr_from_script = lambda script: transaction.get_address_from_output_script(bfh(script))
        ADDR = transaction.TYPE_ADDRESS

        # base58 p2pkh
        self.assertEqual((ADDR, 'XeNTG4aihv1ru8xmaoiQnToSi8hLiTTNbh'), addr_from_script('76a91428662c67561b95c79d2257d2a93d9d151c977e9188ac'))
        self.assertEqual((ADDR, 'XkvgWFLxVmDaVkUF8bFE2QXP4f5C2KKWEg'), addr_from_script('76a914704f4b81cadb7bf7e68c08cd3657220f680f863c88ac'))

        # base58 p2sh
        self.assertEqual((ADDR, '7WHUEVtMDLeereT5r4ZoNKjr3MXr4gqfon'), addr_from_script('a9142a84cf00d47f699ee7bbc1dea5ec1bdecb4ac15487'))
        self.assertEqual((ADDR, '7phNpVKta6kkbP24HfvvQVeHEmgBQYiJCB'), addr_from_script('a914f47c8954e421031ad04ecd8e7752c9479206b9d387'))
Пример #32
0
 def electrum_tx_to_txtype(self, tx):
     t = self.types.TransactionType()
     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
Пример #33
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)
Пример #34
0
    def _do_test_bip32(self, seed, sequence):
        xprv, xpub = bip32_root(bfh(seed), 'standard')
        self.assertEqual("m/", sequence[0:2])
        path = 'm'
        sequence = sequence[2:]
        for n in sequence.split('/'):
            child_path = path + '/' + n
            if n[-1] != "'":
                xpub2 = bip32_public_derivation(xpub, path, child_path)
            xprv, xpub = bip32_private_derivation(xprv, path, child_path)
            if n[-1] != "'":
                self.assertEqual(xpub, xpub2)
            path = child_path

        return xpub, xprv
Пример #35
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._extend_inputs(inputs)
     for vout in d['outputs']:
         o = t._add_bin_outputs()
         o.amount = vout['value']
         o.script_pubkey = bfh(vout['scriptPubKey'])
     return t
Пример #36
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: traceback.print_exception(*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)
Пример #37
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'))
Пример #38
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')))
Пример #39
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._extend_address_n(xpub_n + s)
                        txinputtype.script_type = self.get_trezor_input_script_type(txin['type'])
                    else:
                        def f(x_pubkey):
                            if is_xpubkey(x_pubkey):
                                xpub, s = parse_xpubkey(x_pubkey)
                            else:
                                xpub = xpub_from_pubkey(0, bfh(x_pubkey))
                                s = []
                            return self._make_node_path(xpub, s)
                        pubkeys = list(map(f, x_pubkeys))
                        multisig = self.types.MultisigRedeemScriptType(
                            pubkeys=pubkeys,
                            signatures=list(map(lambda x: bfh(x)[:-1] if x else b'', txin.get('signatures'))),
                            m=txin.get('num_sig'),
                        )
                        script_type = self.get_trezor_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._extend_address_n(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
Пример #40
0
from electrum_dash import storage, bitcoin, keystore, constants
from electrum_dash.transaction import Transaction
from electrum_dash.simple_config import SimpleConfig
from electrum_dash.address_synchronizer import TX_HEIGHT_UNCONFIRMED, TX_HEIGHT_UNCONF_PARENT
from electrum_dash.wallet import sweep, Multisig_Wallet, Standard_Wallet, Imported_Wallet
from electrum_dash.util import bfh, bh2u
from electrum_dash.transaction import TxOutput

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')
# '₿ 😀 😈     う けたま わる 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
Пример #41
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())
Пример #42
0
    def sign_transaction(self, tx, password):
        if tx.is_complete():
            return
        client = self.get_client()
        inputs = []
        inputsPaths = []
        pubKeys = []
        chipInputs = []
        redeemScripts = []
        signatures = []
        preparedTrustedInputs = []
        changePath = ""
        output = None
        p2shTransaction = False
        pin = ""
        self.get_client() # prompt for the PIN before displaying the dialog if necessary

        # Fetch inputs of the transaction to sign
        derivations = self.get_tx_derivations(tx)
        for txin in tx.inputs():
            if txin['type'] == 'coinbase':
                self.give_error("Coinbase not supported")     # should never happen

            if txin['type'] in ['p2sh']:
                p2shTransaction = True

            pubkeys, x_pubkeys = tx.get_sorted_pubkeys(txin)
            for i, x_pubkey in enumerate(x_pubkeys):
                if x_pubkey in derivations:
                    signingPos = i
                    s = derivations.get(x_pubkey)
                    hwAddress = "%s/%d/%d" % (self.get_derivation()[2:], s[0], s[1])
                    break
            else:
                self.give_error("No matching x_key for sign_transaction") # should never happen

            redeemScript = Transaction.get_preimage_script(txin)
            txin_prev_tx = txin.get('prev_tx')
            if txin_prev_tx is None:
                raise Exception(_('Offline signing with {} is not supported for legacy inputs.').format(self.device))
            txin_prev_tx_raw = txin_prev_tx.raw if txin_prev_tx else None
            inputs.append([txin_prev_tx_raw,
                           txin['prevout_n'],
                           redeemScript,
                           txin['prevout_hash'],
                           signingPos,
                           txin.get('sequence', 0xffffffff - 1),
                           txin.get('value')])
            inputsPaths.append(hwAddress)
            pubKeys.append(pubkeys)

        # Sanity check
        if p2shTransaction:
            for txin in tx.inputs():
                if txin['type'] != 'p2sh':
                    self.give_error("P2SH / regular input mixed in same transaction not supported") # should never happen

        txOutput = var_int(len(tx.outputs()))
        for txout in tx.outputs():
            output_type, addr, amount = txout
            txOutput += int_to_hex(amount, 8)
            script = tx.pay_script(output_type, addr)
            txOutput += var_int(len(script)//2)
            txOutput += script
        txOutput = bfh(txOutput)

        # Recognize outputs
        # - only one output and one change is authorized (for hw.1 and nano)
        # - at most one output can bypass confirmation (~change) (for all)
        if not p2shTransaction:
            if not self.get_client_electrum().supports_multi_output():
                if len(tx.outputs()) > 2:
                    self.give_error("Transaction with more than 2 outputs not supported")
            has_change = False
            any_output_on_change_branch = is_any_tx_output_on_change_branch(tx)
            for o in tx.outputs():
                assert o.type == TYPE_ADDRESS
                info = tx.output_info.get(o.address)
                if (info is not None) and len(tx.outputs()) > 1 \
                        and not has_change:
                    index = info.address_index
                    on_change_branch = index[0] == 1
                    # prioritise hiding outputs on the 'change' branch from user
                    # because no more than one change address allowed
                    if on_change_branch == any_output_on_change_branch:
                        changePath = self.get_derivation()[2:] + "/%d/%d"%index
                        has_change = True
                    else:
                        output = o.address
                else:
                    output = o.address
                    if not self.get_client_electrum().canAlternateCoinVersions:
                        v, h = b58_address_to_hash160(address)
                        if v == constants.net.ADDRTYPE_P2PKH:
                            output = hash160_to_b58_address(h, 0)

        self.handler.show_message(_("Confirm Transaction on your Ledger device..."))
        try:
            # Get trusted inputs from the original transactions
            for utxo in inputs:
                sequence = int_to_hex(utxo[5], 4)
                if not p2shTransaction:
                    txtmp = bitcoinTransaction(bfh(utxo[0]))
                    trustedInput = self.get_client().getTrustedInput(txtmp, utxo[1])
                    trustedInput['sequence'] = sequence
                    chipInputs.append(trustedInput)
                    redeemScripts.append(txtmp.outputs[utxo[1]].script)
                else:
                    tmp = bfh(utxo[3])[::-1]
                    tmp += bfh(int_to_hex(utxo[1], 4))
                    chipInputs.append({'value' : tmp, 'sequence' : sequence})
                    redeemScripts.append(bfh(utxo[2]))

            # Sign all inputs
            firstTransaction = True
            inputIndex = 0
            rawTx = tx.serialize_to_network()
            self.get_client().enableAlternate2fa(False)
            while inputIndex < len(inputs):
                self.get_client().startUntrustedTransaction(firstTransaction, inputIndex,
                                                        chipInputs, redeemScripts[inputIndex])
                if changePath:
                    # we don't set meaningful outputAddress, amount and fees
                    # as we only care about the alternateEncoding==True branch
                    outputData = self.get_client().finalizeInput(b'', 0, 0, changePath, bfh(rawTx))
                else:
                    outputData = self.get_client().finalizeInputFull(txOutput)
                outputData['outputData'] = txOutput
                if firstTransaction:
                    transactionOutput = outputData['outputData']
                if outputData['confirmationNeeded']:
                    outputData['address'] = output
                    self.handler.finished()
                    pin = self.handler.get_auth( outputData ) # does the authenticate dialog and returns pin
                    if not pin:
                        raise UserWarning()
                    if pin != 'paired':
                        self.handler.show_message(_("Confirmed. Signing Transaction..."))
                else:
                    # Sign input with the provided PIN
                    inputSignature = self.get_client().untrustedHashSign(inputsPaths[inputIndex], pin, lockTime=tx.locktime)
                    inputSignature[0] = 0x30 # force for 1.4.9+
                    signatures.append(inputSignature)
                    inputIndex = inputIndex + 1
                if pin != 'paired':
                    firstTransaction = False
        except UserWarning:
            self.handler.show_error(_('Cancelled by user'))
            return
        except BTChipException as e:
            if e.sw == 0x6985:  # cancelled by user
                return
            elif e.sw == 0x6982:
                raise  # pin lock. decorator will catch it
            else:
                traceback.print_exc(file=sys.stderr)
                self.give_error(e, True)
        except BaseException as e:
            traceback.print_exc(file=sys.stdout)
            self.give_error(e, True)
        finally:
            self.handler.finished()

        for i, txin in enumerate(tx.inputs()):
            signingPos = inputs[i][4]
            tx.add_signature_to_txin(i, signingPos, bh2u(signatures[i]))
        tx.raw = tx.serialize()