def serialize(self):
     '''Serialize this message to send over the network'''
     # protocol version is 4 bytes little-endian
     result = int_to_little_endian(self.version, 4)
     # number of hashes is a varint
     result += encode_varint(self.num_hashes)
     # start block is in little-endian
     result += self.start_block[::-1]
     # end block is also in little-endian
     result += self.end_block[::-1]
     return result
Ejemplo n.º 2
0
 def serialize(self):
     '''Returns the byte serialization of the transaction output'''
     # serialize amount, 8 bytes, little endian
     result = int_to_little_endian(self.amount, 8)
     # get the scriptPubkey ready (use self.script_pubkey.serialize())
     raw_script_pubkey = self.script_pubkey.serialize()
     # encode_varint on the length of the scriptPubkey
     result += encode_varint(len(raw_script_pubkey))
     # add the scriptPubKey
     result += raw_script_pubkey
     return result
Ejemplo n.º 3
0
 def sig_hash(self, input_index, redeem_script=None):
     '''Returns the integer representation of the hash that needs to get
     signed for index input_index'''
     # start the serialization with version
     # use int_to_little_endian in 4 bytes
     s = int_to_little_endian(self.version, 4)
     # add how many inputs there are using encode_varint
     s += encode_varint(len(self.tx_ins))
     # loop through each input using enumerate, so we have the input index
     for i, tx_in in enumerate(self.tx_ins):
         # if the input index is the one we're signing
         if i == input_index:
             # if the RedeemScript was passed in, that's the ScriptSig
             if redeem_script:
                 script_sig = redeem_script
             # otherwise the previous tx's ScriptPubkey is the ScriptSig
             else:
                 script_sig = tx_in.script_pubkey(self.testnet)
         # Otherwise, the ScriptSig is empty
         else:
             script_sig = None
         # add the serialization of the input with the ScriptSig we want
         s += TxIn(
             prev_tx=tx_in.prev_tx,
             prev_index=tx_in.prev_index,
             script_sig=script_sig,
             sequence=tx_in.sequence,
         ).serialize()
     # add how many outputs there are using encode_varint
     s += encode_varint(len(self.tx_outs))
     # add the serialization of each output
     for tx_out in self.tx_outs:
         s += tx_out.serialize()
     # add the locktime using int_to_little_endian in 4 bytes
     s += int_to_little_endian(self.locktime, 4)
     # add SIGHASH_ALL using int_to_little_endian in 4 bytes
     s += int_to_little_endian(SIGHASH_ALL, 4)
     # hash256 the serialization
     h256 = hash256(s)
     # convert the result to an integer using int.from_bytes(x, 'big')
     return int.from_bytes(h256, 'big')
Ejemplo n.º 4
0
def sig_hash(self, input_index):
    s = int_to_little_endian(self.version, 4)
    s += encode_varint(len(self.tx_ins))
    for i, tx_in in enumerate(self.tx_ins):
        if i == input_index:
            script_sig = tx_in.script_pubkey(self.testnet)
        else:
            script_sig = None
        s += TxIn(
            prev_tx=tx_in.prev_tx,
            prev_index=tx_in.prev_index,
            script_sig=script_sig,
            sequence=tx_in.sequence,
        ).serialize()
    s += encode_varint(len(self.tx_outs))
    for tx_out in self.tx_outs:
        s += tx_out.serialize()
    s += int_to_little_endian(self.locktime, 4)
    s += int_to_little_endian(SIGHASH_ALL, 4)
    h256 = hash256(s)
    return int.from_bytes(h256, 'big')
Ejemplo n.º 5
0
 def serialize(self, prev_block=False):
     '''Returns the byte serialization of the transaction'''
     # serialize version (4 bytes, little endian)
     result = int_to_little_endian(self.version, 4)
     if prev_block:
         result += self.prev_block_hash[::-1]
     # encode_varint on the number of inputs
     result += encode_varint(len(self.tx_ins))
     # iterate inputs
     for tx_in in self.tx_ins:
         # serialize each input
         result += tx_in.serialize()
     # encode_varint on the number of inputs
     result += encode_varint(len(self.tx_outs))
     # iterate outputs
     for tx_out in self.tx_outs:
         # serialize each output
         result += tx_out.serialize()
     # serialize locktime (4 bytes, little endian)
     result += int_to_little_endian(self.locktime, 4)
     return result
Ejemplo n.º 6
0
 def serialize(self):
     # initialize what we'll send back
     result = b''
     # go through each item
     for item in self.items:
         # if the item is an integer, it's an op code
         if type(item) == int:
             # turn the item into a single byte integer using int_to_little_endian
             result += int_to_little_endian(item, 1)
         else:
             # otherwise, this is an element
             # get the length in bytes
             length = len(item)
             # turn the length into a single byte integer using int_to_little_endian
             prefix = int_to_little_endian(length, 1)
             # append to the result both the length and the item
             result += prefix + item
     # get the length of the whole thing
     total = len(result)
     # encode_varint the total length of the result and prepend
     return encode_varint(total) + result
Ejemplo n.º 7
0
    def sig_hash(self, input_index, hash_type):
        '''Returns the integer representation of the hash that needs to get
        signed for index input_index'''

        script_pubkey = self.tx_ins[input_index].script_pubkey()
        if script_pubkey.type() == 'p2wpkh':
            return self.sig_hash_w0(input_index, hash_type)

        # create a new set of tx_ins (alt_tx_ins)
        alt_tx_ins = []
        # iterate over self.tx_ins
        for tx_in in self.tx_ins:
            # create a new TxIn that has a blank script_sig (b'') and add to alt_tx_ins
            alt_tx_ins.append(TxIn(
                prev_tx=tx_in.prev_tx,
                prev_index=tx_in.prev_index,
                script_sig=b'',
                sequence=tx_in.sequence,
            ))
        # grab the input at the input_index
        signing_input = alt_tx_ins[input_index]
        # grab the script_pubkey of the input
        script_pubkey = signing_input.script_pubkey(self.testnet)
        # Exercise 6.2: get the sig type from script_pubkey.type()
        sig_type = script_pubkey.type()
        # Exercise 6.2: the script_sig of the signing_input should be script_pubkey for p2pkh
        if sig_type == 'p2pkh':
            # Exercise 6.2: replace the input's scriptSig with the scriptPubKey
            signing_input.script_sig = script_pubkey
        # Exercise 6.2: the script_sig of the signing_input should be the redeemScript
        #               of the current input of the real tx_in (self.tx_ins[input_index].redeem_script()
        elif sig_type == 'p2sh':
            # Exercise 6.2: replace the input's scriptSig with the RedeemScript
            current_input = self.tx_ins[input_index]
            # Exercise 6.2: replace the input's scriptSig with the Script.parse(redeem_script)
            signing_input.script_sig = Script.parse(
                current_input.redeem_script())
        elif sig_type == 'p2pk':
            signing_input.script_sig = script_pubkey
        else:
            raise RuntimeError('no valid sig_type')
        # create an alternate transaction with the modified tx_ins
        alt_tx = self.__class__(
            version=self.version,
            tx_ins=alt_tx_ins,
            tx_outs=self.tx_outs,
            locktime=self.locktime)
        # add the hash_type int 4 bytes, little endian
        result = alt_tx.serialize() + int_to_little_endian(hash_type, 4)
        # get the double_sha256 of the tx serialization
        s256 = double_sha256(result)
        # convert this to a big-endian integer using int.from_bytes(x, 'big')
        return int.from_bytes(s256, 'big')
Ejemplo n.º 8
0
 def zprv(self):
     if self.testnet:
         version = TESTNET_ZPRV
     else:
         version = MAINNET_ZPRV
     depth = int_to_little_endian(self.depth, 1)
     fingerprint = self.fingerprint
     child_number = self.child_number.to_bytes(4, 'big')
     chain_code = self.chain_code
     prv = b'\x00' + self.private_key.secret.to_bytes(32, 'big')
     return encode_base58_checksum(
         version + depth + fingerprint + child_number + chain_code + prv)
Ejemplo n.º 9
0
 def serialize(self):
     '''Returns the byte serialization of the transaction'''
     if self.is_segwit():
         return self.serialize_segwit()
     # serialize version (4 bytes, little endian)
     result = int_to_little_endian(self.version, 4)
     # encode_varint on the number of inputs
     result += encode_varint(len(self.tx_ins))
     # iterate inputs
     for tx_in in self.tx_ins:
         # serialize each input
         result += tx_in.serialize()
     # encode_varint on the number of inputs
     result += encode_varint(len(self.tx_outs))
     # iterate outputs
     for tx_out in self.tx_outs:
         # serialize each output
         result += tx_out.serialize()
     # serialize locktime (4 bytes, little endian)
     result += int_to_little_endian(self.locktime, 4)
     return result
Ejemplo n.º 10
0
 def serialize_segwit(self):
     result = int_to_little_endian(self.version, 4)
     result += b'\x00\x01'  # <2>
     result += encode_varint(len(self.tx_ins))
     for tx_in in self.tx_ins:
         result += tx_in.serialize()
     result += encode_varint(len(self.tx_outs))
     for tx_out in self.tx_outs:
         result += tx_out.serialize()
     for tx_in in self.tx_ins:  # <3>
         if tx_in.witness is None:
             result += b'\x00'
         else:
             result += int_to_little_endian(len(tx_in.witness), 1)
             for item in tx_in.witness:
                 if type(item) == int:
                     result += int_to_little_endian(item, 1)
                 else:
                     result += encode_varint(len(item)) + item
     result += int_to_little_endian(self.locktime, 4)
     return result
Ejemplo n.º 11
0
 def raw_serialize(self):
     result = b''
     for cmd in self.cmds:
         # if it's an integer, we know it's an opcode because of the parse method.
         # Elements are pushed onto the stack as bytes.
         if type(cmd) == int:
             result += int_to_little_endian(cmd, 1)
         else:
             # number of bytes of the command.
             length = len(cmd)
             # if length <= 75, we encode the length of the element (cmd) as a single byte
             if length <= 75:
                 result += int_to_little_endian(length, 1)
             # for any element with length between 76 and 255, we put a OP_PUSHDATA1 first,
             # then encode the length as a single byte, followed by the element.
             elif length > 75 and length < 256:
                 result += int_to_little_endian(76, 1)
                 result += int_to_little_endian(length, 1)
             # for any element with length between 256 and 520, we put a OP_PUSHDATA2 first,
             # then encode the length as 2 bytes, followed by the element.
             elif length >= 256 and length <= 520:
                 result += int_to_little_endian(77, 1)
                 result += int_to_little_endian(length, 2)
             else:
                 raise ValueError('cmd is too long.')
             # we encode the cmd
             result += cmd
     return result
Ejemplo n.º 12
0
 def raw_serialize(self):
     result = b''
     # cmd should be consist of command (int) and element (byte)
     for cmd in self.cmds:
         # op_command if its type is int
         if type(cmd) == int:
             result += int_to_little_endian(cmd, 1)
         # if its type is byte, element
         else:
             len_element = len(cmd)
             
             # First, add length of element
             if len_element < 75:
                 result += int_to_little_endian(len_element, 1)
             elif len_element > 75 and len_element < 0x100:
                 result += int_to_little_endian(76, 1)
                 result += int_to_little_endian(len_element, 1)
             elif len_element >= 0x100 and len_element <= 520:
                 result += int_to_little_endian(77, 1)
                 result += int_to_little_endian(len_element, 2)
             else:
                 raise ValueError('too long cmd')
             # after length, add element
             result += cmd
     return result
Ejemplo n.º 13
0
 def serialize(self):
     '''Serialize this message to send over the network'''
     # version is 4 bytes little endian
     result = int_to_little_endian(self.version, 4)
     # services is 8 bytes little endian
     result += int_to_little_endian(self.services, 8)
     # timestamp is 8 bytes little endian
     result += int_to_little_endian(self.timestamp, 8)
     # receiver services is 8 bytes little endian
     result += int_to_little_endian(self.receiver_services, 8)
     # IPV4 is 10 00 bytes and 2 ff bytes then receiver ip
     result += b'\x00' * 10 + b'\xff\xff' + self.receiver_ip
     # receiver port is 2 bytes, big endian
     result += self.receiver_port.to_bytes(2, 'big')
     # sender services is 8 bytes little endian
     result += int_to_little_endian(self.sender_services, 8)
     # IPV4 is 10 00 bytes and 2 ff bytes then sender ip
     result += b'\x00' * 10 + b'\xff\xff' + self.sender_ip
     # sender port is 2 bytes, big endian
     result += self.sender_port.to_bytes(2, 'big')
     # nonce
     result += self.nonce
     # useragent is a variable string, so varint first
     result += encode_varint(len(self.user_agent))
     result += self.user_agent
     # latest block is 4 bytes little endian
     result += int_to_little_endian(self.latest_block, 4)
     # relay is 00 if false, 01 if true
     if self.relay:
         result += b'\x01'
     else:
         result += b'\x00'
     return result
Ejemplo n.º 14
0
 def raw_serialize(self):
     # initialize what we'll send back
     result = b''
     # go through each cmd
     for cmd in self.cmds:
         # if the cmd is an integer, it's an opcode
         if type(cmd) == int:
             # turn the cmd into a single byte integer using int_to_little_endian
             result += int_to_little_endian(cmd, 1)
         else:
             # otherwise, this is an element
             # get the length in bytes
             length = len(cmd)
             # for large lengths, we have to use a pushdata opcode
             if length < 75:
                 # turn the length into a single byte integer
                 result += int_to_little_endian(length, 1)
             elif length > 75 and length < 0x100:
                 # 76 is pushdata1
                 result += int_to_little_endian(76, 1)
                 result += int_to_little_endian(length, 1)
             elif length >= 0x100 and length <= 520:
                 # 77 is pushdata2
                 result += int_to_little_endian(77, 1)
                 result += int_to_little_endian(length, 2)
             else:
                 raise ValueError('too long an cmd')
             result += cmd
     return result
Ejemplo n.º 15
0
    def sig_hash_w0_preimage(self, input_index, hash_type):
        # support only ALL type for now
        assert hash_type == SIGHASH_ALL
        # p2wsh and other nested types not yet supported
        tx_in = self.tx_ins[input_index] # tx_in to sign
        assert tx_in.script_pubkey().type() == 'p2wpkh'

        hash_prevouts = self.hash_prevouts(hash_type)
        hash_sequence = self.hash_sequence(hash_type)
        hash_outputs = self.hash_outputs(hash_type)

        result = int_to_little_endian(self.version, 4)
        result += hash_prevouts;
        result += hash_sequence;
        result += tx_in.prev_tx[::-1]
        result += int_to_little_endian(tx_in.prev_index, 4)
        # 88 ac = OP_EQUALVERIFY OP_CHECKSIG
        scriptCode = unhexlify('1976a914') + tx_in.script_pubkey().elements[1] + unhexlify('88ac')
        result += scriptCode
        result += int_to_little_endian(tx_in.value(), 8)
        result += int_to_little_endian(tx_in.sequence, 4)
        result += hash_outputs
        result += int_to_little_endian(self.locktime, 4)
        result += int_to_little_endian(hash_type, 4)
        return result
Ejemplo n.º 16
0
 def sig_hash_bip143(self,
                     input_index,
                     redeem_script=None,
                     witness_script=None):
     '''Returns the integer representation of the hash that needs to get
     signed for index input_index'''
     tx_in = self.tx_ins[input_index]
     # per BIP143 spec
     s = int_to_little_endian(self.version, 4)
     s += self.hash_prevouts() + self.hash_sequence()
     s += tx_in.prev_tx[::-1] + int_to_little_endian(tx_in.prev_index, 4)
     if witness_script:
         script_code = witness_script.serialize()
     elif redeem_script:
         script_code = p2pkh_script(redeem_script.cmds[1]).serialize()
     else:
         script_code = p2pkh_script(
             tx_in.script_pubkey(self.testnet).cmds[1]).serialize()
     s += script_code
     s += int_to_little_endian(tx_in.value(), 8)
     s += int_to_little_endian(tx_in.sequence, 4)
     s += self.hash_outputs()
     s += int_to_little_endian(self.locktime, 4)
     s += int_to_little_endian(SIGHASH_ALL, 4)
     return int.from_bytes(hash256(s), 'big')
Ejemplo n.º 17
0
 def sig_hash(self, input_index):
     '''Returns the integer representation of the hash that needs to get
     signed for index input_index'''
     # create the serialization per spec
     # start with version: int_to_little_endian in 4 bytes
     s = int_to_little_endian(self.version, 4)
     # next, how many inputs there are: encode_varint
     s += encode_varint(len(self.tx_ins))
     # loop through each input: for i, tx_in in enumerate(self.tx_ins)
     for i, tx_in in enumerate(self.tx_ins):
         # if the input index is the one we're signing
         if i == input_index:
             # the previous tx's ScriptPubkey is the ScriptSig
             script_sig = tx_in.script_pubkey(self.testnet)
         # Otherwise, the ScriptSig is empty
         else:
             script_sig = None
         # create a TxIn object with the prev_tx, prev_index and sequence
         # the same as the current tx_in and the script_sig from above
         new_tx_in = TxIn(
             prev_tx=tx_in.prev_tx,
             prev_index=tx_in.prev_index,
             script_sig=script_sig,
             sequence=tx_in.sequence,
         )
         # add the serialization of the TxIn object
         s += new_tx_in.serialize()
     # add how many outputs there are using encode_varint
     s += encode_varint(len(self.tx_outs))
     # add the serialization of each output
     for tx_out in self.tx_outs:
         s += tx_out.serialize()
     # add the locktime using int_to_little_endian in 4 bytes
     s += int_to_little_endian(self.locktime, 4)
     # add SIGHASH_ALL using int_to_little_endian in 4 bytes
     s += int_to_little_endian(SIGHASH_ALL, 4)
     # hash256 the serialization
     h256 = hash256(s)
     # convert the result to an integer using int.from_bytes(x, 'big')
     return int.from_bytes(h256, 'big')
Ejemplo n.º 18
0
 def serialize(self):
     '''Returns the byte serialization of the entire network message'''
     # add the network magic b'\xf9\xbe\xb4\xd9'
     result = b'\xf9\xbe\xb4\xd9'
     # command 12 bytes
     result += self.command
     # payload length 4 bytes, little endian
     result += int_to_little_endian(len(self.payload), 4)
     # checksum 4 bytes, first four of double-sha256 of payload
     result += double_sha256(self.payload)[:4]
     # payload
     result += self.payload
     return result
Ejemplo n.º 19
0
 def zpub(self):
     if self.testnet:
         version = TESTNET_ZPUB
     else:
         version = MAINNET_ZPUB
     depth = int_to_little_endian(self.depth, 1)
     fingerprint = self.fingerprint
     child_number = self.child_number.to_bytes(4, 'big')
     chain_code = self.chain_code
     sec = self.point.sec()
     return encode_base58_checksum(
         version + depth + fingerprint + child_number +
         chain_code + sec)
Ejemplo n.º 20
0
 def serialize(self):
     '''Returns the byte serialization of the entire network message'''
     # add the network magic using self.magic
     result = self.magic
     # command 12 bytes, fill leftover with b'\x00' * (12 - len(self.command))
     result += self.command + b'\x00' * (12 - len(self.command))
     # payload length 4 bytes, little endian
     result += int_to_little_endian(len(self.payload), 4)
     # checksum 4 bytes, first four of hash256 of payload
     result += hash256(self.payload)[:4]
     # payload
     result += self.payload
     return result
Ejemplo n.º 21
0
 def fetch_all_wifs_from_mnemonic(cls,
                                  mnemonic,
                                  password=b'',
                                  path=b'm',
                                  segwit=False):
     # grab all wifs that correspond to addresses that have had any activity
     # for any account, if we have 10 blank addresses, we assume the wallet
     # has no more to look at
     hd_private_key = cls.from_mnemonic(mnemonic, password, path)
     wifs = []
     for account in range(10):
         account_private_key = hd_private_key.child(account, hardened=True)
         if segwit:
             account_index = 3
             change_index = 10
         else:
             xpub = account_private_key.xpub()
             url = 'http://blockchain.info/multiaddr?active={}'.format(xpub)
             data = requests.get(url).json()['addresses'][0]
             received = data['total_received']
             if received == 0:
                 continue
             account_index = data['account_index']
             change_index = data['change_index']
         for chain, max_index in ((0, account_index), (1, change_index)):
             chain_private_key = account_private_key.child(chain)
             index = 0
             for index in range(max_index + 1):
                 current_private_key = chain_private_key.child(index)
                 h160 = current_private_key.h160()
                 socket = cls.get_socket()
                 nonce = int_to_little_endian(randint(0, 2**32), 4)
                 msg = b'blockchain.fetch_history3'
                 socket.send(msg, SNDMORE)
                 socket.send(nonce, SNDMORE)
                 socket.send(h160 + b'\x00\x00\x00\x00')
                 response_msg = socket.recv()
                 response_nonce = socket.recv()
                 if response_msg != msg or response_nonce != nonce:
                     raise RuntimeError('received wrong msg: {}'.format(
                         response_msg.decode('ascii')))
                 response = socket.recv()
                 response_code = little_endian_to_int(response[:4])
                 if response_code != 0:
                     raise RuntimeError(
                         'got code from server: {}'.format(response_code))
                 response = response[4:]
                 if len(response) > 0:
                     print(current_private_key.address())
                     wifs.append(current_private_key.wif())
     return wifs
Ejemplo n.º 22
0
 def fetch_address_utxos(cls, address, at_block_height=None):
     # grab all unspent transaction outputs as of block block_height
     # if block_height is None, we include all utxos
     address_data = cls.get_address_data(address)
     serialized_script_pubkey = address_data['script_pubkey'].serialize()
     socket = cls.get_socket(address_data['testnet'])
     nonce = int_to_little_endian(random.randint(0, 2**32), 4)
     msg = b'blockchain.fetch_history3'
     socket.send(msg, zmq.SNDMORE)
     socket.send(nonce, zmq.SNDMORE)
     socket.send(address_data['h160'] + b'\x00\x00\x00\x00')
     response_msg = socket.recv()
     response_nonce = socket.recv()
     if response_msg != msg or response_nonce != nonce:
         raise RuntimeError('received wrong msg: {}'.format(
             response_msg.decode('ascii')))
     response = socket.recv()
     response_code = little_endian_to_int(response[:4])
     if response_code != 0:
         raise RuntimeError(
             'got code from server: {}'.format(response_code))
     response = response[4:]
     receives = []
     spent = set()
     while len(response) > 0:
         kind = response[0]
         prev_tx = response[1:33]
         prev_index = response[33:37]
         block_height = little_endian_to_int(response[37:41])
         if kind == 0:
             value = little_endian_to_int(response[41:49])
             if at_block_height is None or block_height < at_block_height:
                 receives.append([prev_tx, prev_index, value])
         else:
             if at_block_height is None or block_height < at_block_height:
                 spent.add(little_endian_to_int(response[41:49]))
         response = response[49:]
     utxos = []
     tx_mask = 0xffffffffffff8000
     index_mask = 0x7fff
     for prev_tx, prev_index, value in receives:
         tx_upper_49_bits = (
             little_endian_to_int(prev_tx) >> 12 * 8) & tx_mask
         index_lower_15_bits = little_endian_to_int(prev_index) & index_mask
         key = tx_upper_49_bits | index_lower_15_bits
         if key not in spent:
             utxos.append([
                 serialized_script_pubkey, prev_tx[::-1],
                 little_endian_to_int(prev_index), value
             ])
     return utxos
Ejemplo n.º 23
0
    def sig_hash(self, input_index):
        '''Returns the integer representation of the hash that needs to get
        signed for index input_index'''
        # start the serialization with version
        # use int_to_little_endian in 4 bytes
        result = int_to_little_endian(self.version, 4)
        # add how many inputs there are using encode_varint
        result += encode_varint(len(self.tx_ins))
        # loop through each input using enumerate, so we have the input index
        for (i, tx_in) in enumerate(self.tx_ins):
            # if the input index is the one we're signing
            # the previous tx's ScriptPubkey is the ScriptSig

            # create new tx as copy as not to alter original tx
            new_tx = TxIn(tx_in.prev_tx,
                          tx_in.prev_index,
                          sequence=tx_in.sequence)

            if i == input_index:
                new_tx.script_sig = tx_in.script_pubkey()
            # Otherwise, the ScriptSig is empty
            else:
                new_tx.script_sig = Script()
            # add the serialization of the input with the ScriptSig we want
            result += new_tx.serialize()
        # add how many outputs there are using encode_varint
        result += encode_varint(len(self.tx_outs))
        # add the serialization of each output
        for tx_out in self.tx_outs:
            result += tx_out.serialize()
        # add the locktime using int_to_little_endian in 4 bytes
        result += int_to_little_endian(self.locktime, 4)
        # add SIGHASH_ALL using int_to_little_endian in 4 bytes
        result += int_to_little_endian(SIGHASH_ALL, 4)
        # hash256 the serialization
        result = hash256(result)
        # convert the result to an integer using int.from_bytes(x, 'big')
        return int.from_bytes(result, 'big')
Ejemplo n.º 24
0
    def is_coinbase(self):
        '''Returns whether this transaction is a coinbase transaction or not'''
        # check that there is exactly 1 input
        if len(self.tx_ins) != 1:
            return False
        if self.tx_ins[0].prev_tx != int_to_little_endian(0, 32):
            return False
        # grab the first input
        # check that first input prev_tx is b'\x00' * 32 bytes

        # check that first input prev_index is 0xffffffff
        if self.tx_ins[0].prev_index != 0xffffffff:
            return False
        return True
Ejemplo n.º 25
0
 def __init__(self, raw_tx, host, port, magic=NETWORK_MAGIC, timeout=10):
     self.raw_tx = raw_tx
     self.tx_hash = double_sha256(raw_tx)
     self.inv_payload = b'\x01' + int_to_little_endian(1, 4) + self.tx_hash
     self._sent = False
     self._accepted = False
     self.host = host
     self.port = port
     self.magic = magic
     self.reader = None
     self.writer = None
     self.q = asyncio.Queue()
     self.keep_looping = True
     self.timeout = timeout
Ejemplo n.º 26
0
 def serialize_segwit(self):
     '''Returns the byte serialization of the transaction'''
     # serialize version (4 bytes, little endian)
     result = int_to_little_endian(self.version, 4)
     # segwit marker '0001'
     result += b'\x00\x01'
     # encode_varint on the number of inputs
     result += encode_varint(len(self.tx_ins))
     # iterate inputs
     for tx_in in self.tx_ins:
         # serialize each input
         result += tx_in.serialize()
     # encode_varint on the number of inputs
     result += encode_varint(len(self.tx_outs))
     # iterate outputs
     for tx_out in self.tx_outs:
         # serialize each output
         result += tx_out.serialize()
     # add the witness data
     for tx_in in self.tx_ins:
         result += tx_in.witness_program
     # serialize locktime (4 bytes, little endian)
     result += int_to_little_endian(self.locktime, 4)
     return result
Ejemplo n.º 27
0
 def test_exercise_3(self):
     hex_tx = '0100000001868278ed6ddfb6c1ed3ad5f8181eb0c7a385aa0836f01d5e4789e6bd304d87221a000000db00483045022100dc92655fe37036f47756db8102e0d7d5e28b3beb83a8fef4f5dc0559bddfb94e02205a36d4e4e6c7fcd16658c50783e00c341609977aed3ad00937bf4ee942a8993701483045022100da6bee3c93766232079a01639d07fa869598749729ae323eab8eef53577d611b02207bef15429dcadce2121ea07f233115c6f09034c0be68db99980b9a6c5e75402201475221022626e955ea6ea6d98850c994f9107b036b1334f18ca8830bfff1295d21cfdb702103b287eaf122eea69030a0e9feed096bed8045c8b98bec453e1ffac7fbdbd4bb7152aeffffffff04d3b11400000000001976a914904a49878c0adfc3aa05de7afad2cc15f483a56a88ac7f400900000000001976a914418327e3f3dda4cf5b9089325a4b95abdfa0334088ac722c0c00000000001976a914ba35042cfe9fc66fd35ac2224eebdafd1028ad2788acdc4ace020000000017a91474d691da1574e6b3c192ecfb52cc8984ee7b6c568700000000'
     hex_sec = '03b287eaf122eea69030a0e9feed096bed8045c8b98bec453e1ffac7fbdbd4bb71'
     hex_der = '3045022100da6bee3c93766232079a01639d07fa869598749729ae323eab8eef53577d611b02207bef15429dcadce2121ea07f233115c6f09034c0be68db99980b9a6c5e754022'
     hex_redeem_script = '475221022626e955ea6ea6d98850c994f9107b036b1334f18ca8830bfff1295d21cfdb702103b287eaf122eea69030a0e9feed096bed8045c8b98bec453e1ffac7fbdbd4bb7152ae'
     sec = bytes.fromhex(hex_sec)
     der = bytes.fromhex(hex_der)
     redeem_script = Script.parse(BytesIO(bytes.fromhex(hex_redeem_script)))
     stream = BytesIO(bytes.fromhex(hex_tx))
     tx_obj = Tx.parse(stream)
     s = int_to_little_endian(tx_obj.version, 4)
     s += encode_varint(len(tx_obj.tx_ins))
     i = tx_obj.tx_ins[0]
     s += TxIn(i.prev_tx, i.prev_index, redeem_script,
               i.sequence).serialize()
     s += encode_varint(len(tx_obj.tx_outs))
     for tx_out in tx_obj.tx_outs:
         s += tx_out.serialize()
     s += int_to_little_endian(tx_obj.locktime, 4)
     s += int_to_little_endian(SIGHASH_ALL, 4)
     z = int.from_bytes(hash256(s), 'big')
     point = S256Point.parse(sec)
     sig = Signature.parse(der)
     self.assertTrue(point.verify(z, sig))
Ejemplo n.º 28
0
 def serialize(self):
     '''Returns the byte serialization of the entire network message'''
     # add the network magic
     result = self.magic
     result += self.command + b'\x00' * (12 - len(self.command))
     result += int_to_little_endian(len(self.payload), 4)
     result += hash256(self.payload)[:4]
     result += self.payload
     return result
     # command 12 bytes
     # fill with 0's
     # payload length 4 bytes, little endian
     # checksum 4 bytes, first four of hash256 of payload
     # payload
     raise NotImplementedError
Ejemplo n.º 29
0
 def serialize(self):
     '''Returns the byte serialization of the entire network message'''
     # add the network magic
     s = self.magic
     # command 12 bytes
     # fill with 0's
     s += self.command
     for _ in range(12 - len(self.command)):
         s += b'\x00'
     # payload length 4 bytes, little endian
     s += int_to_little_endian(len(self.payload), 4)
     # checksum 4 bytes, first four of hash256 of payload
     s += hash256(self.payload)[:4]
     # payload
     s += self.payload
     return s
Ejemplo n.º 30
0
 def verify_input(self, input_index):
     '''Returns whether the input has a valid signature'''
     # get the relevant input
     tx_in = self.tx_ins[input_index]
     # grab the previous ScriptPubKey
     script_pubkey = tx_in.script_pubkey(testnet=self.testnet)
     # check to see if the ScriptPubkey is a p2sh
     if script_pubkey.is_p2sh_script_pubkey():
         # the last instruction has to be the RedeemScript to trigger
         instruction = tx_in.script_sig.instructions[-1]
         # parse the RedeemScript
         raw_redeem = int_to_little_endian(len(instruction),
                                           1) + instruction
         redeem_script = Script.parse(BytesIO(raw_redeem))
         # the RedeemScript might be p2wpkh or p2wsh
         if redeem_script.is_p2wpkh_script_pubkey():
             z = self.sig_hash_bip143(input_index, redeem_script)
             witness = tx_in.witness
         elif redeem_script.is_p2wsh_script_pubkey():
             instruction = tx_in.witness[-1]
             raw_witness = encode_varint(len(instruction)) + instruction
             witness_script = Script.parse(BytesIO(raw_witness))
             z = self.sig_hash_bip143(input_index,
                                      witness_script=witness_script)
             witness = tx_in.witness
         else:
             z = self.sig_hash(input_index, redeem_script)
             witness = None
     else:
         # ScriptPubkey might be a p2wpkh or p2wsh
         if script_pubkey.is_p2wpkh_script_pubkey():
             z = self.sig_hash_bip143(input_index)
             witness = tx_in.witness
         elif script_pubkey.is_p2wsh_script_pubkey():
             instruction = tx_in.witness[-1]
             raw_witness = encode_varint(len(instruction)) + instruction
             witness_script = Script.parse(BytesIO(raw_witness))
             z = self.sig_hash_bip143(input_index,
                                      witness_script=witness_script)
             witness = tx_in.witness
         else:
             z = self.sig_hash(input_index)
             witness = None
     # combine the current ScriptSig and the previous ScriptPubKey
     combined = tx_in.script_sig + script_pubkey
     # evaluate the combined script
     return combined.evaluate(z, witness)