Ejemplo n.º 1
0
 def recv_tx(self, ec, tx, node):
     if ec:
         print "Error with new transaction:", ec
         return
     tx_hash = bitcoin.hash_transaction(tx)
     self.memory_buffer.receive(tx, bind(self.store_tx, _1, tx_hash))
     # Re-subscribe to new transactions from node
     node.subscribe_transaction(bind(self.recv_tx, _1, _2, node))
def handle_handshake(ec, node, hs):
    if ec:
        error_exit(ec)
    # 1. Connected to other node
    # 2. Performed version/verack handshake process
    # Node is now ready and communicating with us
    node.send_get_blocks(create_get_blocks_message(),
         bitcoin.bind(handle_send_get_blocks, bitcoin._1))
    node.subscribe_inventory(
        bitcoin.bind(receive_inv, bitcoin._1, bitcoin._2, node))
    hs.fetch_network_address(show_ip)
Ejemplo n.º 3
0
 def recv_tx(self, tx, handle_store):
     tx_hash = str(bitcoin.hash_transaction(tx))
     desc = (tx_hash, [], [])
     for input in tx.inputs:
         prevout = input.previous_output
         desc[1].append((str(prevout.hash), prevout.index))
     for idx, output in enumerate(tx.outputs):
         address = bitcoin.payment_address()
         if address.extract(output.output_script):
             desc[2].append((idx, str(address)))
     self.txpool.store(tx,
         bind(self.confirmed, _1, desc),
         bind(self.mempool_stored, _1, desc, handle_store))
Ejemplo n.º 4
0
 def tx_index(self, ec, block_depth, offset, entry, info):
     if self.stop_on_error(ec):
         return
     info["height"] = block_depth
     # And now for the block hash
     self.chain.fetch_block_header_by_depth(block_depth,
         bind(self.block_header, _1, _2, entry, info))
Ejemplo n.º 5
0
 def load_pool_tx(self, ec, tx, info):
     if self.stop_on_error(ec):
         return
     # block_hash = mempool:5
     # inputs (load from prevtx)
     # outputs (load from tx)
     # raw_output_script (load from tx)
     # height is always None
     # value (get from finish_if_done)
     self.load_tx(tx, info)
     if info["is_input"] == 0:
         our_output = tx.outputs[info["index"]]
         info["value"] = our_output.value
         # Save serialised output script in case this output is unspent
         info["raw_output_script"] = \
             str(bitcoin.save_script(our_output.output_script))
     else:
         assert(info["is_input"] == 1)
         info.previous_output = tx.inputs[info["index"]].previous_output
     # If all the inputs are loaded
     if self.inputs_all_loaded(info["inputs"]):
         # We are the sole input
         assert(info["is_input"] == 1)
         # No more inputs left to load
         # This info has finished loading
         info["height"] = None
         info["block_hash"] = "mempool"
         self.finish_if_done()
     create_handler = lambda prevout_index, input_index: \
         bind(self.load_input_pool_tx, _1, _2, prevout_index, info, input_index)
     self.fetch_input_txs(tx, info, create_handler)
Ejemplo n.º 6
0
 def block_header(self, ec, blk_head, statement_line, info):
     info["timestamp"] = blk_head.timestamp
     info["block_hash"] = str(bitcoin.hash_block_header(blk_head))
     tx_hash = bitcoin.hash_digest(info["tx_hash"])
     self.chain.fetch_transaction(tx_hash,
         bitcoin.bind(self.load_tx, bitcoin._1, bitcoin._2,
             statement_line, info))
Ejemplo n.º 7
0
 def load_tx(self, ec, tx, statement_line, info):
     outputs = []
     for tx_out in tx.outputs:
         script = tx_out.output_script
         if script.type() == bitcoin.payment_type.pubkey_hash:
             pkh = bitcoin.short_hash(str(script.operations()[2].data))
             outputs.append(bitcoin.public_key_hash_to_address(pkh))
         else:
             outputs.append("Unknown")
     info["outputs"] = outputs
     info["inputs"] = [None for i in range(len(tx.inputs))]
     if info["is_input"] == 1:
         info["inputs"][info["index"]] = self.address
     else:
         our_output = tx.outputs[info["index"]]
         info["value"] = our_output.value
         with statement_line.lock:
             statement_line.raw_output_script = \
                 str(bitcoin.save_script(our_output.output_script))
     if not [empty_in for empty_in in info["inputs"] if empty_in is None]:
         # We have the sole input
         assert(info["is_input"] == 1)
         with statement_line.lock:
             statement_line.input_loaded = info
         self.finish_if_done()
     for tx_idx, tx_in in enumerate(tx.inputs):
         if info["is_input"] == 1 and info["index"] == tx_idx:
             continue
         self.chain.fetch_transaction(
             tx_in.previous_output.hash,
             bitcoin.bind(self.load_input, bitcoin._1, bitcoin._2, tx_in.previous_output.index, statement_line, info, tx_idx)
         )
Ejemplo n.º 8
0
 def subscribe(self, request):
     address = str(request["params"][0])
     service = self.backend.mempool_service
     chain = self.backend.blockchain
     txpool = self.backend.transaction_pool
     memory_buff = self.backend.memory_buffer
     history.payment_history(service, chain, txpool, memory_buff, address,
                             bind(self.construct, _1, _2, request))
Ejemplo n.º 9
0
 def monitor_tx(self, node):
     # We will be notified here when connected to new bitcoin nodes
     # Here we subscribe to new transactions from them which we
     # add to the transaction_pool. That way we can track which
     # transactions we are interested in.
     node.subscribe_transaction(bind(self.recv_tx, _1, _2, node))
     # Re-subscribe to next new node
     self.protocol.subscribe_channel(self.monitor_tx)
Ejemplo n.º 10
0
 def load_tx_info(self, point, statement_line, is_input):
     info = {}
     info["tx_hash"] = str(point.hash)
     info["index"] = point.index
     info["is_input"] = 1 if is_input else 0
     self.chain.fetch_transaction_index(point.hash,
         bitcoin.bind(self.tx_index, bitcoin._1, bitcoin._2, bitcoin._3,
             statement_line, info))
Ejemplo n.º 11
0
 def block_header(self, ec, blk_head, entry, info):
     if self.stop_on_error(ec):
         return
     info["timestamp"] = blk_head.timestamp
     info["block_hash"] = str(bitcoin.hash_block_header(blk_head))
     tx_hash = bitcoin.hash_digest(info["tx_hash"])
     # Now load the actual main transaction for this input or output
     self.chain.fetch_transaction(tx_hash, bind(self.load_chain_tx, _1, _2, entry, info))
Ejemplo n.º 12
0
 def load_tx_info(self, point, entry, is_input):
     info = {}
     info["tx_hash"] = str(point.hash)
     info["index"] = point.index
     info["is_input"] = 1 if is_input else 0
     # Before loading the transaction, Stratum requires the hash
     # of the parent block, so we load the block depth and then
     # fetch the block header and hash it.
     self.chain.fetch_transaction_index(point.hash, bind(self.tx_index, _1, _2, _3, entry, info))
Ejemplo n.º 13
0
 def start_loading(self, membuf_result, output_points):
     if len(membuf_result) == 0 and len(output_points) == 0:
         self.handle_finish([])
         self.stopped()
     # Create a bunch of entry lines which are outputs and
     # then their corresponding input (if it exists)
     for outpoint in output_points:
         entry = PaymentEntry(outpoint)
         with self.lock:
             self.statement.append(entry)
         # Attempt to fetch the spend of this output
         self.chain.fetch_spend(outpoint, bind(self.load_spend, _1, _2, entry))
         self.load_tx_info(outpoint, entry, False)
     # Load memory pool transactions
     with self.lock:
         self.membuf_result = membuf_result
     for info in self.membuf_result:
         self.txpool.fetch(bitcoin.hash_digest(info["tx_hash"]), bind(self.load_pool_tx, _1, _2, info))
Ejemplo n.º 14
0
 def start_loading(self, ec, output_points):
     with self.lock:
         for outpoint in output_points:
             statement_line = StatementLine(outpoint)
             self.statement.append(statement_line)
             self.chain.fetch_spend(outpoint,
                 bitcoin.bind(self.load_spend,
                     bitcoin._1, bitcoin._2, statement_line))
             self.load_tx_info(outpoint, statement_line, False)
Ejemplo n.º 15
0
    def start(self, address, handle_finish):
        self.statement = []
        self.membuf_result = None
        self.address = address
        self.handle_finish = handle_finish

        address = bitcoin.payment_address(address)
        # To begin we fetch all the outputs (payments in)
        # associated with this address
        self.chain.fetch_outputs(address, bind(self.check_membuf, _1, _2))
Ejemplo n.º 16
0
 def notify(self, affected_addrs):
     service = self.backend.mempool_service
     chain = self.backend.blockchain
     txpool = self.backend.transaction_pool
     memory_buff = self.backend.memory_buffer
     for address in affected_addrs:
         response = {"id": None,
                     "method": "blockchain.address.subscribe",
                     "params": [str(address)]}
         history.payment_history(service, chain, txpool, memory_buff, address,
                                 bind(self.send_notify, _1, _2, response))
def receive_inv(ec, inv, node):
    if ec:
        error_exit(ec)
    print "Received:"
    for ivv in inv.inventories:
        if ivv.type == bitcoin.inventory_type.block:
            print ivv.hash
        else:
            print "--"
    # Re-subscribe to receive further inventory packets.
    # Bitcoin nodes can respond with any number of hashes split over
    # any number of batches.
    node.subscribe_inventory(
        bitcoin.bind(receive_inv, bitcoin._1, bitcoin._2, node))
Ejemplo n.º 18
0
 def load_chain_tx(self, ec, tx, entry, info):
     if self.stop_on_error(ec):
         return
     self.load_tx(tx, info)
     if info["is_input"] == 0:
         our_output = tx.outputs[info["index"]]
         info["value"] = our_output.value
         # Save serialised output script in case this output is unspent
         with entry.lock:
             entry.raw_output_script = \
                 str(bitcoin.save_script(our_output.output_script))
     # If all the inputs are loaded
     if self.inputs_all_loaded(info["inputs"]):
         # We are the sole input
         assert(info["is_input"] == 1)
         with entry.lock:
             entry.input_loaded = info
         self.finish_if_done()
     create_handler = lambda prevout_index, input_index: \
         bind(self.load_input_chain_tx, _1, _2, prevout_index, entry, info, input_index)
     self.fetch_input_txs(tx, info, create_handler)
Ejemplo n.º 19
0
def payment_history(service, chain, txpool, membuf, address, finish):
    _history.payment_history(service.internal_ptr, chain.internal_ptr,
                             txpool.internal_ptr, membuf.internal_ptr,
                             str(address), bind(wrap_finish, finish, _1, _2))
Ejemplo n.º 20
0
 def tx_index(self, ec, block_depth, offset, statement_line, info):
     info["height"] = block_depth
     self.chain.fetch_block_header_by_depth(
         block_depth,
         bitcoin.bind(self.block_header, bitcoin._1, bitcoin._2, statement_line, info)
     )
def handle_init(ec, hs, net):
    if ec:
        error_exit(ec)
    # Main program thread begins here
    hs.connect(net, "localhost", 8333,
        bitcoin.bind(handle_handshake, bitcoin._1, bitcoin._2, hs))
Ejemplo n.º 22
0
 def check_membuf(self, ec, output_points):
     if self.stop_on_error(ec):
         return
     self.membuf.check(output_points, self.address, bind(self.start_loading, _1, output_points))
Ejemplo n.º 23
0
import bitcoin

def start_polling(ec, node, poll):
    if ec:
        print ec
        return
    poll.query(node)

if __name__ == "__main__":
    s1 = bitcoin.async_service(1)
    s2 = bitcoin.async_service(1)
    chain = bitcoin.bdb_blockchain(s1, "database")
    poll = bitcoin.poller(chain)
    net = bitcoin.network(s2)
    hs = bitcoin.handshake(s2)
    hs.connect(net, "localhost", 8333,
        bitcoin.bind(start_polling, bitcoin._1, bitcoin._2, poll))
    raw_input()

    if ec:
        error_exit(ec)
    print addr.ip

def handle_handshake(ec, node, hs):
    if ec:
        error_exit(ec)
    # 1. Connected to other node
    # 2. Performed version/verack handshake process
    # Node is now ready and communicating with us
    node.send_get_blocks(create_get_blocks_message(),
         bitcoin.bind(handle_send_get_blocks, bitcoin._1))
    node.subscribe_inventory(
        bitcoin.bind(receive_inv, bitcoin._1, bitcoin._2, node))
    hs.fetch_network_address(show_ip)

def handle_init(ec, hs, net):
    if ec:
        error_exit(ec)
    # Main program thread begins here
    hs.connect(net, "localhost", 8333,
        bitcoin.bind(handle_handshake, bitcoin._1, bitcoin._2, hs))

if __name__ == "__main__":
    s = bitcoin.async_service(1)
    net = bitcoin.network(s)
    hs = bitcoin.handshake(s)
    hs.start(bitcoin.bind(handle_init, bitcoin._1, hs, net))
    raw_input()