合约名称
NewWorld

合约账户余额
0 Ether

交易笔数
5503 txns

编译器版本
v0.4.19+commit.c4cbbb05

pragma solidity ^0.4.18;

library SafeMath {

  /**
  * @dev Multiplies two numbers, throws on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    if (a == 0) {
      return 0;
    }
    uint256 c = a * b;
    assert(c / a == b);
    return c;
  }

  /**
  * @dev Integer division of two numbers, truncating the quotient.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return c;
  }

  /**
  * @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  /**
  * @dev Adds two numbers, throws on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}


contract NewWorld {
  using SafeMath for uint256;
  /*** EVENTS ***/
  /// @dev The Birth event is fired whenever a new collectible comes into existence.
  event Birth(uint256 tokenId, uint256 startPrice);
  /// @dev The TokenSold event is fired whenever a token is sold.
  event TokenSold(uint256 indexed tokenId, uint256 price, address prevOwner, address winner);
  // ERC721 Transfer
  event Transfer(address indexed from, address indexed to, uint256 tokenId);
  // ERC721 Approval
  event Approval(address indexed owner, address indexed approved, uint256 tokenId);

  /*** CONSTANTS ***/

  string public constant NAME = "world-youCollect";
  string public constant SYMBOL = "WYC";
  uint256[] private tokens;

  /*** STORAGE ***/

  /// @dev A mapping from collectible IDs to the address that owns them. All collectibles have
  ///  some valid owner address.
  mapping (uint256 => address) public collectibleIndexToOwner;

  /// @dev A mapping from CollectibleIDs to an address that has been approved to call
  ///  transferFrom(). Each Collectible can only have one approved address for transfer
  ///  at any time. A zero value means no approval is outstanding.
  mapping (uint256 => address) public collectibleIndexToApproved;

  // @dev A mapping from CollectibleIDs to the price of the token.
  mapping (uint256 => uint256) public collectibleIndexToPrice;

  // The addresses of the accounts (or contracts) that can execute actions within each roles.
  address public ceoAddress;
  address public cooAddress;

  mapping (uint => address) private subTokenCreator;

  uint16 constant MAX_CONTINENT_INDEX = 10;
  uint16 constant MAX_SUBCONTINENT_INDEX = 100;
  uint16 constant MAX_COUNTRY_INDEX = 10000;
  uint64 constant DOUBLE_TOKENS_INDEX = 10000000000000;
  uint128 constant TRIBLE_TOKENS_INDEX = 10000000000000000000000;
  uint128 constant FIFTY_TOKENS_INDEX = 10000000000000000000000000000000;
  uint256 private constant PROMO_CREATION_LIMIT = 50000;
  uint256 public promoCreatedCount;
  uint8 constant WORLD_TOKEN_ID = 0;
  uint256 constant START_PRICE_CITY = 1 finney;
  uint256 constant START_PRICE_COUNTRY = 10 finney;
  uint256 constant START_PRICE_SUBCONTINENT = 100 finney;
  uint256 constant START_PRICE_CONTINENT = 1 ether;
  uint256 constant START_PRICE_WORLD = 10 ether;


  /*** CONSTRUCTOR ***/
  function NewWorld() public {
    ceoAddress = msg.sender;
    cooAddress = msg.sender;
  }
  function getTotalSupply() public view returns (uint) {
    return tokens.length;
  }
  function getInitialPriceOfToken(uint _tokenId) public pure returns (uint) {
    if (_tokenId > MAX_COUNTRY_INDEX)
      return START_PRICE_CITY;
    if (_tokenId > MAX_SUBCONTINENT_INDEX)
      return START_PRICE_COUNTRY;
    if (_tokenId > MAX_CONTINENT_INDEX)
      return START_PRICE_SUBCONTINENT;
    if (_tokenId > 0)
      return START_PRICE_CONTINENT;
    return START_PRICE_WORLD;
  }

  function getNextPrice(uint price, uint _tokenId) public pure returns (uint) {
    if (_tokenId>DOUBLE_TOKENS_INDEX)
      return price.mul(2);
    if (_tokenId>TRIBLE_TOKENS_INDEX)
      return price.mul(3);
    if (_tokenId>FIFTY_TOKENS_INDEX)
      return price.mul(3).div(2);
    if (price < 1.2 ether)
      return price.mul(200).div(92);
    if (price < 5 ether)
      return price.mul(150).div(92);
    return price.mul(120).div(92);
  }

  function buyToken(uint _tokenId) public payable {
    address oldOwner = collectibleIndexToOwner[_tokenId];
    require(oldOwner!=msg.sender);
    uint256 sellingPrice = collectibleIndexToPrice[_tokenId];
    if (sellingPrice==0) {
      sellingPrice = getInitialPriceOfToken(_tokenId);
      // if it is a new city or other subcountryToken, the creator is saved for rewards on later trades
      if (_tokenId>MAX_COUNTRY_INDEX)
        subTokenCreator[_tokenId] = msg.sender;
    }

    require(msg.value >= sellingPrice);
    uint256 purchaseExcess = msg.value.sub(sellingPrice);

    uint256 payment = sellingPrice.mul(92).div(100);
    uint256 feeOnce = sellingPrice.sub(payment).div(8);

    if (_tokenId > 0) {
      // Taxes for World owner
      if (collectibleIndexToOwner[WORLD_TOKEN_ID]!=address(0))
        collectibleIndexToOwner[WORLD_TOKEN_ID].transfer(feeOnce);
      if (_tokenId > MAX_CONTINENT_INDEX) {
        // Taxes for continent owner
        if (collectibleIndexToOwner[_tokenId % MAX_CONTINENT_INDEX]!=address(0))
          collectibleIndexToOwner[_tokenId % MAX_CONTINENT_INDEX].transfer(feeOnce);
        if (_tokenId > MAX_SUBCONTINENT_INDEX) {
          // Taxes for subcontinent owner
          if (collectibleIndexToOwner[_tokenId % MAX_SUBCONTINENT_INDEX]!=address(0))
            collectibleIndexToOwner[_tokenId % MAX_SUBCONTINENT_INDEX].transfer(feeOnce);
          if (_tokenId > MAX_COUNTRY_INDEX) {
            // Taxes for country owner
            if (collectibleIndexToOwner[_tokenId % MAX_COUNTRY_INDEX]!=address(0))
              collectibleIndexToOwner[_tokenId % MAX_COUNTRY_INDEX].transfer(feeOnce);
            // Taxes for city creator
            subTokenCreator[_tokenId].transfer(feeOnce);
          }
        }
      }
    }
    // Transfers the Token
    collectibleIndexToOwner[_tokenId] = msg.sender;
    if (oldOwner != address(0)) {
      // Payment for old owner
      oldOwner.transfer(payment);
      // clear any previously approved ownership exchange
      delete collectibleIndexToApproved[_tokenId];
    } else {
      Birth(_tokenId, sellingPrice);
      tokens.push(_tokenId);
    }
    // Update prices
    collectibleIndexToPrice[_tokenId] = getNextPrice(sellingPrice, _tokenId);

    TokenSold(_tokenId, sellingPrice, oldOwner, msg.sender);
    Transfer(oldOwner, msg.sender, _tokenId);
    // refund when paid too much
    if (purchaseExcess>0)
      msg.sender.transfer(purchaseExcess);
  }



  /*** ACCESS MODIFIERS ***/
  /// @dev Access modifier for CEO-only functionality
  modifier onlyCEO() {
    require(msg.sender == ceoAddress);
    _;
  }

  /// @dev Access modifier for COO-only functionality
  modifier onlyCOO() {
    require(msg.sender == cooAddress);
    _;
  }

  /// Access modifier for contract owner only functionality
  modifier onlyCLevel() {
    require(
      msg.sender == ceoAddress ||
      msg.sender == cooAddress
    );
    _;
  }

  /*** PUBLIC FUNCTIONS ***/
  /// @notice Grant another address the right to transfer token via takeOwnership() and transferFrom().
  /// @param _to The address to be granted transfer approval. Pass address(0) to
  ///  clear all approvals.
  /// @param _tokenId The ID of the Token that can be transferred if this call succeeds.
  /// @dev Required for ERC-721 compliance.
  function approve(
    address _to,
    uint256 _tokenId
  ) public {
    // Caller must own token.
    require(_owns(msg.sender, _tokenId));

    collectibleIndexToApproved[_tokenId] = _to;

    Approval(msg.sender, _to, _tokenId);
  }

  /// @dev Creates a new promo collectible with the given name, with given _price and assignes it to an address.
  function createPromoCollectible(uint256 tokenId, address _owner, uint256 _price) public onlyCOO {
    require(collectibleIndexToOwner[tokenId]==address(0));
    require(promoCreatedCount < PROMO_CREATION_LIMIT);

    address collectibleOwner = _owner;
    if (collectibleOwner == address(0)) {
      collectibleOwner = cooAddress;
    }

    if (_price <= 0) {
      _price = getInitialPriceOfToken(tokenId);
    }

    promoCreatedCount++;
    _createCollectible(tokenId, _price);
    // This will assign ownership, and also emit the Transfer event as
    // per ERC721 draft
    _transfer(address(0), collectibleOwner, tokenId);

  }

  bool isChangePriceLocked = true;
  // allows owners of tokens to decrease the price of them or if there is no owner the coo can do it
  function changePrice(uint256 newPrice, uint256 _tokenId) public {
    require((_owns(msg.sender, _tokenId) && !isChangePriceLocked) || (_owns(address(0), _tokenId) && msg.sender == cooAddress));
    require(newPrice
暂无注释