{
  "language": "Solidity",
  "sources": {
    "": {
      "content": "pragma solidity ^0.4.8;\ncontract CryptoPunksMarket {\n\n    // You can use this hash to verify the image file containing all the punks\n    string public imageHash = \"ac39af4793119ee46bbff351d8cb6b5f23da60222126add4268e261199a2921b\";\n\n    address owner;\n\n    string public standard = 'CryptoPunks';\n    string public name;\n    string public symbol;\n    uint8 public decimals;\n    uint256 public totalSupply;\n\n    uint public nextPunkIndexToAssign = 0;\n\n    bool public allPunksAssigned = false;\n    uint public punksRemainingToAssign = 0;\n\n    //mapping (address => uint) public addressToPunkIndex;\n    mapping (uint => address) public punkIndexToAddress;\n\n    /* This creates an array with all balances */\n    mapping (address => uint256) public balanceOf;\n\n    struct Offer {\n        bool isForSale;\n        uint punkIndex;\n        address seller;\n        uint minValue;          // in ether\n        address onlySellTo;     // specify to sell only to a specific person\n    }\n\n    struct Bid {\n        bool hasBid;\n        uint punkIndex;\n        address bidder;\n        uint value;\n    }\n\n    // A record of punks that are offered for sale at a specific minimum value, and perhaps to a specific person\n    mapping (uint => Offer) public punksOfferedForSale;\n\n    // A record of the highest punk bid\n    mapping (uint => Bid) public punkBids;\n\n    mapping (address => uint) public pendingWithdrawals;\n\n    event Assign(address indexed to, uint256 punkIndex);\n    event Transfer(address indexed from, address indexed to, uint256 value);\n    event PunkTransfer(address indexed from, address indexed to, uint256 punkIndex);\n    event PunkOffered(uint indexed punkIndex, uint minValue, address indexed toAddress);\n    event PunkBidEntered(uint indexed punkIndex, uint value, address indexed fromAddress);\n    event PunkBidWithdrawn(uint indexed punkIndex, uint value, address indexed fromAddress);\n    event PunkBought(uint indexed punkIndex, uint value, address indexed fromAddress, address indexed toAddress);\n    event PunkNoLongerForSale(uint indexed punkIndex);\n\n    /* Initializes contract with initial supply tokens to the creator of the contract */\n    function CryptoPunksMarket() payable {\n        //        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens\n        owner = msg.sender;\n        totalSupply = 10000;                        // Update total supply\n        punksRemainingToAssign = totalSupply;\n        name = \"CRYPTOPUNKS\";                                   // Set the name for display purposes\n        symbol = \"Ͼ\";                               // Set the symbol for display purposes\n        decimals = 0;                                       // Amount of decimals for display purposes\n    }\n\n    function setInitialOwner(address to, uint punkIndex) {\n        if (msg.sender != owner) throw;\n        if (allPunksAssigned) throw;\n        if (punkIndex >= 10000) throw;\n        if (punkIndexToAddress[punkIndex] != to) {\n            if (punkIndexToAddress[punkIndex] != 0x0) {\n                balanceOf[punkIndexToAddress[punkIndex]]--;\n            } else {\n                punksRemainingToAssign--;\n            }\n            punkIndexToAddress[punkIndex] = to;\n            balanceOf[to]++;\n            Assign(to, punkIndex);\n        }\n    }\n\n    function setInitialOwners(address[] addresses, uint[] indices) {\n        if (msg.sender != owner) throw;\n        uint n = addresses.length;\n        for (uint i = 0; i < n; i++) {\n            setInitialOwner(addresses[i], indices[i]);\n        }\n    }\n\n    function allInitialOwnersAssigned() {\n        if (msg.sender != owner) throw;\n        allPunksAssigned = true;\n    }\n\n    function getPunk(uint punkIndex) {\n        if (!allPunksAssigned) throw;\n        if (punksRemainingToAssign == 0) throw;\n        if (punkIndexToAddress[punkIndex] != 0x0) throw;\n        if (punkIndex >= 10000) throw;\n        punkIndexToAddress[punkIndex] = msg.sender;\n        balanceOf[msg.sender]++;\n        punksRemainingToAssign--;\n        Assign(msg.sender, punkIndex);\n    }\n\n    // Transfer ownership of a punk to another user without requiring payment\n    function transferPunk(address to, uint punkIndex) {\n        if (!allPunksAssigned) throw;\n        if (punkIndexToAddress[punkIndex] != msg.sender) throw;\n        if (punkIndex >= 10000) throw;\n        if (punksOfferedForSale[punkIndex].isForSale) {\n            punkNoLongerForSale(punkIndex);\n        }\n        punkIndexToAddress[punkIndex] = to;\n        balanceOf[msg.sender]--;\n        balanceOf[to]++;\n        Transfer(msg.sender, to, 1);\n        PunkTransfer(msg.sender, to, punkIndex);\n        // Check for the case where there is a bid from the new owner and refund it.\n        // Any other bid can stay in place.\n        Bid bid = punkBids[punkIndex];\n        if (bid.bidder == to) {\n            // Kill bid and refund value\n            pendingWithdrawals[to] += bid.value;\n            punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0);\n        }\n    }\n\n    function punkNoLongerForSale(uint punkIndex) {\n        if (!allPunksAssigned) throw;\n        if (punkIndexToAddress[punkIndex] != msg.sender) throw;\n        if (punkIndex >= 10000) throw;\n        punksOfferedForSale[punkIndex] = Offer(false, punkIndex, msg.sender, 0, 0x0);\n        PunkNoLongerForSale(punkIndex);\n    }\n\n    function offerPunkForSale(uint punkIndex, uint minSalePriceInWei) {\n        if (!allPunksAssigned) throw;\n        if (punkIndexToAddress[punkIndex] != msg.sender) throw;\n        if (punkIndex >= 10000) throw;\n        punksOfferedForSale[punkIndex] = Offer(true, punkIndex, msg.sender, minSalePriceInWei, 0x0);\n        PunkOffered(punkIndex, minSalePriceInWei, 0x0);\n    }\n\n    function offerPunkForSaleToAddress(uint punkIndex, uint minSalePriceInWei, address toAddress) {\n        if (!allPunksAssigned) throw;\n        if (punkIndexToAddress[punkIndex] != msg.sender) throw;\n        if (punkIndex >= 10000) throw;\n        punksOfferedForSale[punkIndex] = Offer(true, punkIndex, msg.sender, minSalePriceInWei, toAddress);\n        PunkOffered(punkIndex, minSalePriceInWei, toAddress);\n    }\n\n    function buyPunk(uint punkIndex) payable {\n        if (!allPunksAssigned) throw;\n        Offer offer = punksOfferedForSale[punkIndex];\n        if (punkIndex >= 10000) throw;\n        if (!offer.isForSale) throw;                // punk not actually for sale\n        if (offer.onlySellTo != 0x0 && offer.onlySellTo != msg.sender) throw;  // punk not supposed to be sold to this user\n        if (msg.value < offer.minValue) throw;      // Didn't send enough ETH\n        if (offer.seller != punkIndexToAddress[punkIndex]) throw; // Seller no longer owner of punk\n\n        address seller = offer.seller;\n\n        punkIndexToAddress[punkIndex] = msg.sender;\n        balanceOf[seller]--;\n        balanceOf[msg.sender]++;\n        Transfer(seller, msg.sender, 1);\n\n        punkNoLongerForSale(punkIndex);\n        pendingWithdrawals[seller] += msg.value;\n        PunkBought(punkIndex, msg.value, seller, msg.sender);\n\n        // Check for the case where there is a bid from the new owner and refund it.\n        // Any other bid can stay in place.\n        Bid bid = punkBids[punkIndex];\n        if (bid.bidder == msg.sender) {\n            // Kill bid and refund value\n            pendingWithdrawals[msg.sender] += bid.value;\n            punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0);\n        }\n    }\n\n    function withdraw() {\n        if (!allPunksAssigned) throw;\n        uint amount = pendingWithdrawals[msg.sender];\n        // Remember to zero the pending refund before\n        // sending to prevent re-entrancy attacks\n        pendingWithdrawals[msg.sender] = 0;\n        msg.sender.transfer(amount);\n    }\n\n    function enterBidForPunk(uint punkIndex) payable {\n        if (punkIndex >= 10000) throw;\n        if (!allPunksAssigned) throw;                \n        if (punkIndexToAddress[punkIndex] == 0x0) throw;\n        if (punkIndexToAddress[punkIndex] == msg.sender) throw;\n        if (msg.value == 0) throw;\n        Bid existing = punkBids[punkIndex];\n        if (msg.value <= existing.value) throw;\n        if (existing.value > 0) {\n            // Refund the failing bid\n            pendingWithdrawals[existing.bidder] += existing.value;\n        }\n        punkBids[punkIndex] = Bid(true, punkIndex, msg.sender, msg.value);\n        PunkBidEntered(punkIndex, msg.value, msg.sender);\n    }\n\n    function acceptBidForPunk(uint punkIndex, uint minPrice) {\n        if (punkIndex >= 10000) throw;\n        if (!allPunksAssigned) throw;                \n        if (punkIndexToAddress[punkIndex] != msg.sender) throw;\n        address seller = msg.sender;\n        Bid bid = punkBids[punkIndex];\n        if (bid.value == 0) throw;\n        if (bid.value < minPrice) throw;\n\n        punkIndexToAddress[punkIndex] = bid.bidder;\n        balanceOf[seller]--;\n        balanceOf[bid.bidder]++;\n        Transfer(seller, bid.bidder, 1);\n\n        punksOfferedForSale[punkIndex] = Offer(false, punkIndex, bid.bidder, 0, 0x0);\n        uint amount = bid.value;\n        punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0);\n        pendingWithdrawals[seller] += amount;\n        PunkBought(punkIndex, bid.value, seller, bid.bidder);\n    }\n\n    function withdrawBidForPunk(uint punkIndex) {\n        if (punkIndex >= 10000) throw;\n        if (!allPunksAssigned) throw;                \n        if (punkIndexToAddress[punkIndex] == 0x0) throw;\n        if (punkIndexToAddress[punkIndex] == msg.sender) throw;\n        Bid bid = punkBids[punkIndex];\n        if (bid.bidder != msg.sender) throw;\n        PunkBidWithdrawn(punkIndex, bid.value, msg.sender);\n        uint amount = bid.value;\n        punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0);\n        // Refund the bid money\n        msg.sender.transfer(amount);\n    }\n\n}\n"
    }
  },
  "settings": {
    "optimizer": {
      "enabled": true,
      "runs": 200
    },
    "outputSelection": {
      "*": {
        "*": [
          "abi",
          "evm.bytecode.object",
          "evm.deployedBytecode.object",
          "metadata"
        ]
      }
    }
  }
}
