Exemplo n.º 1
0
 def test_public_key_from_private_key(self):
     for priv_details in self.priv_pub_addr:
         privkey = PrivateKey.from_text(priv_details['priv'])
         result = privkey.public_key.to_hex()
         self.assertEqual(priv_details['pub'], result)
         self.assertEqual(priv_details['txin_type'], 'p2pkh')
         self.assertEqual(priv_details['compressed'], privkey.is_compressed())
Exemplo n.º 2
0
    def serialize(self, jsontx):
        """Create a transaction from json inputs.
        Inputs must have a redeemPubkey.
        Outputs must be a list of {'address':address, 'value':satoshi_amount}.
        """
        keypairs = {}
        inputs = jsontx.get('inputs')
        outputs = jsontx.get('outputs')
        locktime = jsontx.get('locktime', 0)
        for txin in inputs:
            if txin.get('output'):
                prevout_hash, prevout_n = txin['output'].split(':')
                txin['prevout_n'] = int(prevout_n)
                txin['prevout_hash'] = prevout_hash
            sec = txin.get('privkey')
            if sec:
                privkey = PrivateKey.from_text(sec)
                txin_type, privkey, compressed = ('p2pkh', privkey.to_bytes(),
                                                  privkey.is_compressed())
                pubkey = privkey.public_key.to_hex()
                keypairs[pubkey] = privkey, compressed
                txin['type'] = txin_type
                txin['x_pubkeys'] = [pubkey]
                txin['signatures'] = [None]
                txin['num_sig'] = 1

        outputs = [(TYPE_ADDRESS, Address.from_string(x['address']),
                    int(x['value'])) for x in outputs]
        tx = Transaction.from_io(inputs, outputs, locktime=locktime)
        tx.sign(keypairs)
        return tx.as_dict()
Exemplo n.º 3
0
 def test_import_privkey(self, WIF, pk_string):
     enc_prvkey_text = pw_encode(WIF, "password")
     public_key = PrivateKey.from_text(WIF).public_key
     d = Imported_KeyStore({})
     d.import_private_key(1, public_key, enc_prvkey_text)
     assert d.get_public_key_for_id(1) == public_key
     assert WIF == d.export_private_key(public_key, "password")
Exemplo n.º 4
0
 def check_seed(self, seed):
     secexp = self.stretch_key(seed)
     master_private_key = PrivateKey(int_to_be_bytes(secexp, 32))
     master_public_key = master_private_key.public_key.to_bytes(compressed=False)[1:]
     if master_public_key != bfh(self.mpk):
         logger.error('invalid password (mpk) %s %s', self.mpk, master_public_key.hex())
         raise InvalidPassword()
Exemplo n.º 5
0
class SVRegTestnet(object):
    """The checkpoint cannot be made until the bitcoin node has at least generated 146 blocks (to
    calculate the DAA). Blocks are therefore generated until there are at least 200. A new
    checkpoint at height = 200 is then calculated before allowing anything further to proceed.

    Note: RegTest overflows the max nBits field, presumably due to a very short time interval
    between generated blocks. To modify this field would be to change the hash of the header so
    as a workaround, bitcoinx is monkeypatched to skip the checking of the difficulty target
    (see HeadersRegtestMod)."""

    # hardcoded
    # - WIF private_key:    cT3G2vJGRNbpmoCVXYPYv2JbngzwtznLvioPPJXu39jfQeLpDuX5
    # - Pubkey hash:        mfs8Y8gAwC2vJHCeSXkHs6LF5nu5PA7nxc
    REGTEST_FUNDS_PRIVATE_KEY: PrivateKey = PrivateKey(bytes.fromhex(
        'a2d9803c912ab380c1491d3bd1aaab34ca06742d7885a224ec8d386182d26ed2'),
                                                       coin=BitcoinRegtest)
    REGTEST_FUNDS_PRIVATE_KEY_WIF = REGTEST_FUNDS_PRIVATE_KEY.to_WIF()
    REGTEST_FUNDS_PUBLIC_KEY: PublicKey = REGTEST_FUNDS_PRIVATE_KEY.public_key
    REGTEST_P2PKH_ADDRESS: P2PKH_Address = REGTEST_FUNDS_PUBLIC_KEY.to_address(
    ).to_string()

    # For CI/CD use (restapi will by default reset everything back to empty wallet with this seed)
    # First receive address: mwv1WZTsrtKf3S9mRQABEeMaNefLbQbKpg
    REGTEST_DEFAULT_ACCOUNT_SEED = 'tprv8ZgxMBicQKsPd4wsdaJ11eH84eq4hHLX1K6Mx8EQQhJzq8jr25WH1m8hg' \
        'GkCqnksJDCZPZbDoMbQ6QtroyCyn5ZckCmsLeiHDb1MAxhNUHN'

    MIN_CHECKPOINT_HEIGHT = 0
    ADDRTYPE_P2PKH = 111
    ADDRTYPE_P2SH = 196
    CASHADDR_PREFIX = "bchtest"
    DEFAULT_PORTS = {'t': '51001', 's': '51002'}
    DEFAULT_SERVERS = read_json_dict('servers_regtest.json')
    GENESIS = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
    NAME = 'regtest'
    BITCOIN_URI_PREFIX = "bitcoin"
    PAY_URI_PREFIX = "pay"
    WIF_PREFIX = 0xef
    BIP276_VERSION = 2
    COIN = BitcoinRegtest

    # Use the following for a chain reset.
    CHECKPOINT = CheckPoint(bytes.fromhex(
        '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd'
        '7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff001d1aa4ae18'
    ),
                            height=0,
                            prev_work=0)
    VERIFICATION_BLOCK_MERKLE_ROOT = None

    BIP44_COIN_TYPE = 1

    BLOCK_EXPLORERS: Dict[str, Tuple[str, Dict[str, str]]] = {}

    FAUCET_URL = ""
    KEEPKEY_DISPLAY_COIN_NAME = 'Testnet'
    # Note: testnet allegedly supported only by unofficial firmware
    TREZOR_COIN_NAME = 'Bcash Testnet'
    TWENTY_MINUTE_RULE = True
Exemplo n.º 6
0
class SVRegTestnet(object):
    """The checkpoint cannot be made until the bitcoin node has at least generated 146 blocks (to
    calculate the DAA). Blocks are therefore generated until there are at least 200. A new
    checkpoint at height = 200 is then calculated before allowing anything further to proceed.

    Note: RegTest overflows the max nBits field, presumably due to a very short time interval
    between generated blocks. To modify this field would be to change the hash of the header so
    as a workaround, bitcoinx is monkeypatched to skip the checking of the difficulty target
    (see HeadersRegtestMod)."""

    # hardcoded
    # - WIF private_key:    cT3G2vJGRNbpmoCVXYPYv2JbngzwtznLvioPPJXu39jfQeLpDuX5
    # - Pubkey hash:        mfs8Y8gAwC2vJHCeSXkHs6LF5nu5PA7nxc
    REGTEST_FUNDS_PRIVATE_KEY: PrivateKey = PrivateKey(bytes.fromhex(
        'a2d9803c912ab380c1491d3bd1aaab34ca06742d7885a224ec8d386182d26ed2'),
                                                       coin=BitcoinRegtest)
    REGTEST_FUNDS_PRIVATE_KEY_WIF = REGTEST_FUNDS_PRIVATE_KEY.to_WIF()
    REGTEST_FUNDS_PUBLIC_KEY: PublicKey = REGTEST_FUNDS_PRIVATE_KEY.public_key
    REGTEST_P2PKH_ADDRESS: P2PKH_Address = REGTEST_FUNDS_PUBLIC_KEY.to_address(
    ).to_string()

    # For CI/CD use (restapi will by default reset everything back to empty wallet with this seed)
    REGTEST_DEFAULT_ACCOUNT_SEED = 'tprv8ZgxMBicQKsPd4wsdaJ11eH84eq4hHLX1K6Mx8EQQhJzq8jr25WH1m8hg' \
        'GkCqnksJDCZPZbDoMbQ6QtroyCyn5ZckCmsLeiHDb1MAxhNUHN'

    MIN_CHECKPOINT_HEIGHT = 200
    ADDRTYPE_P2PKH = 111
    ADDRTYPE_P2SH = 196
    CASHADDR_PREFIX = "bchtest"
    DEFAULT_PORTS = {'t': '51001', 's': '51002'}
    DEFAULT_SERVERS = read_json_dict('servers_regtest.json')
    GENESIS = "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943"
    NAME = 'regtest'
    URI_PREFIX = "bitcoin"
    WIF_PREFIX = 0xef
    BIP276_VERSION = 2
    COIN = BitcoinRegtest

    CHECKPOINT = CheckPoint(bytes.fromhex(
        '0000002029f1e3df7fda466242b9b56076792ffdb9e5d7ea51610307bc010000000000007ac1fa84'
        'ef5f0998232fb01cd6fea2c0199e34218df2fb33e4e80e79d22b6a746994435d41c4021a208bae0a'
    ),
                            height=123,
                            prev_work=123)

    VERIFICATION_BLOCK_MERKLE_ROOT = (
        '93414acafdef2dad790c456a424a6a261b66771a3426117125d8c13a1c93f10e')

    BIP44_COIN_TYPE = 1

    BLOCK_EXPLORERS: Dict[str, Tuple[str, Dict[str, str]]] = {}

    FAUCET_URL = ""
    KEEPKEY_DISPLAY_COIN_NAME = 'Testnet'
    # Note: testnet allegedly supported only by unofficial firmware
    TREZOR_COIN_NAME = 'Bcash Testnet'
    TWENTY_MINUTE_RULE = True
Exemplo n.º 7
0
 def test_pubkeys_to_address(self, tmp_storage, network):
     coin = network.COIN
     privkey = PrivateKey.from_random()
     WIF = privkey.to_WIF(coin=coin)
     wallet = ImportedPrivkeyWallet.from_text(tmp_storage, WIF, None)
     public_key = privkey.public_key
     pubkey_hex = public_key.to_hex()
     address = public_key.to_address(coin=coin).to_string()
     assert wallet.pubkeys_to_address(pubkey_hex) == Address.from_string(address)
Exemplo n.º 8
0
 def test_P2PKHK_script(self):
     p = PrivateKey.from_random()
     PC = p.public_key
     PU = PC.complement()
     for P in (PC, PU):
         script = P.P2PKH_script()
         data = P.hash160()
         assert script == (
             bytes([OP_DUP, OP_HASH160, len(data)]) + data +
             bytes([OP_EQUALVERIFY, OP_CHECKSIG]))
Exemplo n.º 9
0
 def test_pubkeys_to_address(self, tmp_storage, network):
     coin = network.COIN
     privkey = PrivateKey.from_random()
     WIF = privkey.to_WIF(coin=coin)
     parent_wallet = _TestableParentWallet.as_legacy_wallet_container(
         tmp_storage)
     wallet = ImportedPrivkeyWallet.from_text(parent_wallet, WIF)
     public_key = privkey.public_key
     pubkey_hex = public_key.to_hex()
     address = public_key.to_address(coin=coin).to_string()
     assert wallet.pubkeys_to_address(pubkey_hex) == address_from_string(
         address)
Exemplo n.º 10
0
def test_verify_wrong_addr():
    key_priv = PrivateKey.from_arbitrary_bytes(b'123test')
    key_pub = key_priv.public_key
    pkh = key_pub.hash160()
    pkh_0_out_wrong = TxOutput(in_sats - miner_fee,
                               P2PKH_Address(pkh, Bitcoin).to_script())
    context = create_input_context(in_sats, acs.locking_script,
                                   pkh_0_out_wrong)
    preimage = scryptlib.utils.get_preimage_from_input_context(
        context, sighash_flag)
    verify_result = acs.unlock(SigHashPreimage(preimage)).verify(context)
    assert verify_result == False
Exemplo n.º 11
0
 def test_from_template_bad(self):
     public_keys = [
         PrivateKey.from_random().public_key.to_bytes() for n in range(2)
     ]
     with pytest.raises(ValueError):
         script = P2MultiSig_Output.from_template(pack_byte(1),
                                                  *public_keys,
                                                  pack_byte(1))
     with pytest.raises(ValueError):
         script = P2MultiSig_Output.from_template(pack_byte(1),
                                                  *public_keys,
                                                  pack_byte(3))
Exemplo n.º 12
0
def test_accumulator_multisig_scriptsig_NofM(masks, scripts_hex):
    for mask in masks:
        pubkeys = []
        signatures = []
        for key_index in range(len(mask)):
            private_key = PrivateKey.from_hex(private_keys_hex[key_index])
            pubkeys.append(private_key.public_key)
            if mask[key_index]:
                signatures.append(bytes.fromhex(signatures_hex[key_index]))
            else:
                signatures.append(NO_SIGNATURE)
        script = create_script_sig(ScriptType.MULTISIG_ACCUMULATOR, sum(mask), pubkeys, signatures)
        assert scripts_hex[mask] == script.to_hex()
Exemplo n.º 13
0
    def test_decrypt_message(self):
        password = '******'
        message = b'BitcoinSV'
        prvkey_text = "5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ"
        enc_prvkey_text = pw_encode(prvkey_text, password)
        public_key = PrivateKey.from_text(prvkey_text).public_key
        d = Imported_KeyStore({})
        d.import_private_key(1, public_key, enc_prvkey_text)

        enc_msg = ('QklFMQNkonLnVmRMF3dl+P0rHSbM4lvDPmnE2CFcD+98gGsOe6qtKtmVbCg4'
                   '9bxmT6vfmzl7udrvT81wH1Ri7wZItndtLiNHii6FBNVzoSV/1ZqN3w==')
        decrypted_message = d.decrypt_message(public_key, enc_msg, password)
        assert decrypted_message == message
Exemplo n.º 14
0
 def signtransaction(self, tx, privkey=None, password=None):
     """Sign a transaction. The wallet keys will be used unless a private key is provided."""
     tx = Transaction.from_hex(tx)
     if privkey:
         privkey2 = PrivateKey.from_text(privkey)
         txin_type, privkey2, compressed = ('p2pkh', privkey2.to_bytes(),
                                            privkey2.is_compressed())
         h160 = hash_160(privkey2.public_key.to_bytes())
         x_pubkey = 'fd' + bh2u(b'\x00' + h160)
         tx.sign({x_pubkey: (privkey2, compressed)})
     else:
         self.wallet.sign_transaction(tx, password)
     return tx.as_dict()
Exemplo n.º 15
0
    def test_sign_transaction(self):
        eckey1 = PrivateKey(bfh('7e1255fddb52db1729fc3ceb21a46f95b8d9fe94cc83425e936a6c5223bb679d'))
        sig1 = eckey1.sign(bfh('5a548b12369a53faaa7e51b5081829474ebdd9c924b3a8230b69aa0be254cd94'), None)
        self.assertEqual(bfh('3045022100902a288b98392254cd23c0e9a49ac6d7920f171b8249a48e484b998f1874a2010220723d844826828f092cf400cb210c4fa0b8cd1b9d1a7f21590e78e022ff6476b9'), sig1)

        eckey2 = PrivateKey(bfh('c7ce8c1462c311eec24dff9e2532ac6241e50ae57e7d1833af21942136972f23'))
        sig2 = eckey2.sign(bfh('642a2e66332f507c92bda910158dfe46fc10afbf72218764899d3af99a043fac'), None)
        self.assertEqual(bfh('30440220618513f4cfc87dde798ce5febae7634c23e7b9254a1eabf486be820f6a7c2c4702204fef459393a2b931f949e63ced06888f35e286e446dc46feb24b5b5f81c6ed52'), sig2)
Exemplo n.º 16
0
    def test_sign_message(self):
        password = '******'
        message = 'BitcoinSV'
        prvkey_text = "5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ"
        enc_prvkey_text = pw_encode(prvkey_text, password)
        public_key = PrivateKey.from_text(prvkey_text).public_key
        d = Imported_KeyStore({})
        d.import_private_key(1, public_key, enc_prvkey_text)

        msg_sig = d.sign_message(public_key, message, password)
        assert msg_sig.hex() == (
            '1c26a18cb236e54bbe7e3db56639ef5cbefcf5a2e28850cdd304970832f84031'
            'fc073bed1a151f0510e5558a22d23f16ed8032a1b74ffcac05227c053e1a1d8af5'
        )
Exemplo n.º 17
0
 def sign(self, keypairs):
     assert all(isinstance(key, XPublicKey) for key in keypairs)
     for txin in self.inputs:
         if txin.is_complete():
             continue
         for j, x_pubkey in enumerate(txin.x_pubkeys):
             if x_pubkey in keypairs.keys():
                 logger.debug("adding signature for %s", x_pubkey)
                 sec, compressed = keypairs.get(x_pubkey)
                 txin.signatures[j] = self.sign_txin(txin, sec)
                 if x_pubkey.kind() == 0xfd:
                     pubkey_bytes = PrivateKey(sec).public_key.to_bytes(compressed=compressed)
                     txin.x_pubkeys[j] = XPublicKey(pubkey_bytes)
     logger.debug("is_complete %s", self.is_complete())
Exemplo n.º 18
0
def test_store__write_encrypted(store_class) -> None:
    privkey = PrivateKey.from_random()
    wallet_path = tempfile.mktemp()
    store = store_class(wallet_path, privkey.public_key.to_hex())
    assert not store.is_primed()
    store.put("number", 10)
    store._write()
    assert store.is_primed()
    # This will raise an assertion if there is not locatible data for the JSON lump.
    store.read_raw_data()
    assert store.get("number") == 10

    store = store_class(wallet_path, privkey.public_key.to_hex())
    assert store.is_primed()
    store.read_raw_data()
    encrypted_data = store.get_encrypted_data()
    print(encrypted_data)
    raw_data = zlib.decompress(privkey.decrypt_message(encrypted_data))
    store.load_data(raw_data)
    assert store.get("number") == 10
Exemplo n.º 19
0
 def sign(self, keypairs):
     for i, txin in enumerate(self.inputs()):
         num = txin['num_sig']
         pubkeys, x_pubkeys = self.get_sorted_pubkeys(txin)
         for j, x_pubkey in enumerate(x_pubkeys):
             signatures = [sig for sig in txin['signatures'] if sig]
             if len(signatures) == num:
                 # txin is complete
                 break
             if x_pubkey in keypairs.keys():
                 logger.debug("adding signature for %s", x_pubkey)
                 sec, compressed = keypairs.get(x_pubkey)
                 sig = self.sign_txin(i, sec)
                 txin['signatures'][j] = sig
                 pubkey = PrivateKey(sec).public_key.to_hex(
                     compressed=compressed)
                 txin['pubkeys'][j] = pubkey  # needed for fd keys
                 self._inputs[i] = txin
     logger.debug("is_complete %s", self.is_complete())
     self.raw = self.serialize()
Exemplo n.º 20
0
 def to_tx_input(txin):
     prev_hash, prev_idx = txin['output'].split(':')
     x_pubkeys = []
     value = txin.get('value')
     sec = txin.get('privkey')
     threshold = 1
     if sec:
         privkey = PrivateKey.from_text(sec)
         privkey, compressed = privkey.to_bytes(), privkey.is_compressed()
         x_pubkey = XPublicKey(privkey.public_key.to_hex())
         keypairs[x_pubkey] = privkey, compressed
         x_pubkeys = [x_pubkey]
     return XTxInput(
         prev_hash=hex_str_to_hash(prev_hash),
         prev_idx=int(prev_idx),
         script_sig=Script(),
         sequence=0xffffffff,
         value=value,
         x_pubkeys=x_pubkeys,
         address=None,
         threshold=threshold,
         signatures=[NO_SIGNATURE] * len(x_pubkeys),
     )
Exemplo n.º 21
0
def test_xpubkey_to_address():
    privkey = PrivateKey.from_random()
    public_key = privkey.public_key
    x_pubkey = 'fd' + public_key.P2PKH_script().to_hex()
    assert xpubkey_to_address(x_pubkey) == (
        x_pubkey, Address.from_string(public_key.to_address().to_string()))
Exemplo n.º 22
0
import pytest

import scryptlib.utils
import scryptlib.contract
from scryptlib.types import Int, PubKey, Sig, SigHashPreimage, Bytes

import bitcoinx
from bitcoinx import PrivateKey, TxOutput, SigHash, pack_byte, Script, sha256, TxInput


key_priv_0 = PrivateKey.from_arbitrary_bytes(b'test123')
key_pub_0 = key_priv_0.public_key
key_priv_1 = PrivateKey.from_arbitrary_bytes(b'123test')
key_pub_1 = key_priv_1.public_key
key_priv_2 = PrivateKey.from_arbitrary_bytes(b'te123st')
key_pub_2 = key_priv_2.public_key

in_sats = 100000
out_sats = 22222

contract = './test/res/tokenUtxo.scrypt'

compiler_result = scryptlib.utils.compile_contract(contract)
desc = compiler_result.to_desc()

Token = scryptlib.contract.build_contract_class(desc)
token = Token()


def test_verify_split_in_two():
    data_part = scryptlib.utils.get_push_item(key_pub_0.to_bytes() + scryptlib.utils.get_push_int(10)[1:] + scryptlib.utils.get_push_int(90)[1:])
import pytest

import scryptlib.utils
import scryptlib.contract
from scryptlib.types import Sig, PubKey, PubKeyHash

import bitcoinx
from bitcoinx import SigHash, PrivateKey, pack_byte

key_priv = PrivateKey.from_arbitrary_bytes(b'test123')
key_pub = key_priv.public_key
pubkey_hash = key_pub.hash160()

wrong_key_priv = PrivateKey.from_arbitrary_bytes(b'somethingelse')
wrong_key_pub = wrong_key_priv.public_key

contract = './test/res/p2pkh.scrypt'

compiler_result = scryptlib.utils.compile_contract(contract)
desc = compiler_result.to_desc()

P2PKH = scryptlib.contract.build_contract_class(desc)
p2pkh_obj = P2PKH(PubKeyHash(pubkey_hash))

context = scryptlib.utils.create_dummy_input_context()

sighash_flag = SigHash(SigHash.ALL | SigHash.FORKID)
input_idx = 0
utxo_satoshis = context.utxo.value
sighash = context.tx.signature_hash(input_idx, utxo_satoshis,
                                    p2pkh_obj.locking_script, sighash_flag)
Exemplo n.º 24
0
 def get_private_key(self, pubkey: PublicKey,
                     password: str) -> Tuple[bytes, bool]:
     '''Returns a (32 byte privkey, is_compressed) pair.'''
     privkey_text = self.export_private_key(pubkey, password)
     privkey = PrivateKey.from_text(privkey_text)
     return privkey.to_bytes(), privkey.is_compressed()
Exemplo n.º 25
0
 def _mpk_from_hex_seed(cls, hex_seed) -> str:
     secexp = cls.stretch_key(hex_seed.encode())
     master_private_key = PrivateKey(int_to_be_bytes(secexp, 32))
     return master_private_key.public_key.to_hex(compressed=False)[2:]
Exemplo n.º 26
0
 def decrypt_message(self, sequence, message, password: str):
     privkey, compressed = self.get_private_key(sequence, password)
     key = PrivateKey(privkey)
     return key.decrypt_message(message)
Exemplo n.º 27
0
 def sign_message(self, derivation_path: Sequence[int], message: bytes,
                  password: str):
     privkey, compressed = self.get_private_key(derivation_path, password)
     key = PrivateKey(privkey, compressed)
     return key.sign_message(message)
Exemplo n.º 28
0
def _public_key_from_private_key_text(text):
    return PrivateKey.from_text(text).public_key
Exemplo n.º 29
0
def is_private_key(text: str) -> bool:
    try:
        PrivateKey.from_text(text)
        return True
    except ValueError:
        return False
Exemplo n.º 30
0
 def sign_message_with_wif_privkey(wif_privkey, msg):
     key = PrivateKey.from_WIF(wif_privkey)
     return key.sign_message(msg)