def check_sign(self, blinded_tx: CTransaction, signed_tx: CTransaction,
                   bundle: Dict[str, Any]) -> None:
        tx_to_sign = blinded_tx.to_mutable()
        for n, vin in enumerate(tx_to_sign.vin):
            utxo = bundle['vin_utxo'][n]
            amount = -1 if utxo['amount'] == -1 else coins_to_satoshi(
                utxo['amount'])

            scriptPubKey = CScript(x(utxo['scriptPubKey']))
            a = CCoinAddress(utxo['address'])
            if 'privkey' in utxo:
                privkey = CCoinKey(utxo['privkey'])
                assert isinstance(a, P2PKHCoinAddress),\
                    "only P2PKH is supported for single-sig"
                assert a == P2PKHElementsAddress.from_pubkey(privkey.pub)
                assert scriptPubKey == a.to_scriptPubKey()
                sighash = SignatureHash(scriptPubKey,
                                        tx_to_sign,
                                        n,
                                        SIGHASH_ALL,
                                        amount=amount,
                                        sigversion=SIGVERSION_BASE)
                sig = privkey.sign(sighash) + bytes([SIGHASH_ALL])
                tx_to_sign.vin[n].scriptSig = CScript(
                    [CScript(sig), CScript(privkey.pub)])
            else:
                pk_list = [CCoinKey(pk) for pk in utxo['privkey_list']]
                redeem_script_data = [utxo['num_p2sh_participants']]
                redeem_script_data.extend([pk.pub for pk in pk_list])
                redeem_script_data.extend([len(pk_list), OP_CHECKMULTISIG])
                redeem_script = CScript(redeem_script_data)
                assert isinstance(a, P2SHCoinAddress),\
                    "only P2SH is supported for multi-sig."
                assert scriptPubKey == redeem_script.to_p2sh_scriptPubKey()
                assert a == P2SHElementsAddress.from_scriptPubKey(
                    redeem_script.to_p2sh_scriptPubKey())
                sighash = SignatureHash(redeem_script,
                                        tx_to_sign,
                                        n,
                                        SIGHASH_ALL,
                                        amount=amount,
                                        sigversion=SIGVERSION_BASE)
                sigs = [
                    pk.sign(sighash) + bytes([SIGHASH_ALL]) for pk in pk_list
                ]
                tx_to_sign.vin[n].scriptSig = CScript([b''] + sigs +
                                                      [redeem_script])

            VerifyScript(tx_to_sign.vin[n].scriptSig,
                         scriptPubKey,
                         tx_to_sign,
                         n,
                         amount=amount)

        self.assertEqual(tx_to_sign.serialize(), signed_tx.serialize())
Esempio n. 2
0
def find_utxo_for_fee(say, die, rpc):
    """Find suitable utxo to pay the fee.
    Retrieve thekey to spend this utxo and add it to
    the returned dict."""

    # Find utxo to use for fee. In our simple example, only Alice pays the fee.
    # To be on a safe side, include only transactions
    # that are confirmed (1 as 'minconf' argument of listunspent)
    # and safe to spend (False as 'include_unsafe' # argument of listunspent)
    say('Searching for utxo for fee asset')
    utxo_list = rpc.listunspent(1, 9999999, [], False,
                                {'asset': fee_asset.to_hex()})
    utxo_list.sort(key=lambda u: u['amount'])
    for utxo in utxo_list:
        # To not deal with possibility of dust outputs,
        # just require fee utxo to be big enough
        if coins_to_satoshi(utxo['amount']) >= FIXED_FEE_SATOSHI * 2:
            utxo['key'] = CCoinKey(rpc.dumpprivkey(utxo['address']))
            if 'assetcommitment' not in utxo:
                # If UTXO is not blinded, Elements daemon will not
                # give us assetcommitment, so we need to generate it ourselves.
                asset = CAsset(lx(utxo['asset']))
                utxo['assetcommitment'] = b2x(asset.to_commitment())
            return utxo
    else:
        die('Cannot find utxo for fee that is >= {} satoshi'.format(
            FIXED_FEE_SATOSHI * 2))
Esempio n. 3
0
def issue_asset(say, asset_amount, rpc):
    """Issue asset and return CAsset instance and utxo to spend"""

    say('Issuing my own new asset, amount: {}'.format(asset_amount))

    # No reissuance, so we specify tokenamount as 0
    issue = rpc.issueasset(asset_amount, 0)

    asset_str = issue['asset']
    say('The asset is {}'.format(asset_str))

    say('Getting unspent utxo for asset {}'.format(asset_str))
    # There should be only one utxo for newly-issued asset, we can use
    # destructuring assignment to get the first element of resulting list.
    # Utxo should be unconfirmed yet, so we specify 0 for minconf and maxconf.
    (asset_utxo, ) = rpc.listunspent(0, 0, [], False, {'asset': asset_str})

    say('Unspent utxo for asset {} is {}:{}'.format(asset_str,
                                                    asset_utxo['txid'],
                                                    asset_utxo['vout']))

    say("Retrieving private key to spend UTXO (source address {})".format(
        asset_utxo['address']))

    # Retrieve key to spend the UTXO and add it to asset_utxo dict
    asset_utxo['key'] = CCoinKey(rpc.dumpprivkey(asset_utxo['address']))

    return asset_str, asset_utxo
Esempio n. 4
0
def print_verbose(signature, key, msg):
    secret = CCoinKey(key)
    address = P2PKHCoinAddress.from_pubkey(secret.pub)
    message = BitcoinMessage(msg)
    print('Address: %s' % address)
    print('Message: %s' % msg)
    print('Signature: %s' % signature)
    print('Verified: %s' % VerifyMessage(address, message, signature))
    print('\nTo verify using bitcoin core:')
    print('\n`bitcoin-cli verifymessage %s \'%s\' \'%s\'`\n' %
          (address, signature.decode('ascii'), msg))
Esempio n. 5
0
def get_dst_addr(say, rpc):
    """Generate an address and retrieve blinding key for it"""

    # Note that we could generate our own keys, and make
    # addresses from them, and then derive the blinding keys,
    # but then we would have to decide how to store the keys
    # for the user to be able to do own exploration
    # after example finishes working. We choose the easiest path.
    #
    # Note that if we have master blinding key
    # (Elements will include master blinding key in wallet dump
    # in future versions), we could derive the blinding key
    # from the master key and the address, with this code:
    # addr.to_scriptPubKey().derive_blinding_key(blinding_derivation_key)
    # derive_blinding_key() follows the logic of blinding key
    # derivation in Elements Core source.

    if say:
        say('Generating new address and retrieving blinding key for it')
    addr_str = rpc.getnewaddress()
    # Retrieve the blinding key
    blinding_key = CCoinKey.from_secret_bytes(x(rpc.dumpblindingkey(addr_str)))

    return CCoinAddress(addr_str), blinding_key
Esempio n. 6
0
    def test(self) -> None:
        xpriv1 = CCoinExtKey(
            'xprv9s21ZrQH143K4TFwadu5VoGfAChTWXUw49YyTWE8SRqC9ZC9AQpHspzgbAcScTmC4MURiMT7pmCbci5oKbWijJmARiUeRiLXYehCtsoVdYf'
        )
        xpriv2 = CCoinExtKey(
            'xprv9uZ4jKNZFfGEQTTunEuy2cLQMckzuy5saCmiKuxYJgHX5pGFCx3KQ8mTkSfuLNaWGNQ9LKCg5YzUihxoQv493ErnkcaS3q1udx9X8WZbwZc'
        )
        priv1 = CCoinKey(
            'L27zAtDgjDC34sG5ZSey1wvdZ9JyZsNnvZEwbbZYWUYXXQtgri5R')
        xpub1 = CCoinExtPubKey(
            'xpub69b6hm71WMe1PGpgUmaDPkbxYoTzpmswX8KGeinv7SPRcKT22RdMM4416kqtEUuXqXCAi7oGx7tHwCRTd3JHatE3WX1Zms6Lgj5mrbFyuro'
        )
        xpub1.assign_derivation_info(
            KeyDerivationInfo(xpub1.parent_fp, BIP32Path('m/0')))
        pub1 = CPubKey(
            x('03b0fe9cfc88fed9fcecf9dcb7bb5c90dd1a4500f4cfc5c854ffc8e54d639d6bc5'
              ))

        kstore = KeyStore(
            external_privkey_lookup=(lambda key_id, dinfo: priv1
                                     if key_id == priv1.pub.key_id else None),
            external_pubkey_lookup=(lambda key_id, dinfo: pub1
                                    if key_id == pub1.key_id else None))
        self.assertEqual(kstore.get_privkey(priv1.pub.key_id), priv1)
        self.assertEqual(kstore.get_pubkey(pub1.key_id), pub1)
        self.assertEqual(kstore.get_pubkey(priv1.pub.key_id), priv1.pub)

        kstore = KeyStore(xpriv1,
                          priv1,
                          xpub1,
                          pub1,
                          require_path_templates=False)
        self.assertEqual(kstore.get_privkey(priv1.pub.key_id), priv1)
        self.assertEqual(kstore.get_pubkey(priv1.pub.key_id), priv1.pub)
        self.assertEqual(kstore.get_pubkey(pub1.key_id), pub1)

        # check that no-derivation lookup for (priv, pub) of extended keys
        # does not return anything if derivation is not supplied,
        # but returns pubkey when empty path is supplied
        self.assertEqual(kstore.get_privkey(xpriv1.pub.key_id), None)
        self.assertEqual(
            kstore.get_privkey(
                xpriv1.pub.key_id,
                KeyDerivationInfo(xpriv1.fingerprint, BIP32Path("m"))),
            xpriv1.priv)
        self.assertEqual(kstore.get_pubkey(xpriv1.pub.key_id), None)
        self.assertEqual(
            kstore.get_pubkey(
                xpriv1.pub.key_id,
                KeyDerivationInfo(xpriv1.fingerprint, BIP32Path("m"))),
            xpriv1.pub)

        # can't find xpub1's pub without derivation
        self.assertEqual(kstore.get_pubkey(xpub1.pub.key_id), None)

        # can find with correct derivation info supplied
        self.assertEqual(
            kstore.get_pubkey(
                xpub1.pub.key_id,
                KeyDerivationInfo(xpub1.parent_fp, BIP32Path("m/0"))),
            xpub1.pub)

        # but not with incorrect derivation info
        self.assertEqual(
            kstore.get_pubkey(
                xpub1.pub.key_id,
                KeyDerivationInfo(xpub1.parent_fp, BIP32Path("m"))), None)

        # check longer derivations
        self.assertEqual(
            kstore.get_privkey(xpriv1.derive_path("0'/1'/2'").pub.key_id),
            None)
        self.assertEqual(
            kstore.get_privkey(
                xpriv1.derive_path("0'/1'/2'").pub.key_id,
                KeyDerivationInfo(xpriv1.fingerprint,
                                  BIP32Path("m/0'/1'/2'"))),
            xpriv1.derive_path("0'/1'/2'").priv)
        self.assertEqual(
            kstore.get_pubkey(
                xpriv1.derive_path("0'/1'/2'").pub.key_id,
                KeyDerivationInfo(xpriv1.fingerprint,
                                  BIP32Path("m/0'/1'/2'"))),
            xpriv1.derive_path("0'/1'/2'").pub)

        self.assertEqual(
            kstore.get_pubkey(
                xpub1.derive_path("0/1/2").pub.key_id,
                KeyDerivationInfo(xpub1.parent_fp, BIP32Path('m/0/0/1/2'))),
            xpub1.derive_path("0/1/2").pub)

        path = BIP32Path("0'/1'/2'")
        derived_xpub = xpriv2.derive_path(path).neuter()
        derived_pub = derived_xpub.derive_path('3/4/5').pub
        self.assertEqual(kstore.get_pubkey(derived_pub.key_id), None)
        kstore.add_key(derived_xpub)
        self.assertEqual(
            kstore.get_pubkey(
                derived_pub.key_id,
                KeyDerivationInfo(xpriv2.parent_fp,
                                  BIP32Path("m/0/0'/1'/2'/3/4/5"))),
            derived_pub)

        kstore.add_key(xpriv2)

        derived_pub = xpriv2.derive_path('3h/4h/5h').pub
        self.assertEqual(
            kstore.get_pubkey(
                derived_pub.key_id,
                KeyDerivationInfo(xpriv2.parent_fp,
                                  BIP32Path("m/0/3'/4'/5'"))), derived_pub)

        derived_priv = xpriv2.derive_path('3h/4h/5h').priv
        self.assertEqual(
            kstore.get_privkey(
                derived_priv.pub.key_id,
                KeyDerivationInfo(xpriv2.parent_fp,
                                  BIP32Path("m/0/3'/4'/5'"))), derived_priv)

        # check that .remove_key() works
        kstore.remove_key(xpriv1)
        kstore.remove_key(xpub1)
        kstore.remove_key(priv1)
        kstore.remove_key(pub1)

        self.assertEqual(kstore.get_privkey(priv1.pub.key_id), None)
        self.assertEqual(kstore.get_pubkey(pub1.key_id), None)
        self.assertEqual(
            kstore.get_privkey(
                xpriv1.derive_path("0'/1'/2'").pub.key_id,
                KeyDerivationInfo(xpriv1.fingerprint,
                                  BIP32Path("m/0'/1'/2'"))), None)
        self.assertEqual(
            kstore.get_pubkey(xpub1.derive_path("0/1/2").pub.key_id), None)
Esempio n. 7
0
    def test_path_template_enforcement(self) -> None:
        xpriv1 = CCoinExtKey(
            'xprv9s21ZrQH143K4TFwadu5VoGfAChTWXUw49YyTWE8SRqC9ZC9AQpHspzgbAcScTmC4MURiMT7pmCbci5oKbWijJmARiUeRiLXYehCtsoVdYf'
        )
        xpriv2 = CCoinExtKey(
            'xprv9s21ZrQH143K3QgBvK4tkeHuvuWc6KETTTcgGQ4NmW7g16AtCPV4hZpujiimpLM9ivFPgsMdNNVuVUnDwChutxczNKYHzP1Mo5HuqG7CNYv'
        )
        assert xpriv2.derivation_info
        assert len(xpriv2.derivation_info.path) == 0
        priv1 = CCoinKey(
            'L27zAtDgjDC34sG5ZSey1wvdZ9JyZsNnvZEwbbZYWUYXXQtgri5R')
        xpub1 = CCoinExtPubKey(
            'xpub69b6hm71WMe1PGpgUmaDPkbxYoTzpmswX8KGeinv7SPRcKT22RdMM4416kqtEUuXqXCAi7oGx7tHwCRTd3JHatE3WX1Zms6Lgj5mrbFyuro'
        )
        xpub2 = xpriv2.derive(333).neuter()
        xpub1.assign_derivation_info(
            KeyDerivationInfo(xpub1.parent_fp, BIP32Path('m/0')))
        pub1 = CPubKey(
            x('03b0fe9cfc88fed9fcecf9dcb7bb5c90dd1a4500f4cfc5c854ffc8e54d639d6bc5'
              ))

        xpub3 = xpub1.derive(0)
        xpub3.assign_derivation_info(
            KeyDerivationInfo(x('abcdef10'), BIP32Path('m/0/0')))

        # No error when require_path_templates is not set
        KeyStore(xpriv1,
                 xpriv2,
                 priv1,
                 xpub1,
                 pub1,
                 require_path_templates=False)

        with self.assertRaisesRegex(ValueError,
                                    'only make sense for extended keys'):
            KeyStore((priv1, BIP32PathTemplate('')))  # type: ignore
        with self.assertRaisesRegex(ValueError,
                                    'only make sense for extended keys'):
            KeyStore((pub1, [BIP32PathTemplate('')]))  # type: ignore
        with self.assertRaisesRegex(ValueError,
                                    'path templates must be specified'):
            KeyStore(xpriv1)
        with self.assertRaisesRegex(ValueError,
                                    'path templates must be specified'):
            KeyStore(xpub1)

        # same but via add_key
        ks = KeyStore()
        with self.assertRaisesRegex(ValueError,
                                    'only make sense for extended keys'):
            ks.add_key((priv1, BIP32PathTemplate('')))  # type: ignore
        with self.assertRaisesRegex(ValueError,
                                    'only make sense for extended keys'):
            ks.add_key((pub1, [BIP32PathTemplate('')]))  # type: ignore
        with self.assertRaisesRegex(ValueError,
                                    'path templates list is empty'):
            ks.add_key((pub1, []))  # type: ignore
        with self.assertRaisesRegex(ValueError,
                                    'only make sense for extended keys'):
            ks.add_key((pub1, ''))  # type: ignore
        with self.assertRaisesRegex(ValueError,
                                    'index template format is not valid'):
            ks.add_key((xpub1, 'abc'))  # type: ignore
        with self.assertRaisesRegex(TypeError,
                                    'is expected to be an instance of '):
            ks.add_key((xpub1, [10]))  # type: ignore
        with self.assertRaisesRegex(ValueError,
                                    'path templates must be specified'):
            ks.add_key(xpriv1)
        with self.assertRaisesRegex(ValueError,
                                    'path templates must be specified'):
            ks.add_key(xpub1)

        # No error when path templates are specified for extended keys
        ks = KeyStore(
            (xpriv1, BIP32PathTemplate('m')),
            (xpriv2, 'm/[44,49,84]h/0h/0h/[0-1]/*'),
            (xpub1, ''),  # '' same as BIP32PathTemplate('')
            (xpub2, ['0/1', 'm/333/3/33']),
            (xpub3, BIP32PathTemplate('m/0/0/1')),
            priv1,
            pub1)

        self.assertEqual(ks.get_privkey(priv1.pub.key_id), priv1)
        self.assertEqual(ks.get_pubkey(pub1.key_id), pub1)

        # still can find non-extended priv even if derivation info is
        # specified, because there's exact match.
        self.assertEqual(
            ks.get_privkey(priv1.pub.key_id,
                           KeyDerivationInfo(xpriv1.parent_fp,
                                             BIP32Path("m"))), priv1)
        self.assertEqual(ks.get_pubkey(pub1.key_id), pub1)

        # can't find without derivation specified
        self.assertEqual(ks.get_privkey(xpriv1.pub.key_id), None)
        # but can find with derivation specified
        self.assertEqual(
            ks.get_privkey(
                xpriv1.pub.key_id,
                KeyDerivationInfo(xpriv1.fingerprint, BIP32Path('m'))),
            xpriv1.priv)

        # can't find without derivation specified
        self.assertEqual(ks.get_pubkey(xpub1.pub.key_id), None)

        # can find with derivation specified
        self.assertEqual(
            ks.get_pubkey(xpub1.pub.key_id,
                          KeyDerivationInfo(xpub1.parent_fp,
                                            BIP32Path('m/0'))), xpub1.pub)

        # exception when derivation goes beyond template
        with self.assertRaises(BIP32PathTemplateViolation):
            ks.get_pubkey(
                xpub1.derive(1).pub.key_id,
                KeyDerivationInfo(xpub1.parent_fp, BIP32Path('m/0/1')))

        # success when template allows
        self.assertEqual(
            ks.get_pubkey(
                xpub3.derive(1).pub.key_id,
                KeyDerivationInfo(x('abcdef10'), BIP32Path('m/0/0/1'))),
            xpub3.derive(1).pub)

        # fails when template not allows
        with self.assertRaises(BIP32PathTemplateViolation):
            ks.get_pubkey(
                xpub3.derive(2).pub.key_id,
                KeyDerivationInfo(x('abcdef10'), BIP32Path('m/0/0/2')))

        long_path = BIP32Path(
            "m/43435/646/5677/5892/58885/2774/9943/75532/8888")

        with self.assertRaises(BIP32PathTemplateViolation):
            ks.get_privkey(
                xpriv2.derive_path(long_path).pub.key_id,
                KeyDerivationInfo(xpriv2.fingerprint, long_path))

        with self.assertRaises(BIP32PathTemplateViolation):
            ks.get_privkey(
                xpriv2.derive_path("44'/0'/0'/3/25").pub.key_id,
                KeyDerivationInfo(xpriv2.fingerprint,
                                  BIP32Path('m/44h/0h/0h/3/25')))

        with self.assertRaises(BIP32PathTemplateViolation):
            ks.get_privkey(
                xpriv2.derive_path("44'/0'/0'/0/1'").pub.key_id,
                KeyDerivationInfo(xpriv2.fingerprint,
                                  BIP32Path('m/44h/0h/0h/0/1h')))

        self.assertEqual(
            ks.get_privkey(
                xpriv2.derive_path("44'/0'/0'/1/25").pub.key_id,
                KeyDerivationInfo(xpriv2.fingerprint,
                                  BIP32Path('m/44h/0h/0h/1/25'))),
            xpriv2.derive_path("44'/0'/0'/1/25").priv)

        with self.assertRaises(BIP32PathTemplateViolation):
            ks.get_pubkey(
                xpub2.derive_path('0').pub.key_id,
                KeyDerivationInfo(xpub2.parent_fp, BIP32Path('m/333/0')))

        with self.assertRaises(BIP32PathTemplateViolation):
            ks.get_pubkey(
                xpub2.derive_path('3/34').pub.key_id,
                KeyDerivationInfo(xpub2.parent_fp, BIP32Path('m/333/3/34')))

        self.assertEqual(
            ks.get_pubkey(
                xpub2.derive_path('3/33').pub.key_id,
                KeyDerivationInfo(xpub2.parent_fp, BIP32Path('m/333/3/33'))),
            xpub2.derive_path('3/33').pub)

        xpub49 = xpriv2.derive_path("m/49'/0'/0'/0").neuter()

        with self.assertRaisesRegex(ValueError, 'must specify full path'):
            ks = KeyStore(
                xpriv2,
                xpub49,
                default_path_template='[44,49,84]h/0h/0h/[0-1]/[0-50000]')

        ks = KeyStore(
            xpriv2,
            xpub49,
            default_path_template='m/[44,49,84]h/0h/0h/[0-1]/[0-50000]')

        with self.assertRaises(BIP32PathTemplateViolation):
            ks.get_privkey(
                xpriv2.derive_path(long_path).pub.key_id,
                KeyDerivationInfo(xpriv2.fingerprint, long_path))

        with self.assertRaises(BIP32PathTemplateViolation):
            ks.get_privkey(
                xpriv2.derive_path("44'/0'/0'/1/50001").pub.key_id,
                KeyDerivationInfo(xpriv2.fingerprint,
                                  BIP32Path('m/44h/0h/0h/1/50001')))

        self.assertEqual(
            ks.get_privkey(
                xpriv2.derive_path("44'/0'/0'/1/25").pub.key_id,
                KeyDerivationInfo(xpriv2.fingerprint,
                                  BIP32Path('m/44h/0h/0h/1/25'))),
            xpriv2.derive_path("44'/0'/0'/1/25").priv)

        with self.assertRaises(BIP32PathTemplateViolation):
            ks.get_pubkey(
                xpub49.derive_path('50001').pub.key_id,
                KeyDerivationInfo(xpriv2.fingerprint,
                                  BIP32Path('m/49h/0h/0h/0/50001')))

        with self.assertRaises(BIP32PathTemplateViolation):
            ks.get_pubkey(
                xpub49.derive_path('50000/3').pub.key_id,
                KeyDerivationInfo(xpriv2.fingerprint,
                                  BIP32Path('m/49h/0h/0h/0/50000/3')))

        self.assertEqual(
            ks.get_pubkey(
                xpub49.derive_path('50000').pub.key_id,
                KeyDerivationInfo(xpriv2.fingerprint,
                                  BIP32Path('m/49h/0h/0h/0/50000'))),
            xpub49.derive_path('50000').pub)
Esempio n. 8
0
    
    f = sys.argv[1]
    #with open(sys.argv[1]) as f:
        # We could use CTransaction here, but if we want to
        # use mypy to do static checking, we need to use the elements-specific
        # classes. mypy does cannot know about dynamic class dispatch.
    #tx = CElementsTransaction.deserialize(x(f.readline().rstrip()))                                                                                                     [16/1870]
    tx = CElementsTransaction.deserialize(x(f))


    # Read in the blinding key, expected to be in WIF format.
    
    f = sys.argv[2]
    #with open(sys.argv[2]) as f:
    #bkey = CCoinKey.from_secret_bytes(x(f.readline().rstrip()))
    bkey = CCoinKey.from_secret_bytes(x(f))


    # Iterate through transaction ouptputs, and unblind what we can.
    print("")
    for n, vout in enumerate(tx.vout):
        # Note that nValue of vout in Elements is not a simple int,
        # but CConfidentialValue, which can either be explicit, and can be
        # converted to satoshis with to_amount(), or it can be blinded, in
        # which case you need to unblind the output to know its value.
        if vout.nValue.is_explicit():
            # The output is not blinded, we can access the values right away
            assert vout.nAsset.is_explicit(), "unblinding just the asset is not supported"
            if vout.is_fee():
                print("vout {}: fee".format(n))
            else:
Esempio n. 9
0
    path_template = None
    require_path_templates = True
    if args.path_template is not None:
        if args.without_path_template_checks:
            print('--without-path-template-checks conflicts with '
                  '--path-template argument')
            sys.exit(-1)
        path_template = BIP32PathTemplate(args.path_template)
    elif args.without_path_template_checks:
        require_path_templates = False

    keys = []
    for key_index, key_data in enumerate(args.key or []):
        k: Optional[Union[CCoinKey, CCoinExtKey]] = None
        try:
            k = CCoinKey(key_data)
        except (ValueError, Base58Error):
            pass

        try:
            k = CCoinExtKey(key_data)
        except (ValueError, Base58Error):
            pass

        if k is None:
            print(f'key at position {key_index} is not in recognized format')
            sys.exit(-1)
        keys.append(k)

    psbt = PartiallySignedTransaction.from_base64_or_binary(psbt_data)
    sign_result = psbt.sign(KeyStore.from_iterable(
Esempio n. 10
0
        sys.exit(-1)

    # Switch the chain parameters to Elements
    select_chain_params('elements')

    # Read in and decode the blinded transaction.
    # expected to be hex-encoded as one line.
    with open(sys.argv[1]) as f:
        # We could use CTransaction here, but if we want to
        # use mypy to do static checking, we need to use the elements-specific
        # classes. mypy does cannot know about dynamic class dispatch.
        input_tx = CElementsTransaction.deserialize(x(f.readline().rstrip()))

    # Read in the key, expected to be in WIF format.
    with open(sys.argv[2]) as f:
        key = CCoinKey(f.readline().rstrip())

    # Read in the unblinding key, expected to be in HEX format.
    with open(sys.argv[3]) as f:
        bkey = CCoinKey.from_secret_bytes(x(f.readline().rstrip()))

    dst_addr = CElementsAddress(sys.argv[4])

    # Construct P2SH_P2WPKH address from the loaded key
    spk = CScript([0, Hash160(key.pub)]).to_p2sh_scriptPubKey()
    src_addr = P2SHCoinAddress.from_scriptPubKey(spk)

    sys.stderr.write(
        '\nSearching for ouptut with address {}\n'.format(src_addr))

    utxo = None
Esempio n. 11
0
def sign_message(key, msg):
    secret = CCoinKey(key)
    message = BitcoinMessage(msg)
    return SignMessage(secret, message)
Esempio n. 12
0
def sign_message(key: str, msg: str) -> bytes:
    secret = CCoinKey(key)
    message = BitcoinMessage(msg)
    return SignMessage(secret, message)
Esempio n. 13
0
        sys.exit(-1)

    # Switch the chain parameters to Elements
    select_chain_params('elements')

    # Read in and decode the blinded transaction.
    # expected to be hex-encoded as one line.
    with open(sys.argv[1]) as f:
        # We could use CTransaction here, but if we want to
        # use mypy to do static checking, we need to use the elements-specific
        # classes. mypy does cannot know about dynamic class dispatch.
        tx = CElementsTransaction.deserialize(x(f.readline().rstrip()))

    # Read in the blinding key, expected to be in WIF format.
    with open(sys.argv[2]) as f:
        bkey = CCoinKey.from_secret_bytes(x(f.readline().rstrip()))

    # Iterate through transaction ouptputs, and unblind what we can.
    print("")
    for n, vout in enumerate(tx.vout):
        # Note that nValue of vout in Elements is not a simple int,
        # but CConfidentialValue, which can either be explicit, and can be
        # converted to satoshis with to_amount(), or it can be blinded, in
        # which case you need to unblind the output to know its value.
        if vout.nValue.is_explicit():
            # The output is not blinded, we can access the values right away
            assert vout.nAsset.is_explicit(
            ), "unblinding just the asset is not supported"
            if vout.is_fee():
                print("vout {}: fee".format(n))
            else:
Esempio n. 14
0
elif args.verbosity >= 1:
    logging.root.setLevel(logging.DEBUG)
elif args.verbosity == -1:
    logging.root.setLevel(logging.WARNING)
elif args.verbosity <= -2:
    logging.root.setLevel(logging.ERROR)

if args.testnet:
    bitcointx.select_chain_params('bitcoin/testnet')
elif args.regtest:
    bitcointx.select_chain_params('bitcoin/regtest')

rpc = bitcointx.rpc.RPCCaller(allow_default_conf=True)

if args.privkey is None:
    args.privkey = CCoinKey.from_secret_bytes(os.urandom(32))

else:
    args.privkey = CCoinKey(args.privkey)

logging.info('Using keypair %s %s' % (b2x(args.privkey.pub), args.privkey))

# Turn the text file into padded lines
if args.fd is sys.stdin:
    # work around a bug where even though we specified binary encoding we get
    # the sys.stdin instead.
    args.fd = sys.stdin.buffer
raw_padded_lines = [
    b'\x00' + line.rstrip().ljust(args.min_len) + b'\x00'
    for line in args.fd.readlines()
]