Пример #1
0
 def sign(self, private_keys):
     '''Signs the transaction. 
     prvkeys (list of PrivateKey items)'''
     for i, txin in enumerate(self._inputs):
         prvkeys = private_keys[i]
         if isinstance(prvkeys, PrivateKey):
             assert txin['nsigs'] == 1
             prvkeys = [prvkeys]
         elif isinstance(prvkeys, list):
             assert len(prvkeys) == txin['nsigs']
             # Sorting keys
             sorted_prvkeys = []
             for prvkey in prvkeys:
                 pubkey = PublicKey.from_prvkey(prvkey)
                 assert (pubkey in txin['pubkeys'])
                 sorted_prvkeys += [(txin['pubkeys'].index(pubkey), prvkey)]
             sorted_prvkeys.sort(key=lambda x: x[0])
             prvkeys = [k[1] for k in sorted_prvkeys]
         else:
             raise TransactionError('wrong type for private keys')
         if txin['type'] in ('p2pkh', 'p2sh'):
             prehash = dsha256(self.serialize_legacy_preimage(txin))
         elif txin['type'] in ('p2wpkh', 'p2wsh', 'p2sh-p2wpkh',
                               'p2sh-p2wsh'):
             prehash = dsha256(self.serialize_preimage(txin))
         hashtype = bytes([self.hashtype & 0xff]).hex()
         self._inputs[i]['signatures'] = [
             prvkey.sign(prehash, alg="ecdsa", strtype=True) + hashtype
             for prvkey in prvkeys
         ]
Пример #2
0
def unwrap_network_message(data):
    datacpy = data

    if len(data) < 24:
        return None, None, None, data

    magic, data = read_bytes(data, 4, int, 'little')
    assert magic == Constants.NETWORK_MAGIC

    cmd, data = read_bytes(data, 12, bytes, 'big')

    i = 0
    while cmd[i] != 0 and i < 12:
        i += 1
    try:
        command = cmd[:i].decode('ascii')
    except UnicodeDecodeError:
        raise NetworkError("Invalid command encoding")
    except Exception as e:
        print(e)

    length, data = read_bytes(data, 4, int, 'little')
    if (len(data) - 4) < length:
        return command, None, length, datacpy

    checksum, data = read_bytes(data, 4, bytes, 'big')
    payload, data = read_bytes(data, length, bytes, 'big')
    assert checksum == dsha256(payload)[:4]

    return command, payload, length, data
Пример #3
0
def wrap_network_message(command, payload):
    ''' Message Structure for Bitcoin Protocol.
    command (str) : command (e.g. "version")
    payload (bytes) : actual data '''
    magic = Constants.NETWORK_MAGIC.to_bytes(4, 'little')
    cmdb = command.encode('ascii')
    cmd = cmdb + ((12 - len(cmdb)) * b"\00")
    length = len(payload).to_bytes(4, 'little')
    checksum = dsha256(payload)[:4]
    return magic + cmd + length + checksum + payload
Пример #4
0
    def serialize_preimage(self, txin):
        ''' Serializes the preimage of the transaction (BIP-143).'''
        nVersion = self.version.to_bytes(4, 'little')
        nLocktime = self.locktime.to_bytes(4, 'little')
        nHashtype = self.hashtype.to_bytes(
            4, 'little')  # signature hashtype (little-endian)

        hashPrevouts = dsha256(bytes().join(
            self.serialize_outpoint(txi) for txi in self._inputs))
        hashSequence = dsha256(bytes().join(
            txi['sequence'].to_bytes(4, 'little') for txi in self._inputs))

        outpoint = self.serialize_outpoint(txin)
        prevLockingScript = self.get_preimage_script(txin)
        prevLockingScriptSize = var_int(len(prevLockingScript))
        prevValue = txin['value'].to_bytes(8, 'little')
        nSequence = txin['sequence'].to_bytes(4, 'little')

        hashOutputs = dsha256(bytes().join(
            self.serialize_output(txo) for txo in self._outputs))

        return (nVersion + hashPrevouts + hashSequence + outpoint +
                prevLockingScriptSize + prevLockingScript + prevValue +
                nSequence + hashOutputs + nLocktime + nHashtype)
Пример #5
0
 def txid(self):
     '''Returns transaction identifier.'''
     if self.is_complete():
         return dsha256(self.serialize())[::-1]
     else:
         return None
Пример #6
0
 def check(self):
     return int.from_bytes(dsha256(self.serialize()),
                           'little') <= self.target()
Пример #7
0
 def block_id(self):
     raw = self.serialize()
     return dsha256(raw)[::-1]