def total_out(self): total = sum(tx_out.coin_value for tx_out in self.txs_out) if TransactionUtils.isCFTransation(self): if self.cf_header.lack_amount <= 0: pre_tx = TransactionDao.searchByHash(self.cf_header.pre_hash) total = total - self.txs_out[0].coin_value + pre_tx.cf_header.lack_amount - self.cf_header.lack_amount return total
def __init__(self, tx): self.tx_hash = tx.hash().hex() inputs = [] for txin in tx.txs_in: inputs.append(TransactionUtils.getTxinPublicAddressByPre(txin)) self.tx_inputs = inputs outputs = [] for txout in tx.txs_out: if TransactionUtils.isCFTransationOut(txout): txout_type = '众筹交易' else: txout_type = '普通交易' outputs.append([ txout.address(), txout.coin_value, txout_type, TransactionUtils.getTransactionAndOutTime(txout), txout.usedState ]) self.tx_outputs = outputs self.time = time.ctime(TransactionUtils.getTransactionAndOutTime(tx)) self.total_coin = tx.total_in() self.fee = tx.fee() if TransactionUtils.isCFTransation(tx): self.tx_type = '众筹交易' self.lock_time = time.ctime(tx.cf_header.end_time) self.pre_hash = tx.cf_header.pre_hash.hex() else: self.tx_type = '普通交易' self.get_detail(tx)
def stream(self, f, blank_solutions=False, include_unspents=False, include_witness_data=True): """Stream a Bitcoin transaction Tx to the file-like object f.""" include_witnesses = include_witness_data and self.has_witness_data() #### if TransactionUtils.isCFTransation(self): stream_struct("L", f, 2) stream_struct("#", f, self.cf_header.original_hash) stream_struct("Q", f, self.cf_header.target_amount) stream_struct("S", f, self.cf_header.pubkey.encode(encoding="utf-8")) stream_struct("L", f, self.cf_header.end_time) stream_struct("#", f, self.cf_header.pre_hash) stream_struct("Q", f, self.cf_header.lack_amount) else: stream_struct("L", f, 1) #### stream_struct("L", f, self.version) if include_witnesses: f.write(b'\0\1') stream_struct("I", f, len(self.txs_in)) for t in self.txs_in: t.stream(f, blank_solutions=blank_solutions) stream_struct("I", f, len(self.txs_out)) for t in self.txs_out: t.stream(f) if include_witnesses: for tx_in in self.txs_in: witness = tx_in.witness stream_struct("I", f, len(witness)) for w in witness: stream_bc_string(f, w) stream_struct("L", f, self.lock_time) if include_unspents and not self.missing_unspents(): self.stream_unspents(f)
def update(tx): if TransactionUtils.isCFTransation(tx): CoinSqlite3().exec_sql('Update TransactionInfo set `version`=?,`lock_time`=?,`parentBlockId`=?,`state`=?, `type` = ? ,original_hash = ?, target_amount = ?, pubkey = ?, end_time = ?, pre_hash = ?, lack_amount = ? , cert = ? where hash = ?', tx.version, tx.lock_time, tx.getBlockHash(), tx.state, 2, tx.cf_header.original_hash, tx.cf_header.target_amount, tx.cf_header.pubkey, tx.cf_header.end_time, tx.cf_header.pre_hash, tx.cf_header.lack_amount, tx.cf_header.cert, tx.hash()) else: CoinSqlite3().exec_sql('Update TransactionInfo set `version`=?,`lock_time`=?,`parentBlockId`=?, `state`=?, `type` = ? where hash = ?', tx.version, tx.lock_time, tx.getBlockHash(), tx.state, 1, tx.hash()) for index, txIn in enumerate(tx.txs_in): TransactionInDao.save(txIn, tx, index) for index, txOut in enumerate(tx.txs_out): TransactionOutDao.save(txOut, tx, index)
def insert(tx): if TransactionUtils.isCFTransation(tx): CoinSqlite3().exec_sql('INSERT INTO TransactionInfo(hash, version,lock_time,parentBlockId,state,type,original_hash, target_amount, pubkey, end_time, pre_hash, lack_amount, cert) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)', tx.hash(), tx.version, tx.lock_time, tx.getBlockHash(), tx.state, 2, tx.cf_header.original_hash, tx.cf_header.target_amount, tx.cf_header.pubkey, tx.cf_header.end_time, tx.cf_header.pre_hash, tx.cf_header.lack_amount, tx.cf_header.cert) else: CoinSqlite3().exec_sql('INSERT INTO TransactionInfo(hash, version,lock_time,parentBlockId,state,type) VALUES (?,?,?,?,?,?)', tx.hash(), tx.version, tx.lock_time, tx.getBlockHash(), tx.state, 1) for index, txIn in enumerate(tx.txs_in): TransactionInDao.save(txIn, tx, index) for index, txOut in enumerate(tx.txs_out): TransactionOutDao.save(txOut, tx, index)
def save(txOut, tx, index): deleteOld(tx, index) pubicAddress = txOut.address() end_time = 0 if TransactionUtils.isCFTransation(tx): if 0 == index: end_time = tx.cf_header.end_time CoinSqlite3().exec_sql( 'INSERT INTO TransactionInfoOut(coin_value, script, parentBlockId, parentTxId, state, `index`, pubicAddress, isToMe, usedState, end_time, isMyTx) VALUES (?,?,?,?,?,?,?,?,?,?,?)', txOut.coin_value, txOut.script, tx.getBlockHash(), tx.hash(), txOut.state, index, pubicAddress, SecretKeyDao.isMypubicAddress(pubicAddress), 0, end_time, SecretKeyDao.isMypubicAddress(txOut.address()))
def dump_tx(tx, netcode, verbose_signature, disassembly_level, do_trace, use_pdb): address_prefix = address_prefix_for_netcode(netcode) tx_bin = stream_to_bytes(tx.stream) # print("Tx_type:%2d" % tx.tx_type) if TransactionUtils.isCFTransation(tx): print("original_hash : %s" % tx.cf_header.original_hash) print("target_amount : %s" % tx.cf_header.target_amount) print("pubkey : %s" % tx.cf_header.pubkey) print("end_time : %s" % tx.cf_header.end_time) print("pre_hash : %s" % tx.cf_header.pre_hash) print("lack_amount : %s" % tx.cf_header.lack_amount) print("Version: %2d tx hash %s %d bytes " % (tx.version, tx.id(), len(tx_bin))) print("TransactionIn count: %d; TransactionOut count: %d" % (len(tx.txs_in), len(tx.txs_out))) if tx.lock_time == 0: meaning = "valid anytime" elif tx.lock_time < LOCKTIME_THRESHOLD: meaning = "valid after block index %d" % tx.lock_time else: when = datetime.datetime.utcfromtimestamp(tx.lock_time) meaning = "valid on or after %s utc" % when.isoformat() print("Lock time: %d (%s)" % (tx.lock_time, meaning)) print("Input%s:" % ('s' if len(tx.txs_in) != 1 else '')) missing_unspents = tx.missing_unspents() def trace_script(old_pc, opcode, data, stack, altstack, if_condition_stack, is_signature): from pycoin.tx.script.tools import disassemble_for_opcode_data print("%3d : %02x %s" % (old_pc, opcode, disassemble_for_opcode_data(opcode, data))) if use_pdb: import pdb from pycoin.serialize import b2h print("stack: [%s]" % ', '.join(b2h(s) for s in stack)) if len(altstack) > 0: print("altstack: %s" % altstack) if len(if_condition_stack) > 0: print("condition stack: %s" % ', '.join(int(s) for s in if_condition_stack)) pdb.set_trace() traceback_f = trace_script if do_trace or use_pdb else None for idx, tx_in in enumerate(tx.txs_in): if disassembly_level > 0: def signature_for_hash_type_f(hash_type, script): return tx.signature_hash(script, idx, hash_type) if tx.is_coinbase(): print("%4d: COINBASE %12.5f mBTC" % (idx, satoshi_to_mbtc(tx.total_in()))) else: suffix = "" if tx.missing_unspent(idx): tx_out = None address = tx_in.bitcoin_address(address_prefix=address_prefix) else: tx_out = tx.unspents[idx] sig_result = " sig ok" if tx.is_signature_ok( idx, traceback_f=traceback_f) else " BAD SIG" suffix = " %12.5f mBTC %s" % (satoshi_to_mbtc( tx_out.coin_value), sig_result) address = tx_out.bitcoin_address(netcode=netcode) t = "%4d: %34s from %s:%-4d%s" % (idx, address, b2h_rev(tx_in.previous_hash), tx_in.previous_index, suffix) print(t.rstrip()) if disassembly_level > 0: out_script = b'' if tx_out: out_script = tx_out.script for (pre_annotations, pc, opcode, instruction, post_annotations) in \ disassemble_scripts( tx_in.script, out_script, tx.lock_time, signature_for_hash_type_f): for l in pre_annotations: print(" %s" % l) print(" %4x: %02x %s" % (pc, opcode, instruction)) for l in post_annotations: print(" %s" % l) if verbose_signature: signatures = [] for opcode in opcode_list(tx_in.script): if not opcode.startswith("OP_"): try: signatures.append(parse_signature_blob( h2b(opcode))) except UnexpectedDER: pass if signatures: sig_types_identical = (zip(*signatures)[1]).count( signatures[0][1]) == len(signatures) i = 1 if len(signatures) > 1 else '' for sig_pair, sig_type in signatures: print(" r{0}: {1:#x}\n s{0}: {2:#x}".format( i, *sig_pair)) if not sig_types_identical and tx_out: print(" z{}: {:#x} {}".format( i, tx.signature_hash(tx_out.script, idx, sig_type), sighash_type_to_string(sig_type))) if i: i += 1 if sig_types_identical and tx_out: print(" z:{} {:#x} {}".format( ' ' if i else '', tx.signature_hash(tx_out.script, idx, sig_type), sighash_type_to_string(sig_type))) print("Output%s:" % ('s' if len(tx.txs_out) != 1 else '')) for idx, tx_out in enumerate(tx.txs_out): amount_mbtc = satoshi_to_mbtc(tx_out.coin_value) address = tx_out.bitcoin_address(netcode=netcode) or "(unknown)" print("%4d: %34s receives %12.5f mBTC" % (idx, address, amount_mbtc)) if disassembly_level > 0: for (pre_annotations, pc, opcode, instruction, post_annotations) in \ disassemble_scripts(b'', tx_out.script, tx.lock_time, signature_for_hash_type_f): for l in pre_annotations: print(" %s" % l) print(" %4x: %02x %s" % (pc, opcode, instruction)) for l in post_annotations: print(" %s" % l) if not missing_unspents: print("Total input %12.5f mBTC" % satoshi_to_mbtc(tx.total_in())) print("Total output %12.5f mBTC" % satoshi_to_mbtc(tx.total_out())) if not missing_unspents: print("Total fees %12.5f mBTC" % satoshi_to_mbtc(tx.fee()))
def cf_tc_number(self): cf_tc = 0 for tx in self.txs: if TransactionUtils.isCFTransation(tx): ++cf_tc return cf_tc
def normal_tc_number(self): normal_tc = 0 for tx in self.txs: if not TransactionUtils.isCFTransation(tx): ++normal_tc return normal_tc