def check_contract(prev_tx, prev_vout, contract_hash, asset):
    a = wally.hex_from_bytes(wally.hex_to_bytes(prev_tx)[::-1])+wally.hex_from_bytes(struct.pack('<L', int(prev_vout)))
    a = wally.hex_from_bytes(wally.sha256d(wally.hex_to_bytes(a)))
    b = a + contract_hash
    merkle = wally.hex_from_bytes(wally.sha256_midstate(wally.hex_to_bytes(b)))
    c = merkle + '0000000000000000000000000000000000000000000000000000000000000000'
    asset_id = wally.hex_from_bytes(wally.sha256_midstate(wally.hex_to_bytes(c))[::-1])
    return(asset_id == asset)
Esempio n. 2
0
    def __init__(self, pubkeys, testnet):
        self.redeem_script = get_redeem_script(pubkeys)
        self.redeem_script_hex = wally.hex_from_bytes(self.redeem_script)

        script_hash = wally.hash160(self.get_witness_script())
        script_hash_hex = wally.hex_from_bytes(script_hash)
        self.scriptPubKey = get_scriptpubkey_hex(script_hash_hex)

        ver = b'\xc4' if testnet else b'\x05'
        self.address = wally.base58check_from_bytes(ver + script_hash)
Esempio n. 3
0
    def __init__(self, pubkeys, network):
        self.redeem_script = get_redeem_script(pubkeys)
        self.redeem_script_hex = wally.hex_from_bytes(self.redeem_script)

        script_hash = wally.hash160(self.get_witness_script())
        script_hash_hex = wally.hex_from_bytes(script_hash)
        self.scriptPubKey = get_scriptpubkey_hex(script_hash_hex)

        ver = {'testnet': b'\xc4', 'mainnet': b'\x05'}[network]
        self.address = wally.base58check_from_bytes(ver + script_hash)
Esempio n. 4
0
def gait_paths_from_seed(seed):
    """Get the paths for deriving the GreenAddress xpubs from a hex seed, rather than mnemonic

    This is an alternative derivation path used with hardware wallets where the mnemonic may not
    be available. It is based on a hardened public key derived from the backed up hw wallet seed.

    Returns two possible paths corresponding to two different client implementations.
    """
    assert len(seed) == wally.BIP39_SEED_LEN_512

    # Passing version=BIP32_VER_MAIN_PRIVATE here although it may be either MAIN or TEST
    # This version indicator only matters if you serialize the key
    version = wally.BIP32_VER_MAIN_PRIVATE
    root_key = wally.bip32_key_from_seed(seed, version, wally.BIP32_FLAG_SKIP_HASH)

    # path = m/18241'
    # 18241 = 0x4741 = 'GA'
    flags = wally.BIP32_FLAG_KEY_PUBLIC | wally.BIP32_FLAG_SKIP_HASH
    path = [gaconstants.HARDENED | 18241]
    derived_public_key = wally.bip32_key_from_parent_path(root_key, path, flags)
    chain_code = wally.bip32_key_get_chain_code(derived_public_key)
    pub_key = wally.bip32_key_get_pub_key(derived_public_key)

    # For historic reasons some old clients use a hexlified input path here - generate both
    path_input = chain_code + pub_key
    path_input_hex = bytearray(wally.hex_from_bytes(chain_code + pub_key), 'ascii')
    return [get_gait_path(path_input) for path_input in [path_input, path_input_hex]]
Esempio n. 5
0
    def _sign_tx(self, details, wally_tx):
        txdetails = details['transaction']
        utxos = txdetails['used_utxos'] or txdetails['old_used_utxos']

        signatures = []
        for index, utxo in enumerate(utxos):

            is_segwit = utxo['script_type'] in [14, 15, 159, 162]  # FIXME!!
            if not is_segwit:
                # FIXME
                raise NotImplementedError("Non-segwit input")

            txhash = self._get_sighash(wally_tx, index, utxo)

            path = utxo['user_path']
            privkey = self.get_privkey(path)
            signature = wally.ec_sig_from_bytes(
                privkey, txhash, wally.EC_FLAG_ECDSA | wally.EC_FLAG_GRIND_R)
            signature = wally.ec_sig_to_der(signature)
            signature.append(wally.WALLY_SIGHASH_ALL)
            signatures.append(wally.hex_from_bytes(signature))
            logging.debug('Signature (der) input %s path %s: %s', index, path,
                          signature)

        return {'signatures': signatures}
Esempio n. 6
0
    def sign_tx(self, details):
        txdetails = details['transaction']

        utxos = txdetails['used_utxos'] or txdetails['old_used_utxos']
        signatures = []
        for index, utxo in enumerate(utxos):
            wally_tx = wally.tx_from_hex(txdetails['transaction'],
                                         wally.WALLY_TX_FLAG_USE_WITNESS)
            is_segwit = utxo['script_type'] in [14, 15, 159, 162]  # FIXME!!
            if not is_segwit:
                # FIXME
                raise NotImplementedError("Non-segwit input")
            flags = wally.WALLY_TX_FLAG_USE_WITNESS if is_segwit else 0
            prevout_script = wally.hex_to_bytes(utxo['prevout_script'])
            txhash = wally.tx_get_btc_signature_hash(wally_tx, index,
                                                     prevout_script,
                                                     utxo['satoshi'],
                                                     wally.WALLY_SIGHASH_ALL,
                                                     flags)

            path = utxo['user_path']
            privkey = self.get_privkey(path)
            signature = wally.ec_sig_from_bytes(
                privkey, txhash, wally.EC_FLAG_ECDSA | wally.EC_FLAG_GRIND_R)
            signature = wally.ec_sig_to_der(signature)
            signature.append(wally.WALLY_SIGHASH_ALL)
            signatures.append(wally.hex_from_bytes(signature))
            logging.debug('Signature (der) input %s path %s: %s', index, path,
                          signature)

        return json.dumps({'signatures': signatures})
Esempio n. 7
0
 def resolve(self, details):
     """Resolve a requested action using the device"""
     logging.debug("%s resolving %s", self.name, details)
     details = details['required_data']
     if details['action'] == 'get_xpubs':
         xpubs = []
         paths = details['paths']
         logging.debug('get_xpubs paths = %s', paths)
         for path in paths:
             xpub = self.get_xpub(path)
             logging.debug('xpub for path %s: %s', path, xpub)
             xpubs.append(xpub)
         response = json.dumps({'xpubs': xpubs})
         logging.debug('resolving: %s', response)
         return response
     if details['action'] == 'sign_message':
         logging.debug('sign message path = %s', details['path'])
         message = details['message']
         logging.debug('signing message "%s"', message)
         signature = self.sign_message(details['path'], message)
         signature_hex = wally.hex_from_bytes(signature)
         result = json.dumps({'signature': signature_hex})
         logging.debug('resolving %s', result)
         return result
     if details['action'] == 'sign_tx':
         return self.sign_tx(details)
     raise NotImplementedError("action = \"{}\"".format(details['action']))
Esempio n. 8
0
    def resolve(self, details):
        """Resolve a requested action using the device"""
        logging.debug("%s resolving %s", self.name, details)
        details = details['required_data']
        if details['action'] == 'get_xpubs':
            xpubs = []
            paths = details['paths']
            logging.debug('get_xpubs paths = %s', paths)
            for path in paths:
                xpub = self.get_xpub(path)
                logging.debug('xpub for path %s: %s', path, xpub)
                xpubs.append(xpub)
            response = json.dumps({'xpubs': xpubs})
            logging.debug('resolving: %s', response)
            return response
        if details['action'] == 'sign_message':
            logging.debug('sign message path = %s', details['path'])
            message = details['message']
            logging.debug('signing message "%s"', message)
            signature = self.sign_message(details['path'], message)
            signature_hex = wally.hex_from_bytes(signature)
            result = json.dumps({'signature': signature_hex})
            logging.debug('resolving %s', result)
            return result
        if details['action'] == 'sign_tx':
            return self.sign_tx(details)
        if details['action'] == 'get_receive_address':
            blinding_script_hash = bytes.fromhex(
                details['address']['blinding_script_hash'])
            public_blinding_key = self.get_public_blinding_key(
                blinding_script_hash)
            return json.dumps({'blinding_key': public_blinding_key.hex()})

        retval = {}
        if details['action'] == 'create_transaction':
            blinding_keys = {}
            change_addresses = details['transaction'].get('change_address', {})
            for asset, addr in change_addresses.items():
                blinding_script_hash = bytes.fromhex(
                    addr['blinding_script_hash'])
                blinding_keys[asset] = self.get_public_blinding_key(
                    blinding_script_hash).hex()
            retval['blinding_keys'] = blinding_keys
        if 'blinded_scripts' in details:
            nonces = []
            for elem in details['blinded_scripts']:
                pubkey = bytes.fromhex(elem['pubkey'])
                script = bytes.fromhex(elem['script'])
                nonces.append(self.get_shared_nonce(pubkey, script).hex())
            retval['nonces'] = nonces

        if not retval:
            raise NotImplementedError("action = \"{}\"".format(
                details['action']))

        return json.dumps(retval)
def check_tx(issuance_txid, issuance_vin, asset, explorer):
    if (explorer):
        resp = requests.get(url=explorerURL+issuance_txid, verify=True)
        issuance = resp.json()
        c = issuance['vin'][issuance_vin]['issuance']['asset_entropy'] + '0000000000000000000000000000000000000000000000000000000000000000'
        asset_id = wally.hex_from_bytes(wally.sha256_midstate(wally.hex_to_bytes(c))[::-1])
    else:
        issuance = host.call('getrawtransaction', issuance_txid, 1)
        asset_id = issuance['vin'][issuance_vin]['issuance']['asset']

    return(asset_id == asset)
Esempio n. 10
0
    def fixup_old_nlocktimes(self):
        """Fixup data from old format nlocktimes files

        Older nlocktimes files do not contain explicit prevout_signatures, prevout_scripts or
        prevout_script_types. Detect this and extract them from the raw transaction to make the
        txdata look consistent to the rest of the code. Note that segwit is not being handled
        here because old style nlocktimes predate segwit
        """
        for txdata in self.txdata:
            if 'prevout_signatures' not in txdata:
                tx = txutil.from_hex(txdata['tx'])
                txdata['prevout_script_types'] = []
                txdata['prevout_signatures'] = []
                txdata['prevout_scripts'] = []
                for i in range(wally.tx_get_num_inputs(tx)):
                    inp = wally.tx_get_input_script(tx, i)
                    ga_signature = wally.hex_from_bytes(inp[2:inp[1]+2])
                    redeem_script = wally.hex_from_bytes(inp[-71:])
                    txdata['prevout_signatures'].append(ga_signature)
                    txdata['prevout_scripts'].append(redeem_script)
                    txdata['prevout_script_types'].append(gaconstants.P2SH_FORTIFIED_OUT)
Esempio n. 11
0
 def _get_unspent(self, address):
     imported = self.imported.get(address, None)
     if imported is None:
         return None
     tx, i = imported
     script = wally.tx_get_output_script(tx, i)
     return {
         "txid": txutil.get_txhash_bin(tx),
         "vout": i,
         "address": address,
         "scriptPubKey": wally.hex_from_bytes(script)
     }
Esempio n. 12
0
        def __init__(self, pointer):
            logging.debug('Derive keys for subaccount={}, pointer={}'.format(
                subaccount, pointer))

            self.subaccount = subaccount
            self.pointer = pointer

            # Derive the GreenAddress public key for this pointer value
            ga_key = gacommon.derive_hd_key(ga_xpub, [pointer],
                                            wally.BIP32_FLAG_KEY_PUBLIC)
            self.ga_key = wally.bip32_key_get_pub_key(ga_key)
            logging.debug("ga_key = {}".format(
                wally.hex_from_bytes(self.ga_key)))

            # Derive the user private keys for this pointer value
            flags = wally.BIP32_FLAG_KEY_PRIVATE
            user_key_paths = [(key, [pointer]) for key in user_keys]
            private_keys = [
                gacommon.derive_hd_key(*path, flags=flags)
                for path in user_key_paths
            ]
            self.private_keys = [
                wally.bip32_key_get_priv_key(k) for k in private_keys
            ]

            # Derive the user public keys from the private keys
            user_public_keys = [
                wally.ec_public_key_from_private_key(k)
                for k in self.private_keys
            ]
            public_keys = [self.ga_key] + user_public_keys

            # Script could be segwit or not - generate both segwit and non-segwit addresses
            self.witnesses = {
                cls.type_: cls(public_keys, network)
                for cls in (P2SH, P2WSH)
            }
            logging.debug('p2sh address: {}'.format(
                self.witnesses['p2sh'].address))
            logging.debug('p2wsh address: {}'.format(
                self.witnesses['p2wsh'].address))
def check_website(domain, asset):
    asserURL = 'https://'+domain+'/.well-known/liquid-asset-proof-'+asset
    resp = requests.get(url=asserURL, verify=True)
    if (re.match(r'^.*'+domain+'.*'+asset, resp.text)):
        return(True)
    else:
        return(False)


host = RPCHost(liquidURL)
resp = requests.get(url=registryURL, verify=True)
assets = resp.json()
for asset in assets.keys():
    contract = json.dumps(assets[asset]['contract'], separators=(',',':'), sort_keys=True)
    contract_hash = wally.hex_from_bytes(wally.sha256(contract.encode('ascii')))
    prev_tx = assets[asset]['issuance_prevout']['txid']
    prev_vout = assets[asset]['issuance_prevout']['vout']
    issuance_txid = assets[asset]['issuance_txin']['txid']
    issuance_vin = assets[asset]['issuance_txin']['vin']
    domain = assets[asset]['contract']['entity']['domain']

    if(check_contract(prev_tx, prev_vout, contract_hash, asset)):
        contract = 'valid contract'
    else:
        contract = 'invalid contract'

    if(check_tx(issuance_txid, issuance_vin, asset, False)):
        tx = 'valid transaction'
    else:
        tx = 'invalid transaction'
Esempio n. 14
0
def get_redeem_script(keys):
    """Return a 2of3 multisig redeem script as a hex string"""
    keys = [wally.hex_from_bytes(key) for key in keys]
    logging.debug("get_redeem_script public keys = {}".format(keys))
    return wally.hex_to_bytes("5221{}21{}21{}53ae".format(*keys))
Esempio n. 15
0
import argparse
import json
import logging
import sys

import wallycore as wally

b2h = lambda b: wally.hex_from_bytes(b)
h2b = lambda h: wally.hex_to_bytes(h)
b2h_rev = lambda b: b2h(b[::-1])
h2b_rev = lambda h: h2b(h)[::-1]


def err(s):
    logging.error(s)
    sys.exit(1)


def parse_tx_file(file):
    with file as f:
        try:
            return wally.tx_from_hex(
                f.read().strip(), wally.WALLY_TX_FLAG_USE_WITNESS
                | wally.WALLY_TX_FLAG_USE_ELEMENTS)
        except ValueError:
            err("Invalid transaction")


def parse_uint256_hex(h):
    try:
        b = h2b_rev(h)
Esempio n. 16
0
def issuer(asset_amount, asset_address, token_amount, token_address,
           issuer_pubkey, name, ticker, precision, domain):
    data = {}
    version = 0  # don't change
    blind = False
    feerate = 0.00003000

    asset_amount = int(asset_amount) / 10**(8 - int(precision))
    token_amount = int(token_amount) / 10**(8 - int(precision))

    # Create funded base tx
    base = host.call('createrawtransaction', [], [{'data': '00'}])
    funded = host.call('fundrawtransaction', base, {'feeRate': feerate})

    # Create the contact and calculate the asset id (Needed for asset registry!)
    contract = json.dumps(
        {
            'name': name,
            'ticker': ticker,
            'precision': int(precision),
            'entity': {
                'domain': domain
            },
            'issuer_pubkey': issuer_pubkey,
            'version': version
        },
        separators=(',', ':'),
        sort_keys=True)
    contract_hash = wally.hex_from_bytes(wally.sha256(
        contract.encode('ascii')))
    data['contract'] = contract

    # Create the rawissuance transaction
    contract_hash_rev = wally.hex_from_bytes(
        wally.hex_to_bytes(contract_hash)[::-1])
    rawissue = host.call('rawissueasset', funded['hex'],
                         [{
                             'asset_amount': asset_amount,
                             'asset_address': asset_address,
                             'token_amount': token_amount,
                             'token_address': token_address,
                             'blind': blind,
                             'contract_hash': contract_hash_rev
                         }])

    # Blind the transaction
    blind = host.call('blindrawtransaction', rawissue[0]['hex'], True, [],
                      False)

    # Sign transaction
    signed = host.call('signrawtransactionwithwallet', blind)
    decoded = host.call('decoderawtransaction', signed['hex'])
    data['asset_id'] = decoded['vin'][0]['issuance']['asset']

    # Test transaction
    test = host.call('testmempoolaccept', [signed['hex']])
    if test[0]['allowed'] is True:
        txid = host.call('sendrawtransaction', signed['hex'])
        data['txid'] = txid
        data['registry'] = json.dumps({
            'asset_id': data['asset_id'],
            'contract': json.loads(data['contract'])
        })

    return data
Esempio n. 17
0
 def get_pubkey_for_pointer_hex(xpub):
     """Return hex encoded public key derived from xpub for pointer"""
     xpub = gacommon.derive_hd_key(xpub, [pointer], wally.BIP32_FLAG_KEY_PUBLIC)
     return wally.hex_from_bytes(wally.bip32_key_get_pub_key(xpub))
Esempio n. 18
0
import wallycore as wally

h2b = wally.hex_to_bytes
b2h = wally.hex_from_bytes

h2b_rev = lambda h: wally.hex_to_bytes(h)[::-1]
b2h_rev = lambda b: wally.hex_from_bytes(b[::-1])
Esempio n. 19
0
def get_txhash_hex(tx):
    return wally.hex_from_bytes(get_txhash_bin(tx)[::-1])
Esempio n. 20
0
# Create the contact and calculate the asset id (Needed for asset registry!)
contract = json.dumps(
    {
        'name': name,
        'ticker': ticker,
        'precision': precision,
        'entity': {
            'domain': domain
        },
        'issuer_pubkey': issuer_pubkey,
        'version': version
    },
    separators=(',', ':'),
    sort_keys=True)
contract_hash = wally.hex_from_bytes(wally.sha256(contract.encode('ascii')))
a = wally.hex_from_bytes(
    wally.hex_to_bytes(prev_tx)[::-1]) + wally.hex_from_bytes(
        struct.pack('<L', int(prev_vout)))
a = wally.hex_from_bytes(wally.sha256d(wally.hex_to_bytes(a)))
b = a + contract_hash
merkle = wally.hex_from_bytes(wally.sha256_midstate(wally.hex_to_bytes(b)))
c = merkle + '0000000000000000000000000000000000000000000000000000000000000000'
merkle = wally.hex_from_bytes(
    wally.sha256_midstate(wally.hex_to_bytes(c))[::-1])
res['asset_id'] = merkle
res['contract'] = contract
res['contract_hash'] = contract_hash

# Create the rawissuance transaction
contract_hash_rev = wally.hex_from_bytes(