github.com/diadata-org/diadata@v1.4.593/config/nftContracts/cryptopunk/cryptopunk.sol (about)

     1  /**
     2   *Submitted for verification at Etherscan.io on 2017-07-19
     3  */
     4  
     5  pragma solidity ^0.4.8;
     6  contract CryptoPunksMarket {
     7  
     8      // You can use this hash to verify the image file containing all the punks
     9      string public imageHash = "ac39af4793119ee46bbff351d8cb6b5f23da60222126add4268e261199a2921b";
    10  
    11      address owner;
    12  
    13      string public standard = 'CryptoPunks';
    14      string public name;
    15      string public symbol;
    16      uint8 public decimals;
    17      uint256 public totalSupply;
    18  
    19      uint public nextPunkIndexToAssign = 0;
    20  
    21      bool public allPunksAssigned = false;
    22      uint public punksRemainingToAssign = 0;
    23  
    24      //mapping (address => uint) public addressToPunkIndex;
    25      mapping (uint => address) public punkIndexToAddress;
    26  
    27      /* This creates an array with all balances */
    28      mapping (address => uint256) public balanceOf;
    29  
    30      struct Offer {
    31          bool isForSale;
    32          uint punkIndex;
    33          address seller;
    34          uint minValue;          // in ether
    35          address onlySellTo;     // specify to sell only to a specific person
    36      }
    37  
    38      struct Bid {
    39          bool hasBid;
    40          uint punkIndex;
    41          address bidder;
    42          uint value;
    43      }
    44  
    45      // A record of punks that are offered for sale at a specific minimum value, and perhaps to a specific person
    46      mapping (uint => Offer) public punksOfferedForSale;
    47  
    48      // A record of the highest punk bid
    49      mapping (uint => Bid) public punkBids;
    50  
    51      mapping (address => uint) public pendingWithdrawals;
    52  
    53      event Assign(address indexed to, uint256 punkIndex);
    54      event Transfer(address indexed from, address indexed to, uint256 value);
    55      event PunkTransfer(address indexed from, address indexed to, uint256 punkIndex);
    56      event PunkOffered(uint indexed punkIndex, uint minValue, address indexed toAddress);
    57      event PunkBidEntered(uint indexed punkIndex, uint value, address indexed fromAddress);
    58      event PunkBidWithdrawn(uint indexed punkIndex, uint value, address indexed fromAddress);
    59      event PunkBought(uint indexed punkIndex, uint value, address indexed fromAddress, address indexed toAddress);
    60      event PunkNoLongerForSale(uint indexed punkIndex);
    61  
    62      /* Initializes contract with initial supply tokens to the creator of the contract */
    63      function CryptoPunksMarket() payable {
    64          //        balanceOf[msg.sender] = initialSupply;              // Give the creator all initial tokens
    65          owner = msg.sender;
    66          totalSupply = 10000;                        // Update total supply
    67          punksRemainingToAssign = totalSupply;
    68          name = "CRYPTOPUNKS";                                   // Set the name for display purposes
    69          symbol = "ΟΎ";                               // Set the symbol for display purposes
    70          decimals = 0;                                       // Amount of decimals for display purposes
    71      }
    72  
    73      function setInitialOwner(address to, uint punkIndex) {
    74          if (msg.sender != owner) throw;
    75          if (allPunksAssigned) throw;
    76          if (punkIndex >= 10000) throw;
    77          if (punkIndexToAddress[punkIndex] != to) {
    78              if (punkIndexToAddress[punkIndex] != 0x0) {
    79                  balanceOf[punkIndexToAddress[punkIndex]]--;
    80              } else {
    81                  punksRemainingToAssign--;
    82              }
    83              punkIndexToAddress[punkIndex] = to;
    84              balanceOf[to]++;
    85              Assign(to, punkIndex);
    86          }
    87      }
    88  
    89      function setInitialOwners(address[] addresses, uint[] indices) {
    90          if (msg.sender != owner) throw;
    91          uint n = addresses.length;
    92          for (uint i = 0; i < n; i++) {
    93              setInitialOwner(addresses[i], indices[i]);
    94          }
    95      }
    96  
    97      function allInitialOwnersAssigned() {
    98          if (msg.sender != owner) throw;
    99          allPunksAssigned = true;
   100      }
   101  
   102      function getPunk(uint punkIndex) {
   103          if (!allPunksAssigned) throw;
   104          if (punksRemainingToAssign == 0) throw;
   105          if (punkIndexToAddress[punkIndex] != 0x0) throw;
   106          if (punkIndex >= 10000) throw;
   107          punkIndexToAddress[punkIndex] = msg.sender;
   108          balanceOf[msg.sender]++;
   109          punksRemainingToAssign--;
   110          Assign(msg.sender, punkIndex);
   111      }
   112  
   113      // Transfer ownership of a punk to another user without requiring payment
   114      function transferPunk(address to, uint punkIndex) {
   115          if (!allPunksAssigned) throw;
   116          if (punkIndexToAddress[punkIndex] != msg.sender) throw;
   117          if (punkIndex >= 10000) throw;
   118          if (punksOfferedForSale[punkIndex].isForSale) {
   119              punkNoLongerForSale(punkIndex);
   120          }
   121          punkIndexToAddress[punkIndex] = to;
   122          balanceOf[msg.sender]--;
   123          balanceOf[to]++;
   124          Transfer(msg.sender, to, 1);
   125          PunkTransfer(msg.sender, to, punkIndex);
   126          // Check for the case where there is a bid from the new owner and refund it.
   127          // Any other bid can stay in place.
   128          Bid bid = punkBids[punkIndex];
   129          if (bid.bidder == to) {
   130              // Kill bid and refund value
   131              pendingWithdrawals[to] += bid.value;
   132              punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0);
   133          }
   134      }
   135  
   136      function punkNoLongerForSale(uint punkIndex) {
   137          if (!allPunksAssigned) throw;
   138          if (punkIndexToAddress[punkIndex] != msg.sender) throw;
   139          if (punkIndex >= 10000) throw;
   140          punksOfferedForSale[punkIndex] = Offer(false, punkIndex, msg.sender, 0, 0x0);
   141          PunkNoLongerForSale(punkIndex);
   142      }
   143  
   144      function offerPunkForSale(uint punkIndex, uint minSalePriceInWei) {
   145          if (!allPunksAssigned) throw;
   146          if (punkIndexToAddress[punkIndex] != msg.sender) throw;
   147          if (punkIndex >= 10000) throw;
   148          punksOfferedForSale[punkIndex] = Offer(true, punkIndex, msg.sender, minSalePriceInWei, 0x0);
   149          PunkOffered(punkIndex, minSalePriceInWei, 0x0);
   150      }
   151  
   152      function offerPunkForSaleToAddress(uint punkIndex, uint minSalePriceInWei, address toAddress) {
   153          if (!allPunksAssigned) throw;
   154          if (punkIndexToAddress[punkIndex] != msg.sender) throw;
   155          if (punkIndex >= 10000) throw;
   156          punksOfferedForSale[punkIndex] = Offer(true, punkIndex, msg.sender, minSalePriceInWei, toAddress);
   157          PunkOffered(punkIndex, minSalePriceInWei, toAddress);
   158      }
   159  
   160      function buyPunk(uint punkIndex) payable {
   161          if (!allPunksAssigned) throw;
   162          Offer offer = punksOfferedForSale[punkIndex];
   163          if (punkIndex >= 10000) throw;
   164          if (!offer.isForSale) throw;                // punk not actually for sale
   165          if (offer.onlySellTo != 0x0 && offer.onlySellTo != msg.sender) throw;  // punk not supposed to be sold to this user
   166          if (msg.value < offer.minValue) throw;      // Didn't send enough ETH
   167          if (offer.seller != punkIndexToAddress[punkIndex]) throw; // Seller no longer owner of punk
   168  
   169          address seller = offer.seller;
   170  
   171          punkIndexToAddress[punkIndex] = msg.sender;
   172          balanceOf[seller]--;
   173          balanceOf[msg.sender]++;
   174          Transfer(seller, msg.sender, 1);
   175  
   176          punkNoLongerForSale(punkIndex);
   177          pendingWithdrawals[seller] += msg.value;
   178          PunkBought(punkIndex, msg.value, seller, msg.sender);
   179  
   180          // Check for the case where there is a bid from the new owner and refund it.
   181          // Any other bid can stay in place.
   182          Bid bid = punkBids[punkIndex];
   183          if (bid.bidder == msg.sender) {
   184              // Kill bid and refund value
   185              pendingWithdrawals[msg.sender] += bid.value;
   186              punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0);
   187          }
   188      }
   189  
   190      function withdraw() {
   191          if (!allPunksAssigned) throw;
   192          uint amount = pendingWithdrawals[msg.sender];
   193          // Remember to zero the pending refund before
   194          // sending to prevent re-entrancy attacks
   195          pendingWithdrawals[msg.sender] = 0;
   196          msg.sender.transfer(amount);
   197      }
   198  
   199      function enterBidForPunk(uint punkIndex) payable {
   200          if (punkIndex >= 10000) throw;
   201          if (!allPunksAssigned) throw;                
   202          if (punkIndexToAddress[punkIndex] == 0x0) throw;
   203          if (punkIndexToAddress[punkIndex] == msg.sender) throw;
   204          if (msg.value == 0) throw;
   205          Bid existing = punkBids[punkIndex];
   206          if (msg.value <= existing.value) throw;
   207          if (existing.value > 0) {
   208              // Refund the failing bid
   209              pendingWithdrawals[existing.bidder] += existing.value;
   210          }
   211          punkBids[punkIndex] = Bid(true, punkIndex, msg.sender, msg.value);
   212          PunkBidEntered(punkIndex, msg.value, msg.sender);
   213      }
   214  
   215      function acceptBidForPunk(uint punkIndex, uint minPrice) {
   216          if (punkIndex >= 10000) throw;
   217          if (!allPunksAssigned) throw;                
   218          if (punkIndexToAddress[punkIndex] != msg.sender) throw;
   219          address seller = msg.sender;
   220          Bid bid = punkBids[punkIndex];
   221          if (bid.value == 0) throw;
   222          if (bid.value < minPrice) throw;
   223  
   224          punkIndexToAddress[punkIndex] = bid.bidder;
   225          balanceOf[seller]--;
   226          balanceOf[bid.bidder]++;
   227          Transfer(seller, bid.bidder, 1);
   228  
   229          punksOfferedForSale[punkIndex] = Offer(false, punkIndex, bid.bidder, 0, 0x0);
   230          uint amount = bid.value;
   231          punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0);
   232          pendingWithdrawals[seller] += amount;
   233          PunkBought(punkIndex, bid.value, seller, bid.bidder);
   234      }
   235  
   236      function withdrawBidForPunk(uint punkIndex) {
   237          if (punkIndex >= 10000) throw;
   238          if (!allPunksAssigned) throw;                
   239          if (punkIndexToAddress[punkIndex] == 0x0) throw;
   240          if (punkIndexToAddress[punkIndex] == msg.sender) throw;
   241          Bid bid = punkBids[punkIndex];
   242          if (bid.bidder != msg.sender) throw;
   243          PunkBidWithdrawn(punkIndex, bid.value, msg.sender);
   244          uint amount = bid.value;
   245          punkBids[punkIndex] = Bid(false, punkIndex, 0x0, 0);
   246          // Refund the bid money
   247          msg.sender.transfer(amount);
   248      }
   249  
   250  }