def close_dispute(self, order_id, resolution, buyer_percentage,
                      vendor_percentage, moderator_percentage, moderator_address):
        """
        Called when a moderator closes a dispute. It will create a payout transactions refunding both
        parties and send it to them in a dispute_close message.
        """
        if float(vendor_percentage) < 0 or float(moderator_percentage) < 0 or float(buyer_percentage) < 0:
            raise Exception("Payouts percentages must be positive")
        if float(vendor_percentage) + float(buyer_percentage) > 1:
            raise Exception("Payout exceeds 100% of value")
        if not self.protocol.multiplexer.blockchain.connected:
            raise Exception("Libbitcoin server not online")
        if not self.protocol.multiplexer.testnet and \
                not (moderator_address[:1] == "1" or moderator_address[:1] == "3"):
            raise Exception("Bitcoin address is not a mainnet address")
        elif self.protocol.multiplexer.testnet and not \
                (moderator_address[:1] == "n" or moderator_address[:1] == "m" or moderator_address[:1] == "2"):
            raise Exception("Bitcoin address is not a testnet address")
        try:
            bitcointools.b58check_to_hex(moderator_address)
        except AssertionError:
            raise Exception("Invalid Bitcoin address")

        with open(os.path.join(DATA_FOLDER, "cases", order_id + ".json"), "r") as filename:
            contract = json.load(filename, object_pairs_hook=OrderedDict)

        buyer_address = contract["buyer_order"]["order"]["refund_address"]

        buyer_guid = contract["buyer_order"]["order"]["id"]["guid"]
        buyer_enc_key = nacl.signing.VerifyKey(
            contract["buyer_order"]["order"]["id"]["pubkeys"]["guid"],
            encoder=nacl.encoding.HexEncoder).to_curve25519_public_key()
        vendor_guid = contract["vendor_offer"]["listing"]["id"]["guid"]
        vendor_enc_key = nacl.signing.VerifyKey(
            contract["vendor_offer"]["listing"]["id"]["pubkeys"]["guid"],
            encoder=nacl.encoding.HexEncoder).to_curve25519_public_key()

        payment_address = contract["buyer_order"]["order"]["payment"]["address"]

        def history_fetched(ec, history):
            outpoints = []
            satoshis = 0
            outputs = []
            dispute_json = {"dispute_resolution": {"resolution": {}}}
            timeout.cancel()
            if ec:
                print ec
            else:
                for tx_type, txid, i, height, value in history:  # pylint: disable=W0612
                    if tx_type == obelisk.PointIdent.Output:
                        satoshis += value
                        o = {
                            "txid": txid.encode("hex"),
                            "vout": i,
                            "value": value,
                            "scriptPubKey": "00"
                        }
                        if o not in outpoints:
                            outpoints.append(o)

                if satoshis <= 0:
                    d.callback(False)
                else:
                    satoshis -= TRANSACTION_FEE
                    moderator_fee = int(float(moderator_percentage) * satoshis)
                    satoshis -= moderator_fee

                    if moderator_fee > 0:
                        outputs.append({'value': moderator_fee, 'address': moderator_address})
                    dispute_json["dispute_resolution"]["resolution"]["moderator_address"] = moderator_address
                    dispute_json["dispute_resolution"]["resolution"]["moderator_fee"] = \
                        round(moderator_fee / float(100000000), 8)
                    dispute_json["dispute_resolution"]["resolution"]["transaction_fee"] = \
                        round(TRANSACTION_FEE / float(100000000), 8)
                    if float(buyer_percentage) > 0:
                        amt = int(float(buyer_percentage) * satoshis)
                        dispute_json["dispute_resolution"]["resolution"]["buyer_payout"] = \
                            round(amt / float(100000000), 8)
                        outputs.append({'value': amt,
                                        'address': buyer_address})
                    if float(vendor_percentage) > 0:
                        amt = int(float(vendor_percentage) * satoshis)
                        dispute_json["dispute_resolution"]["resolution"]["vendor_payout"] = \
                            round(amt / float(100000000), 8)
                        outputs.append({'value': amt,
                                        'address': vendor_address})

                    tx = BitcoinTransaction.make_unsigned(outpoints, outputs,
                                                          testnet=self.protocol.multiplexer.testnet)
                    chaincode = contract["buyer_order"]["order"]["payment"]["chaincode"]
                    redeem_script = str(contract["buyer_order"]["order"]["payment"]["redeem_script"])
                    masterkey_m = bitcointools.bip32_extract_key(KeyChain(self.db).bitcoin_master_privkey)
                    moderator_priv = derive_childkey(masterkey_m, chaincode, bitcointools.MAINNET_PRIVATE)

                    signatures = tx.create_signature(moderator_priv, redeem_script)
                    dispute_json["dispute_resolution"]["resolution"]["order_id"] = order_id
                    dispute_json["dispute_resolution"]["resolution"]["tx_signatures"] = signatures
                    dispute_json["dispute_resolution"]["resolution"]["claim"] = self.db.cases.get_claim(order_id)
                    dispute_json["dispute_resolution"]["resolution"]["decision"] = resolution
                    dispute_json["dispute_resolution"]["signature"] = \
                        base64.b64encode(KeyChain(self.db).signing_key.sign(json.dumps(
                            dispute_json["dispute_resolution"]["resolution"], indent=4))[:64])

                    contract["dispute_resolution"] = dispute_json["dispute_resolution"]
                    with open(DATA_FOLDER + "cases/" + order_id + ".json", 'wb') as outfile:
                        outfile.write(json.dumps(contract, indent=4))

                    send(dispute_json)

        def send(dispute_json):
            def get_node(node_to_ask, recipient_guid, public_key):
                def parse_response(response):
                    if not response[0]:
                        self.send_message(Node(unhexlify(recipient_guid)),
                                          public_key.encode(),
                                          objects.PlaintextMessage.Type.Value("DISPUTE_CLOSE"),
                                          dispute_json,
                                          order_id,
                                          store_only=True)

                if node_to_ask:
                    skephem = PrivateKey.generate()
                    pkephem = skephem.public_key.encode(nacl.encoding.RawEncoder)
                    box = Box(skephem, public_key)
                    nonce = nacl.utils.random(Box.NONCE_SIZE)
                    ciphertext = box.encrypt(json.dumps(dispute_json, indent=4), nonce)
                    self.protocol.callDisputeClose(node_to_ask, pkephem, ciphertext).addCallback(parse_response)
                else:
                    parse_response([False])

            self.kserver.resolve(unhexlify(vendor_guid)).addCallback(get_node, vendor_guid, vendor_enc_key)
            self.kserver.resolve(unhexlify(buyer_guid)).addCallback(get_node, buyer_guid, buyer_enc_key)
            self.db.cases.update_status(order_id, 1)
            d.callback(True)

        d = defer.Deferred()

        if "dispute_resolution" not in contract:
            if "vendor_order_confirmation" in contract and float(vendor_percentage) > 0:
                vendor_address = contract["vendor_order_confirmation"]["invoice"]["payout"]["address"]
            elif "vendor_order_confirmation" not in contract and float(vendor_percentage) > 0:
                raise Exception("Cannot refund seller before order confirmation is sent")

            def libbitcoin_timeout():
                d.callback("timed out")

            timeout = reactor.callLater(5, libbitcoin_timeout)
            self.protocol.multiplexer.blockchain.fetch_history2(payment_address, history_fetched)
        else:
            dispute_json = {"dispute_resolution": contract["dispute_resolution"]}
            send(dispute_json)
        return d
dataset/ETHPy150Open OpenBazaar/OpenBazaar-Server/market/network.py/Server.close_dispute/original