def accept_order(self, new_order): # auto new_order['state'] = 'accepted' seller = new_order['seller'].decode('hex') buyer = new_order['buyer'].decode('hex') print "accept order", new_order new_order['escrows'] = [new_order.get('escrows')[0]] escrow = new_order['escrows'][0].decode('hex') self._multisig = Multisig(None, 2, [buyer, seller, escrow]) new_order['address'] = self._multisig.address self._orders[new_order['id']] = new_order self._transport.send(new_order, new_order['buyer'].decode('hex'))
def accept_order(self, new_order): # TODO: Need to have a check for the vendor to agree to the order new_order['state'] = 'accepted' seller = new_order['seller'].decode('hex') buyer = new_order['buyer'].decode('hex') new_order['escrows'] = [new_order.get('escrows')[0]] escrow = new_order['escrows'][0].decode('hex') self._multisig = Multisig(None, 2, [buyer, seller, escrow]) new_order['address'] = self._multisig.address self._transport.send(new_order, new_order['buyer'].decode('hex'))
def accept_order(self, new_order): # TODO: Need to have a check for the vendor to agree to the order new_order['state'] = Orders.State.ACCEPTED seller = new_order['seller'] buyer = new_order['buyer'] new_order['escrows'] = [new_order.get('escrows')[0]] escrow = new_order['escrows'][0] # Create 2 of 3 multisig address self._multisig = Multisig(None, 2, [seller, buyer, escrow]) new_order['address'] = self._multisig.address if len(self.db.selectEntries("orders", {"order_id": new_order['id']})) > 0: self.db.updateEntries("orders", {"order_id": new_order['id']}, {new_order}) else: self.db.insertEntry("orders", new_order) self.transport.send(new_order, new_order['buyer'].decode('hex'))
def handle_notarized_order(self, msg): self._log.info(msg['rawContract']) contract = msg['rawContract'] # 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] self._log.info('Offer Data: %s' % offer_data_json) offer_data_json = json.loads(str(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) self._log.info('Bid Data: %s' % 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) # Generate multi-sig address multisig = Multisig(None, 2, [ 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_address = multisig.address seller_GUID = offer_data_json['Seller']['seller_GUID'] order_id = bid_data_json['Buyer']['buyer_order_id'] contract_key = hashlib.sha1(str(contract)).hexdigest() hash_value = hashlib.new('ripemd160') hash_value.update(contract_key) contract_key = hash_value.hexdigest() if seller_GUID == self._transport._guid: self._log.info('I am the seller!') state = 'Waiting for Payment' merchant_order_id = random.randint(0, 1000000) while self._db.numEntries("orders", "id = '%s'" % order_id) > 0: merchant_order_id = random.randint(0, 1000000) buyer_id = str(bid_data_json['Buyer']['buyer_GUID']) + '-' + str( bid_data_json['Buyer']['buyer_order_id']) self._db.insertEntry( "orders", { 'market_id': self._transport._market_id, 'contract_key': contract_key, 'order_id': merchant_order_id, 'signed_contract_body': str(contract), 'state': state, 'buyer_order_id': buyer_id, 'merchant': offer_data_json['Seller']['seller_GUID'], 'buyer': bid_data_json['Buyer']['buyer_GUID'], 'notary': notary_data_json['Notary']['notary_GUID'], 'address': multisig_address, 'item_price': offer_data_json['Contract']['item_price'], 'shipping_price': offer_data_json['Contract']['item_delivery'] ['shipping_price'] if offer_data_json['Contract'] ['item_delivery'].has_key('shipping_price') else "", 'note_for_merchant': bid_data_json['Buyer']['note_for_seller'], "updated": time.time() }) else: self._log.info('I am the buyer') state = 'Need to Pay' self._db.updateEntries("orders", {'order_id': order_id}, { 'market_id': self._transport._market_id, 'contract_key': contract_key, 'signed_contract_body': str(contract), 'state': state, 'merchant': offer_data_json['Seller']['seller_GUID'], 'buyer': bid_data_json['Buyer']['buyer_GUID'], 'notary': notary_data_json['Notary']['notary_GUID'], 'address': multisig_address, 'item_price': offer_data_json['Contract']['item_price'], 'shipping_price': offer_data_json['Contract']['item_delivery']['shipping_price'] if offer_data_json['Contract']['item_delivery'].has_key( 'shipping_price') else "", 'note_for_merchant': bid_data_json['Buyer']['note_for_seller'], "updated": time.time() })
def handle_bid_order(self, bid): self._log.info('Bid Order: %s' % bid) # Generate unique id for this bid order_id = random.randint(0, 1000000) while self._db.numEntries("contracts", "id = '%s'" % order_id) > 0: order_id = random.randint(0, 1000000) # Add to contract and sign contract = bid.get('rawContract') # Check signature and verify of seller and bidder contract seed_contract = self.get_seed_contract_from_doublesigned(contract) seed_contract_json = self.get_json_from_doublesigned_contract( seed_contract) #seed_contract = seed_contract.replace('- -----','-----') #self._log.debug('seed contract %s' % seed_contract) self._log.debug('seed contract json %s' % seed_contract_json) contract_stripped = "".join(contract.split('\n')) self._log.info(contract_stripped) bidder_pgp_start_index = contract_stripped.find( "buyer_pgp", 0, len(contract_stripped)) bidder_pgp_end_index = contract_stripped.find("buyer_GUID", 0, len(contract_stripped)) bidder_pgp = contract_stripped[bidder_pgp_start_index + 13:bidder_pgp_end_index] self._log.info(bidder_pgp) self._gpg.import_keys(bidder_pgp) v = self._gpg.verify(contract) if v: self._log.info('Sellers contract verified') notary = {} notary['Notary'] = { 'notary_GUID': self._transport._guid, 'notary_BTC_uncompressed_pubkey': self._transport.settings['pubkey'], 'notary_pgp': self._transport.settings['PGPPubKey'], 'notary_fee': "1%", 'notary_order_id': order_id } self._log.debug('Notary: %s' % notary) gpg = self._gpg # Prepare contract body json_string = json.dumps(notary, indent=0) seg_len = 52 out_text = string.join( map(lambda x: json_string[x:x + seg_len], range(0, len(json_string), seg_len)), "\n") # Append new data to contract out_text = "%s\n%s" % (contract, out_text) signed_data = gpg.sign( out_text, passphrase='P@ssw0rd', keyid=self._transport.settings.get('PGPPubkeyFingerprint')) self._log.debug('Double-signed Contract: %s' % signed_data) # Hash the contract for storage contract_key = hashlib.sha1(str(signed_data)).hexdigest() hash_value = hashlib.new('ripemd160') hash_value.update(contract_key) contract_key = hash_value.hexdigest() self._log.info('Order ID: %s' % order_id) # Push buy order to DHT and node if available # self._transport._dht.iterativeStore(self._transport, contract_key, str(signed_data), self._transport._guid) #self.update_listings_index() # 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 = "{\"Seller\": {" + offer_data[ 0:index_of_seller_signature] self._log.info('Offer Data: %s' % offer_data_json) offer_data_json = json.loads(str(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) self._log.info('Bid Data: %s' % bid_data_json) buyer_order_id = bid_data_json['Buyer']['buyer_GUID'] + '-' + str( bid_data_json['Buyer']['buyer_order_id']) multisig = Multisig(None, 2, [ offer_data_json['Seller']['seller_BTC_uncompressed_pubkey'].decode( 'hex'), bid_data_json['Buyer']['buyer_BTC_uncompressed_pubkey'].decode( 'hex'), self._transport.settings['pubkey'].decode('hex') ]) multisig_address = multisig.address self._db.insertEntry( "orders", { 'market_id': self._transport._market_id, 'contract_key': contract_key, 'signed_contract_body': str(signed_data), 'state': Orders.State.NOTARIZED, 'buyer_order_id': buyer_order_id, 'order_id': order_id, 'merchant': offer_data_json['Seller']['seller_GUID'], 'buyer': bid_data_json['Buyer']['buyer_GUID'], 'address': multisig_address, 'item_price': offer_data_json['Contract']['item_price'], 'shipping_price': offer_data_json['Contract']['item_delivery']['shipping_price'] if offer_data_json['Contract']['item_delivery'].has_key( 'shipping_price') else "", 'note_for_merchant': bid_data_json['Buyer']['note_for_seller'], "updated": time.time() }) # Send order to seller and buyer self._log.info('Sending notarized contract to buyer and seller %s' % bid) notarized_order = { "type": "order", "state": "Notarized", "rawContract": str(signed_data) } self._log.info('SELLER %s' % offer_data_json['Seller']['seller_GUID']) self._transport.send(notarized_order, offer_data_json['Seller']['seller_GUID']) self._transport.send(notarized_order, bid_data_json['Buyer']['buyer_GUID'])
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)
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)
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 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)