function buy (uint256 _auctionId, address _referral) payable public {
    NFTToken CNDERC721 = NFTToken(ERC721Contract);
    require(auctions[_auctionId].endTime > now);
    require(CNDERC721.ownerOf(auctions[_auctionId].monsterId) != address(0));
    require(ceil(msg.value) >= ceil(auctions[_auctionId].price + increaseRate));
    require(CNDERC721.ownerOf(auctions[_auctionId].monsterId) != msg.sender);
    require(!isContract(msg.sender));
    require(msg.sender != address(0));
    address oldOwner = CNDERC721.ownerOf(auctions[_auctionId].monsterId);
    address newOwner = msg.sender;
    uint256 oldPrice = auctions[_auctionId].price;
    uint256 price = ceil(msg.value);
    setGenes(price,auctions[_auctionId].monsterId);
    CNDERC721.transferAuction(oldOwner, newOwner, auctions[_auctionId].monsterId);
    auctions[_auctionId].price = ceil(price);
    auctions[_auctionId].bidder = msg.sender;
    DTT DTTtoken = DTT(dragonTreasureToken);
    if(masterToReferral[msg.sender] != address(0) && masterToReferral[msg.sender] != msg.sender){
      DTTtoken.approve(masterToReferral[msg.sender], DTTtoken.allowance(this,masterToReferral[msg.sender]) + (price - oldPrice) / 1000000000 * 5);
    }else if(_referral != address(0) && _referral != msg.sender){
      masterToReferral[msg.sender] = _referral;
      DTTtoken.approve(_referral, DTTtoken.allowance(this,_referral) + (price - oldPrice) / 1000000000 * 5);
    }

    DTTtoken.approve(msg.sender, DTTtoken.allowance(this,msg.sender) + (price - oldPrice) / 1000000000 * 5);
    if(oldPrice > 0)
      oldOwner.transfer(oldPrice);
    Bought(auctions[_auctionId].monsterId, newOwner, price);
    Sold(auctions[_auctionId].monsterId, oldOwner, price);
  }