예제 #1
0
    def from_bytes(VarInt, byte_string):
        '''
        byte-like -> VarInt
        accepts arbitrary length input, gets a VarInt off the front
        '''
        num = byte_string
        if num[0] <= 0xfc:
            num = num[0:1]
            non_compact = False
        elif num[0] == 0xfd:
            num = num[1:3]
            non_compact = (num[-1:] == b'\x00')
        elif num[0] == 0xfe:
            num = num[1:5]
            non_compact = (num[-2:] == b'\x00\x00')
        elif num[0] == 0xff:
            num = num[1:9]
            non_compact = (num[-4:] == b'\x00\x00\x00\x00')
        if len(num) not in [1, 2, 4, 8]:
            raise ValueError('Malformed VarInt. Got: {}'.format(
                byte_string.hex()))

        if (non_compact
                and ('overwinter' in riemann.get_current_network_name()
                     or 'sapling' in riemann.get_current_network_name())):
            raise ValueError('VarInt must be compact. Got: {}'.format(
                byte_string.hex()))

        ret = VarInt(utils.le2i(num),
                     length=len(num) + 1 if non_compact else 0)

        return ret
예제 #2
0
def hash256(msg_bytes):
    '''
    byte-like -> bytes
    '''
    if 'decred' in riemann.get_current_network_name():
        return blake256(blake256(msg_bytes))
    return hashlib.sha256(hashlib.sha256(msg_bytes).digest()).digest()
예제 #3
0
def make_pkh_output_script(pubkey, witness=False):
    '''
    bytearray -> bytearray
    '''
    if witness and not riemann.network.SEGWIT:
        raise ValueError(
            'Network {} does not support witness scripts.'
            .format(riemann.get_current_network_name()))

    output_script = bytearray()

    if type(pubkey) is not bytearray and type(pubkey) is not bytes:
        raise ValueError('Unknown pubkey format. '
                         'Expected bytes. Got: {}'.format(type(pubkey)))

    pubkey_hash = utils.hash160(pubkey)

    if witness:
        output_script.extend(riemann.network.P2WPKH_PREFIX)
        output_script.extend(pubkey_hash)
    else:
        output_script.extend(b'\x76\xa9\x14')  # OP_DUP OP_HASH160 PUSH14
        output_script.extend(pubkey_hash)
        output_script.extend(b'\x88\xac')  # OP_EQUALVERIFY OP_CHECKSIG
    return output_script
예제 #4
0
def make_pkh_output_script(pubkey: bytes, witness: bool = False) -> bytes:
    '''
    Makes a P2PKH or P2WPKH script pubkey from a raw public key. Does not
    support Compatibility p2wpkh-via-p2sh output scripts.

    Args:
        pubkey: The 33- or 65-byte public key.
        witness: Pass True to make a P2WSH script pubkey.
    Returns:
        The script pubkey containing the hash of the pubkey.
    '''
    if witness and not riemann.network.SEGWIT:
        raise ValueError('Network {} does not support witness scripts.'.format(
            riemann.get_current_network_name()))

    output_script = bytearray()

    if type(pubkey) is not bytearray and type(pubkey) is not bytes:
        raise ValueError('Unknown pubkey format. '
                         'Expected bytes. Got: {}'.format(type(pubkey)))

    pubkey_hash = utils.hash160(pubkey)

    if witness:
        output_script.extend(riemann.network.P2WPKH_PREFIX)
        output_script.extend(pubkey_hash)
    else:
        output_script.extend(b'\x76\xa9\x14')  # OP_DUP OP_HASH160 PUSH14
        output_script.extend(pubkey_hash)
        output_script.extend(b'\x88\xac')  # OP_EQUALVERIFY OP_CHECKSIG
    return bytes(output_script)
예제 #5
0
파일: bech32.py 프로젝트: summa-tx/riemann
def encode(data: bytes) -> str:
    '''Convert bytes to bech32'''
    if riemann.network.BECH32_HRP is None:
        raise ValueError(
            'Network ({}) does not support bech32 encoding.'.format(
                riemann.get_current_network_name()))
    return segwit_encode(riemann.network.BECH32_HRP, data[0], data[2:])
예제 #6
0
def _make_output(  # noqa: F811
        value, output_script, version=None):
    '''Instantiates a TxOut from value and output script'''
    if 'decred' in riemann.get_current_network_name():
        return decred.DecredTxOut(value=value,
                                  version=cast(int, version),
                                  output_script=output_script)
    return tx.TxOut(value=value, output_script=output_script)
예제 #7
0
def hash160(msg_bytes: bytes) -> bytes:
    '''rmd160 of sha256 of message'''
    h = hashlib.new('ripemd160')
    if 'decred' in riemann.get_current_network_name():
        h.update(blake256(msg_bytes))
        return h.digest()
    h.update(sha256(msg_bytes))
    return h.digest()
예제 #8
0
def make_witness_input(outpoint, sequence):  # noqa: F811
    '''Make a witness input'''
    if 'decred' in riemann.get_current_network_name():
        return decred.DecredTxIn(outpoint=outpoint,
                                 sequence=utils.i2le_padded(sequence, 4))
    return tx.TxIn(outpoint=outpoint,
                   stack_script=b'',
                   redeem_script=b'',
                   sequence=utils.i2le_padded(sequence, 4))
예제 #9
0
def make_tx(version, tx_ins, tx_outs, lock_time,
            expiry=None, value_balance=None, tx_shielded_spends=None,
            tx_shielded_outputs=None, tx_witnesses=None, tx_joinsplits=None,
            joinsplit_pubkey=None, joinsplit_sig=None, binding_sig=None):
    '''
    int, list(TxIn), list(TxOut), int, list(InputWitness) -> Tx
    '''
    n = riemann.get_current_network_name()
    if 'decred' in n:
        return tx.DecredTx(
            version=utils.i2le_padded(version, 4),
            tx_ins=tx_ins,
            tx_outs=tx_outs,
            lock_time=utils.i2le_padded(lock_time, 4),
            expiry=utils.i2le_padded(expiry, 4),
            tx_witnesses=[tx_witnesses])
    if 'sprout' in n and tx_joinsplits is not None:
        return tx.SproutTx(
            version=version,
            tx_ins=tx_ins,
            tx_outs=tx_outs,
            lock_time=utils.i2le_padded(lock_time, 4),
            tx_joinsplits=tx_joinsplits if tx_joinsplits is not None else [],
            joinsplit_pubkey=joinsplit_pubkey,
            joinsplit_sig=joinsplit_sig)
    if 'overwinter' in n:
        return tx.OverwinterTx(
            tx_ins=tx_ins,
            tx_outs=tx_outs,
            lock_time=utils.i2le_padded(lock_time, 4),
            expiry_height=utils.i2le_padded(expiry, 4),
            tx_joinsplits=tx_joinsplits if tx_joinsplits is not None else [],
            joinsplit_pubkey=joinsplit_pubkey,
            joinsplit_sig=joinsplit_sig)
    if 'sapling' in n:
        return tx.SaplingTx(
            tx_ins=tx_ins,
            tx_outs=tx_outs,
            lock_time=utils.i2le_padded(lock_time, 4),
            expiry_height=utils.i2le_padded(expiry, 4),
            value_balance=utils.i2le_padded[value_balance],
            tx_shielded_spends=(tx_shielded_spends
                                if tx_shielded_spends is not None else []),
            tx_shielded_outputs=(tx_shielded_outputs
                                 if tx_shielded_outputs is not None else []),
            tx_joinsplits=tx_joinsplits if tx_joinsplits is not None else [],
            joinsplit_pubkey=joinsplit_pubkey,
            joinsplit_sig=joinsplit_sig,
            binding_sig=binding_sig)
    flag = riemann.network.SEGWIT_TX_FLAG \
        if tx_witnesses is not None else None
    return tx.Tx(version=utils.i2le_padded(version, 4),
                 flag=flag,
                 tx_ins=tx_ins,
                 tx_outs=tx_outs,
                 tx_witnesses=tx_witnesses,
                 lock_time=utils.i2le_padded(lock_time, 4))
예제 #10
0
def _make_output(value, output_script, version=None):
    '''
    byte-like, byte-like -> TxOut
    '''
    if 'decred' in riemann.get_current_network_name():
        return tx.DecredTxOut(value=value,
                              version=version,
                              output_script=output_script)
    return tx.TxOut(value=value, output_script=output_script)
예제 #11
0
def make_outpoint(tx_id_le, index, tree=None):
    '''
    byte-like, int, int -> Outpoint
    '''
    if 'decred' in riemann.get_current_network_name():
        return tx.DecredOutpoint(tx_id=tx_id_le,
                                 index=utils.i2le_padded(index, 4),
                                 tree=utils.i2le_padded(tree, 1))
    return tx.Outpoint(tx_id=tx_id_le, index=utils.i2le_padded(index, 4))
예제 #12
0
def make_outpoint(tx_id_le, index, tree=None):  # noqa: F811
    '''
    byte-like, int, int -> Outpoint
    '''
    if 'decred' in riemann.get_current_network_name():
        tree_bytes = b'\x00' if tree is None else utils.i2le_padded(tree, 1)
        return decred.DecredOutpoint(tx_id=tx_id_le,
                                     index=utils.i2le_padded(index, 4),
                                     tree=tree_bytes)
    return tx.Outpoint(tx_id=tx_id_le, index=utils.i2le_padded(index, 4))
예제 #13
0
def make_legacy_input(  # noqa: F811
        outpoint, stack_script, redeem_script, sequence):
    '''Make a legacy input'''
    if 'decred' in riemann.get_current_network_name():
        return decred.DecredTxIn(outpoint=outpoint,
                                 sequence=utils.i2le_padded(sequence, 4))
    return tx.TxIn(outpoint=outpoint,
                   stack_script=stack_script,
                   redeem_script=redeem_script,
                   sequence=utils.i2le_padded(sequence, 4))
예제 #14
0
def make_sh_output_script(script_string, witness=False):
    '''
    str -> bytearray
    '''
    if witness and not riemann.network.SEGWIT:
        raise ValueError('Network {} does not support witness scripts.'.format(
            riemann.get_current_network_name()))

    script_bytes = serialization.serialize(script_string)
    return make_sh_script_pubkey(script_bytes=script_bytes, witness=witness)
예제 #15
0
파일: tx_builder.py 프로젝트: tynes/riemann
def make_witness_input(outpoint, sequence):
    '''
    Outpoint, int -> TxIn
    '''
    if 'decred' in riemann.get_current_network_name():
        return tx.DecredTxIn(outpoint=outpoint, sequence=sequence)
    return tx.TxIn(outpoint=outpoint,
                   stack_script=b'',
                   redeem_script=b'',
                   sequence=sequence)
예제 #16
0
def hash160(msg_bytes):
    '''
    byte-like -> bytes
    '''
    h = hashlib.new('ripemd160')
    if 'decred' in riemann.get_current_network_name():
        h.update(blake256(msg_bytes))
        return h.digest()
    h.update(sha256(msg_bytes))
    return h.digest()
예제 #17
0
def make_legacy_input(outpoint, stack_script, redeem_script, sequence):
    '''
    Outpoint, byte-like, byte-like, int -> TxIn
    '''
    if 'decred' in riemann.get_current_network_name():
        return tx.DecredTxIn(outpoint=outpoint,
                             sequence=utils.i2le_padded(sequence, 4))
    return tx.TxIn(outpoint=outpoint,
                   stack_script=stack_script,
                   redeem_script=redeem_script,
                   sequence=utils.i2le_padded(sequence, 4))
예제 #18
0
def make_witness_input_and_witness(outpoint, sequence, stack=None, **kwargs):
    '''
    Outpoint, int, list(bytearray) -> (Input, InputWitness)
    '''
    if 'decred' in riemann.get_current_network_name():
        return (make_witness_input(outpoint, sequence),
                make_decred_witness(value=kwargs['value'],
                                    height=kwargs['height'],
                                    index=kwargs['index'],
                                    stack_script=kwargs['stack_script'],
                                    redeem_script=kwargs['redeem_script']))
    return (make_witness_input(outpoint, sequence), make_witness(stack))
예제 #19
0
def decode(bech):
    if riemann.network.BECH32_HRP is None:
        raise ValueError(
            'Network ({}) does not support bech32 encoding.'.format(
                riemann.get_current_network_name()))

    (version_prefix, hash_int_array) = \
        segwit_decode(riemann.network.BECH32_HRP, bech)
    ret = bytearray()
    ret.extend([version_prefix])
    ret.extend([len(hash_int_array)])
    ret.extend(hash_int_array)
    return bytes(ret)
예제 #20
0
def encode(data: bytes) -> str:
    '''Convert bytes to cashaddr-bech32'''
    if riemann.network.CASHADDR_PREFIX is None:
        raise ValueError('Network {} does not support cashaddresses.'.format(
            riemann.get_current_network_name()))

    data = convertbits(data, 8, 5)
    checksum = calculate_checksum(riemann.network.CASHADDR_PREFIX, data)

    payload = b32encode(data + checksum)

    form = '{prefix}:{payload}'
    return form.format(prefix=riemann.network.CASHADDR_PREFIX, payload=payload)
예제 #21
0
def guess_version(redeem_script):
    '''
    str -> int
    Bitcoin uses tx version 2 for nSequence signaling.
    Zcash uses tx version 2 for joinsplits.

    We want to signal nSequence if we're using OP_CSV.
    Unless we're in zcash.
    '''
    if 'zcash' in riemann.get_current_network_name():
        return 1
    try:
        script_array = redeem_script.split()
        script_array.index('OP_CHECKSEQUENCEVERIFY')
        return 2
    except ValueError:
        return 1  # Enable lock_time, disable RBF
예제 #22
0
def make_sh_output_script(script_string: str, witness: bool = False) -> bytes:
    '''
    Make a P2SH or P2WSH script pubkey from a human-readable script. Does not
    support Compatibility p2wsh-via-p2sh output scripts.

    Args:
        script_string: The human-readable redeem script or witness script.
        witness: Pass True to make a P2WSH script pubkey.
    Returns:
        The script pubkey containing the hash of the serialized script.
    '''
    if witness and not riemann.network.SEGWIT:
        raise ValueError('Network {} does not support witness scripts.'.format(
            riemann.get_current_network_name()))

    script_bytes = serialization.serialize(script_string)
    return make_sh_script_pubkey(script_bytes=script_bytes, witness=witness)
예제 #23
0
def _make_output(  # noqa: F811
        value, output_script, version=None):
    '''
    Instantiates a TxOut from value and output script.

    Args:
        value: The 8-byte LE-encoded integer value of the output.
        output_script: The non-length-prepended output script.
        version: Only in Decred transactions, the output version.

    Returns:
        The TxOut object. A DecredTxOut if version was passed in.
    '''
    if 'decred' in riemann.get_current_network_name():
        return decred.DecredTxOut(value=value,
                                  version=cast(int, version),
                                  output_script=output_script)
    return tx.TxOut(value=value, output_script=output_script)
예제 #24
0
def make_witness_input(outpoint, sequence):  # noqa: F811
    '''
    Make a Segwit input. This is clearly superior to `make_legacy_input` and
    you should use witness always.

    Args:
        outpoint: The Outpoint object
        sequence: The 4-byte LE-encoded sequence number
    Returns:
        A Segwit TxIn object.
    '''
    if 'decred' in riemann.get_current_network_name():
        return decred.DecredTxIn(outpoint=outpoint,
                                 sequence=utils.i2le_padded(sequence, 4))
    return tx.TxIn(outpoint=outpoint,
                   stack_script=b'',
                   redeem_script=b'',
                   sequence=utils.i2le_padded(sequence, 4))
예제 #25
0
def decode(data: str) -> bytes:
    '''Convert cashaddr-bech32 to bytes'''

    if riemann.network.CASHADDR_PREFIX is None:
        raise ValueError('Network {} does not support cashaddresses.'.format(
            riemann.get_current_network_name()))
    if data.find(riemann.network.CASHADDR_PREFIX) != 0:
        raise ValueError('Malformed cashaddr. Cannot locate prefix: {}'.format(
            riemann.network.CASHADDR_PREFIX))

    # the data is everything after the colon
    prefix, data = data.split(':')
    decoded = b32decode(data)
    if not verify_checksum(prefix, decoded):
        raise ValueError('Bad cash address checksum')
    converted = convertbits(decoded, 5, 8)

    return bytes(converted[:-6])  # remove the checksum from the end
예제 #26
0
def make_outpoint(tx_id_le, index, tree=None):  # noqa: F811
    '''
    Instantiate an Outpoint object from a transaction id and an index.

    Args:
        tx_id_le: The 32-byte LE hash of the transaction that created the
                  prevout being referenced.
        index: The index of the TxOut that created the prevout in its
               transaction's output vector
        tree: Only in Decred transactions. Specifies the commitment tree.
    Returns:
        An Outpoint object. If network is set to Decred, a DecredOutpoint
    '''
    if 'decred' in riemann.get_current_network_name():
        tree_bytes = b'\x00' if tree is None else utils.i2le_padded(tree, 1)
        return decred.DecredOutpoint(tx_id=tx_id_le,
                                     index=utils.i2le_padded(index, 4),
                                     tree=tree_bytes)
    return tx.Outpoint(tx_id=tx_id_le, index=utils.i2le_padded(index, 4))
예제 #27
0
def make_legacy_input(  # noqa: F811
        outpoint, stack_script, redeem_script, sequence):
    '''
    Make a legacy input. This supports creating Compatibility inputs by passing
    the witness program to `redeem_script` while passing an empty bytestring
    for `stack_script`.

    Args:
        outpoint: The Outpoint object
        stack_script: A serialized Script program that sets the initial stack
        redeem_script: A serialized Script program that is run on the stack
        sequence: The 4-byte LE-encoded sequence number
    Returns:
        A Legacy TxIn object.
    '''
    if 'decred' in riemann.get_current_network_name():
        return decred.DecredTxIn(outpoint=outpoint,
                                 sequence=utils.i2le_padded(sequence, 4))
    return tx.TxIn(outpoint=outpoint,
                   stack_script=stack_script,
                   redeem_script=redeem_script,
                   sequence=utils.i2le_padded(sequence, 4))
예제 #28
0
파일: tx_builder.py 프로젝트: tynes/riemann
def make_sh_output_script(script_string, witness=False):
    '''
    str -> bytearray
    '''
    if witness and not riemann.network.SEGWIT:
        raise ValueError('Network {} does not support witness scripts.'.format(
            riemann.get_current_network_name()))

    output_script = bytearray()

    script_bytes = serialization.serialize(script_string)

    if witness:
        script_hash = utils.sha256(script_bytes)
        output_script.extend(riemann.network.P2WSH_PREFIX)
        output_script.extend(script_hash)
    else:
        script_hash = utils.hash160(script_bytes)
        output_script.extend(b'\xa9')  # OP_HASH160
        output_script.extend(script_hash)
        output_script.extend(b'\x87')  # OP_EQUAL

    return output_script
예제 #29
0
파일: tx_builder.py 프로젝트: tynes/riemann
def make_tx(version,
            tx_ins,
            tx_outs,
            lock_time,
            expiry=None,
            tx_witnesses=None):
    '''
    int, list(TxIn), list(TxOut), int, list(InputWitness) -> Tx
    '''
    if 'decred' in riemann.get_current_network_name():
        return tx.DecredTx(version=version,
                           tx_ins=tx_ins,
                           tx_outs=tx_outs,
                           lock_time=lock_time,
                           expiry=expiry,
                           tx_witnesses=tx_witnesses)
    flag = riemann.network.SEGWIT_TX_FLAG \
        if tx_witnesses is not None else None
    return tx.Tx(version=utils.i2le_padded(version, 4),
                 flag=flag,
                 tx_ins=tx_ins,
                 tx_outs=tx_outs,
                 tx_witnesses=tx_witnesses,
                 lock_time=utils.i2le_padded(lock_time, 4))
예제 #30
0
파일: tx.py 프로젝트: tynes/riemann
 def __init__(self):
     if 'decred' not in riemann.get_current_network_name():
         raise ValueError('Decred classes not supported by network {}. '
                          'How did you get here?'.format(
                              riemann.get_current_network_name()))
     super().__init__()