def get_merkle_tree(block): merkle_tree = [] merkle_tree.append( [hash_tx(tx).get_bytestr() for tx in block.transactions]) while (len(merkle_tree[-1]) != 1): merkle_tree.append(next_merkle_level(merkle_tree[-1])) return (merkle_tree)
def _mark_blockinputs_spent(self, block, spent=True): for tx in block.transactions: txhash = hash_tx(tx) if not tx.iscoinbase(): for txin in tx.in_list: txprev_handle = self.database.get_transaction_handle(txin.previous_output.hash) txprev_handle.mark_spent(txin.previous_output.index, spent, txhash)
def check_tx_finalized(self, prevblockhandle, hash, block): height = prevblockhandle.get_height() + 1 #Check that all transactions are finalized (can this be done somewhere else?) for tx in block.transactions: if not tx.isfinal(height, block.blockheader.time): raise Exception("transaction is not final: %s" % str(hash_tx(tx)))
def __init__(self, block, block_view): block_view.set_hash(hash_block(block).get_hexstr()) block_view.set_previous_block(block.blockheader.hash_prev.get_hexstr()) str_blocktime = time.strftime("%Y-%m-%d %H:%m:%S", time.gmtime(block.blockheader.time)) block_view.set_time(str_blocktime) block_view.set_difficulty("%x" % (block.blockheader.bits)) block_view.set_merkle(block.blockheader.hash_merkle.get_hexstr()) block_view.set_nonce(str(block.blockheader.nonce)) for tx in block.transactions: amount_out = sum(out.value for out in tx.out_list) block_view.add_transaction(hash_tx(tx).get_hexstr(), str(amount_out/ COIN) , "0", "")
def on_tx(self, event): peer, message = event.handler, event.message hash = hash_tx(message.tx) self.log.info("on_tx hash:%s" % (str(hash))) if (hash not in self.requested_tx): self.misbehaving(peer, "peer sending unrequest 'tx'") return del self.requested_tx[hash] #check for orphan transactions try: yield self.verified_add_tx(message.tx) except Exception as e: self.log.error("peer %s sending errorneous 'tx': %s" %(str(peer), str(e))) self.misbehaving(peer, "peer sending errorneous 'tx': ")
def __init__(self, block, block_view): block_view.set_hash(hash_block(block).get_hexstr()) block_view.set_previous_block(block.blockheader.hash_prev.get_hexstr()) str_blocktime = time.strftime("%Y-%m-%d %H:%m:%S", time.gmtime(block.blockheader.time)) block_view.set_time(str_blocktime) block_view.set_difficulty("%x" % (block.blockheader.bits)) block_view.set_merkle(block.blockheader.hash_merkle.get_hexstr()) block_view.set_nonce(str(block.blockheader.nonce)) for tx in block.transactions: amount_out = sum(out.value for out in tx.out_list) block_view.add_transaction( hash_tx(tx).get_hexstr(), str(amount_out / COIN), "0", "")
def send_transaction(self, planned_tx, passphrases): try: self.wallet.unlock(passphrases) privkey_list = [] for outpoint, txout in planned_tx.selected_outputs: privkey_list.append( self.wallet.get_txout_private_key_secret(txout)) finally: self.wallet.lock() sign_transaction( planned_tx.tx, [txout for outpoint, txout in planned_tx.selected_outputs], privkey_list) txhash = hash_tx(planned_tx.tx) self.log.info( "Sending %f to %s (fee:%f), change address: %s, hash:%s" % (planned_tx.amount, str(planned_tx.address), planned_tx.fee, str(planned_tx.change_address), str(txhash))) #Initially, create an empty MerkleTx (the tx is not yet in a block) merkle_tx = MerkleTx(planned_tx.tx, Uint256.zero(), [], 4294967295) self.wallet.begin_updates() self.wallet.allocate_key(planned_tx.change_public_key, ischange=True) #Set the spend flags for the input transactions for outpoint, txout in planned_tx.selected_outputs: input_wallet_tx = self.wallet.get_transaction(outpoint.hash) input_wallet_tx.set_spent(outpoint.index) self.wallet.set_transaction(outpoint.hash, input_wallet_tx) #Add the wallet_tx (contains supporting transations) txtime = int(time.time()) wallet_tx = create_wallet_tx(self.blockchain, merkle_tx, txtime) self.wallet.add_transaction(txhash, wallet_tx) self.wallet.commit_updates() self.fire(self.EVT_NEW_TRANSACTION_ITEM, item=(planned_tx.tx, txhash, txtime, planned_tx.address, "", -planned_tx.amount, False)) self.compute_balances() # we could only compute delta here self.fire(self.EVT_PUBLISH_TRANSACTION, txhash=txhash, tx=planned_tx.tx) self.last_tx_publish[txhash] = txtime #update description of change address new_description = self.wallet.get_address_description( planned_tx.change_public_key) self.fire(self.EVT_NEW_ADDRESS_DESCRIPTION, public_key=planned_tx.change_public_key, description=new_description)
def append_block(self, block): """ """ blkhash = hash_block(block) self.indexed_blocks[blkhash] = block self.block_heights[blkhash] = len(self.blocks) if self.blocks: self.next_main_chain[hash_block(self.blocks[-1])] = blkhash self.next_main_chain[hash_block(block)] = None self.blocks.append(block) for tx in block.transactions: txhash = hash_tx(tx) self.indexed_tx[txhash] = tx self.tx_blkhashes[txhash] = blkhash self.spend_outputs[txhash] = [None] * len(tx.out_list) if not tx.iscoinbase(): for txin in tx.in_list: self.spend_outputs[txin.previous_output.hash][txin.previous_output.index] = txhash
def _index_transactions(self, blockhash, block=None): block_handle = self.get_block_handle(blockhash) #Add all transactions to the indexdb if not block: block = block_handle.get_block() size_blockheader = BlockheaderSerializer().get_size(block.blockheader) size_tx_size = VarintSerializer().get_size(len(block.transactions)) tx_serializer = TxSerializer() blockpos = block_handle.blockindex.blockpos txpos = block_handle.blockindex.blockpos + size_blockheader + size_tx_size for i, tx in enumerate(block.transactions): txindex = DbTxIndex(1, DiskTxPos(1, blockpos, txpos), [DiskTxPos() for _ in range(tx.output_count())]) self.indexdb.set_transactionindex(hash_tx(tx), txindex) #TODO: speed this up... if tx.rawdata: txpos += len(tx.rawdata) else: txpos += tx_serializer.get_size(tx)
def append_block(self, block): """ """ blkhash = hash_block(block) self.indexed_blocks[blkhash] = block self.block_heights[blkhash] = len(self.blocks) if self.blocks: self.next_main_chain[hash_block(self.blocks[-1])] = blkhash self.next_main_chain[hash_block(block)] = None self.blocks.append(block) for tx in block.transactions: txhash = hash_tx(tx) self.indexed_tx[txhash] = tx self.tx_blkhashes[txhash] = blkhash self.spend_outputs[txhash] = [None] * len(tx.out_list) if not tx.iscoinbase(): for txin in tx.in_list: self.spend_outputs[txin.previous_output.hash][ txin.previous_output.index] = txhash
def verified_add_tx(self, tx): txhash = hash_tx(tx) if self.txpool.contains_transaction(txhash): return self.txverifier.basic_checks(tx) if tx.iscoinbase(): raise Exception("Coinbase transactions aren't allowed in memory pool") #check for orphan transactions. contains_txins = [self.blockchain.contains_transaction(txin.previous_output.hash) for txin in tx.in_list] if not all(contains_txins): self.log.info("Adding orphan tx %s" % str(txhash)) self.orphan_tx[txhash] = tx self.fire(self.EVT_ADDED_ORPHAN_TX, hash=txhash) return self.log.info("Connecting tx %s" % str(txhash)) self.blockchain.connect_pool_tx(tx, self.blockchain.get_height() + 1, self.process_pool) self.log.info("Adding tx %s" % str(tx)) self.txpool.add_tx(txhash, tx) yield
def send_transaction(self, planned_tx, passphrases): try: self.wallet.unlock(passphrases) privkey_list = [] for outpoint, txout in planned_tx.selected_outputs: privkey_list.append(self.wallet.get_txout_private_key_secret(txout)) finally: self.wallet.lock() sign_transaction(planned_tx.tx, [txout for outpoint, txout in planned_tx.selected_outputs], privkey_list) txhash = hash_tx(planned_tx.tx) self.log.info( "Sending %f to %s (fee:%f), change address: %s, hash:%s" % (planned_tx.amount, str(planned_tx.address), planned_tx.fee, str(planned_tx.change_address), str(txhash)) ) # Initially, create an empty MerkleTx (the tx is not yet in a block) merkle_tx = MerkleTx(planned_tx.tx, Uint256.zero(), [], 4294967295) self.wallet.begin_updates() self.wallet.allocate_key(planned_tx.change_public_key, ischange=True) # Set the spend flags for the input transactions for outpoint, txout in planned_tx.selected_outputs: input_wallet_tx = self.wallet.get_transaction(outpoint.hash) input_wallet_tx.set_spent(outpoint.index) self.wallet.set_transaction(outpoint.hash, input_wallet_tx) # Add the wallet_tx (contains supporting transations) txtime = int(time.time()) wallet_tx = create_wallet_tx(self.blockchain, merkle_tx, txtime) self.wallet.add_transaction(txhash, wallet_tx) self.wallet.commit_updates() self.fire( self.EVT_NEW_TRANSACTION_ITEM, item=(planned_tx.tx, txhash, txtime, planned_tx.address, "", -planned_tx.amount, False), ) self.compute_balances() # we could only compute delta here self.fire(self.EVT_PUBLISH_TRANSACTION, txhash=txhash, tx=planned_tx.tx) self.last_tx_publish[txhash] = txtime # update description of change address new_description = self.wallet.get_address_description(planned_tx.change_public_key) self.fire( self.EVT_NEW_ADDRESS_DESCRIPTION, public_key=planned_tx.change_public_key, description=new_description )
def pop_block(self): """ raises RemovingGenesisException: if the blockchain only contains the genesis block. """ block = self.blocks.pop() blkhash = hash_block(block) #remove indexes del self.next_main_chain[blkhash] self.next_main_chain[block.blockheader.hash_prev] = None del self.indexed_blocks[blkhash] del self.block_heights[blkhash] for tx in block.transactions: txhash = hash_tx(tx) if not tx.iscoinbase(): for txin in tx.in_list: self.spend_outputs[txin.previous_output.hash][txin.previous_output.index] = None del self.indexed_tx[txhash] del self.tx_blkhashes[txhash] del self.spend_outputs[txhash] return block
def pop_block(self): """ raises RemovingGenesisException: if the blockchain only contains the genesis block. """ block = self.blocks.pop() blkhash = hash_block(block) #remove indexes del self.next_main_chain[blkhash] self.next_main_chain[block.blockheader.hash_prev] = None del self.indexed_blocks[blkhash] del self.block_heights[blkhash] for tx in block.transactions: txhash = hash_tx(tx) if not tx.iscoinbase(): for txin in tx.in_list: self.spend_outputs[txin.previous_output.hash][ txin.previous_output.index] = None del self.indexed_tx[txhash] del self.tx_blkhashes[txhash] del self.spend_outputs[txhash] return block
def compute_merkle_root(transactions): hashes = [hash_tx(tx).get_bytestr() for tx in transactions] while (len(hashes) != 1): hashes = next_merkle_level(hashes) return (Uint256.from_bytestr(hashes[0]))
def check_tx_finalized(self, prevblockhandle, hash, block): height = prevblockhandle.get_height()+1 #Check that all transactions are finalized (can this be done somewhere else?) for tx in block.transactions: if not tx.isfinal(height, block.blockheader.time): raise Exception("transaction is not final: %s" % str(hash_tx(tx)))
def get_spending_transactionu_hash(self, n): disktxpos = self.txindex.spent[n] tx = self.blockstorage.load_tx(disktxpos.file, disktxpos.txpos) return hash_tx(tx)
def _unindex_transactions(self, blockhash): block_handle = self.get_block_handle(blockhash) block = block_handle.get_block() for tx in block.transactions: self.indexdb.del_transactionindex(hash_tx(tx))
def get_merkle_tree(block): merkle_tree = [] merkle_tree.append([hash_tx(tx).get_bytestr() for tx in block.transactions]) while (len(merkle_tree[-1]) != 1): merkle_tree.append(next_merkle_level(merkle_tree[-1])) return (merkle_tree)