Example #1
0
def test_int_to_little_endian():
    n = 1
    want = b'\x01\x00\x00\x00'
    assert util.int_to_little_endian(n, 4) == want
    n = 10011545
    want = b'\x99\xc3\x98\x00\x00\x00\x00\x00'
    assert util.int_to_little_endian(n, 8) == want
Example #2
0
def serialize_txi(txi):
    result = txi["txid"][::-1]  # serialize prev_tx, little endian
    result += util.int_to_little_endian(
        txi["idx"], 4)  # serialize prev_index, 4 bytes, little endian
    result += script.serialize(txi["script"])  # serialize the unlock_script
    result += util.int_to_little_endian(
        txi["seq.no"], 4)  # serialize sequence, 4 bytes, little endian
    return result
Example #3
0
def hash_all_txis(tx):
    if tx["hash_all"] is None:
        all_prevouts = b''
        all_sequence = b''
        for txi in tx["txis"]:
            all_prevouts += txi["txid"][::-1] + util.int_to_little_endian(txi["idx"], 4)
            all_sequence += util.int_to_little_endian(txi["seq.no"], 4)
        tx["hash_all"] = (util.hash256(all_prevouts), util.hash256(all_sequence))
    return tx["hash_all"]
Example #4
0
def serialize_legacy(tx):
    result = util.int_to_little_endian(tx["version"], 4)
    result += util.encode_varint(tx["txi.count"])
    for txi in tx["txis"]:
        result += serialize_txi(txi)
    result += util.encode_varint(tx["txo.count"])
    for txo in tx["txos"]:
        result += serialize_txo(txo)
    result += util.int_to_little_endian(tx["locktime"], 4)
    return result
Example #5
0
def serialize_filterload(payload, flag=1):
    """Return the filterload message"""
    # start the payload with the size of the filter in bytes
    result = util.encode_varint(payload['size'])
    # next add the bit field using self.filter_bytes()
    result += bloomfilter.bit_field_to_bytes(payload['bit_field'])
    # function count is 4 bytes little endian
    result += util.int_to_little_endian(payload['function_count'], 4)
    # tweak is 4 bytes little endian
    result += util.int_to_little_endian(payload['tweak'], 4)
    # flag is 1 byte little endian
    result += util.int_to_little_endian(flag, 1)
    return result
Example #6
0
def serialize(obj):
    """
     4: version (LE)
    32: prev_block_hash (LE)
    32: merkle_root (LE)
     4: timestamp (LE)
     4: bits
     4: nonce
    """
    result = util.int_to_little_endian(obj['version'], 4)
    result += obj['prev_block_hash'][::-1]
    result += obj['merkle_root'][::-1]
    result += util.int_to_little_endian(obj['timestamp'], 4)
    result += obj['bits']
    result += obj['nonce']
    return result
Example #7
0
def gen_version(version=70015,
                services=0,
                timestamp=None,
                receiver_services=0,
                receiver_ip=b'\x00\x00\x00\x00',
                receiver_port=8333,
                sender_services=0,
                sender_ip=b'\x00\x00\x00\x00',
                sender_port=8333,
                nonce=None,
                user_agent=b'/bitcoinpy:0.1/',
                latest_block=0,
                relay=False):
    payload = {}
    payload['version'] = version
    payload['services'] = services
    if timestamp is None:
        payload['timestamp'] = int(time.time())
    else:
        payload['timestamp'] = timestamp
    payload['receiver_services'] = receiver_services
    payload['receiver_ip'] = receiver_ip
    payload['receiver_port'] = receiver_port
    payload['sender_services'] = sender_services
    payload['sender_ip'] = sender_ip
    payload['sender_port'] = sender_port
    if nonce is None:
        payload['nonce'] = util.int_to_little_endian(randint(0, 2**64), 8)
    else:
        payload['nonce'] = nonce
    payload['user_agent'] = user_agent
    payload['latest_block'] = latest_block
    payload['relay'] = relay

    return payload
Example #8
0
def serialize_segwit(tx):
    result = util.int_to_little_endian(tx["version"], 4)
    result += tx["mark"]
    result += tx["flag"]
    result += util.encode_varint(tx["txi.count"])
    for txi in tx["txis"]:
        result += serialize_txi(txi)
    result += util.encode_varint(tx["txo.count"])
    for txo in tx["txos"]:
        result += serialize_txo(txo)
    for txi in tx["txis"]:
        result += util.int_to_little_endian(len(txi["wits"]), 1)
        for item in txi["wits"]:
            if type(item) == int:
                result += util.int_to_little_endian(item, 1)
            else:
                result += util.encode_varint(len(item)) + item
    result += util.int_to_little_endian(tx["locktime"], 4)
    return result
Example #9
0
def serialize_getdata(payload):
    # start with the number of items as a varint
    result = util.encode_varint(len(payload['data']))
    # loop through each tuple (data_type, identifier) in self.data
    for data_type, identifier in payload['data']:
        # data type is 4 bytes Little-Endian
        result += util.int_to_little_endian(data_type, 4)
        # identifier needs to be in Little-Endian
        result += identifier[::-1]
    return result
Example #10
0
def serialize_getheaders(payload):
    """Serialize this message to send over the network"""
    # protocol version is 4 bytes little-endian
    result = util.int_to_little_endian(payload['version'], 4)
    # number of hashes is a varint
    result += util.encode_varint(payload['num_hashes'])
    # start block is in little-endian
    result += payload['start_block'][::-1]
    # end block is also in little-endian
    result += payload['end_block'][::-1]
    return result
Example #11
0
def sig_hash_bip143(prev_tx, tx, txi, redeem_script=None, witness_script=None, testnet=False):
    """
    bip143
    1:04LE       version
    2:32         hash prevouts
    3:32         hash sequence
    4:32+4LE     outpoint
    5:*          script_code of the input
    6:08LE       value of output spent
    7:04LE       n_sequence of the input
    8:32         hash outputs
    9:4LE        n_locktime
    10:4LE       sighash
    """
    s = util.int_to_little_endian(tx["version"], 4)  # 1
    hash_all_prevouts, hash_all_sequence = hash_all_txis(tx)
    s += hash_all_prevouts + hash_all_sequence  # 2,3
    s += txi["txid"][::-1] + util.int_to_little_endian(txi["idx"], 4)  # 4

    # 5
    if witness_script:
        script_code = script.serialize(witness_script)
    elif redeem_script:
        script_code = script.serialize(script.p2pkh_script(redeem_script[1]))
    else:
        script_code = script.serialize(script.p2pkh_script(prev_tx["txos"][txi["idx"]]["script"][1]))
    s += script_code

    s += util.int_to_little_endian(prev_tx["txos"][txi["idx"]]["amount"], 8)  # 6
    s += util.int_to_little_endian(txi["seq.no"], 4)  # 7
    s += hash_all_txos(tx)  # 8
    s += util.int_to_little_endian(tx["locktime"], 4)  # 9
    s += util.int_to_little_endian(util.SIGHASH_ALL, 4)  # 10
    return int.from_bytes(util.hash256(s), 'big')
Example #12
0
def serialize_version(payload):
    """Serialize this message to send over the network"""
    # version is 4 bytes little endian
    result = util.int_to_little_endian(payload['version'], 4)
    # services is 8 bytes little endian
    result += util.int_to_little_endian(payload['services'], 8)
    # timestamp is 8 bytes little endian
    result += util.int_to_little_endian(payload['timestamp'], 8)
    # receiver services is 8 bytes little endian
    result += util.int_to_little_endian(payload['receiver_services'], 8)
    # IPV4 is 10 00 bytes and 2 ff bytes then receiver ip
    result += b'\x00' * 10 + b'\xff\xff' + payload['receiver_ip']
    # receiver port is 2 bytes, big endian
    result += payload['receiver_port'].to_bytes(2, 'big')
    # sender services is 8 bytes little endian
    result += util.int_to_little_endian(payload['sender_services'], 8)
    # IPV4 is 10 00 bytes and 2 ff bytes then sender ip
    result += b'\x00' * 10 + b'\xff\xff' + payload['sender_ip']
    # sender port is 2 bytes, big endian
    result += payload['sender_port'].to_bytes(2, 'big')
    # nonce should be 8 bytes
    result += payload['nonce']
    # useragent is a variable string, so varint first
    result += util.encode_varint(len(payload['user_agent']))
    result += payload['user_agent']
    # latest block is 4 bytes little endian
    result += util.int_to_little_endian(payload['latest_block'], 4)
    # relay is 00 if false, 01 if true
    if payload['relay']:
        result += b'\x01'
    else:
        result += b'\x00'

    return result
Example #13
0
def serialize_msg(msg):
    """Returns the byte serialization of the entire network message"""
    # add the network magic
    result = msg['magic']
    # command 12 bytes
    # fill with 0's
    result += msg['command'] + b'\x00' * (12 - len(msg['command']))
    # payload length 4 bytes, little endian
    result += util.int_to_little_endian(len(msg['payload_bytes']), 4)
    # checksum 4 bytes, first four of hash256 of payload
    result += util.hash256(msg['payload_bytes'])[:4]
    # payload
    result += msg['payload_bytes']
    return result
Example #14
0
def sig_hash(tx, idx, lock_script):
    tx4sig = copy.deepcopy(tx)
    for i, txi in enumerate(tx4sig['txis']):
        if i != idx:
            # script.len is calculated when it is serialized.
            # txi["script.len"] = 0
            txi["script"] = []
        else:
            # script.len is calculated when it is serialized.
            # script = serialize_script(script_unlock)
            # txi["script.len"] = len(script)
            txi["script"] = lock_script
    s = serialize(tx4sig)
    s += util.int_to_little_endian(util.SIGHASH_ALL, 4)
    h256 = util.hash256(s)
    return int.from_bytes(h256, 'big')
Example #15
0
def serialize(script):
    result = b''  # initialize what we'll send back
    for token in script:  # go through each token
        if type(token) == int:  # if the token is an integer, it's an opcode
            result += util.int_to_little_endian(token, 1)
        else:  # otherwise, this is an element
            length = len(token)  # get the length in bytes
            if length < 75:  # turn the length into a single byte integer
                result += util.int_to_little_endian(length, 1)
            elif 75 < length < 0x100:  # 76 is pushdata1
                result += util.int_to_little_endian(76, 1)
                result += util.int_to_little_endian(length, 1)
            elif 0x100 <= length <= 520:  # 77 is pushdata2
                result += util.int_to_little_endian(77, 1)
                result += util.int_to_little_endian(length, 2)
            else:
                raise ValueError('too long an token')
            result += token
    total = len(result)
    return util.encode_varint(total) + result
Example #16
0
def serialize_txo(txo):
    result = util.int_to_little_endian(txo["amount"], 8)  # serialize amount, 8 bytes, little endian
    result += script.serialize(txo["script"])  # serialize the script_pubkey
    return result