def process(self, block): if not block.complete: self.postpone(block) return print "Processing block...", block # Check hash of keys + values matches root hash if not block.verify(): # Invalid block so reject it. print >> sys.stderr, "Rejecting invalid block." return # Fetch tx to check it's valid assert block.header.tx_hash # Forging callback def tx_fetched(ec, tx): print ec if ec is not None: print >> sys.stderr, "Block doesn't exist (yet)." self.postpone(block) return self._tx_fetched(block, tx, block.header.tx_hash) if forge.client is None: forge.client = obelisk.ObeliskOfLightClient( "tcp://obelisk.unsystem.net:8081") forge.client.fetch_transaction(block.header.tx_hash, tx_fetched)
def main(args): global address global client address = args[0] client = obelisk.ObeliskOfLightClient("tcp://dev.unsystem.net:9091") client.fetch_history2(address, history_fetched) obelisk.start()
def send_root_hash(root_hash, finished_cb): global client if client is None: client = obelisk.ObeliskOfLightClient("tcp://obelisk.unsystem.net:8081") print "Sending", root_hash.encode("hex") cb = HistoryCallback(root_hash, finished_cb) client.fetch_history(address, cb.fetched)
def setUpClass(cls): cls.pubkeys_hex = ( "035b175132eeb8aa6e8455b6f1c1e4b2784bea1add47a6ded7fc9fc6b7aff16700", "0351e400c871e08f96246458dae79a55a59730535b13d6e1d4858035dcfc5f16e2", "02d53a92e3d43db101db55e351e9b42b4f711d11f6a31efbd4597695330d75d250" ) cls.pubkeys = tuple(key.decode('hex') for key in cls.pubkeys_hex) cls.client = obelisk.ObeliskOfLightClient("tcp://85.25.198.97:8081")
def __init__(self, seed): self.wallet = obelisk.HighDefWallet.root(seed) self.key_index = 0 self.client = obelisk.ObeliskOfLightClient('tcp://37.139.11.99:9091') self.addrs = {self.current_address: []} self.keys = { self.current_address: self.current_key, self.current_change_address: self.current_change_key } self.last_height = None
def __init__(self, service): settings = dict(debug=True) settings.update(options.as_dict()) # legacy support if config.get('legacy-url', False): if ws_legacy_enabled: self.ws_client = LegacyClient("wss://" + config.get('legacy-url')) else: print "legacy-url is configured but autobahn not installed" self.ws_client = False client = obelisk.ObeliskOfLightClient(service) self.obelisk_handler = obelisk_handler.ObeliskHandler( client, self.ws_client) self.brc_handler = broadcast.BroadcastHandler() self.p2p = CryptoTransportLayer(config.get('p2p-port', 8889), config.get('external-ip', '127.0.0.1'), config.get('internal-ip', None)) self.p2p.join_network(config.get('seeds', [])) self.json_chan_handler = jsonchan.JsonChanHandler(self.p2p) self.ticker_handler = ticker.TickerHandler() handlers = [ # /block/<block hash> (r"/block/([^/]*)(?:/)?", rest_handlers.BlockHeaderHandler), # /block/<block hash>/transactions (r"/block/([^/]*)/transactions(?:/)?", rest_handlers.BlockTransactionsHandler), # /tx/ (r"/tx(?:/)?", rest_handlers.TransactionPoolHandler), # /tx/<txid> (r"/tx/([^/]*)(?:/)?", rest_handlers.TransactionHandler), # /address/<address> (r"/address/([^/]*)(?:/)?", rest_handlers.AddressHistoryHandler), # /height (r"/height(?:/)?", rest_handlers.HeightHandler), # /height (r"/status(?:/)?", status.StatusHandler, { "app": self }), # / (r"/", QuerySocketHandler) ] tornado.web.Application.__init__(self, handlers, **settings)
def main(): ########################################################## # ESCROW TEST ########################################################## pubkeys = [ "035b175132eeb8aa6e8455b6f1c1e4b2784bea1add47a6ded7fc9fc6b7aff16700".decode("hex"), "0351e400c871e08f96246458dae79a55a59730535b13d6e1d4858035dcfc5f16e2".decode("hex"), "02d53a92e3d43db101db55e351e9b42b4f711d11f6a31efbd4597695330d75d250".decode("hex") ] client = obelisk.ObeliskOfLightClient("tcp://85.25.198.97:8081") escrow = Escrow(client, pubkeys[0], pubkeys[1], pubkeys[2]) def finished(tx): buyer_sigs = escrow.release_funds(tx, "b28c7003a7b6541cd1cd881928863abac0eff85f5afb40ff5561989c9fb95fb2".decode("hex")) completed_tx = escrow.claim_funds(tx, "5b05667dac199c48051932f14736e6f770e7a5917d2994a15a1508daa43bc9b0".decode("hex"), buyer_sigs) print 'COMPLETED TX: ', completed_tx.serialize().encode("hex") # TODO: Send to the bitcoin network escrow.initiate("1Fufjpf9RM2aQsGedhSpbSCGRHrmLMJ7yY", finished) ########################################################## # MULTISIGNATURE TEST ########################################################## msig = Multisig(client, 2, pubkeys) print "Multisig address: ", msig.address def finished(tx): print tx print '' print tx.serialize().encode("hex") print '' sigs1 = msig.sign_all_inputs(tx, "b28c7003a7b6541cd1cd881928863abac0eff85f5afb40ff5561989c9fb95fb2".decode("hex")) sigs3 = msig.sign_all_inputs(tx, "b74dbef0909c96d5c2d6971b37c8c71d300e41cad60aeddd6b900bba61c49e70".decode("hex")) for i, input in enumerate(tx.inputs): sigs = (sigs1[i], sigs3[i]) script = "\x00" for sig in sigs: script += chr(len(sig)) + sig script += "\x4c" assert len(msig.script) < 255 script += chr(len(msig.script)) + msig.script print "Script:", script.encode("hex") tx.inputs[i].script = script print tx print tx.serialize().encode("hex") msig.create_unsigned_transaction("1Fufjpf9RM2aQsGedhSpbSCGRHrmLMJ7yY", finished) reactor.run()
def get_unspent(addr, callback): # print('get_unspent call') def history_fetched(ec, history): # print('history_fetched') if ec is not None: # print >> sys.stderr, "Error fetching history:", ec return unspent_rows = [row[:4] for row in history if row[4] is None] unspent = build_output_info_list(unspent_rows) unspent = obelisk.select_outputs(unspent, 10000) if unspent is None: callback(0) return points = unspent.points if len(points) != 1: callback(0) return point = points[0] value = point.value callback(value) if TESTNET: obelisk_addr = OBELISK_SERVER_TESTNET else: obelisk_addr = OBELISK_SERVER_MAINNET # print('unspent query to obelisk server at %s' % obelisk_addr) client = obelisk.ObeliskOfLightClient(obelisk_addr) # print('Obelisk client instantiated') def get_history(): # print("get_history called from thread") client.fetch_history(addr, history_fetched) reactor.callFromThread(get_history)
def main(address): c = obelisk.ObeliskOfLightClient("tcp://localhost:9091") def history_fetched(ec, history): if ec: print ec else: for id, hash, index, height, value in history: if id == obelisk.PointIdent.Output: type = "Output" #print " checksum =", obelisk.spend_checksum(hash, index) else: # == obelisk.PointIdent.Spend type = "Spend " print type, hash.encode("hex") + ":" + str( index), height, value reactor.stop() c.fetch_history2(address, history_fetched) reactor.run()
def __init__(self, service): settings = dict(debug=True) settings.update(options.as_dict()) client = obelisk.ObeliskOfLightClient(service) self.obelisk_handler = obelisk_handler.ObeliskHandler(client) self.brc_handler = broadcast.BroadcastHandler() self.p2p = CryptoTransportLayer(config.get('p2p-port', 8889), config.get('external-ip', '127.0.0.1')) self.p2p.join_network(config.get('seeds', [])) self.json_chan_handler = jsonchan.JsonChanHandler(self.p2p) self.ticker_handler = ticker.TickerHandler() handlers = [ # /block/<block hash> (r"/block/([^/]*)(?:/)?", rest_handlers.BlockHeaderHandler), # /block/<block hash>/transactions (r"/block/([^/]*)/transactions(?:/)?", rest_handlers.BlockTransactionsHandler), # /tx/ (r"/tx(?:/)?", rest_handlers.TransactionPoolHandler), # /tx/<txid> (r"/tx/([^/]*)(?:/)?", rest_handlers.TransactionHandler), # /address/<address> (r"/address/([^/]*)(?:/)?", rest_handlers.AddressHistoryHandler), # /height (r"/height(?:/)?", rest_handlers.HeightHandler), # /height (r"/status(?:/)?", status.StatusHandler, {"app": self}), # / (r"/", QuerySocketHandler) ] tornado.web.Application.__init__(self, handlers, **settings)
def main(txhash): c = obelisk.ObeliskOfLightClient("tcp://localhost:9091") txhash = txhash.decode("hex") def cb_txpool(ec, result): if ec: c.fetch_transaction(txhash, cb_chain) else: print "From Txpool:" print result.encode("hex") reactor.stop() def cb_chain(ec, result): if ec: print ec else: print "From Blockchain:" print result.encode("hex") reactor.stop() c.fetch_txpool_transaction(txhash, cb_txpool) reactor.run()
def poll_latest(client): print "poll_latest..." def last_height_fetched(ec, height): client.fetch_block_header(height, header_fetched) def header_fetched(ec, header): print "Last:", header client.fetch_last_height(last_height_fetched) reactor.callLater(20, poll_latest, client) if __name__ == '__main__': c = obelisk.ObeliskOfLightClient('tcp://85.25.198.97:8081') #c.fetch_last_height(print_height) #blk_hash = "000000000000000471988cc24941335b" \ # "91d35d646971b7de682b4236dc691919".decode("hex") #assert len(blk_hash) == 32 #c.fetch_block_header(blk_hash, print_blk_header) #c.fetch_block_header(270778, print_blk_header) addresses = [ '1Evy47MqD82HGx6n1KHkHwBgCwbsbQQT8m', '1GUUpMm899Tr1w5mMvwnXcxbs77fmspTVC' ] if os.path.exists('addresses.txt'): f = open('addresses.txt') addresses = map(lambda s: s.strip(), f.readlines()) addresses = filter(lambda s: s, addresses)
def client_release_payment(self, socket_handler, msg): self._log.info('Releasing payment to Merchant %s' % msg) order = self._market.orders.get_order(msg['orderId']) contract = order['signed_contract_body'] # Find Seller Data in Contract offer_data = ''.join(contract.split('\n')[8:]) index_of_seller_signature = offer_data.find( '- - -----BEGIN PGP SIGNATURE-----', 0, len(offer_data)) offer_data_json = offer_data[0:index_of_seller_signature] offer_data_json = json.loads(offer_data_json) self._log.info('Offer Data: %s' % offer_data_json) # Find Buyer Data in Contract bid_data_index = offer_data.find('"Buyer"', index_of_seller_signature, len(offer_data)) end_of_bid_index = offer_data.find('- -----BEGIN PGP SIGNATURE', bid_data_index, len(offer_data)) bid_data_json = "{" + offer_data[bid_data_index:end_of_bid_index] bid_data_json = json.loads(bid_data_json) # Find Notary Data in Contract notary_data_index = offer_data.find('"Notary"', end_of_bid_index, len(offer_data)) end_of_notary_index = offer_data.find('-----BEGIN PGP SIGNATURE', notary_data_index, len(offer_data)) notary_data_json = "{" + offer_data[ notary_data_index:end_of_notary_index] notary_data_json = json.loads(notary_data_json) self._log.info('Notary Data: %s' % notary_data_json) try: client = obelisk.ObeliskOfLightClient( 'tcp://obelisk.openbazaar.org:9091') pubkeys = [ offer_data_json['Seller'] ['seller_BTC_uncompressed_pubkey'].decode('hex'), bid_data_json['Buyer']['buyer_BTC_uncompressed_pubkey'].decode( 'hex'), notary_data_json['Notary'] ['notary_BTC_uncompressed_pubkey'].decode('hex') ] multisig = Multisig(client, 2, pubkeys) def cb(ec, history): # Debug self._log.info('%s %s' % (ec, history)) for item in history: self._log.info(item[0].encode('hex')) if ec is not None: self._log.error("Error fetching history: %s" % ec) # TODO: Send error message to GUI return # Create unsigned transaction unspent = [row[:4] for row in history if row[4] is None] tx = multisig._build_actual_tx(unspent, '') self._log.info('TX %s' % tx) def get_history(): client.fetch_history(multisig.address, cb) reactor.callFromThread(get_history) def finished_cb(msg): self._log.info('tx %s' % msg) #multisig.create_unsigned_transaction('16uniUFpbhrAxAWMZ9qEkcT9Wf34ETB4Tt', finished_cb) def fetched(ec, history): self._log.info(history) if ec is not None: self._log.error("Error fetching history: %s" % ec) return self._fetched(history, '1Fufjpf9RM2aQsGedhSpbSCGRHrmLMJ7yY', finished_cb) #client.fetch_history('16uniUFpbhrAxAWMZ9qEkcT9Wf34ETB4Tt', fetched) except Exception, e: self._log.error('%s' % e)
import obelisk import sys from twisted.internet import reactor def build_output_info_list(unspent_rows): unspent_infos = [] for row in unspent_rows: assert len(row) == 4 outpoint = obelisk.OutPoint() outpoint.hash = row[0] outpoint.index = row[1] value = row[3] unspent_infos.append( obelisk.OutputInfo(outpoint, value)) return unspent_infos def history_fetched(ec, history): if ec is not None: print >> sys.stderr, "Error fetching history:", ec return unspent_rows = [row[:4] for row in history if row[4] is None] unspent = build_output_info_list(unspent_rows) print obelisk.select_outputs(unspent, 10000) if __name__ == '__main__': client = obelisk.ObeliskOfLightClient("tcp://85.25.198.97:9091") client.fetch_history("1PRBVdCHoPPD3bz8sCZRTm6iAtuoqFctvx", history_fetched) reactor.run()
def client_release_payment(self, socket_handler, msg): self.log.info('Releasing payment to Merchant %s', msg) order = self.market.orders.get_order(msg['orderId']) contract = order['signed_contract_body'] # Find Seller Data in Contract offer_data = ''.join(contract.split('\n')[8:]) index_of_seller_signature = offer_data.find( '- - -----BEGIN PGP SIGNATURE-----', 0, len(offer_data)) offer_data_json = offer_data[0:index_of_seller_signature] offer_data_json = json.loads(offer_data_json) self.log.info('Offer Data: %s', offer_data_json) # Find Buyer Data in Contract bid_data_index = offer_data.find('"Buyer"', index_of_seller_signature, len(offer_data)) end_of_bid_index = offer_data.find('- -----BEGIN PGP SIGNATURE', bid_data_index, len(offer_data)) bid_data_json = "{" bid_data_json += offer_data[bid_data_index:end_of_bid_index] bid_data_json = json.loads(bid_data_json) # Find Notary Data in Contract notary_data_index = offer_data.find('"Notary"', end_of_bid_index, len(offer_data)) end_of_notary_index = offer_data.find('-----BEGIN PGP SIGNATURE', notary_data_index, len(offer_data)) notary_data_json = "{" notary_data_json += offer_data[notary_data_index:end_of_notary_index] notary_data_json = json.loads(notary_data_json) self.log.info('Notary Data: %s', notary_data_json) try: client = obelisk.ObeliskOfLightClient( 'tcp://obelisk.coinkite.com:9091') seller = offer_data_json['Seller'] buyer = bid_data_json['Buyer'] notary = notary_data_json['Notary'] pubkeys = [ seller['seller_BTC_uncompressed_pubkey'], buyer['buyer_BTC_uncompressed_pubkey'], notary['notary_BTC_uncompressed_pubkey'] ] script = mk_multisig_script(pubkeys, 2, 3) multi_address = scriptaddr(script) def cb(ec, history, order): settings = self.market.get_settings() private_key = settings.get('privkey') if ec is not None: self.log.error("Error fetching history: %s", ec) # TODO: Send error message to GUI return # Create unsigned transaction unspent = [row[:4] for row in history if row[4] is None] # Send all unspent outputs (everything in the address) minus # the fee total_amount = 0 inputs = [] for row in unspent: assert len(row) == 4 inputs.append( str(row[0].encode('hex')) + ":" + str(row[1])) value = row[3] total_amount += value # Constrain fee so we don't get negative amount to send fee = min(total_amount, 10000) send_amount = total_amount - fee payment_output = order['payment_address'] tx = mktx(inputs, [str(payment_output) + ":" + str(send_amount)]) signatures = [] for x in range(0, len(inputs)): ms = multisign(tx, x, script, private_key) signatures.append(ms) print signatures self.market.release_funds_to_merchant(buyer['buyer_order_id'], tx, script, signatures, order.get('merchant')) def get_history(): client.fetch_history( multi_address, lambda ec, history, order=order: cb(ec, history, order)) reactor.callFromThread(get_history) except Exception as e: self.log.error('%s', e)
def client_release_payment(self, socket_handler, msg): self._log.info('Releasing payment to Merchant %s' % msg) order = self._market.orders.get_order(msg['orderId']) contract = order['signed_contract_body'] # Find Seller Data in Contract offer_data = ''.join(contract.split('\n')[8:]) index_of_seller_signature = offer_data.find( '- - -----BEGIN PGP SIGNATURE-----', 0, len(offer_data)) offer_data_json = offer_data[0:index_of_seller_signature] offer_data_json = json.loads(offer_data_json) self._log.info('Offer Data: %s' % offer_data_json) # Find Buyer Data in Contract bid_data_index = offer_data.find('"Buyer"', index_of_seller_signature, len(offer_data)) end_of_bid_index = offer_data.find('- -----BEGIN PGP SIGNATURE', bid_data_index, len(offer_data)) bid_data_json = "{" + offer_data[bid_data_index:end_of_bid_index] bid_data_json = json.loads(bid_data_json) # Find Notary Data in Contract notary_data_index = offer_data.find('"Notary"', end_of_bid_index, len(offer_data)) end_of_notary_index = offer_data.find('-----BEGIN PGP SIGNATURE', notary_data_index, len(offer_data)) notary_data_json = "{" + offer_data[ notary_data_index:end_of_notary_index] notary_data_json = json.loads(notary_data_json) self._log.info('Notary Data: %s' % notary_data_json) try: client = obelisk.ObeliskOfLightClient( 'tcp://obelisk.openbazaar.org:9091') pubkeys = [ offer_data_json['Seller'] ['seller_BTC_uncompressed_pubkey'].decode('hex'), bid_data_json['Buyer']['buyer_BTC_uncompressed_pubkey'].decode( 'hex'), notary_data_json['Notary'] ['notary_BTC_uncompressed_pubkey'].decode('hex') ] multisig = Multisig(client, 2, pubkeys) def cb(ec, history): # Debug self._log.info('%s %s' % (ec, history)) if ec is not None: self._log.error("Error fetching history: %s" % ec) # TODO: Send error message to GUI return # Create unsigned transaction unspent = [row[:4] for row in history if row[4] is None] tx = multisig._build_actual_tx( unspent, '16uniUFpbhrAxAWMZ9qEkcT9Wf34ETB4Tt') self._log.info(tx.serialize().encode("hex")) private_key = self._market.private_key() multisig.sign_all_inputs(tx, private_key.decode('hex')) self.send_to_client(None, { "type": "signed_tx_sent", "test": "teest" }) def get_history(): client.fetch_history(multisig.address, cb) reactor.callFromThread(get_history) # def finished_cb(msg): # self._log.info('tx %s' % msg) # # #multisig.create_unsigned_transaction('16uniUFpbhrAxAWMZ9qEkcT9Wf34ETB4Tt', finished_cb) # # def fetched(ec, history): # self._log.info(history) # if ec is not None: # self._log.error("Error fetching history: %s" % ec) # return # self._fetched(history, '1EzD5Tj9fa5jqV1mCCBy7kW43TYEsJsZw6', finished_cb) # # #client.fetch_history('16uniUFpbhrAxAWMZ9qEkcT9Wf34ETB4Tt', fetched) except Exception, e: self._log.error('%s' % e)
output = obelisk.TxOut() output.value = 0 output.script = "\x6a\x14" + data tx.outputs.append(output) def add_output(tx, address, value): output = obelisk.TxOut() output.value = value output.script = obelisk.output_script(address) tx.outputs.append(output) def build_output_info_list(unspent_rows): unspent_infos = [] for row in unspent_rows: assert len(row) == 4 outpoint = obelisk.OutPoint() outpoint.hash = row[0] outpoint.index = row[1] value = row[3] unspent_infos.append(obelisk.OutputInfo(outpoint, value)) return unspent_infos if __name__ == "__main__": from twisted.internet import reactor client = obelisk.ObeliskOfLightClient("tcp://obelisk.unsystem.net:9091") client.fetch_history(address, history_fetched) reactor.run()
import obelisk from twisted.internet import reactor if __name__ == '__main__': c = obelisk.ObeliskOfLightClient("tcp://localhost:9091") h = "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f" def cb(*args): ec, result = args print result.encode("hex") reactor.stop() c.fetch_block_header(h.decode("hex"), cb) reactor.run()
def on_release_funds_tx(self, msg): self._log.info('Receiving signed tx from buyer') buyer_order_id = str(msg['senderGUID']) + '-' + str( msg['buyer_order_id']) order = self._market.orders.get_order(buyer_order_id, by_buyer_id=True) contract = order['signed_contract_body'] # Find Seller Data in Contract offer_data = ''.join(contract.split('\n')[8:]) index_of_seller_signature = offer_data.find( '- - -----BEGIN PGP SIGNATURE-----', 0, len(offer_data)) offer_data_json = offer_data[0:index_of_seller_signature] offer_data_json = json.loads(offer_data_json) self._log.info('Offer Data: %s' % offer_data_json) # Find Buyer Data in Contract bid_data_index = offer_data.find('"Buyer"', index_of_seller_signature, len(offer_data)) end_of_bid_index = offer_data.find('- -----BEGIN PGP SIGNATURE', bid_data_index, len(offer_data)) bid_data_json = "{" bid_data_json += offer_data[bid_data_index:end_of_bid_index] bid_data_json = json.loads(bid_data_json) # Find Notary Data in Contract notary_data_index = offer_data.find('"Notary"', end_of_bid_index, len(offer_data)) end_of_notary_index = offer_data.find('-----BEGIN PGP SIGNATURE', notary_data_index, len(offer_data)) notary_data_json = "{" notary_data_json += offer_data[notary_data_index:end_of_notary_index] notary_data_json = json.loads(notary_data_json) self._log.info('Notary Data: %s' % notary_data_json) try: client = obelisk.ObeliskOfLightClient( 'tcp://obelisk2.airbitz.co:9091') seller = offer_data_json['Seller'] buyer = bid_data_json['Buyer'] notary = notary_data_json['Notary'] seller_key = seller['seller_BTC_uncompressed_pubkey'] buyer_key = buyer['buyer_BTC_uncompressed_pubkey'] notary_key = notary['notary_BTC_uncompressed_pubkey'] pubkeys = [ seller_key.decode('hex'), buyer_key.decode('hex'), notary_key.decode('hex') ] self._log.info('multisig pubkeys %s' % pubkeys) multisig = Multisig(client, 2, pubkeys) def cb(ec, history, order): # Debug self._log.info('%s %s' % (ec, history)) if ec is not None: self._log.error("Error fetching history: %s" % ec) # TODO: Send error message to GUI return # Create unsigned transaction unspent = [row[:4] for row in history if row[4] is None] tx = multisig._build_actual_tx(unspent, order['payment_address']) self._log.info(tx.serialize().encode("hex")) private_key = self._market.private_key() merchant_sigs = multisig.sign_all_inputs( tx, private_key.decode('hex')) buyer_sigs = msg['signature'] for i, input in enumerate(tx.inputs): sigs = (buyer_sigs[i].decode('hex'), merchant_sigs[i].decode('hex')) script = "\x00" for sig in sigs: script += chr(len(sig)) + sig script += "\x4c" assert len(multisig.script) < 255 script += chr(len(multisig.script)) + multisig.script print "Script:", script.encode("hex") tx.inputs[i].script = script print tx print tx.serialize().encode("hex") Multisig.broadcast(tx) def get_history(): client.fetch_history( multisig.address, lambda ec, history, order=order: cb(ec, history, order)) reactor.callFromThread(get_history) except Exception, e: self._log.error('%s' % e)
def run(*args): TESTNET = args[0] # database db = Database(TESTNET) # key generation keys = KeyChain(db) # logging # TODO: prune this log file and prevent it from getting too large? logFile = logfile.LogFile.fromFullPath(DATA_FOLDER + "debug.log") log.addObserver(log.FileLogObserver(logFile).emit) log.startLogging(sys.stdout) # stun # TODO: accept port from command line port = 18467 if not TESTNET else 28467 print "Finding NAT Type.." # TODO: maintain a list of backup STUN servers and try them if ours fails response = stun.get_ip_info(stun_host="seed.openbazaar.org", source_port=port) print "%s on %s:%s" % (response[0], response[1], response[2]) ip_address = response[1] port = response[2] # TODO: try UPnP if restricted NAT # TODO: maintain open connection to seed node if STUN/UPnP fail # TODO: use TURN if symmetric NAT def on_bootstrap_complete(resp): mlistener = MessageListenerImpl(ws_factory, db) mserver.get_messages(mlistener) mserver.protocol.add_listener(mlistener) nlistener = NotificationListenerImpl(ws_factory, db) mserver.protocol.add_listener(nlistener) protocol = OpenBazaarProtocol((ip_address, port), testnet=TESTNET) # kademlia node = Node(keys.guid, ip_address, port, signed_pubkey=keys.guid_signed_pubkey) try: kserver = Server.loadState(DATA_FOLDER + 'cache.pickle', ip_address, port, protocol, db, on_bootstrap_complete, storage=PersistentStorage(db.DATABASE)) except Exception: kserver = Server(node, db, KSIZE, ALPHA, storage=PersistentStorage(db.DATABASE)) kserver.protocol.connect_multiplexer(protocol) kserver.bootstrap( kserver.querySeed("seed.openbazaar.org:8080", "ddd862778e3ed71af06db0e3619a4c6269ec7468c745132dbb73982b319fc572"))\ .addCallback(on_bootstrap_complete) # TODO: load seeds from config file kserver.saveStateRegularly(DATA_FOLDER + 'cache.pickle', 10) protocol.register_processor(kserver.protocol) # market mserver = network.Server(kserver, keys.signing_key, db) mserver.protocol.connect_multiplexer(protocol) protocol.register_processor(mserver.protocol) reactor.listenUDP(port, protocol) # websockets api ws_factory = WSFactory("ws://127.0.0.1:18466", mserver, kserver) ws_factory.protocol = WSProtocol ws_factory.setProtocolOptions(allowHixie76=True) listenWS(ws_factory) webdir = File(".") web = Site(webdir) reactor.listenTCP(9000, web, interface="127.0.0.1") # rest api api = OpenBazaarAPI(mserver, kserver, protocol) site = Site(api, timeout=None) reactor.listenTCP(18469, site, interface="127.0.0.1") # TODO: add optional SSL on rest and websocket servers # blockchain # TODO: listen on the libbitcoin heartbeat port instead fetching height def height_fetched(ec, height): print "Libbitcoin server online" try: timeout.cancel() except Exception: pass def timeout(client): print "Libbitcoin server offline" client = None if TESTNET: libbitcoin_client = obelisk.ObeliskOfLightClient( "tcp://libbitcoin2.openbazaar.org:9091") else: libbitcoin_client = obelisk.ObeliskOfLightClient( "tcp://libbitcoin1.openbazaar.org:9091") # TODO: load libbitcoin server url from config file libbitcoin_client.fetch_last_height(height_fetched) timeout = reactor.callLater(5, timeout, libbitcoin_client) protocol.set_servers(ws_factory, libbitcoin_client) reactor.run()
def on_release_funds_tx(self, msg): self.log.info('Receiving signed tx from buyer') buyer_order_id = "%s-%s" % (msg['senderGUID'], msg['buyer_order_id']) order = self.market.orders.get_order(buyer_order_id, by_buyer_id=True) contract = order['signed_contract_body'] # Find Seller Data in Contract offer_data = ''.join(contract.split('\n')[8:]) index_of_seller_signature = offer_data.find( '- - -----BEGIN PGP SIGNATURE-----', 0, len(offer_data)) offer_data_json = offer_data[0:index_of_seller_signature] offer_data_json = json.loads(offer_data_json) self.log.info('Offer Data: %s', offer_data_json) # Find Buyer Data in Contract bid_data_index = offer_data.find('"Buyer"', index_of_seller_signature, len(offer_data)) end_of_bid_index = offer_data.find('- -----BEGIN PGP SIGNATURE', bid_data_index, len(offer_data)) bid_data_json = "{" bid_data_json += offer_data[bid_data_index:end_of_bid_index] bid_data_json = json.loads(bid_data_json) # Find Notary Data in Contract notary_data_index = offer_data.find('"Notary"', end_of_bid_index, len(offer_data)) end_of_notary_index = offer_data.find('-----BEGIN PGP SIGNATURE', notary_data_index, len(offer_data)) notary_data_json = "{" notary_data_json += offer_data[notary_data_index:end_of_notary_index] notary_data_json = json.loads(notary_data_json) self.log.info('Notary Data: %s', notary_data_json) try: client = obelisk.ObeliskOfLightClient( 'tcp://obelisk.coinkite.com:9091') script = msg['script'] tx = msg['tx'] multi_addr = scriptaddr(script) def cb(ec, history, order): if ec is not None: self.log.error("Error fetching history: %s", ec) # TODO: Send error message to GUI return unspent = [row[:4] for row in history if row[4] is None] # Send all unspent outputs (everything in the address) minus # the fee inputs = [] for row in unspent: assert len(row) == 4 inputs.append( str(row[0].encode('hex')) + ":" + str(row[1])) seller_signatures = [] print 'private key ', self.transport.settings['privkey'] for x in range(0, len(inputs)): ms = multisign(tx, x, script, self.transport.settings['privkey']) print 'seller sig', ms seller_signatures.append(ms) tx2 = apply_multisignatures(tx, 0, script, seller_signatures[0], msg['signatures'][0]) print 'FINAL SCRIPT: %s' % tx2 print 'Sent', eligius_pushtx(tx2) self.send_to_client( None, { "type": "order_notify", "msg": "Funds were released for your sale." }) def get_history(): client.fetch_history( multi_addr, lambda ec, history, order=order: cb(ec, history, order)) reactor.callFromThread(get_history) except Exception as e: self.log.error('%s', e)
def client_release_payment(self, socket_handler, msg): self._log.info('Releasing payment to Merchant %s' % msg) order = self._market.orders.get_order(msg['orderId']) contract = order['signed_contract_body'] # Find Seller Data in Contract offer_data = ''.join(contract.split('\n')[8:]) index_of_seller_signature = offer_data.find( '- - -----BEGIN PGP SIGNATURE-----', 0, len(offer_data)) offer_data_json = offer_data[0:index_of_seller_signature] offer_data_json = json.loads(offer_data_json) self._log.info('Offer Data: %s' % offer_data_json) # Find Buyer Data in Contract bid_data_index = offer_data.find('"Buyer"', index_of_seller_signature, len(offer_data)) end_of_bid_index = offer_data.find('- -----BEGIN PGP SIGNATURE', bid_data_index, len(offer_data)) bid_data_json = "{" bid_data_json += offer_data[bid_data_index:end_of_bid_index] bid_data_json = json.loads(bid_data_json) # Find Notary Data in Contract notary_data_index = offer_data.find('"Notary"', end_of_bid_index, len(offer_data)) end_of_notary_index = offer_data.find('-----BEGIN PGP SIGNATURE', notary_data_index, len(offer_data)) notary_data_json = "{" notary_data_json += offer_data[notary_data_index:end_of_notary_index] notary_data_json = json.loads(notary_data_json) self._log.info('Notary Data: %s' % notary_data_json) try: client = obelisk.ObeliskOfLightClient( 'tcp://obelisk2.airbitz.co:9091') seller = offer_data_json['Seller'] buyer = bid_data_json['Buyer'] notary = notary_data_json['Notary'] seller_key = seller['seller_BTC_uncompressed_pubkey'] buyer_key = buyer['buyer_BTC_uncompressed_pubkey'] notary_key = notary['notary_BTC_uncompressed_pubkey'] pubkeys = [ seller_key.decode('hex'), buyer_key.decode('hex'), notary_key.decode('hex') ] multisig = Multisig(client, 2, pubkeys) def cb(ec, history, order): # Debug self._log.info('%s %s' % (ec, history)) if ec is not None: self._log.error("Error fetching history: %s" % ec) # TODO: Send error message to GUI return # Create unsigned transaction unspent = [row[:4] for row in history if row[4] is None] tx = multisig._build_actual_tx(unspent, order['payment_address']) self._log.info(tx.serialize().encode("hex")) private_key = self._market.private_key() signatures = multisig.sign_all_inputs( tx, private_key.decode('hex')) tx_serialized = tx.serialize().encode("hex") self._market.release_funds_to_merchant(buyer['buyer_order_id'], tx_serialized, signatures, order.get('merchant')) self._log.debug('Sent tx and signed inputs to merchant') def get_history(): client.fetch_history( multisig.address, lambda ec, history, order=order: cb(ec, history, order)) reactor.callFromThread(get_history) except Exception, e: self._log.error('%s' % e)