예제 #1
0
 def confirm_order(self, request):
     try:
         def respond(success):
             if success:
                 request.write(json.dumps({"success": True}))
                 request.finish()
             else:
                 request.write(json.dumps({"success": False, "reason": "Failed to send order confirmation"}))
                 request.finish()
         file_path = DATA_FOLDER + "store/listings/in progress/" + request.args["id"][0] + ".json"
         with open(file_path, 'r') as filename:
             order = json.load(filename, object_pairs_hook=OrderedDict)
         c = Contract(self.db, contract=order, testnet=self.protocol.testnet)
         c.add_order_confirmation(self.protocol.blockchain,
                                  request.args["payout_address"][0],
                                  comments=request.args["comments"][0] if "comments" in request.args else None,
                                  shipper=request.args["shipper"][0] if "shipper" in request.args else None,
                                  tracking_number=request.args["tracking_number"][0]
                                  if "tracking_number" in request.args else None,
                                  est_delivery=request.args["est_delivery"][0]
                                  if "est_delivery" in request.args else None,
                                  url=request.args["url"][0] if "url" in request.args else None,
                                  password=request.args["password"][0] if "password" in request.args else None)
         guid = c.contract["buyer_order"]["order"]["id"]["guid"]
         self.mserver.confirm_order(guid, c).addCallback(respond)
         return server.NOT_DONE_YET
     except Exception, e:
         request.write(json.dumps({"success": False, "reason": e.message}, indent=4))
         request.finish()
         return server.NOT_DONE_YET
예제 #2
0
    def check_for_payment(self, request):
        if not self.protocol.blockchain.connected:
            request.write(
                json.dumps(
                    {
                        "success": False,
                        "reason": "libbitcoin server offline"
                    },
                    indent=4))
            request.finish()
            return server.NOT_DONE_YET
        try:
            file_path = DATA_FOLDER + "purchases/unfunded/" + request.args[
                "order_id"][0] + ".json"
            with open(file_path, 'r') as filename:
                order = json.load(filename, object_pairs_hook=OrderedDict)
            c = Contract(self.db,
                         contract=order,
                         testnet=self.protocol.testnet)
            c.blockchain = self.protocol.blockchain
            c.notification_listener = self.mserver.protocol.get_notification_listener(
            )
            c.is_purchase = True
            addr = c.contract["buyer_order"]["order"]["payment"]["address"]

            def history_fetched(ec, history):
                if not ec:
                    # pylint: disable=W0612
                    # pylint: disable=W0640
                    for objid, txhash, index, height, value in history:

                        def cb_txpool(ec, result):
                            if ec:
                                self.protocol.blockchain.fetch_transaction(
                                    txhash, cb_chain)
                            else:
                                c.on_tx_received(None, None, None, None,
                                                 result)

                        def cb_chain(ec, result):
                            if not ec:
                                c.on_tx_received(None, None, None, None,
                                                 result)

                        self.protocol.blockchain.fetch_txpool_transaction(
                            txhash, cb_txpool)

            self.protocol.blockchain.fetch_history2(addr, history_fetched)

            request.write(json.dumps({"success": True}, indent=4))
            request.finish()
            return server.NOT_DONE_YET
        except Exception, e:
            request.write(
                json.dumps({
                    "success": False,
                    "reason": e.message
                }, indent=4))
            request.finish()
            return server.NOT_DONE_YET
예제 #3
0
 def rpc_order(self, sender, pubkey, encrypted):
     try:
         box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey))
         order = box.decrypt(encrypted)
         c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict),
                      testnet=self.multiplexer.testnet)
         if c.verify(sender.signed_pubkey[64:]):
             self.router.addContact(sender)
             self.log.info("received an order from %s, waiting for payment..." % sender)
             payment_address = c.contract["buyer_order"]["order"]["payment"]["address"]
             chaincode = c.contract["buyer_order"]["order"]["payment"]["chaincode"]
             masterkey_b = c.contract["buyer_order"]["order"]["id"]["pubkeys"]["bitcoin"]
             buyer_key = derive_childkey(masterkey_b, chaincode)
             amount = c.contract["buyer_order"]["order"]["payment"]["amount"]
             listing_hash = c.contract["buyer_order"]["order"]["ref_hash"]
             signature = self.signing_key.sign(
                 str(payment_address) + str(amount) + str(listing_hash) + str(buyer_key))[:64]
             c.await_funding(self.multiplexer.ws, self.multiplexer.blockchain, signature, False)
             return [signature]
         else:
             self.log.warning("received invalid order from %s" % sender)
             return ["False"]
     except Exception:
         self.log.error("unable to decrypt order from %s" % sender)
         return ["False"]
예제 #4
0
    def set_contract(self, request):
        print request
        c = Contract()
        c.create(
            str(request.args["expiration_date"][0]),
            request.args["metadata_category"][0],
            request.args["title"][0],
            request.args["description"][0],
            request.args["currency_code"][0],
            request.args["price"][0],
            request.args["process_time"][0],
            True if "nsfw" in request.args else False,
            request.args["shipping_origin"][0],
            request.args["ships_to"],
            est_delivery_domestic=request.args["est_delivery_domestic"][0],
            est_delivery_international=request.
            args["est_delivery_international"][0],
            shipping_currency_code=request.args["shipping_currency_code"][0],
            shipping_domestic=request.args["shipping_domestic"][0],
            shipping_international=request.args["shipping_international"][0],
            keywords=request.args["keywords"]
            if "keywords" in request.args else None,
            category=request.args["category"][0]
            if request.args["category"][0] is not "" else None,
            condition=request.args["condition"][0]
            if request.args["condition"][0] is not "" else None,
            sku=request.args["sku"][0]
            if request.args["sku"][0] is not "" else None,
            images=request.args["images"],
            free_shipping=True if "free_shipping" in request.args else False)

        for keyword in request.args["keywords"]:
            self.kserver.set(keyword.lower(), c.get_contract_id(),
                             self.kserver.node.getProto().SerializeToString())
예제 #5
0
 def parse_messages(messages):
     if messages is not None:
         for message in messages:
             try:
                 value = objects.Value()
                 value.ParseFromString(message)
                 try:
                     box = Box(PrivateKey(self.signing_key.encode()), PublicKey(value.valueKey))
                     ciphertext = value.serializedData
                     plaintext = box.decrypt(ciphertext)
                     p = objects.Plaintext_Message()
                     p.ParseFromString(plaintext)
                     signature = p.signature
                     p.ClearField("signature")
                     verify_key = nacl.signing.VerifyKey(p.signed_pubkey[64:])
                     verify_key.verify(p.SerializeToString(), signature)
                     h = nacl.hash.sha512(p.signed_pubkey)
                     pow_hash = h[64:128]
                     if int(pow_hash[:6], 16) >= 50 or hexlify(p.sender_guid) != h[:40]:
                         raise Exception('Invalid guid')
                     if p.type == objects.Plaintext_Message.Type.Value("ORDER_CONFIRMATION"):
                         c = Contract(self.db, hash_value=unhexlify(p.subject))
                         c.accept_order_confirmation(self.protocol.multiplexer.ws,
                                                     confirmation_json=p.message)
                     else:
                         listener.notify(p.sender_guid, p.encryption_pubkey, p.subject,
                                         objects.Plaintext_Message.Type.Name(p.type), p.message)
                 except Exception:
                     pass
                 signature = self.signing_key.sign(value.valueKey)[:64]
                 self.kserver.delete(self.kserver.node.id, value.valueKey, signature)
             except Exception:
                 pass
예제 #6
0
 def rpc_order(self, sender, pubkey, encrypted):
     try:
         box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey))
         order = box.decrypt(encrypted)
         c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict),
                      testnet=self.multiplexer.testnet)
         v = c.verify(sender.pubkey)
         if v is True:
             self.router.addContact(sender)
             self.log.info("received an order from %s, waiting for payment..." % sender)
             payment_address = c.contract["buyer_order"]["order"]["payment"]["address"]
             chaincode = c.contract["buyer_order"]["order"]["payment"]["chaincode"]
             masterkey_b = c.contract["buyer_order"]["order"]["id"]["pubkeys"]["bitcoin"]
             buyer_key = derive_childkey(masterkey_b, chaincode)
             amount = c.contract["buyer_order"]["order"]["payment"]["amount"]
             listing_hash = c.contract["vendor_offer"]["listing"]["contract_id"]
             signature = self.signing_key.sign(
                 str(payment_address) + str(amount) + str(listing_hash) + str(buyer_key))[:64]
             c.await_funding(self.get_notification_listener(), self.multiplexer.blockchain, signature, False)
             return [signature]
         else:
             self.log.warning("received invalid order from %s reason %s" % (sender, v))
             return ["False"]
     except Exception, e:
         self.log.error("Exception (%s) occurred processing order from %s" % (e.message, sender))
         return ["False"]
예제 #7
0
    def set_contract(self, request):
        print request
        c = Contract()
        c.create(
            str(request.args["expiration_date"][0]),
            request.args["metadata_category"][0],
            request.args["title"][0],
            request.args["description"][0],
            request.args["currency_code"][0],
            request.args["price"][0],
            request.args["process_time"][0],
            True if "nsfw" in request.args else False,
            request.args["shipping_origin"][0],
            request.args["ships_to"],
            est_delivery_domestic=request.args["est_delivery_domestic"][0],
            est_delivery_international=request.args["est_delivery_international"][0],
            shipping_currency_code=request.args["shipping_currency_code"][0],
            shipping_domestic=request.args["shipping_domestic"][0],
            shipping_international=request.args["shipping_international"][0],
            keywords=request.args["keywords"] if "keywords" in request.args else None,
            category=request.args["category"][0] if request.args["category"][0] is not "" else None,
            condition=request.args["condition"][0] if request.args["condition"][0] is not "" else None,
            sku=request.args["sku"][0] if request.args["sku"][0] is not "" else None,
            images=request.args["images"],
            free_shipping=True if "free_shipping" in request.args else False)

        for keyword in request.args["keywords"]:
            self.kserver.set(keyword.lower(), c.get_contract_id(), self.kserver.node.getProto().SerializeToString())
예제 #8
0
    def complete_order(self, request):
        def respond(success):
            if success:
                request.write(json.dumps({"success": True}))
                request.finish()
            else:
                request.write(
                    json.dumps({
                        "success": False,
                        "reason": "Failed to send receipt to vendor"
                    }))
                request.finish()

        file_path = DATA_FOLDER + "purchases/in progress/" + request.args[
            "id"][0] + ".json"
        with open(file_path, 'r') as filename:
            order = json.load(filename, object_pairs_hook=OrderedDict)
        c = Contract(self.db, contract=order, testnet=self.protocol.testnet)
        c.add_receipt(True,
                      self.protocol.blockchain,
                      feedback=request.args["feedback"][0]
                      if "feedback" in request.args else None,
                      quality=request.args["quality"][0]
                      if "quality" in request.args else None,
                      description=request.args["description"][0]
                      if "description" in request.args else None,
                      delivery_time=request.args["delivery_time"][0]
                      if "delivery_time" in request.args else None,
                      customer_service=request.args["customer_service"][0]
                      if "customer_service" in request.args else None,
                      review=request.args["review"][0]
                      if "review" in request.args else "")
        guid = c.contract["vendor_offer"]["listing"]["id"]["guid"]
        self.mserver.complete_order(guid, c).addCallback(respond)
        return server.NOT_DONE_YET
예제 #9
0
 def rpc_order(self, sender, pubkey, encrypted):
     try:
         box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey))
         order = box.decrypt(encrypted)
         c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict),
                      testnet=self.multiplexer.testnet)
         if c.verify(sender.signed_pubkey[64:]):
             self.router.addContact(sender)
             self.log.info("received an order from %s, waiting for payment..." % sender)
             payment_address = c.contract["buyer_order"]["order"]["payment"]["address"]
             chaincode = c.contract["buyer_order"]["order"]["payment"]["chaincode"]
             masterkey_b = c.contract["buyer_order"]["order"]["id"]["pubkeys"]["bitcoin"]
             buyer_key = derive_childkey(masterkey_b, chaincode)
             amount = c.contract["buyer_order"]["order"]["payment"]["amount"]
             listing_hash = c.contract["buyer_order"]["order"]["ref_hash"]
             signature = self.signing_key.sign(
                 str(payment_address) + str(amount) + str(listing_hash) + str(buyer_key))[:64]
             c.await_funding(self.get_notification_listener(), self.multiplexer.blockchain, signature, False)
             return [signature]
         else:
             self.log.warning("received invalid order from %s" % sender)
             return ["False"]
     except Exception:
         self.log.error("unable to decrypt order from %s" % sender)
         return ["False"]
예제 #10
0
 def parse_messages(messages):
     if messages is not None:
         for message in messages:
             try:
                 value = objects.Value()
                 value.ParseFromString(message)
                 try:
                     box = Box(PrivateKey(self.signing_key.encode()), PublicKey(value.valueKey))
                     ciphertext = value.serializedData
                     plaintext = box.decrypt(ciphertext)
                     p = objects.Plaintext_Message()
                     p.ParseFromString(plaintext)
                     signature = p.signature
                     p.ClearField("signature")
                     verify_key = nacl.signing.VerifyKey(p.signed_pubkey[64:])
                     verify_key.verify(p.SerializeToString(), signature)
                     h = nacl.hash.sha512(p.signed_pubkey)
                     pow_hash = h[64:128]
                     if int(pow_hash[:6], 16) >= 50 or hexlify(p.sender_guid) != h[:40]:
                         raise Exception('Invalid guid')
                     if p.type == objects.Plaintext_Message.Type.Value("ORDER_CONFIRMATION"):
                         c = Contract(self.db, hash_value=unhexlify(p.subject))
                         c.accept_order_confirmation(self.protocol.multiplexer.ws,
                                                     confirmation_json=p.message)
                     else:
                         listener.notify(p.sender_guid, p.encryption_pubkey, p.subject,
                                         objects.Plaintext_Message.Type.Name(p.type), p.message)
                 except Exception:
                     pass
                 signature = self.signing_key.sign(value.valueKey)[:64]
                 self.kserver.delete(self.kserver.node.id, value.valueKey, signature)
             except Exception:
                 pass
예제 #11
0
 def confirm_order(self, request):
     try:
         def respond(success):
             if success:
                 request.write(json.dumps({"success": True}))
                 request.finish()
             else:
                 request.write(json.dumps({"success": False, "reason": "Failed to send order confirmation"}))
                 request.finish()
         file_path = DATA_FOLDER + "store/contracts/in progress/" + request.args["id"][0] + ".json"
         with open(file_path, 'r') as filename:
             order = json.load(filename, object_pairs_hook=OrderedDict)
         c = Contract(self.db, contract=order, testnet=self.protocol.testnet)
         c.add_order_confirmation(self.protocol.blockchain,
                                  request.args["payout_address"][0],
                                  comments=request.args["comments"][0] if "comments" in request.args else None,
                                  shipper=request.args["shipper"][0] if "shipper" in request.args else None,
                                  tracking_number=request.args["tracking_number"][0]
                                  if "tracking_number" in request.args else None,
                                  est_delivery=request.args["est_delivery"][0]
                                  if "est_delivery" in request.args else None,
                                  url=request.args["url"][0] if "url" in request.args else None,
                                  password=request.args["password"][0] if "password" in request.args else None)
         guid = c.contract["buyer_order"]["order"]["id"]["guid"]
         self.mserver.confirm_order(guid, c).addCallback(respond)
         return server.NOT_DONE_YET
     except Exception, e:
         request.write(json.dumps({"success": False, "reason": e.message}, indent=4))
         request.finish()
         return server.NOT_DONE_YET
예제 #12
0
    def rpc_complete_order(self, sender, pubkey, encrypted):
        try:
            box = Box(
                PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)),
                PublicKey(pubkey))
            order = box.decrypt(encrypted)
            c = Contract(self.db,
                         contract=json.loads(order,
                                             object_pairs_hook=OrderedDict),
                         testnet=self.multiplexer.testnet)

            def handle_result(contract_id):
                if contract_id:
                    self.router.addContact(sender)
                    self.log.info("Received receipt for order %s" %
                                  contract_id)
                    return ["True"]
                else:
                    self.log.error("Received invalid receipt from %s" % sender)
                    return ["False"]

            d = c.accept_receipt(self.multiplexer.ws,
                                 self.multiplexer.blockchain)
            d.addCallback(handle_result)
        except Exception:
            self.log.error("Unable to decrypt order receipt from %s" % sender)
            return ["False"]
예제 #13
0
 def rpc_order_confirmation(self, sender, pubkey, encrypted):
     try:
         box = Box(
             PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)),
             PublicKey(pubkey))
         order = box.decrypt(encrypted)
         c = Contract(self.db,
                      contract=json.loads(order,
                                          object_pairs_hook=OrderedDict),
                      testnet=self.multiplexer.testnet)
         contract_id = c.accept_order_confirmation(
             self.get_notification_listener())
         if contract_id:
             self.router.addContact(sender)
             self.log.info("received confirmation for order %s" %
                           contract_id)
             return ["True"]
         else:
             self.log.warning(
                 "received invalid order confirmation from %s" % sender)
             return ["False"]
     except Exception:
         self.log.error("unable to decrypt order confirmation from %s" %
                        sender)
         return ["False"]
예제 #14
0
 def rpc_order(self, sender, pubkey, encrypted):
     try:
         box = Box(
             PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)),
             PublicKey(pubkey))
         order = box.decrypt(encrypted)
         c = Contract(self.db,
                      contract=json.loads(order,
                                          object_pairs_hook=OrderedDict),
                      testnet=self.multiplexer.testnet)
         if c.verify(sender.signed_pubkey[64:]):
             self.router.addContact(sender)
             self.log.info("Received an order from %s" % sender)
             payment_address = c.contract["buyer_order"]["order"][
                 "payment"]["address"]
             signature = self.signing_key.sign(str(payment_address))[:64]
             c.await_funding(self.multiplexer.ws,
                             self.multiplexer.blockchain, signature, False)
             return [signature]
         else:
             self.log.error("Received invalid order from %s" % sender)
             return ["False"]
     except Exception:
         self.log.error("Unable to decrypt order from %s" % sender)
         return ["False"]
예제 #15
0
 def complete_order(self, request):
     def respond(success):
         if success:
             request.write(json.dumps({"success": True}))
             request.finish()
         else:
             request.write(json.dumps({"success": False, "reason": "Failed to send receipt to vendor"}))
             request.finish()
     file_path = DATA_FOLDER + "purchases/in progress/" + request.args["id"][0] + ".json"
     with open(file_path, 'r') as filename:
         order = json.load(filename, object_pairs_hook=OrderedDict)
     c = Contract(self.db, contract=order, testnet=self.protocol.testnet)
     c.add_receipt(True,
                   self.protocol.blockchain,
                   feedback=request.args["feedback"][0] if "feedback" in request.args else None,
                   quality=request.args["quality"][0] if "quality" in request.args else None,
                   description=request.args["description"][0] if "description" in request.args else None,
                   delivery_time=request.args["delivery_time"][0]
                   if "delivery_time" in request.args else None,
                   customer_service=request.args["customer_service"][0]
                   if "customer_service" in request.args else None,
                   review=request.args["review"][0] if "review" in request.args else "")
     guid = c.contract["vendor_offer"]["listing"]["id"]["guid"]
     self.mserver.complete_order(guid, c).addCallback(respond)
     return server.NOT_DONE_YET
예제 #16
0
 def delete_contract(self, request):
     if "id" in request.args:
         c = Contract(hash_value=unhexlify(request.args["id"][0]))
         for keyword in c.contract["vendor_offer"]["listing"]["item"]["keywords"]:
             self.kserver.delete(keyword.lower(), c.get_contract_id(),
                                 KeyChain().signing_key.sign(c.get_contract_id())[:64])
         c.delete()
예제 #17
0
    def purchase_contract(self, request):
        try:

            def handle_response(resp, contract):
                if resp:
                    contract.await_funding(
                        self.mserver.protocol.get_notification_listener(), self.protocol.blockchain, resp
                    )
                    request.write(
                        json.dumps(
                            {
                                "success": True,
                                "payment_address": payment[0],
                                "amount": payment[1],
                                "order_id": c.get_contract_id().encode("hex"),
                            },
                            indent=4,
                        )
                    )
                    request.finish()
                else:
                    request.write(json.dumps({"success": False, "reason": "seller rejected contract"}, indent=4))
                    request.finish()

            options = None
            if "options" in request.args:
                options = {}
                for option in request.args["options"]:
                    options[option] = request.args[option][0]
            c = Contract(self.db, hash_value=unhexlify(request.args["id"][0]), testnet=self.protocol.testnet)
            payment = c.add_purchase_info(
                int(request.args["quantity"][0]),
                request.args["ship_to"][0] if "ship_to" in request.args else None,
                request.args["address"][0] if "address" in request.args else None,
                request.args["city"][0] if "city" in request.args else None,
                request.args["state"][0] if "state" in request.args else None,
                request.args["postal_code"][0] if "postal_code" in request.args else None,
                request.args["country"][0] if "country" in request.args else None,
                request.args["moderator"][0] if "moderator" in request.args else None,
                options,
            )

            def get_node(node):
                if node is not None:
                    self.mserver.purchase(node, c).addCallback(handle_response, c)
                else:
                    request.write(json.dumps({"success": False, "reason": "unable to reach vendor"}, indent=4))
                    request.finish()

            seller_guid = unhexlify(c.contract["vendor_offer"]["listing"]["id"]["guid"])
            self.kserver.resolve(seller_guid).addCallback(get_node)
            return server.NOT_DONE_YET
        except Exception, e:
            request.write(json.dumps({"success": False, "reason": e.message}, indent=4))
            request.finish()
            return server.NOT_DONE_YET
예제 #18
0
 def set_contract(self, request):
     try:
         if "options" in request.args:
             options = {}
             for option in request.args["options"]:
                 options[option] = request.args[option]
         c = Contract(self.db)
         c.create(
             str(request.args["expiration_date"][0]),
             request.args["metadata_category"][0],
             request.args["title"][0],
             request.args["description"][0],
             request.args["currency_code"][0],
             request.args["price"][0],
             request.args["process_time"][0],
             str_to_bool(request.args["nsfw"][0]),
             shipping_origin=request.args["shipping_origin"][0] if "shipping_origin" in request.args else None,
             shipping_regions=request.args["ships_to"] if "ships_to" in request.args else None,
             est_delivery_domestic=request.args["est_delivery_domestic"][0]
             if "est_delivery_domestic" in request.args
             else None,
             est_delivery_international=request.args["est_delivery_international"][0]
             if "est_delivery_international" in request.args
             else None,
             terms_conditions=request.args["terms_conditions"][0]
             if request.args["terms_conditions"][0] is not ""
             else None,
             returns=request.args["returns"][0] if request.args["returns"][0] is not "" else None,
             shipping_currency_code=request.args["shipping_currency_code"][0],
             shipping_domestic=request.args["shipping_domestic"][0],
             shipping_international=request.args["shipping_international"][0],
             keywords=request.args["keywords"] if "keywords" in request.args else None,
             category=request.args["category"][0] if request.args["category"][0] is not "" else None,
             condition=request.args["condition"][0] if request.args["condition"][0] is not "" else None,
             sku=request.args["sku"][0] if request.args["sku"][0] is not "" else None,
             images=request.args["images"],
             free_shipping=str_to_bool(request.args["free_shipping"][0]),
             options=options if "options" in request.args else None,
             moderators=request.args["moderators"] if "moderators" in request.args else None,
         )
         for keyword in request.args["keywords"]:
             self.kserver.set(
                 digest(keyword.lower()), c.get_contract_id(), self.kserver.node.getProto().SerializeToString()
             )
         request.write(json.dumps({"success": True, "id": c.get_contract_id().encode("hex")}))
         request.finish()
         return server.NOT_DONE_YET
     except Exception, e:
         request.write(json.dumps({"success": False, "reason": e.message}, indent=4))
         request.finish()
         return server.NOT_DONE_YET
예제 #19
0
    def rpc_complete_order(self, sender, pubkey, encrypted):
        try:
            box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey))
            order = box.decrypt(encrypted)
            c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict),
                         testnet=self.multiplexer.testnet)

            contract_id = c.accept_receipt(self.get_notification_listener(), self.multiplexer.blockchain)
            self.router.addContact(sender)
            self.log.info("received receipt for order %s" % contract_id)
            return ["True"]
        except Exception:
            self.log.error("unable to parse receipt from %s" % sender)
            return ["False"]
예제 #20
0
 def rpc_refund(self, sender, pubkey, encrypted):
     try:
         box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey))
         refund = box.decrypt(encrypted)
         refund_json = json.loads(refund, object_pairs_hook=OrderedDict)
         c = Contract(self.db, hash_value=unhexlify(refund_json["refund"]["order_id"]),
                      testnet=self.multiplexer.testnet)
         c.process_refund(refund_json, self.multiplexer.blockchain, self.get_notification_listener())
         self.router.addContact(sender)
         self.log.info("order %s refunded by vendor" % refund_json["refund"]["order_id"])
         return ["True"]
     except Exception, e:
         self.log.error("unable to parse refund message from %s" % sender)
         return [e.message]
예제 #21
0
 def delete_contract(self, request):
     try:
         if "id" in request.args:
             file_path = self.db.HashMap().get_file(
                 unhexlify(request.args["id"][0]))
             with open(file_path, 'r') as filename:
                 contract = json.load(filename,
                                      object_pairs_hook=OrderedDict)
             c = Contract(self.db, contract=contract)
             if "keywords" in c.contract["vendor_offer"]["listing"]["item"]:
                 for keyword in c.contract["vendor_offer"]["listing"][
                         "item"]["keywords"]:
                     self.kserver.delete(
                         keyword.lower(), c.get_contract_id(),
                         self.keychain.signing_key.sign(
                             c.get_contract_id())[:64])
             if "delete_images" in request.args:
                 c.delete(delete_images=True)
             else:
                 c.delete()
         request.write(json.dumps({"success": True}))
         request.finish()
         return server.NOT_DONE_YET
     except Exception, e:
         request.write(
             json.dumps({
                 "success": False,
                 "reason": e.message
             }, indent=4))
         request.finish()
         return server.NOT_DONE_YET
예제 #22
0
 def rpc_refund(self, sender, pubkey, encrypted):
     try:
         box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey))
         refund = box.decrypt(encrypted)
         refund_json = json.loads(refund, object_pairs_hook=OrderedDict)
         c = Contract(self.db, hash_value=unhexlify(refund_json["refund"]["order_id"]),
                      testnet=self.multiplexer.testnet)
         c.process_refund(refund_json, self.multiplexer.blockchain, self.get_notification_listener())
         self.router.addContact(sender)
         self.log.info("order %s refunded by vendor" % refund_json["refund"]["order_id"])
         return ["True"]
     except Exception, e:
         self.log.error("unable to parse refund message from %s" % sender)
         return [e.message]
예제 #23
0
 def rpc_order_confirmation(self, sender, pubkey, encrypted):
     try:
         box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey))
         order = box.decrypt(encrypted)
         c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict),
                      testnet=self.multiplexer.testnet)
         contract_id = c.accept_order_confirmation(self.multiplexer.ws)
         if contract_id:
             self.router.addContact(sender)
             self.log.info("received confirmation for order %s" % contract_id)
             return ["True"]
         else:
             self.log.warning("received invalid order confirmation from %s" % sender)
             return ["False"]
     except Exception:
         self.log.error("unable to decrypt order confirmation from %s" % sender)
         return ["False"]
예제 #24
0
 def rpc_order_confirmation(self, sender, pubkey, encrypted):
     try:
         box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey))
         order = box.decrypt(encrypted)
         c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict),
                      testnet=self.multiplexer.testnet)
         valid = c.accept_order_confirmation(self.get_notification_listener())
         if valid is True:
             self.router.addContact(sender)
             self.log.info("received confirmation for order %s" % c.get_order_id())
             return ["True"]
         else:
             self.log.warning("received invalid order confirmation from %s" % sender)
             return [valid]
     except Exception, e:
         self.log.error("unable to decrypt order confirmation from %s" % sender)
         return [str(e.message)]
예제 #25
0
 def set_contract(self, request):
     try:
         if "options" in request.args:
             options = {}
             for option in request.args["options"]:
                 options[option] = request.args[option]
         c = Contract(self.db)
         c.create(
             str(request.args["expiration_date"][0]),
             request.args["metadata_category"][0],
             request.args["title"][0],
             request.args["description"][0],
             request.args["currency_code"][0],
             request.args["price"][0],
             request.args["process_time"][0],
             True if "nsfw" in request.args else False,
             shipping_origin=request.args["shipping_origin"][0] if "shipping_origin" in request.args else None,
             shipping_regions=request.args["ships_to"] if "ships_to" in request.args else None,
             est_delivery_domestic=request.args["est_delivery_domestic"][0]
             if "est_delivery_domestic" in request.args else None,
             est_delivery_international=request.args["est_delivery_international"][0]
             if "est_delivery_international" in request.args else None,
             terms_conditions=request.args["terms_conditions"][0]
             if request.args["terms_conditions"][0] is not "" else None,
             returns=request.args["returns"][0] if request.args["returns"][0] is not "" else None,
             shipping_currency_code=request.args["shipping_currency_code"][0],
             shipping_domestic=request.args["shipping_domestic"][0],
             shipping_international=request.args["shipping_international"][0],
             keywords=request.args["keywords"] if "keywords" in request.args else None,
             category=request.args["category"][0] if request.args["category"][0] is not "" else None,
             condition=request.args["condition"][0] if request.args["condition"][0] is not "" else None,
             sku=request.args["sku"][0] if request.args["sku"][0] is not "" else None,
             images=request.args["images"],
             free_shipping=True if "free_shipping" in request.args else False,
             options=options if "options" in request.args else None,
             moderators=request.args["moderators"] if "moderators" in request.args else None)
         for keyword in request.args["keywords"]:
             self.kserver.set(digest(keyword.lower()), c.get_contract_id(),
                              self.kserver.node.getProto().SerializeToString())
         request.write(json.dumps({"success": True}))
         request.finish()
         return server.NOT_DONE_YET
     except Exception, e:
         request.write(json.dumps({"success": False, "reason": e.message}, indent=4))
         request.finish()
         return server.NOT_DONE_YET
예제 #26
0
 def rpc_order_confirmation(self, sender, pubkey, encrypted):
     try:
         box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey))
         order = box.decrypt(encrypted)
         c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict),
                      testnet=self.multiplexer.testnet)
         valid = c.accept_order_confirmation(self.get_notification_listener())
         if valid is True:
             self.router.addContact(sender)
             self.log.info("received confirmation for order %s" % c.get_order_id())
             return ["True"]
         else:
             self.log.warning("received invalid order confirmation from %s" % sender)
             return [valid]
     except Exception, e:
         self.log.error("unable to decrypt order confirmation from %s" % sender)
         return [str(e.message)]
예제 #27
0
 def delete_contract(self, request):
     try:
         if "id" in request.args:
             file_path = self.db.HashMap().get_file(request.args["id"][0])
             with open(file_path, "r") as filename:
                 contract = json.load(filename, object_pairs_hook=OrderedDict)
             c = Contract(self.db, contract=contract)
             if "keywords" in c.contract["vendor_offer"]["listing"]["item"]:
                 for keyword in c.contract["vendor_offer"]["listing"]["item"]["keywords"]:
                     self.kserver.delete(
                         keyword.lower(),
                         c.get_contract_id(),
                         self.keychain.signing_key.sign(c.get_contract_id())[:64],
                     )
             if "delete_images" in request.args:
                 c.delete(delete_images=True)
             else:
                 c.delete()
         request.write(json.dumps({"success": True}))
         request.finish()
         return server.NOT_DONE_YET
     except Exception, e:
         request.write(json.dumps({"success": False, "reason": e.message}, indent=4))
         request.finish()
         return server.NOT_DONE_YET
예제 #28
0
 def rpc_order(self, sender, pubkey, encrypted):
     try:
         box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey))
         order = box.decrypt(encrypted)
         c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict),
                      testnet=self.multiplexer.testnet)
         if c.verify(sender.signed_pubkey[64:]):
             self.router.addContact(sender)
             self.log.info("Received an order from %s" % sender)
             payment_address = c.contract["buyer_order"]["order"]["payment"]["address"]
             signature = self.signing_key.sign(str(payment_address))[:64]
             c.await_funding(self.multiplexer.ws, self.multiplexer.blockchain, signature, False)
             return [signature]
         else:
             self.log.error("Received invalid order from %s" % sender)
             return ["False"]
     except Exception:
         self.log.error("Unable to decrypt order from %s" % sender)
         return ["False"]
예제 #29
0
    def rpc_complete_order(self, sender, pubkey, encrypted):
        try:
            box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(pubkey))
            order = box.decrypt(encrypted)
            json.loads(order, object_pairs_hook=OrderedDict)
            temp = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict),
                            testnet=self.multiplexer.testnet)
            c = Contract(self.db, hash_value=unhexlify(temp.get_order_id()),
                         testnet=self.multiplexer.testnet)

            contract_id = c.accept_receipt(self.get_notification_listener(),
                                           self.multiplexer.blockchain,
                                           receipt_json=json.dumps(temp.contract["buyer_receipt"], indent=4))
            self.router.addContact(sender)
            self.log.info("received receipt for order %s" % contract_id)
            return ["True"]
        except Exception, e:
            self.log.error("unable to parse receipt from %s" % sender)
            return [e.message]
예제 #30
0
    def check_for_payment(self, request):
        if not self.protocol.blockchain.connected:
            request.write(json.dumps({"success": False, "reason": "libbitcoin server offline"}, indent=4))
            request.finish()
            return server.NOT_DONE_YET
        try:
            file_path = DATA_FOLDER + "purchases/unfunded/" + request.args["order_id"][0] + ".json"
            with open(file_path, 'r') as filename:
                order = json.load(filename, object_pairs_hook=OrderedDict)
            c = Contract(self.db, contract=order, testnet=self.protocol.testnet)
            self.protocol.blockchain.refresh_connection()
            c.blockchain = self.protocol.blockchain
            c.notification_listener = self.mserver.protocol.get_notification_listener()
            c.is_purchase = True
            addr = c.contract["buyer_order"]["order"]["payment"]["address"]

            def history_fetched(ec, history):
                if not ec:
                    # pylint: disable=W0612
                    # pylint: disable=W0640
                    for objid, txhash, index, height, value in history:
                        def cb_txpool(ec, result):
                            if ec:
                                self.protocol.blockchain.fetch_transaction(txhash, cb_chain)
                            else:
                                c.on_tx_received(None, None, None, None, result)

                        def cb_chain(ec, result):
                            if not ec:
                                c.on_tx_received(None, None, None, None, result)

                        self.protocol.blockchain.fetch_txpool_transaction(txhash, cb_txpool)

            self.protocol.blockchain.fetch_history2(addr, history_fetched)

            request.write(json.dumps({"success": True}, indent=4))
            request.finish()
            return server.NOT_DONE_YET
        except Exception, e:
            request.write(json.dumps({"success": False, "reason": e.message}, indent=4))
            request.finish()
            return server.NOT_DONE_YET
예제 #31
0
    def rpc_complete_order(self, sender, pubkey, encrypted):
        try:
            box = Box(PrivateKey(self.signing_key.encode(nacl.encoding.RawEncoder)), PublicKey(pubkey))
            order = box.decrypt(encrypted)
            c = Contract(self.db, contract=json.loads(order, object_pairs_hook=OrderedDict),
                         testnet=self.multiplexer.testnet)

            def handle_result(contract_id):
                if contract_id:
                    self.router.addContact(sender)
                    self.log.info("Received receipt for order %s" % contract_id)
                    return ["True"]
                else:
                    self.log.error("Received invalid receipt from %s" % sender)
                    return ["False"]
            d = c.accept_receipt(self.multiplexer.ws, self.multiplexer.blockchain)
            d.addCallback(handle_result)
        except Exception:
            self.log.error("Unable to decrypt order receipt from %s" % sender)
            return ["False"]
예제 #32
0
    def rpc_complete_order(self, sender, pubkey, encrypted):
        try:
            box = Box(self.signing_key.to_curve25519_private_key(),
                      PublicKey(pubkey))
            order = box.decrypt(encrypted)
            c = Contract(self.db,
                         contract=json.loads(order,
                                             object_pairs_hook=OrderedDict),
                         testnet=self.multiplexer.testnet)

            contract_id = c.accept_receipt(self.get_notification_listener(),
                                           self.multiplexer.blockchain)
            self.router.addContact(sender)
            self.log.info("received receipt for order %s" % contract_id)
            return ["True"]
        except Exception:
            import traceback
            traceback.print_exc()
            self.log.error("unable to parse receipt from %s" % sender)
            return ["False"]
예제 #33
0
 def setcontract():
     parser = argparse.ArgumentParser(
         description="Sets a new contract in the database and filesystem.",
         usage='''usage:
 networkcli.py setcontract [-f FILEPATH]''')
     parser.add_argument('-f',
                         '--filepath',
                         help="a path to a completed json contract")
     args = parser.parse_args(sys.argv[2:])
     with open(args.filepath) as data_file:
         contract = json.load(data_file, object_pairs_hook=OrderedDict)
     Contract(contract).save()
예제 #34
0
 def delete_contract(self, request):
     if "id" in request.args:
         c = Contract(hash_value=unhexlify(request.args["id"][0]))
         for keyword in c.contract["vendor_offer"]["listing"]["item"]["keywords"]:
             self.kserver.delete(keyword.lower(), c.get_contract_id(),
                                 KeyChain().signing_key.sign(c.get_contract_id())[:64])
         c.delete()
예제 #35
0
 def rpc_order(self, sender, pubkey, encrypted):
     try:
         box = Box(self.signing_key.to_curve25519_private_key(),
                   PublicKey(pubkey))
         order = box.decrypt(encrypted)
         c = Contract(self.db,
                      contract=json.loads(order,
                                          object_pairs_hook=OrderedDict),
                      testnet=self.multiplexer.testnet)
         v = c.verify(sender.pubkey)
         if v is True:
             self.router.addContact(sender)
             self.log.info(
                 "received an order from %s, waiting for payment..." %
                 sender)
             payment_address = c.contract["buyer_order"]["order"][
                 "payment"]["address"]
             chaincode = c.contract["buyer_order"]["order"]["payment"][
                 "chaincode"]
             masterkey_b = c.contract["buyer_order"]["order"]["id"][
                 "pubkeys"]["bitcoin"]
             buyer_key = derive_childkey(masterkey_b, chaincode)
             amount = c.contract["buyer_order"]["order"]["payment"][
                 "amount"]
             listing_hash = c.contract["vendor_offer"]["listing"][
                 "contract_id"]
             signature = self.signing_key.sign(
                 str(payment_address) + str(amount) + str(listing_hash) +
                 str(buyer_key))[:64]
             c.await_funding(self.get_notification_listener(),
                             self.multiplexer.blockchain, signature, False)
             return [signature]
         else:
             self.log.warning("received invalid order from %s reason %s" %
                              (sender, v))
             return ["False"]
     except Exception, e:
         self.log.error("Exception (%s) occurred processing order from %s" %
                        (e.message, sender))
         return ["False"]
예제 #36
0
    def rpc_complete_order(self, sender, pubkey, encrypted):
        try:
            box = Box(self.signing_key.to_curve25519_private_key(),
                      PublicKey(pubkey))
            order = box.decrypt(encrypted)
            json.loads(order, object_pairs_hook=OrderedDict)
            temp = Contract(self.db,
                            contract=json.loads(order,
                                                object_pairs_hook=OrderedDict),
                            testnet=self.multiplexer.testnet)
            c = Contract(self.db,
                         hash_value=unhexlify(temp.get_order_id()),
                         testnet=self.multiplexer.testnet)

            contract_id = c.accept_receipt(self.get_notification_listener(),
                                           self.multiplexer.blockchain,
                                           receipt_json=json.dumps(
                                               temp.contract["buyer_receipt"],
                                               indent=4))
            self.router.addContact(sender)
            self.log.info("received receipt for order %s" % contract_id)
            return ["True"]
        except Exception, e:
            self.log.error("unable to parse receipt from %s" % sender)
            return [e.message]
예제 #37
0
 def parse_messages(messages):
     if messages is not None:
         self.log.info("retrieved %s message(s) from the dht" %
                       len(messages))
         for message in messages:
             try:
                 value = objects.Value()
                 value.ParseFromString(message)
                 try:
                     box = Box(PrivateKey(self.signing_key.encode()),
                               PublicKey(value.valueKey))
                     ciphertext = value.serializedData
                     plaintext = box.decrypt(ciphertext).decode("zlib")
                     p = objects.Plaintext_Message()
                     p.ParseFromString(plaintext)
                     signature = p.signature
                     p.ClearField("signature")
                     verify_key = nacl.signing.VerifyKey(
                         p.signed_pubkey[64:])
                     verify_key.verify(p.SerializeToString(), signature)
                     h = nacl.hash.sha512(p.signed_pubkey)
                     pow_hash = h[64:128]
                     if int(pow_hash[:6],
                            16) >= 50 or p.sender_guid.encode(
                                "hex") != h[:40]:
                         raise Exception('Invalid guid')
                     if p.type == objects.Plaintext_Message.Type.Value(
                             "ORDER_CONFIRMATION"):
                         c = Contract(self.db, hash_value=p.subject)
                         c.accept_order_confirmation(
                             self.protocol.get_notification_listener(),
                             confirmation_json=p.message)
                     elif p.type == objects.Plaintext_Message.Type.Value(
                             "RECEIPT"):
                         c = Contract(self.db, hash_value=p.subject)
                         c.accept_receipt(
                             self.protocol.get_notification_listener(),
                             self.protocol.multiplexer.blockchain,
                             receipt_json=p.message)
                     else:
                         listener.notify(p, signature)
                 except Exception:
                     pass
                 signature = self.signing_key.sign(value.valueKey)[:64]
                 self.kserver.delete(self.kserver.node.id,
                                     value.valueKey, signature)
             except Exception:
                 pass
예제 #38
0
 def parse_messages(messages):
     if messages is not None:
         self.log.info("retrieved %s message(s) from the dht" % len(messages))
         for message in messages:
             try:
                 value = objects.Value()
                 value.ParseFromString(message)
                 try:
                     box = Box(self.signing_key.to_curve25519_private_key(), PublicKey(value.valueKey))
                     ciphertext = value.serializedData
                     plaintext = box.decrypt(ciphertext).decode("zlib")
                     p = objects.PlaintextMessage()
                     p.ParseFromString(plaintext)
                     signature = p.signature
                     p.ClearField("signature")
                     verify_key = nacl.signing.VerifyKey(p.pubkey)
                     verify_key.verify(p.SerializeToString(), signature)
                     h = nacl.hash.sha512(p.pubkey)
                     pow_hash = h[40:]
                     if int(pow_hash[:6], 16) >= 50 or p.sender_guid.encode("hex") != h[:40]:
                         raise Exception("Invalid guid")
                     if p.type == objects.PlaintextMessage.Type.Value("ORDER_CONFIRMATION"):
                         c = Contract(
                             self.db, hash_value=unhexlify(p.subject), testnet=self.protocol.multiplexer.testnet
                         )
                         c.accept_order_confirmation(
                             self.protocol.get_notification_listener(), confirmation_json=p.message
                         )
                     elif p.type == objects.PlaintextMessage.Type.Value("RECEIPT"):
                         c = Contract(
                             self.db, hash_value=unhexlify(p.subject), testnet=self.protocol.multiplexer.testnet
                         )
                         c.accept_receipt(
                             self.protocol.get_notification_listener(),
                             self.protocol.multiplexer.blockchain,
                             receipt_json=p.message,
                         )
                     elif p.type == objects.PlaintextMessage.Type.Value("DISPUTE_OPEN"):
                         process_dispute(
                             json.loads(p.message, object_pairs_hook=OrderedDict),
                             self.db,
                             self.protocol.get_message_listener(),
                             self.protocol.get_notification_listener(),
                             self.protocol.multiplexer.testnet,
                         )
                     else:
                         listener.notify(p, signature)
                 except Exception:
                     pass
                 signature = self.signing_key.sign(value.valueKey)[:64]
                 self.kserver.delete(self.kserver.node.id, value.valueKey, signature)
             except Exception:
                 pass
예제 #39
0
    def purchase_contract(self, request):
        try:
            def handle_response(resp, contract):
                if resp:
                    contract.await_funding(self.protocol.ws, self.protocol.blockchain, resp)
                    request.write(json.dumps({"success": True, "payment_address": payment[0],
                                              "amount": payment[1],
                                              "order_id": c.get_contract_id().encode("hex")},
                                             indent=4))
                    request.finish()
                else:
                    request.write(json.dumps({"success": False, "reason": "seller rejected contract"}, indent=4))
                    request.finish()
            options = None
            if "options" in request.args:
                options = {}
                for option in request.args["options"]:
                    options[option] = request.args[option][0]
            c = Contract(self.db, hash_value=unhexlify(request.args["id"][0]), testnet=self.protocol.testnet)
            payment = c.\
                add_purchase_info(int(request.args["quantity"][0]),
                                  request.args["ship_to"][0] if "ship_to" in request.args else None,
                                  request.args["address"][0] if "address" in request.args else None,
                                  request.args["city"][0] if "city" in request.args else None,
                                  request.args["state"][0] if "state" in request.args else None,
                                  request.args["postal_code"][0] if "postal_code" in request.args else None,
                                  request.args["country"][0] if "country" in request.args else None,
                                  request.args["moderator"][0] if "moderator" in request.args else None,
                                  options)

            def get_node(node):
                if node is not None:
                    self.mserver.purchase(node, c).addCallback(handle_response, c)
                else:
                    request.write(json.dumps({"success": False, "reason": "unable to reach vendor"}, indent=4))
                    request.finish()
            seller_guid = unhexlify(c.contract["vendor_offer"]["listing"]["id"]["guid"])
            self.kserver.resolve(seller_guid).addCallback(get_node)
            return server.NOT_DONE_YET
        except Exception, e:
            request.write(json.dumps({"success": False, "reason": e.message}, indent=4))
            request.finish()
            return server.NOT_DONE_YET
예제 #40
0
 def delete_contract(self, request):
     try:
         if "id" in request.args:
             c = Contract(self.db, hash_value=unhexlify(request.args["id"][0]))
             for keyword in c.contract["vendor_offer"]["listing"]["item"]["keywords"]:
                 self.kserver.delete(keyword.lower(), c.get_contract_id(),
                                     self.keychain.signing_key.sign(c.get_contract_id())[:64])
             c.delete()
         request.write(json.dumps({"success": True}))
         request.finish()
         return server.NOT_DONE_YET
     except Exception, e:
         request.write(json.dumps({"success": False, "reason": e.message}, indent=4))
         request.finish()
         return server.NOT_DONE_YET
예제 #41
0
def process_dispute(contract, db, message_listener, notification_listener, testnet):
    """
    This function processes a dispute message received from another node. It checks the
    contract to see if this a dispute for a purchase we made, a dispute for one of our
    sales, or a new case if we are the moderator.

    If it's a purchase or sale it will
    update the order status to disputed and push a notification to the listener.

    If it's a new case it will validate the contract, create a new case in the db,
    and push a notification to the listener.

    Args:
        contract: a json contract of the current order state. Should have a "dispute"
            object attached with dispute info.
        db: a `Database` object.
        message_listener: a `MessageListenerImpl` object.
        notification_listener: a `NotificationListenerImpl` object.
        testnet: `bool` of whether we're on testnet or not.
    """
    tmp_contract = deepcopy(contract)
    if "vendor_order_confirmation" in tmp_contract:
        del tmp_contract["vendor_order_confirmation"]
    if "buyer_receipt" in tmp_contract:
        del tmp_contract["buyer_receipt"]
    del tmp_contract["dispute"]

    order_id = digest(json.dumps(tmp_contract, indent=4)).encode("hex")
    own_guid = KeyChain(db).guid.encode("hex")

    if contract["dispute"]["info"]["guid"] == contract["vendor_offer"]["listing"]["id"]["guid"]:
        guid = unhexlify(contract["vendor_offer"]["listing"]["id"]["guid"])
        public_key = unhexlify(contract["vendor_offer"]["listing"]["id"]["pubkeys"]["guid"])
        if "blockchain_id" in contract["vendor_offer"]["listing"]["id"]:
            handle = contract["vendor_offer"]["listing"]["id"]["blockchain_id"]
        else:
            handle = ""
        proof_sig = None
    elif contract["dispute"]["info"]["guid"] == contract["buyer_order"]["order"]["id"]["guid"]:
        guid = unhexlify(contract["buyer_order"]["order"]["id"]["guid"])
        public_key = unhexlify(contract["buyer_order"]["order"]["id"]["pubkeys"]["guid"])
        if "blockchain_id" in contract["buyer_order"]["order"]["id"]:
            handle = contract["buyer_order"]["order"]["id"]["blockchain_id"]
        else:
            handle = ""
        proof_sig = contract["dispute"]["info"]["proof_sig"]
    else:
        raise Exception("Dispute guid not in contract")

    verify_key = nacl.signing.VerifyKey(public_key)
    verify_key.verify(json.dumps(contract["dispute"]["info"], indent=4),
                      base64.b64decode(contract["dispute"]["signature"]))

    p = PlaintextMessage()
    p.sender_guid = guid
    p.handle = handle
    p.pubkey = public_key
    p.subject = str(order_id)
    p.type = PlaintextMessage.Type.Value("DISPUTE_OPEN")
    p.message = str(contract["dispute"]["info"]["claim"])
    p.timestamp = int(time.time())
    p.avatar_hash = unhexlify(str(contract["dispute"]["info"]["avatar_hash"]))

    if db.purchases.get_purchase(order_id) is not None:
        db.purchases.update_status(order_id, 4)

    elif db.sales.get_sale(order_id) is not None:
        db.sales.update_status(order_id, 4)

    elif "moderators" in contract["vendor_offer"]["listing"]:
        # TODO: make sure a case isn't already open in the db
        is_selected = False
        for moderator in contract["vendor_offer"]["listing"]["moderators"]:
            if moderator["guid"] == own_guid and contract["buyer_order"]["order"]["moderator"] == own_guid:
                is_selected = True
        if not is_selected:
            raise Exception("Not a moderator for this contract")
        else:
            if "blockchain_id" in contract["vendor_offer"]["listing"]["id"] and \
                            contract["vendor_offer"]["listing"]["id"]["blockchain_id"] != "":
                vendor = contract["vendor_offer"]["listing"]["id"]["blockchain_id"]
            else:
                vendor = contract["vendor_offer"]["listing"]["id"]["guid"]
            if "blockchain_id" in contract["buyer_order"]["order"]["id"] and \
                            contract["buyer_order"]["order"]["id"]["blockchain_id"] != "":
                buyer = contract["buyer_order"]["order"]["id"]["blockchain_id"]
            else:
                buyer = contract["buyer_order"]["order"]["id"]["guid"]

            c = Contract(db, contract=contract, testnet=testnet)

            validation_failures = c.validate_for_moderation(proof_sig)

            db.cases.new_case(order_id,
                              contract["vendor_offer"]["listing"]["item"]["title"],
                              time.time(),
                              contract["buyer_order"]["order"]["date"],
                              float(contract["buyer_order"]["order"]["payment"]["amount"]),
                              contract["vendor_offer"]["listing"]["item"]["image_hashes"][0],
                              buyer, vendor, json.dumps(validation_failures),
                              contract["dispute"]["info"]["claim"])

            with open(os.path.join(DATA_FOLDER, "cases", order_id + ".json"), 'wb') as outfile:
                outfile.write(json.dumps(contract, indent=4))
    else:
        raise Exception("Order ID for dispute not found")

    message_listener.notify(p, "")
    title = contract["vendor_offer"]["listing"]["item"]["title"]
    notification_listener.notify(guid, handle, "dispute_open", order_id,
                                 title,
                                 unhexlify(contract["vendor_offer"]["listing"]["item"]["image_hashes"][0]))

    # Send SMTP notification
    notification = SMTPNotification(db)
    guid = guid.encode("hex")
    notification.send("[OpenBazaar] Dispute Opened",
                      "A dispute has been opened.\n\n"
                      "Order: %s\n"
                      "Opened By: %s\n"
                      "Title: %s" % (order_id, guid, title))