Esempio n. 1
0
 def serialize(self, SER_GETHASH=False):
     r = self.outpoint.serialize()
     r += self.addr.serialize()
     r += serialize.ser_string(self.pubkey_collateral)
     r += serialize.ser_string(self.pubkey_masternode)
     if not SER_GETHASH:
         r += serialize.ser_string(self.vchSig)
     r += serialize.ser_int64(self.sig_time)
     r += serialize.ser_int32(self.n_protocol_version)
     if not SER_GETHASH:
         r += self.last_ping.serialize(False)
     return r
Esempio n. 2
0
 def serialize(self, SER_GETHASH=False):
     r = self.mn_outpoint.serialize()
     r += serialize.ser_uint256(self.block_hash)
     r += serialize.ser_int64(self.sig_time)
     if not SER_GETHASH:
         r += serialize.ser_string(self.vchSig)
     r += serialize.ser_bool(self.fSentinelIsCurrent)
     r += serialize.ser_uint32(self.nSentinelVersion)
     r += serialize.ser_uint32(self.nDaemonVersion)
     return r
Esempio n. 3
0
 def serialize(self, SER_GETHASH=False):
     r = self.outpoint.serialize()
     r += self.addr.serialize()
     r += serialize.ser_string(self.pubkey_collateral)
     r += serialize.ser_string(self.pubkey_masternode)
     r += self.last_ping.serialize(SER_GETHASH)
     r += serialize.ser_string(self.vchSig)
     r += serialize.ser_int64(self.sig_time)
     r += serialize.ser_int64(self.n_last_dsq)
     r += serialize.ser_int64(self.n_time_last_checked)
     r += serialize.ser_int64(self.n_last_dsq)
     r += serialize.ser_int32(self.n_active_state)
     r += serialize.ser_uint256(self.n_collateral_hash)
     r += serialize.ser_int32(self.n_block_last_paid)
     r += serialize.ser_int32(self.n_protocol_version)
     r += serialize.ser_int32(self.n_po_se_ban_score)
     r += serialize.ser_int32(self.n_po_se_ban_height)
     r += serialize.ser_bool(self.f_allow_mixing_tx)
     r += serialize.ser_bool(self.f_unit_test)
     r += serialize.ser_map_uint256_int(self.gov_votes)
     return r
Esempio n. 4
0
 def serialize(self):
     return struct.pack('<q', self.nValue) + ser_string(self.scriptPubKey)
Esempio n. 5
0
 def serialize(self):
     b = self.prevout.serialize()
     b += ser_string(self.scriptSig)
     b += struct.pack('<I', self.nSequence)
     return b
Esempio n. 6
0
def sign_tx(tx_in, address_d, change_path = None, txid_d = None):
    tx = CTransaction(tx_in)

    # First, we need a trusted input blob for each vin[i].
    sys.stdout.write('Loading input transactions (%d)...  ' % len(tx.vin)); sys.stdout.flush()
    til = []
    for i in range(len(tx.vin)):
        d = {}

        # get the txid for the output this input refers to
        txid = tx.vin[i].prevout.hash
        txid_hs = serialize.b2hs(txid[::-1])

        # and the index into vout
        n = tx.vin[i].prevout.n

        # get the transaction from energid
        tx_i_hex = eel.get_hex_transaction(txid_hs) if txid_d is None else txid_d[txid_hs]['hex']
        tx_i = CTransaction().deserialize(BytesIO(serialize.hs2b(tx_i_hex)))

        # save scriptPubKey for later
        d['scriptPubKey'] = tx_i.vout[n].scriptPubKey

        # we'll send this in chunks; the first includes up to vin len
        buf = struct.pack('<i', tx_i.nVersion) + serialize.ser_compact_size(len(tx_i.vin))
        r = ledger.call_get_trusted_input_first(n, buf)
        if r != b'':
            raise RuntimeError('get_trusted_input_first: %s' % r)

        # now send vin
        for j in range(len(tx_i.vin)):
            buf = tx_i.vin[j].serialize()
            r = ledger.call_get_trusted_input_next(buf)
            if r != b'':
                raise RuntimeError('get_trusted_input_next: %s' % r)

        # send len of vout and vout[0]
        buf = serialize.ser_compact_size(len(tx_i.vout)) + tx_i.vout[0].serialize()
        r = ledger.call_get_trusted_input_next(buf)
        if r != b'':
            raise RuntimeError('get_trusted_input_next (0): %s' % (r))

        # send the rest of vout
        for j in range(1, len(tx_i.vout)):
            buf = tx_i.vout[j].serialize()
            r = ledger.call_get_trusted_input_next(buf)
            if r != b'':
                raise RuntimeError('get_trusted_input_next (%d): %s' % (j, r))

        # send locktime
        buf = struct.pack('<I', tx_i.nLockTime)
        r = ledger.call_get_trusted_input_next(buf)
        if r == b'':
            raise RuntimeError('bad trusted input response')

        d['tib'] = r
        til.append(d)

    # Second, we need a signature to put in each vin[i].scriptSig.
    sigs = []
    for i in range(len(tx.vin)):

        tx_i = CTransaction(tx)
        for v in tx_i.vin:
            v.scriptSig = b''
        tx_i.vin[i].scriptSig = til[i]['scriptPubKey']

        # get (hash160) public key we need to sign with
        if not script.is_standard(til[i]['scriptPubKey']):
            raise RuntimeError('we can only include P2PKH transactions')

        sd = script.disass(til[i]['scriptPubKey'])

        # save for later
        hpubkey = sd[2]['data']

        # again, we'll send the transaction in chunks
        buf = struct.pack('<i', tx_i.nVersion) + serialize.ser_compact_size(len(tx_i.vin)) + bytes([1, len(til[0]['tib'])]) + til[0]['tib'] + serialize.ser_string(tx_i.vin[0].scriptSig) + struct.pack('<I', tx_i.vin[0].nSequence)
        r = ledger.call_hash_input_start_first(buf)
        if b'' != r:
            raise RuntimeError('hash_input_start_first: %s' % r)

        for j in range(1, len(tx_i.vin)):
            buf = bytes([1, len(til[j]['tib'])]) + til[j]['tib'] + serialize.ser_string(tx_i.vin[j].scriptSig) + struct.pack('<I', tx_i.vin[j].nSequence)
            r = ledger.call_hash_input_start_next(buf)
            if b'' != r:
                raise RuntimeError('hash_input_start_next: %s' % r)

        # okay, all the inputs have been given; now the outputs
        buf = serialize.ser_vector(tx_i.vout)
        bufl = [buf[x:x + 200] for x in range(0, len(buf), 200)] # can be broken up arbitrarily

        # everything but the very last one
        for b in bufl[:-1]:
            r = ledger.call_hash_input_finalize_full(b)
            if b'' != r:
                raise RuntimeError('hash_input_finalize_full: %s' % r)

        # register the change path if we have it
        if change_path is not None:
            r = ledger.call_hash_input_finalize_full_change(change_path)
            if b'' != r:
                raise RuntimeError('hash_input_finalize_full_change: %s' % r)

        sys.stdout.write('\nSign input %d: ' % (i + 1)); sys.stdout.flush()

        # now the last part of the outputs
        r = ledger.call_hash_input_finalize_full_last(bufl[-1])
        if r != bytearray(b'\x00\x00'):
            raise RuntimeError('hash_input_finalize_full: %s' % r)

        sys.stdout.write('signed'); sys.stdout.flush()

        # get the address path for the given hashed pubkey
        addr = energi.address_repr(hpubkey)
        keypath = energi.serialize_pathd(address_d[addr])

        # now sign
        buf = serialize.hs2b(keypath) + b'\x00' + struct.pack('>I', tx_i.nLockTime) + bytes([_hashtype_d['SIGHASH_ALL']])
        r = ledger.call_hash_sign(buf) # last byte is hashtype

        # save for scriptSig
        pubkey = address_d[addr]['pubkey'] if 'pubkey' in address_d[addr] else address_d[addr]['public_key']
        if energi.hash160(pubkey) != hpubkey:
            pubkey = energi.compress_public_key(pubkey)
            if energi.hash160(pubkey) != hpubkey:
                raise RuntimeError('address confusion')
        sigs.append({'signature': r, 'pubkey': pubkey})

    sys.stdout.write('\n'); sys.stdout.flush()

    # Finally, everything should be signed.  Construct scriptSig for each vin
    for i in range(len(tx.vin)):
        tx.vin[i].scriptSig = script.standard_scriptsig(sigs[i]['signature'], sigs[i]['pubkey'])

    return tx