ETH Price: $2,427.01 (-0.53%)

Transaction Decoder

Block:
22798867 at Jun-27-2025 10:51:23 PM +UTC
Transaction Fee:
0.000090309484472376 ETH $0.22
Gas Used:
137,332 Gas / 0.657599718 Gwei

Account State Difference:

  Address   Before After State Difference Code
(Titan Builder)
11.648448892451578431 Eth11.648473178959606135 Eth0.000024286508027704
0x4D96f2d2...86fa6ed55
0.079192633359277404 Eth
Nonce: 796
0.079102323874805028 Eth
Nonce: 797
0.000090309484472376
0x99502080...4f2659cA1
0xcf085b8D...Fc4B46B21 From: 0 To: 22892027083798243345887011238991163994727796301571201015

Execution Trace

0xcf085b8dc7c5acee93df07dbe6fa4abfc4b46b21.a516a5bf( )
  • TulipCore.transfer( _to=0x4D96f2d2143DD74A96D015a70953A5686fa6ed55, _tokenId=1641 )
  • TulipCore.transfer( _to=0x4D96f2d2143DD74A96D015a70953A5686fa6ed55, _tokenId=1640 )
    pragma solidity ^0.4.18;
    
    contract AccessControl {
      address public owner;
      address[] public admins;
    
      modifier onlyOwner {
        require(msg.sender == owner);
        _;
      }
    
      modifier onlyAdmins {
        bool found = false;
    
        for (uint i = 0; i < admins.length; i++) {
          if (admins[i] == msg.sender) {
            found = true;
            break;
          }
        }
    
        require(found);
        _;
      }
    
      function addAdmin(address _adminAddress) public onlyOwner {
        admins.push(_adminAddress);
      }
    }
    
    contract ERC721 {
        // Required Functions
        function implementsERC721() public pure returns (bool);
        function totalSupply() public view returns (uint256);
        function balanceOf(address _owner) public view returns (uint256);
        function ownerOf(uint256 _tokenId) public view returns (address);
        function transfer(address _to, uint _tokenId) public;
        function approve(address _to, uint256 _tokenId) public;
        function transferFrom(address _from, address _to, uint256 _tokenId) public;
    
        // Optional Functions
        function name() public pure returns (string);
        function symbol() public pure returns (string);
        function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256);
        // function tokenMetadata(uint256 _tokenId) public view returns (string infoUrl);
    
        // Required Events
        event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
        event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
    }
    
    contract TulipBase is AccessControl {
      struct Tulip {
        uint256 genes;
        uint256 createTime;
        bytes32 name;
      }
    
      Tulip[] public tulips;
      mapping (uint256 => address) public tulipToOwner;
      mapping (address => uint256[]) internal ownerToTulips;
      mapping (uint256 => address) public tulipToApproved;
    
      function _generateTulip(bytes32 _name, address _owner, uint16 _gen) internal returns (uint256 id) {
        id = tulips.length;
        uint256 createTime = block.timestamp;
    
        // Insecure RNG, but good enough for our purposes
        uint256 seed = uint(block.blockhash(block.number - 1)) + uint(block.blockhash(block.number - 100))
          + uint(block.coinbase) + createTime + id;
        uint256 traits = uint256(keccak256(seed));
        // last 16 bits are generation number
        uint256 genes = traits / 0x10000 * 0x10000 + _gen;
    
        Tulip memory newTulip = Tulip(genes, createTime, _name);
        tulips.push(newTulip);
        tulipToOwner[id] = _owner;
        ownerToTulips[_owner].push(id);
      }
    
      function _transferTulip(address _from, address _to, uint256 _id) internal {
        tulipToOwner[_id] = _to;
        ownerToTulips[_to].push(_id);
        tulipToApproved[_id] = address(0);
    
        uint256[] storage fromTulips = ownerToTulips[_from];
        for (uint256 i = 0; i < fromTulips.length; i++) {
          if (fromTulips[i] == _id) {
            break;
          }
        }
        assert(i < fromTulips.length);
    
        fromTulips[i] = fromTulips[fromTulips.length - 1];
        delete fromTulips[fromTulips.length - 1];
        fromTulips.length--;
      }
    }
    
    contract TulipToken is TulipBase, ERC721 {
    
      function implementsERC721() public pure returns (bool) {
        return true;
      }
    
      function totalSupply() public view returns (uint256) {
        return tulips.length;
      }
    
      function balanceOf(address _owner) public view returns (uint256 balance) {
        return ownerToTulips[_owner].length;
      }
    
      function ownerOf(uint256 _tokenId) public view returns (address owner) {
        owner = tulipToOwner[_tokenId];
        require(owner != address(0));
      }
    
      function transfer(address _to, uint256 _tokenId) public {
        require(_to != address(0));
        require(tulipToOwner[_tokenId] == msg.sender);
    
        _transferTulip(msg.sender, _to, _tokenId);
        Transfer(msg.sender, _to, _tokenId);
      }
    
      function approve(address _to, uint256 _tokenId) public {
        require(tulipToOwner[_tokenId] == msg.sender);
        tulipToApproved[_tokenId] = _to;
    
        Approval(msg.sender, _to, _tokenId);
      }
    
      function transferFrom(address _from, address _to, uint256 _tokenId) public {
        require(_to != address(0));
        require(tulipToApproved[_tokenId] == msg.sender);
        require(tulipToOwner[_tokenId] == _from);
    
        _transferTulip(_from, _to, _tokenId);
        Transfer(_from, _to, _tokenId);
      }
    
      function name() public pure returns (string) {
        return "Ether Tulips";
      }
    
      function symbol() public pure returns (string) {
        return "ETHT";
      }
    
      function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256) {
        require(_index < ownerToTulips[_owner].length);
        return ownerToTulips[_owner][_index];
      }
    
      // function tokenMetadata(uint256 _tokenId) public view returns (string infoUrl);
    }
    
    contract TulipSales is TulipToken {
      event Purchase(address indexed owner, uint256 unitPrice, uint32 amount);
    
      uint128 public increasePeriod = 6000; // around 1 day
      uint128 public startBlock;
      uint256[] public genToStartPrice;
      uint256[23] internal exp15;
    
      function TulipSales() public {
        startBlock = uint128(block.number);
        genToStartPrice.push(10 finney);
        _setExp15();
      }
    
      // The price increases from the starting price at a rate of 1.5x a day, until
      // a max of 10000x the original price. For gen 0, this corresponds to a cap
      // of 100 ETH.
      function price(uint16 _gen) public view returns (uint256) {
        require(_gen < genToStartPrice.length);
    
        uint128 periodsElapsed = (uint128(block.number) - startBlock) / increasePeriod;
        return _priceAtPeriod(periodsElapsed, _gen);
      }
    
      function nextPrice(uint16 _gen) public view returns (uint256 futurePrice, uint128 blocksRemaining, uint128 changeBlock) {
        require(_gen < genToStartPrice.length);
    
        uint128 periodsElapsed = (uint128(block.number) - startBlock) / increasePeriod;
        futurePrice = _priceAtPeriod(periodsElapsed + 1, _gen);
        blocksRemaining = increasePeriod - (uint128(block.number) - startBlock) % increasePeriod;
        changeBlock = uint128(block.number) + blocksRemaining;
      }
    
      function buyTulip(bytes32 _name, uint16 _gen) public payable returns (uint256 id) {
        require(_gen < genToStartPrice.length);
        require(msg.value == price(_gen));
    
        id = _generateTulip(_name, msg.sender, _gen);
        Transfer(address(0), msg.sender, id);
        Purchase(msg.sender, price(_gen), 1);
      }
    
      function buyTulips(uint32 _amount, uint16 _gen) public payable returns (uint256 firstId) {
        require(_gen < genToStartPrice.length);
        require(msg.value == price(_gen) * _amount);
        require(_amount <= 100);
    
        for (uint32 i = 0; i < _amount; i++) {
          uint256 id = _generateTulip("", msg.sender, _gen);
          Transfer(address(0), msg.sender, id);
    
          if (i == 0) {
            firstId = id;
          }
        }
        Purchase(msg.sender, price(_gen), _amount);
      }
    
      function renameTulip(uint256 _id, bytes32 _name) public {
        require(tulipToOwner[_id] == msg.sender);
    
        tulips[_id].name = _name;
      }
    
      function addGen(uint256 _startPrice) public onlyAdmins {
        require(genToStartPrice.length < 65535);
    
        genToStartPrice.push(_startPrice);
      }
    
      function withdrawBalance(uint256 _amount) external onlyAdmins {
        require(_amount <= this.balance);
    
        msg.sender.transfer(_amount);
      }
    
      function _priceAtPeriod(uint128 _period, uint16 _gen) internal view returns (uint256) {
        if (_period >= exp15.length) {
          return genToStartPrice[_gen] * 10000;
        } else {
          return genToStartPrice[_gen] * exp15[_period] / 1 ether;
        }
      }
    
      // Set 1 ETH * 1.5^i for 0 <= i <= 22 with 3 significant figures
      function _setExp15() internal {
        exp15 = [
          1000 finney,
          1500 finney,
          2250 finney,
          3380 finney,
          5060 finney,
          7590 finney,
          11400 finney,
          17100 finney,
          25600 finney,
          38400 finney,
          57700 finney,
          86500 finney,
          130 ether,
          195 ether,
          292 ether,
          438 ether,
          657 ether,
          985 ether,
          1480 ether,
          2220 ether,
          3330 ether,
          4990 ether,
          7480 ether
        ];
      }
    }
    
    contract TulipCore is TulipSales {
      event ContractUpgrade(address newContract);
      event MaintenanceUpdate(bool maintenance);
    
      bool public underMaintenance = false;
      bool public deprecated = false;
      address public newContractAddress;
    
      function TulipCore() public {
        owner = msg.sender;
      }
    
      function getTulip(uint256 _id) public view returns (
        uint256 genes,
        uint256 createTime,
        string name
      ) {
        Tulip storage tulip = tulips[_id];
        genes = tulip.genes;
        createTime = tulip.createTime;
    
        bytes memory byteArray = new bytes(32);
        for (uint8 i = 0; i < 32; i++) {
          byteArray[i] = tulip.name[i];
        }
        name = string(byteArray);
      }
    
      function myTulips() public view returns (uint256[]) {
        uint256[] memory tulipsMemory = ownerToTulips[msg.sender];
        return tulipsMemory;
      }
    
      function myTulipsBatched(uint256 _startIndex, uint16 _maxAmount) public view returns (
        uint256[] tulipIds,
        uint256 amountRemaining
      ) {
        uint256[] storage tulipArr = ownerToTulips[msg.sender];
        int256 j = int256(tulipArr.length) - 1 - int256(_startIndex);
        uint256 amount = _maxAmount;
    
        if (j < 0) {
          return (
            new uint256[](0),
            0
          );
        } else if (j + 1 < _maxAmount) {
          amount = uint256(j + 1);
        }
        uint256[] memory resultIds = new uint256[](amount);
    
        for (uint16 i = 0; i < amount; i++) {
          resultIds[i] = tulipArr[uint256(j)];
          j--;
        }
    
        return (
          resultIds,
          uint256(j+1)
        );
      }
    
      function setMaintenance(bool _underMaintenance) public onlyAdmins {
        underMaintenance = _underMaintenance;
        MaintenanceUpdate(underMaintenance);
      }
    
      function upgradeContract(address _newContractAddress) public onlyAdmins {
        newContractAddress = _newContractAddress;
        deprecated = true;
        ContractUpgrade(_newContractAddress);
      }
    }