Latest 25 transactions from a total of 32350 transactions

TxHash Age From To Value [TxFee]
0xb3bee1be097f0534ba4e9a06285945ac7309a1f5a5fb52cb2d13f0713f3d494122 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161169
0x077d7f8ec7c1a91ade0085f49882e03c4a90f512d76eb0ca3cc0f7108c3d674822 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161169
0x6db879478e8cbeeb7971daf712b73e69239b1141e1bd0d2c3cca6a6dc10bdd0322 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161233
0xb217f2c1d0414e2020c81fb06581e93dba941a8bde94868ba35478930cd2da3b22 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161233
0xf610a535755d7a7d509e73cdf4ea82c9287f6522a0957657aca828b5692e3d8a22 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161233
0xb3927a38d5eff486ee6801535fbf3c6a3e937d6639b2d545ed13b8c53d9c886922 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161233
0x9cb5cf3e85fe7aa610f964505e4801282ab7362808db03fc4ce3d619f327c4b622 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000031572
0x0726d8b3608e6f41c0ddbb1888f24a95a4a4cbc8dc929712bbd86515b68fb5a322 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000031572
0x58b7ee7b9f9c1a32d8c81ae42e16d76f769fbcc9fb48b836a3e8b4a49a7724dd22 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000031508
0x3326c76693f87da42b871b2d1cf035e98d89efcc66d28b1b155e5022a5dab80222 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000106454
0xaa7212b4ddc18b843f31422958f1d4439f8ebea3f205c41918aaf78c93ebfae822 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000106454
0x41e67d39ed805d3f5da71190c93c868af17ba48a13a0267182589ce1211b7c6e22 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000106454
0x4f32a4f075d9def5b7a76ece2cfb83c993fe5be0a1b9c86447ed7fe6f18e2b1422 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000106454
0x2b8900e594a413884e0328219aa8c2dc1b66c4c510e2157619089b0b174ec02722 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000106454
0xee1c9c867e75b658d781bfd2d0c295f359df385a547f67c47c1070839f0a323222 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000106454
0x32d64c8a66173ef2fb48af1777e994112757fb0d89987fc20a66e324b44c560922 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161233
0x88b141ddd05a318d499487d037671a5ce23be6b09968f56f1fb660af3e2b918e22 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161169
0x267b0414ea7f79a71a6dd7fdbad4adb636734c8e3e753968116d97b8a1ee670722 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000106454
0x3402924dd9729e9c0e25df36bf37ea3a2edf8d9eba2bda07030643a84fa09c7422 days 12 hrs ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000106454
0x184b298a45139f657a3544a1c2c6ae81f5150b9ba6867ca58cb69f549c8c2a7623 days 7 mins ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161169
0x631736f515ed96bed90ce0a036fd7ae4c83f58c0a4c13df3cca43684cc1e0edc23 days 7 mins ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161233
0x5a35984788ba6020fb077d49af9a6d7b4344cedf339d70fbf71a210b94a5c82623 days 7 mins ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161233
0xb21367d3c59599c32ef0230652b4ed7b527186a4f3657868764dc7b6ff3c59a323 days 7 mins ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161233
0xe6e0bedf5bbbe9c8a35b1475cfa181963d7671d875d56bebf1b07439d69eaddc23 days 7 mins ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161233
0xcc82141ec01dcfdba8f3419c409afd8c1902b6454336d6497929923fd24cde7d23 days 7 mins ago0xa9dcab43c4ef178c8d67f67e9c2fe722abc9de1b  IN   0x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether0.000161233
[ Download CSV Export  ] 
 Internal Transactions as a result of Contract Execution
 Latest 25 Internal Txns, Click here To View More View All
ParentTxHash Block Age From To Value
0xc91e8730d3930e4cd657c9c799e707caeed1c2aa1eb6082b88ee4a0182aec53f491181622 days 11 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0xc91e8730d3930e4cd657c9c799e707caeed1c2aa1eb6082b88ee4a0182aec53f491181622 days 11 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0xc91e8730d3930e4cd657c9c799e707caeed1c2aa1eb6082b88ee4a0182aec53f491181622 days 11 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0x41b7abf5d4e3170c257d9663bb6ba81965ad2553f5393d9f50f921f31815e6fb491181622 days 11 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0x41b7abf5d4e3170c257d9663bb6ba81965ad2553f5393d9f50f921f31815e6fb491181622 days 11 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0x41b7abf5d4e3170c257d9663bb6ba81965ad2553f5393d9f50f921f31815e6fb491181622 days 11 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0x390910bbaadec267bd21277e7325baaee74d201262ccfee0b806c4e5c2436d6e491181622 days 11 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0x390910bbaadec267bd21277e7325baaee74d201262ccfee0b806c4e5c2436d6e491181622 days 11 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0x390910bbaadec267bd21277e7325baaee74d201262ccfee0b806c4e5c2436d6e491181622 days 11 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0x35b82adc58c0550db956621bcfb27fe8f13fdbac06d278302a34b161b29d14b2491181522 days 11 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0x35b82adc58c0550db956621bcfb27fe8f13fdbac06d278302a34b161b29d14b2491181522 days 11 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0x35b82adc58c0550db956621bcfb27fe8f13fdbac06d278302a34b161b29d14b2491181522 days 11 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0xbf8c62e56aac894fe84938492013a381019dbe7e162a6e6299d71c4d702346f2491170822 days 12 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0xbf8c62e56aac894fe84938492013a381019dbe7e162a6e6299d71c4d702346f2491170822 days 12 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0xbf8c62e56aac894fe84938492013a381019dbe7e162a6e6299d71c4d702346f2491170822 days 12 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0x376048218abc608b1d6237b5b92d4c2735e54c66d5b0e275aa9de7cd6e93047d491170822 days 12 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0x376048218abc608b1d6237b5b92d4c2735e54c66d5b0e275aa9de7cd6e93047d491170822 days 12 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0x376048218abc608b1d6237b5b92d4c2735e54c66d5b0e275aa9de7cd6e93047d491170822 days 12 hrs ago0x880fc7d7b1b00d8ef5c313bf8e3aeba6530c7ff00x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0xb3bee1be097f0534ba4e9a06285945ac7309a1f5a5fb52cb2d13f0713f3d4941491163522 days 12 hrs ago0xbb12fb1b5f26e6b11d6846ab4070e1ec52cd88050x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0xb3bee1be097f0534ba4e9a06285945ac7309a1f5a5fb52cb2d13f0713f3d4941491163522 days 12 hrs ago0xbb12fb1b5f26e6b11d6846ab4070e1ec52cd88050x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0xb3bee1be097f0534ba4e9a06285945ac7309a1f5a5fb52cb2d13f0713f3d4941491163522 days 12 hrs ago0xbb12fb1b5f26e6b11d6846ab4070e1ec52cd88050x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0xb3bee1be097f0534ba4e9a06285945ac7309a1f5a5fb52cb2d13f0713f3d4941491163522 days 12 hrs ago0xbb12fb1b5f26e6b11d6846ab4070e1ec52cd88050x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0xb3bee1be097f0534ba4e9a06285945ac7309a1f5a5fb52cb2d13f0713f3d4941491163522 days 12 hrs ago0xbb12fb1b5f26e6b11d6846ab4070e1ec52cd88050x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0xb3bee1be097f0534ba4e9a06285945ac7309a1f5a5fb52cb2d13f0713f3d4941491163522 days 12 hrs ago0xbb12fb1b5f26e6b11d6846ab4070e1ec52cd88050x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
0xb3bee1be097f0534ba4e9a06285945ac7309a1f5a5fb52cb2d13f0713f3d4941491163522 days 12 hrs ago0xbb12fb1b5f26e6b11d6846ab4070e1ec52cd88050x9fd050f5584cfe07010c21b2c69b2f0674e6151b0 Ether
[ Download CSV Export  ] 
Warning: The Compiled Contract might be susceptible to ExpExponentCleanup (medium/high-severity), EventStructWrongData (very low-severity) SolidityCompiler Bugs.

Contract Source Code Verified (Exact Match)
Contract Name: LicenseNFTProxiable
Compiler Version: v0.4.24+commit.e67f0147
Optimization Enabled: No
Runs (Optimiser):  200



  Contract Source Code   Find Similiar Contracts

pragma solidity ^0.4.24;

// imported contracts/proposals/OCP-IP-4/Proxiable.sol
// imported contracts/access/roles/ProxyManagerRole.sol
// imported node_modules/openzeppelin-solidity/contracts/access/Roles.sol
/**
 * @title Roles
 * @dev Library for managing addresses assigned to a Role.
 */
library Roles {
  struct Role {
    mapping (address => bool) bearer;
  }
  /**
   * @dev give an account access to this role
   */
  function add(Role storage role, address account) internal {
    require(account != address(0));
    require(!has(role, account));
    role.bearer[account] = true;
  }
  /**
   * @dev remove an account's access to this role
   */
  function remove(Role storage role, address account) internal {
    require(account != address(0));
    require(has(role, account));
    role.bearer[account] = false;
  }
  /**
   * @dev check if an account has this role
   * @return bool
   */
  function has(Role storage role, address account)
    internal
    view
    returns (bool)
  {
    require(account != address(0));
    return role.bearer[account];
  }
}

contract ProxyManagerRole {
  using Roles for Roles.Role;
  event ProxyManagerAdded(address indexed account);
  event ProxyManagerRemoved(address indexed account);
  Roles.Role private proxyManagers;
  constructor() public {
    proxyManagers.add(msg.sender);
  }
  modifier onlyProxyManager() {
    require(isProxyManager(msg.sender));
    _;
  }
  function isProxyManager(address account) public view returns (bool) {
    return proxyManagers.has(account);
  }
  function addProxyManager(address account) public onlyProxyManager {
    proxyManagers.add(account);
    emit ProxyManagerAdded(account);
  }
  function renounceProxyManager() public {
    proxyManagers.remove(msg.sender);
  }
  function _removeProxyManager(address account) internal {
    proxyManagers.remove(account);
    emit ProxyManagerRemoved(account);
  }
}

// implementation from https://github.com/open-city-protocol/OCP-IPs/blob/master/OCP-IPs/ocp-ip-4.md
contract Proxiable is ProxyManagerRole {
  mapping(address => bool) private _globalProxies; // proxy -> valid
  mapping(address => mapping(address => bool)) private _senderProxies; // sender -> proxy -> valid
  event ProxyAdded(address indexed proxy, uint256 updatedAtUtcSec);
  event ProxyRemoved(address indexed proxy, uint256 updatedAtUtcSec);
  event ProxyForSenderAdded(address indexed proxy, address indexed sender, uint256 updatedAtUtcSec);
  event ProxyForSenderRemoved(address indexed proxy, address indexed sender, uint256 updatedAtUtcSec);
  modifier proxyOrSender(address claimedSender) {
    require(isProxyOrSender(claimedSender));
    _;
  }
  function isProxyOrSender(address claimedSender) public view returns (bool) {
    return msg.sender == claimedSender ||
    _globalProxies[msg.sender] ||
    _senderProxies[claimedSender][msg.sender];
  }
  function isProxy(address proxy) public view returns (bool) {
    return _globalProxies[proxy];
  }
  function isProxyForSender(address proxy, address sender) public view returns (bool) {
    return _senderProxies[sender][proxy];
  }
  function addProxy(address proxy) public onlyProxyManager {
    require(!_globalProxies[proxy]);
    _globalProxies[proxy] = true;
    emit ProxyAdded(proxy, now); // solhint-disable-line
  }
  function removeProxy(address proxy) public onlyProxyManager {
    require(_globalProxies[proxy]);
    delete _globalProxies[proxy];
    emit ProxyRemoved(proxy, now); // solhint-disable-line
  }
  function addProxyForSender(address proxy, address sender) public proxyOrSender(sender) {
    require(!_senderProxies[sender][proxy]);
    _senderProxies[sender][proxy] = true;
    emit ProxyForSenderAdded(proxy, sender, now); // solhint-disable-line
  }
  function removeProxyForSender(address proxy, address sender) public proxyOrSender(sender) {
    require(_senderProxies[sender][proxy]);
    delete _senderProxies[sender][proxy];
    emit ProxyForSenderRemoved(proxy, sender, now); // solhint-disable-line
  }
}

// imported contracts/proposals/OCP-IP-7/ILicenseNFTProxiable.sol
contract ILicenseNFTProxiable {
  function split(
    address tokenOwner,
    uint256 tokenId,
    uint256 secondTokenId,
    uint256 secondDurationSec
  ) public returns(bool);
  function merge(
    address tokenOwner,
    uint256 tokenId,
    uint256 secondTokenId
  ) public returns(bool);
  function setSealableProperty(
    address tokenOwner,
    uint256 tokenId,
    bytes32 key,
    bytes32 value
  ) public returns(bool);
  function seal(
    address dataStreamSealer,
    address tokenOwner,
    uint256 tokenId
  ) public returns(bool);
  function sealDataStream(
    address dataStreamSealer,
    address tokenOwner,
    uint256 tokenId,
    bytes32 dataStreamHash,
    uint256 startTimeUtcSec,
    bytes32 hashedDataStreamLicenseTerms
  ) public returns(bool);
}

// imported contracts/proposals/OCP-IP-7/LicenseNFT.sol
// imported contracts/proposals/OCP-IP-7/ILicenseNFT.sol
// imported node_modules/openzeppelin-solidity/contracts/token/ERC721/ERC721MetadataMintable.sol
// imported node_modules/openzeppelin-solidity/contracts/token/ERC721/ERC721Metadata.sol
// imported node_modules/openzeppelin-solidity/contracts/token/ERC721/ERC721.sol
// imported node_modules/openzeppelin-solidity/contracts/token/ERC721/IERC721.sol
// imported node_modules/openzeppelin-solidity/contracts/introspection/IERC165.sol
/**
 * @title IERC165
 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
 */
interface IERC165 {
  /**
   * @notice Query if a contract implements an interface
   * @param interfaceId The interface identifier, as specified in ERC-165
   * @dev Interface identification is specified in ERC-165. This function
   * uses less than 30,000 gas.
   */
  function supportsInterface(bytes4 interfaceId)
    external
    view
    returns (bool);
}

/**
 * @title ERC721 Non-Fungible Token Standard basic interface
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract IERC721 is IERC165 {
  event Transfer(
    address indexed from,
    address indexed to,
    uint256 indexed tokenId
  );
  event Approval(
    address indexed owner,
    address indexed approved,
    uint256 indexed tokenId
  );
  event ApprovalForAll(
    address indexed owner,
    address indexed operator,
    bool approved
  );
  function balanceOf(address owner) public view returns (uint256 balance);
  function ownerOf(uint256 tokenId) public view returns (address owner);
  function approve(address to, uint256 tokenId) public;
  function getApproved(uint256 tokenId)
    public view returns (address operator);
  function setApprovalForAll(address operator, bool _approved) public;
  function isApprovedForAll(address owner, address operator)
    public view returns (bool);
  function transferFrom(address from, address to, uint256 tokenId) public;
  function safeTransferFrom(address from, address to, uint256 tokenId)
    public;
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes data
  )
    public;
}

// imported node_modules/openzeppelin-solidity/contracts/token/ERC721/IERC721Receiver.sol
/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
contract IERC721Receiver {
  /**
   * @notice Handle the receipt of an NFT
   * @dev The ERC721 smart contract calls this function on the recipient
   * after a `safeTransfer`. This function MUST return the function selector,
   * otherwise the caller will revert the transaction. The selector to be
   * returned can be obtained as `this.onERC721Received.selector`. This
   * function MAY throw to revert and reject the transfer.
   * Note: the ERC721 contract address is always the message sender.
   * @param operator The address which called `safeTransferFrom` function
   * @param from The address which previously owned the token
   * @param tokenId The NFT identifier which is being transferred
   * @param data Additional data with no specified format
   * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
   */
  function onERC721Received(
    address operator,
    address from,
    uint256 tokenId,
    bytes data
  )
    public
    returns(bytes4);
}

// imported node_modules/openzeppelin-solidity/contracts/math/SafeMath.sol
/**
 * @title SafeMath
 * @dev Math operations with safety checks that revert on error
 */
library SafeMath {
  /**
  * @dev Multiplies two numbers, reverts on overflow.
  */
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
    // benefit is lost if 'b' is also tested.
    // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
    if (a == 0) {
      return 0;
    }
    uint256 c = a * b;
    require(c / a == b);
    return c;
  }
  /**
  * @dev Integer division of two numbers truncating the quotient, reverts on division by zero.
  */
  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b > 0); // Solidity only automatically asserts 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 Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend).
  */
  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b <= a);
    uint256 c = a - b;
    return c;
  }
  /**
  * @dev Adds two numbers, reverts on overflow.
  */
  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    require(c >= a);
    return c;
  }
  /**
  * @dev Divides two numbers and returns the remainder (unsigned integer modulo),
  * reverts when dividing by zero.
  */
  function mod(uint256 a, uint256 b) internal pure returns (uint256) {
    require(b != 0);
    return a % b;
  }
}

// imported node_modules/openzeppelin-solidity/contracts/utils/Address.sol
/**
 * Utility library of inline functions on addresses
 */
library Address {
  /**
   * Returns whether the target address is a contract
   * @dev This function will return false if invoked during the constructor of a contract,
   * as the code is not actually created until after the constructor finishes.
   * @param account address of the account to check
   * @return whether the target address is a contract
   */
  function isContract(address account) internal view returns (bool) {
    uint256 size;
    // XXX Currently there is no better way to check if there is a contract in an address
    // than to check the size of the code at that address.
    // See https://ethereum.stackexchange.com/a/14016/36603
    // for more details about how this works.
    // TODO Check this again before the Serenity release, because all addresses will be
    // contracts then.
    // solium-disable-next-line security/no-inline-assembly
    assembly { size := extcodesize(account) }
    return size > 0;
  }
}

// imported node_modules/openzeppelin-solidity/contracts/introspection/ERC165.sol
/**
 * @title ERC165
 * @author Matt Condon (@shrugs)
 * @dev Implements ERC165 using a lookup table.
 */
contract ERC165 is IERC165 {
  bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7;
  /**
   * 0x01ffc9a7 ===
   *   bytes4(keccak256('supportsInterface(bytes4)'))
   */
  /**
   * @dev a mapping of interface id to whether or not it's supported
   */
  mapping(bytes4 => bool) private _supportedInterfaces;
  /**
   * @dev A contract implementing SupportsInterfaceWithLookup
   * implement ERC165 itself
   */
  constructor()
    internal
  {
    _registerInterface(_InterfaceId_ERC165);
  }
  /**
   * @dev implement supportsInterface(bytes4) using a lookup table
   */
  function supportsInterface(bytes4 interfaceId)
    external
    view
    returns (bool)
  {
    return _supportedInterfaces[interfaceId];
  }
  /**
   * @dev internal method for registering an interface
   */
  function _registerInterface(bytes4 interfaceId)
    internal
  {
    require(interfaceId != 0xffffffff);
    _supportedInterfaces[interfaceId] = true;
  }
}

/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract ERC721 is ERC165, IERC721 {
  using SafeMath for uint256;
  using Address for address;
  // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
  // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
  bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;
  // Mapping from token ID to owner
  mapping (uint256 => address) private _tokenOwner;
  // Mapping from token ID to approved address
  mapping (uint256 => address) private _tokenApprovals;
  // Mapping from owner to number of owned token
  mapping (address => uint256) private _ownedTokensCount;
  // Mapping from owner to operator approvals
  mapping (address => mapping (address => bool)) private _operatorApprovals;
  bytes4 private constant _InterfaceId_ERC721 = 0x80ac58cd;
  /*
   * 0x80ac58cd ===
   *   bytes4(keccak256('balanceOf(address)')) ^
   *   bytes4(keccak256('ownerOf(uint256)')) ^
   *   bytes4(keccak256('approve(address,uint256)')) ^
   *   bytes4(keccak256('getApproved(uint256)')) ^
   *   bytes4(keccak256('setApprovalForAll(address,bool)')) ^
   *   bytes4(keccak256('isApprovedForAll(address,address)')) ^
   *   bytes4(keccak256('transferFrom(address,address,uint256)')) ^
   *   bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
   *   bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
   */
  constructor()
    public
  {
    // register the supported interfaces to conform to ERC721 via ERC165
    _registerInterface(_InterfaceId_ERC721);
  }
  /**
   * @dev Gets the balance of the specified address
   * @param owner address to query the balance of
   * @return uint256 representing the amount owned by the passed address
   */
  function balanceOf(address owner) public view returns (uint256) {
    require(owner != address(0));
    return _ownedTokensCount[owner];
  }
  /**
   * @dev Gets the owner of the specified token ID
   * @param tokenId uint256 ID of the token to query the owner of
   * @return owner address currently marked as the owner of the given token ID
   */
  function ownerOf(uint256 tokenId) public view returns (address) {
    address owner = _tokenOwner[tokenId];
    require(owner != address(0));
    return owner;
  }
  /**
   * @dev Approves another address to transfer the given token ID
   * The zero address indicates there is no approved address.
   * There can only be one approved address per token at a given time.
   * Can only be called by the token owner or an approved operator.
   * @param to address to be approved for the given token ID
   * @param tokenId uint256 ID of the token to be approved
   */
  function approve(address to, uint256 tokenId) public {
    address owner = ownerOf(tokenId);
    require(to != owner);
    require(msg.sender == owner || isApprovedForAll(owner, msg.sender));
    _tokenApprovals[tokenId] = to;
    emit Approval(owner, to, tokenId);
  }
  /**
   * @dev Gets the approved address for a token ID, or zero if no address set
   * Reverts if the token ID does not exist.
   * @param tokenId uint256 ID of the token to query the approval of
   * @return address currently approved for the given token ID
   */
  function getApproved(uint256 tokenId) public view returns (address) {
    require(_exists(tokenId));
    return _tokenApprovals[tokenId];
  }
  /**
   * @dev Sets or unsets the approval of a given operator
   * An operator is allowed to transfer all tokens of the sender on their behalf
   * @param to operator address to set the approval
   * @param approved representing the status of the approval to be set
   */
  function setApprovalForAll(address to, bool approved) public {
    require(to != msg.sender);
    _operatorApprovals[msg.sender][to] = approved;
    emit ApprovalForAll(msg.sender, to, approved);
  }
  /**
   * @dev Tells whether an operator is approved by a given owner
   * @param owner owner address which you want to query the approval of
   * @param operator operator address which you want to query the approval of
   * @return bool whether the given operator is approved by the given owner
   */
  function isApprovedForAll(
    address owner,
    address operator
  )
    public
    view
    returns (bool)
  {
    return _operatorApprovals[owner][operator];
  }
  /**
   * @dev Transfers the ownership of a given token ID to another address
   * Usage of this method is discouraged, use `safeTransferFrom` whenever possible
   * Requires the msg sender to be the owner, approved, or operator
   * @param from current owner of the token
   * @param to address to receive the ownership of the given token ID
   * @param tokenId uint256 ID of the token to be transferred
  */
  function transferFrom(
    address from,
    address to,
    uint256 tokenId
  )
    public
  {
    require(_isApprovedOrOwner(msg.sender, tokenId));
    require(to != address(0));
    _clearApproval(from, tokenId);
    _removeTokenFrom(from, tokenId);
    _addTokenTo(to, tokenId);
    emit Transfer(from, to, tokenId);
  }
  /**
   * @dev Safely transfers the ownership of a given token ID to another address
   * If the target address is a contract, it must implement `onERC721Received`,
   * which is called upon a safe transfer, and return the magic value
   * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
   * the transfer is reverted.
   *
   * Requires the msg sender to be the owner, approved, or operator
   * @param from current owner of the token
   * @param to address to receive the ownership of the given token ID
   * @param tokenId uint256 ID of the token to be transferred
  */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId
  )
    public
  {
    // solium-disable-next-line arg-overflow
    safeTransferFrom(from, to, tokenId, "");
  }
  /**
   * @dev Safely transfers the ownership of a given token ID to another address
   * If the target address is a contract, it must implement `onERC721Received`,
   * which is called upon a safe transfer, and return the magic value
   * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
   * the transfer is reverted.
   * Requires the msg sender to be the owner, approved, or operator
   * @param from current owner of the token
   * @param to address to receive the ownership of the given token ID
   * @param tokenId uint256 ID of the token to be transferred
   * @param _data bytes data to send along with a safe transfer check
   */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes _data
  )
    public
  {
    transferFrom(from, to, tokenId);
    // solium-disable-next-line arg-overflow
    require(_checkOnERC721Received(from, to, tokenId, _data));
  }
  /**
   * @dev Returns whether the specified token exists
   * @param tokenId uint256 ID of the token to query the existence of
   * @return whether the token exists
   */
  function _exists(uint256 tokenId) internal view returns (bool) {
    address owner = _tokenOwner[tokenId];
    return owner != address(0);
  }
  /**
   * @dev Returns whether the given spender can transfer a given token ID
   * @param spender address of the spender to query
   * @param tokenId uint256 ID of the token to be transferred
   * @return bool whether the msg.sender is approved for the given token ID,
   *  is an operator of the owner, or is the owner of the token
   */
  function _isApprovedOrOwner(
    address spender,
    uint256 tokenId
  )
    internal
    view
    returns (bool)
  {
    address owner = ownerOf(tokenId);
    // Disable solium check because of
    // https://github.com/duaraghav8/Solium/issues/175
    // solium-disable-next-line operator-whitespace
    return (
      spender == owner ||
      getApproved(tokenId) == spender ||
      isApprovedForAll(owner, spender)
    );
  }
  /**
   * @dev Internal function to mint a new token
   * Reverts if the given token ID already exists
   * @param to The address that will own the minted token
   * @param tokenId uint256 ID of the token to be minted by the msg.sender
   */
  function _mint(address to, uint256 tokenId) internal {
    require(to != address(0));
    _addTokenTo(to, tokenId);
    emit Transfer(address(0), to, tokenId);
  }
  /**
   * @dev Internal function to burn a specific token
   * Reverts if the token does not exist
   * @param tokenId uint256 ID of the token being burned by the msg.sender
   */
  function _burn(address owner, uint256 tokenId) internal {
    _clearApproval(owner, tokenId);
    _removeTokenFrom(owner, tokenId);
    emit Transfer(owner, address(0), tokenId);
  }
  /**
   * @dev Internal function to add a token ID to the list of a given address
   * Note that this function is left internal to make ERC721Enumerable possible, but is not
   * intended to be called by custom derived contracts: in particular, it emits no Transfer event.
   * @param to address representing the new owner of the given token ID
   * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
   */
  function _addTokenTo(address to, uint256 tokenId) internal {
    require(_tokenOwner[tokenId] == address(0));
    _tokenOwner[tokenId] = to;
    _ownedTokensCount[to] = _ownedTokensCount[to].add(1);
  }
  /**
   * @dev Internal function to remove a token ID from the list of a given address
   * Note that this function is left internal to make ERC721Enumerable possible, but is not
   * intended to be called by custom derived contracts: in particular, it emits no Transfer event,
   * and doesn't clear approvals.
   * @param from address representing the previous owner of the given token ID
   * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
   */
  function _removeTokenFrom(address from, uint256 tokenId) internal {
    require(ownerOf(tokenId) == from);
    _ownedTokensCount[from] = _ownedTokensCount[from].sub(1);
    _tokenOwner[tokenId] = address(0);
  }
  /**
   * @dev Internal function to invoke `onERC721Received` on a target address
   * The call is not executed if the target address is not a contract
   * @param from address representing the previous owner of the given token ID
   * @param to target address that will receive the tokens
   * @param tokenId uint256 ID of the token to be transferred
   * @param _data bytes optional data to send along with the call
   * @return whether the call correctly returned the expected magic value
   */
  function _checkOnERC721Received(
    address from,
    address to,
    uint256 tokenId,
    bytes _data
  )
    internal
    returns (bool)
  {
    if (!to.isContract()) {
      return true;
    }
    bytes4 retval = IERC721Receiver(to).onERC721Received(
      msg.sender, from, tokenId, _data);
    return (retval == _ERC721_RECEIVED);
  }
  /**
   * @dev Private function to clear current approval of a given token ID
   * Reverts if the given address is not indeed the owner of the token
   * @param owner owner of the token
   * @param tokenId uint256 ID of the token to be transferred
   */
  function _clearApproval(address owner, uint256 tokenId) private {
    require(ownerOf(tokenId) == owner);
    if (_tokenApprovals[tokenId] != address(0)) {
      _tokenApprovals[tokenId] = address(0);
    }
  }
}

// imported node_modules/openzeppelin-solidity/contracts/token/ERC721/IERC721Metadata.sol
/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
 */
contract IERC721Metadata is IERC721 {
  function name() external view returns (string);
  function symbol() external view returns (string);
  function tokenURI(uint256 tokenId) external view returns (string);
}

contract ERC721Metadata is ERC165, ERC721, IERC721Metadata {
  // Token name
  string private _name;
  // Token symbol
  string private _symbol;
  // Optional mapping for token URIs
  mapping(uint256 => string) private _tokenURIs;
  bytes4 private constant InterfaceId_ERC721Metadata = 0x5b5e139f;
  /**
   * 0x5b5e139f ===
   *   bytes4(keccak256('name()')) ^
   *   bytes4(keccak256('symbol()')) ^
   *   bytes4(keccak256('tokenURI(uint256)'))
   */
  /**
   * @dev Constructor function
   */
  constructor(string name, string symbol) public {
    _name = name;
    _symbol = symbol;
    // register the supported interfaces to conform to ERC721 via ERC165
    _registerInterface(InterfaceId_ERC721Metadata);
  }
  /**
   * @dev Gets the token name
   * @return string representing the token name
   */
  function name() external view returns (string) {
    return _name;
  }
  /**
   * @dev Gets the token symbol
   * @return string representing the token symbol
   */
  function symbol() external view returns (string) {
    return _symbol;
  }
  /**
   * @dev Returns an URI for a given token ID
   * Throws if the token ID does not exist. May return an empty string.
   * @param tokenId uint256 ID of the token to query
   */
  function tokenURI(uint256 tokenId) external view returns (string) {
    require(_exists(tokenId));
    return _tokenURIs[tokenId];
  }
  /**
   * @dev Internal function to set the token URI for a given token
   * Reverts if the token ID does not exist
   * @param tokenId uint256 ID of the token to set its URI
   * @param uri string URI to assign
   */
  function _setTokenURI(uint256 tokenId, string uri) internal {
    require(_exists(tokenId));
    _tokenURIs[tokenId] = uri;
  }
  /**
   * @dev Internal function to burn a specific token
   * Reverts if the token does not exist
   * @param owner owner of the token to burn
   * @param tokenId uint256 ID of the token being burned by the msg.sender
   */
  function _burn(address owner, uint256 tokenId) internal {
    super._burn(owner, tokenId);
    // Clear metadata (if any)
    if (bytes(_tokenURIs[tokenId]).length != 0) {
      delete _tokenURIs[tokenId];
    }
  }
}

// imported node_modules/openzeppelin-solidity/contracts/access/roles/MinterRole.sol
contract MinterRole {
  using Roles for Roles.Role;
  event MinterAdded(address indexed account);
  event MinterRemoved(address indexed account);
  Roles.Role private minters;
  constructor() internal {
    _addMinter(msg.sender);
  }
  modifier onlyMinter() {
    require(isMinter(msg.sender));
    _;
  }
  function isMinter(address account) public view returns (bool) {
    return minters.has(account);
  }
  function addMinter(address account) public onlyMinter {
    _addMinter(account);
  }
  function renounceMinter() public {
    _removeMinter(msg.sender);
  }
  function _addMinter(address account) internal {
    minters.add(account);
    emit MinterAdded(account);
  }
  function _removeMinter(address account) internal {
    minters.remove(account);
    emit MinterRemoved(account);
  }
}

/**
 * @title ERC721MetadataMintable
 * @dev ERC721 minting logic with metadata
 */
contract ERC721MetadataMintable is ERC721, ERC721Metadata, MinterRole {
  /**
   * @dev Function to mint tokens
   * @param to The address that will receive the minted tokens.
   * @param tokenId The token id to mint.
   * @param tokenURI The token URI of the minted token.
   * @return A boolean that indicates if the operation was successful.
   */
  function mintWithTokenURI(
    address to,
    uint256 tokenId,
    string tokenURI
  )
    public
    onlyMinter
    returns (bool)
  {
    _mint(to, tokenId);
    _setTokenURI(tokenId, tokenURI);
    return true;
  }
}

// imported contracts/proposals/OCP-IP-7/ILicenseNFTDataStream.sol
contract ILicenseNFTDataStream {
  // mintable keys
  // keccak256(abi.encodePacked("licenseTerms"))
  bytes32 public constant LICENSE_TERMS_KEY = 0xb275e7ea4f8ae6075626a6bc37c558f4265ba49512523cf4d68c05b249cf20b9;
  // keccak256(abi.encodePacked("schema"))
  bytes32 public constant SCHEMA_KEY = 0xa91efd13169e3bceace525b23b7f968b3cc611248271e35f04c5c917311fc7f7;
  // sealable keys
  // keccak256(abi.encodePacked("dataStreamHash"))
  bytes32 public constant DATA_STREAM_HASH_KEY = 0xa0aa0714617b83af6568cf05c25404b309565ed9fdda7f53f4f6f60105eb0337;
  // keccak256(abi.encodePacked("hashedDataStreamLicenseTerms"))
  bytes32 public constant HASHED_DATA_STREAM_LICENSE_TERMS_KEY = 0x5fbb821d7c8660396e9025a6eae37db36accc5621c22f0bc3e7f6ce9ea20a9b8;
  // keccak256(abi.encodePacked("startTimeUtcSec"))
  bytes32 public constant START_TIME_UTC_SEC_KEY = 0xf3f6170cfbf7600c536f76f63bd1f6cd1df950659eea69fca42323a7b8918538;
  function mintDataStream(
    address to,
    uint256 tokenId,
    bytes32 schema,
    bytes32 licenseTerms,
    uint256 durationSec
  ) public returns(bool);
  function sealDataStream(
    address dataStreamSealer,
    uint256 tokenId,
    bytes32 dataStreamHash,
    uint256 startTimeUtcSec,
    bytes32 hashedDataStreamLicenseTerms
  ) public returns(bool);
}

contract ILicenseNFT is ERC721MetadataMintable, ILicenseNFTDataStream {
  // keccak256(abi.encodePacked("splitParent"))
  bytes32 public constant SPLIT_PARENT_KEY = 0x82f1bb612577f02f2d28d75a6004227778388d11803f2c7faa961f947a84c847;
  // keccak256(abi.encodePacked("durationSec"))
  bytes32 public constant DURATION_SEC_KEY = 0x3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c;
  // keccak256(abi.encodePacked("bidHash"))
  bytes32 public constant BID_HASH_KEY = 0x4eba03e4695ef490bd0d99b2e8fa2d0aa4c54ddfc1a74b32febd9142981e7176;
  event Sealed(uint256 tokenId);
  function mintableProperties(uint256 tokenId, bytes32 key) public view returns(bytes32);
  function sealableProperties(uint256 tokenId, bytes32 key) public view returns(bytes32);
  function tokenSealer(uint256 tokenId) public view returns(address);
  function setMintableProperty(
    uint256 tokenId,
    bytes32 key,
    bytes32 value
  ) public returns(bool);
  function split(uint256 tokenId, uint256 secondTokenId, uint256 secondDuration) public returns(bool);
  function merge(uint256 tokenId, uint256 secondTokenId) public returns(bool);
  function setSealableProperty(
    uint256 tokenId,
    bytes32 key,
    bytes32 value
  ) public returns(bool);
  function seal(address dataStreamSealer, uint256 tokenId) public returns(bool);
  function mint(address to, uint256 tokenId) public returns (bool);
}

// imported contracts/proposals/OCP-IP-7/ILicenseNFTSealer.sol
contract ILicenseNFTSealer {
   // @return `bytes4(keccak256("onSealed(address,address,uint256)"))`
  function onSealed(address licenseNFT, address tokenOwner, uint256 tokenId) public returns(bytes4);
}

contract LicenseNFT is ILicenseNFT {
  event Sealed(uint256 tokenId);
  string private constant NFT_NAME = "Open City License NFT";
  string private constant NFT_SYMBOL = "OCL";
  // Mapping from token ID to key to value
  mapping(uint256 => mapping(bytes32 => bytes32)) private _mintableProperties;
  mapping(uint256 => mapping(bytes32 => bytes32)) private _sealableProperties;
  // Mapping from token Id to sealer address
  mapping(uint256 => address) private _tokenSealer;
  // `bytes4(keccak256("onSealed(address,address,uint256)"))`
  bytes4 private constant LICENSENFT_SEALED = 0x8f3de282;
  modifier onlyTokenOwner(uint256 tokenId) {
    require(ownerOf(tokenId) == msg.sender);
    _;
  }
  // solhint-disable-next-line
  constructor() public ERC721Metadata(NFT_NAME, NFT_SYMBOL) {}
  function mintableProperties(uint256 tokenId, bytes32 key) public view returns(bytes32) {
    uint256 splitParent = uint256(_mintableProperties[tokenId][SPLIT_PARENT_KEY]);
    if (splitParent == 0 || key == SPLIT_PARENT_KEY || key == DURATION_SEC_KEY) {
      return _mintableProperties[tokenId][key];
    } else {
      return _mintableProperties[splitParent][key];
    }
  }
  function sealableProperties(uint256 tokenId, bytes32 key) public view returns(bytes32) {
    return _sealableProperties[tokenId][key];
  }
  function tokenSealer(uint256 tokenId) public view returns(address) {
    return _tokenSealer[tokenId];
  }
  function transferFrom(address, address, uint256) public {
    revert();
  }
  function setMintableProperty(
    uint256 tokenId,
    bytes32 key,
    bytes32 value
  ) public onlyMinter returns(bool) {
    return _setMintableProperty(tokenId, key, value);
  }
  function split(
    uint256 tokenId,
    uint256 secondTokenId,
    uint256 secondDurationSec
  ) public onlyTokenOwner(tokenId) returns(bool) {
    return _split(tokenId, secondTokenId, secondDurationSec);
  }
  function merge(
    uint256 firstTokenId,
    uint256 secondTokenId
  ) public onlyTokenOwner(firstTokenId) onlyTokenOwner(secondTokenId) returns(bool) {
    return _merge(firstTokenId, secondTokenId);
  }
  function setSealableProperty(
    uint256 tokenId,
    bytes32 key,
    bytes32 value
  ) public onlyTokenOwner(tokenId) returns(bool) {
    return _setSealableProperty(tokenId, key, value);
  }
  function seal(
    address dataStreamSealer,
    uint256 tokenId
  ) public onlyTokenOwner(tokenId) returns(bool) {
    return _seal(dataStreamSealer, msg.sender, tokenId);
  }
  function sealDataStream(
    address dataStreamSealer,
    uint256 tokenId,
    bytes32 dataStreamHash,
    uint256 startTimeUtcSec,
    bytes32 hashedDataStreamLicenseTerms
  ) public onlyTokenOwner(tokenId) returns(bool) {
    return _sealDataStream(
      dataStreamSealer,
      msg.sender,
      tokenId,
      dataStreamHash,
      startTimeUtcSec,
      hashedDataStreamLicenseTerms
    );
  }
  function mint(address to, uint256 tokenId) public onlyMinter returns (bool) {
    _mint(to, tokenId);
    return true;
  }
  function mintDataStream(
    address to,
    uint256 tokenId,
    bytes32 schema,
    bytes32 licenseTerms,
    uint256 durationSec
  ) public onlyMinter returns(bool) {
    return _mintDataStream(to, tokenId, schema, licenseTerms, durationSec);
  }
  function _mintDataStream(
    address to,
    uint256 tokenId,
    bytes32 schema,
    bytes32 licenseTerms,
    uint256 durationSec
  ) internal returns(bool) {
    _setMintableProperty(tokenId, SCHEMA_KEY, schema);
    _setMintableProperty(tokenId, LICENSE_TERMS_KEY, licenseTerms);
    _setMintableProperty(tokenId, DURATION_SEC_KEY, bytes32(durationSec));
    _mint(to, tokenId);
    return true;
  }
  function _setMintableProperty(uint256 tokenId, bytes32 key, bytes32 value) internal returns(bool) {
    require(!_exists(tokenId));
    _mintableProperties[tokenId][key] = value;
    return true;
  }
  function _split(
    uint256 tokenId,
    uint256 secondTokenId,
    uint256 secondDurationSec
  ) internal returns(bool) {
    require(_exists(tokenId) && !_exists(secondTokenId));
    require(_tokenSealer[tokenId] == 0);
    require(_mintableProperties[secondTokenId][DURATION_SEC_KEY] == 0);
    require(_mintableProperties[secondTokenId][SPLIT_PARENT_KEY] == 0);
    uint256 durationSec = uint256(_mintableProperties[tokenId][DURATION_SEC_KEY]);
    require(secondDurationSec < durationSec);
    uint256 firstDurationSec = durationSec - secondDurationSec;
    _mintableProperties[tokenId][DURATION_SEC_KEY] = bytes32(firstDurationSec);
    _mintableProperties[secondTokenId][DURATION_SEC_KEY] = bytes32(secondDurationSec);
    bytes32 splitParent = _mintableProperties[tokenId][SPLIT_PARENT_KEY];
    if (splitParent == 0) {
      splitParent = bytes32(tokenId);
    }
    _mintableProperties[secondTokenId][SPLIT_PARENT_KEY] = splitParent;
    _mint(ownerOf(tokenId), secondTokenId);
    return true;
  }
  function _merge(uint256 tokenId, uint256 secondTokenId) internal returns(bool) {
    require(tokenId != secondTokenId);
    require(ownerOf(tokenId) == ownerOf(secondTokenId));
    require(_tokenSealer[tokenId] == 0 && _tokenSealer[secondTokenId] == 0);
    bytes32 firstSplitParent = _mintableProperties[tokenId][SPLIT_PARENT_KEY];
    bytes32 secondSplitParent = _mintableProperties[secondTokenId][SPLIT_PARENT_KEY];
    require(secondSplitParent != 0);
    require(bytes32(tokenId) == secondSplitParent || firstSplitParent == secondSplitParent);
    uint256 firstDurationSec = uint256(_mintableProperties[tokenId][DURATION_SEC_KEY]);
    uint256 secondDurationSec = uint256(_mintableProperties[secondTokenId][DURATION_SEC_KEY]);
    uint256 totalDuration = firstDurationSec + secondDurationSec;
    _mintableProperties[secondTokenId][DURATION_SEC_KEY] = 0x0;
    _mintableProperties[tokenId][DURATION_SEC_KEY] = bytes32(totalDuration);
    _burn(ownerOf(secondTokenId), secondTokenId);
    return true;
  }
  function _burn(address owner, uint256 tokenId) internal {
    require(_exists(tokenId));
    delete _mintableProperties[tokenId][SPLIT_PARENT_KEY];
    delete _mintableProperties[tokenId][DURATION_SEC_KEY];
    delete _tokenSealer[tokenId];
    require(ownerOf(tokenId) == owner);
    require(1 <= balanceOf(owner));
    super._burn(owner, tokenId);
  }
  function _setSealableProperty(
    uint256 tokenId,
    bytes32 key,
    bytes32 value
  ) internal returns(bool) {
    require(_tokenSealer[tokenId] == 0x0);
    _sealableProperties[tokenId][key] = value;
    return true;
  }
  function _seal(
    address dataStreamSealer,
    address tokenOwner,
    uint256 tokenId
  ) internal returns(bool) {
    require(_tokenSealer[tokenId] == 0x0);
    _tokenSealer[tokenId] = dataStreamSealer;
    require(_checkSeal(this, dataStreamSealer, tokenOwner, tokenId));
    emit Sealed(tokenId);
    return true;
  }
  function _checkSeal(
    address licenseNFT,
    address sealer,
    address tokenOwner,
    uint256 tokenId
  ) internal returns(bool) {
    bytes4 retval = ILicenseNFTSealer(sealer).onSealed(licenseNFT, tokenOwner, tokenId);
    return (retval == LICENSENFT_SEALED);
  }
  function _sealDataStream(
    address dataStreamSealer,
    address tokenOwner,
    uint256 tokenId,
    bytes32 dataStreamHash,
    uint256 startTimeUtcSec,
    bytes32 hashedDataStreamLicenseTerms
  ) internal returns(bool) {
    _setSealableProperty(tokenId, DATA_STREAM_HASH_KEY, dataStreamHash);
    _setSealableProperty(tokenId, START_TIME_UTC_SEC_KEY, bytes32(startTimeUtcSec));
    _setSealableProperty(tokenId, HASHED_DATA_STREAM_LICENSE_TERMS_KEY, hashedDataStreamLicenseTerms);
    return _seal(dataStreamSealer, tokenOwner, tokenId);
  }
}

contract LicenseNFTProxiable is ILicenseNFTProxiable, LicenseNFT, Proxiable {
  modifier onlyClaimedTokenOwner(address tokenOwner, uint256 tokenId) {
    require(ownerOf(tokenId) == tokenOwner);
    _;
  }
  function split(
    address tokenOwner,
    uint256 tokenId,
    uint256 secondTokenId,
    uint256 secondDurationSec
  ) public proxyOrSender(tokenOwner) onlyClaimedTokenOwner(tokenOwner, tokenId) returns(bool) {
    return _split(tokenId, secondTokenId, secondDurationSec);
  }
  function merge(
    address tokenOwner,
    uint256 tokenId,
    uint256 secondTokenId
  ) public
    proxyOrSender(tokenOwner)
    onlyClaimedTokenOwner(tokenOwner, tokenId)
    onlyClaimedTokenOwner(tokenOwner, secondTokenId)
    returns(bool)
  {
    return _merge(tokenId, secondTokenId);
  }
  function setSealableProperty(
    address tokenOwner,
    uint256 tokenId,
    bytes32 key,
    bytes32 value
  ) public proxyOrSender(tokenOwner) onlyClaimedTokenOwner(tokenOwner, tokenId) returns(bool) {
    return _setSealableProperty(tokenId, key, value);
  }
  function seal(
    address dataStreamSealer,
    address tokenOwner,
    uint256 tokenId
  ) public proxyOrSender(tokenOwner) onlyClaimedTokenOwner(tokenOwner, tokenId) returns(bool) {
    return _seal(dataStreamSealer, tokenOwner, tokenId);
  }
  function sealDataStream(
    address dataStreamSealer,
    address tokenOwner,
    uint256 tokenId,
    bytes32 dataStreamHash,
    uint256 startTimeUtcSec,
    bytes32 hashedDataStreamLicenseTerms
  ) public proxyOrSender(tokenOwner) onlyClaimedTokenOwner(tokenOwner, tokenId) returns(bool) {
    return _sealDataStream(
      dataStreamSealer,
      tokenOwner,
      tokenId,
      dataStreamHash,
      startTimeUtcSec,
      hashedDataStreamLicenseTerms
    );
  }
}

    Contract ABI  
[{"constant":true,"inputs":[{"name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"claimedSender","type":"address"}],"name":"isProxyOrSender","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SCHEMA_KEY","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dataStreamSealer","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"dataStreamHash","type":"bytes32"},{"name":"startTimeUtcSec","type":"uint256"},{"name":"hashedDataStreamLicenseTerms","type":"bytes32"}],"name":"sealDataStream","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"},{"name":"key","type":"bytes32"}],"name":"mintableProperties","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"addProxyManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"BID_HASH_KEY","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"proxy","type":"address"}],"name":"addProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"","type":"address"},{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"proxy","type":"address"}],"name":"isProxy","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dataStreamSealer","type":"address"},{"name":"tokenOwner","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"seal","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"proxy","type":"address"},{"name":"sender","type":"address"}],"name":"addProxyForSender","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"mint","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokenOwner","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"secondTokenId","type":"uint256"}],"name":"merge","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"START_TIME_UTC_SEC_KEY","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceProxyManager","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"tokenURI","type":"string"}],"name":"mintWithTokenURI","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"dataStreamSealer","type":"address"},{"name":"tokenOwner","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"dataStreamHash","type":"bytes32"},{"name":"startTimeUtcSec","type":"uint256"},{"name":"hashedDataStreamLicenseTerms","type":"bytes32"}],"name":"sealDataStream","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokenId","type":"uint256"},{"name":"key","type":"bytes32"},{"name":"value","type":"bytes32"}],"name":"setMintableProperty","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"proxy","type":"address"},{"name":"sender","type":"address"}],"name":"isProxyForSender","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"tokenSealer","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokenId","type":"uint256"},{"name":"key","type":"bytes32"},{"name":"value","type":"bytes32"}],"name":"setSealableProperty","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"account","type":"address"}],"name":"addMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"renounceMinter","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"},{"name":"key","type":"bytes32"}],"name":"sealableProperties","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isMinter","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"HASHED_DATA_STREAM_LICENSE_TERMS_KEY","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"proxy","type":"address"}],"name":"removeProxy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokenId","type":"uint256"},{"name":"secondTokenId","type":"uint256"},{"name":"secondDurationSec","type":"uint256"}],"name":"split","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"DURATION_SEC_KEY","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"SPLIT_PARENT_KEY","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"firstTokenId","type":"uint256"},{"name":"secondTokenId","type":"uint256"}],"name":"merge","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"tokenOwner","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"secondTokenId","type":"uint256"},{"name":"secondDurationSec","type":"uint256"}],"name":"split","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"DATA_STREAM_HASH_KEY","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"dataStreamSealer","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"seal","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"LICENSE_TERMS_KEY","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"tokenOwner","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"key","type":"bytes32"},{"name":"value","type":"bytes32"}],"name":"setSealableProperty","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"account","type":"address"}],"name":"isProxyManager","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"proxy","type":"address"},{"name":"sender","type":"address"}],"name":"removeProxyForSender","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"},{"name":"schema","type":"bytes32"},{"name":"licenseTerms","type":"bytes32"},{"name":"durationSec","type":"uint256"}],"name":"mintDataStream","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proxy","type":"address"},{"indexed":false,"name":"updatedAtUtcSec","type":"uint256"}],"name":"ProxyAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proxy","type":"address"},{"indexed":false,"name":"updatedAtUtcSec","type":"uint256"}],"name":"ProxyRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proxy","type":"address"},{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"updatedAtUtcSec","type":"uint256"}],"name":"ProxyForSenderAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"proxy","type":"address"},{"indexed":true,"name":"sender","type":"address"},{"indexed":false,"name":"updatedAtUtcSec","type":"uint256"}],"name":"ProxyForSenderRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"ProxyManagerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"ProxyManagerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"tokenId","type":"uint256"}],"name":"Sealed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"approved","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"operator","type":"address"},{"indexed":false,"name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"}]

  Contract Creation Code Switch To Opcodes View
60806040526040805190810160405280601581526020017f4f70656e2043697479204c6963656e7365204e465400000000000000000000008152506040805190810160405280600381526020017f4f434c0000000000000000000000000000000000000000000000000000000000815250620000ad6301ffc9a77c0100000000000000000000000000000000000000000000000000000000026200019f640100000000026401000000009004565b620000ea6380ac58cd7c0100000000000000000000000000000000000000000000000000000000026200019f640100000000026401000000009004565b8160059080519060200190620001029291906200041f565b5080600690805190602001906200011b9291906200041f565b5062000159635b5e139f7c0100000000000000000000000000000000000000000000000000000000026200019f640100000000026401000000009004565b505062000175336200025d640100000000026401000000009004565b6200019933600c620002c76401000000000262002e5d179091906401000000009004565b620004ce565b63ffffffff7c010000000000000000000000000000000000000000000000000000000002817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614151515620001f157600080fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b62000281816008620002c76401000000000262002e5d179091906401000000009004565b8073ffffffffffffffffffffffffffffffffffffffff167f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f660405160405180910390a250565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141515156200030457600080fd5b6200031f82826200038a640100000000026401000000009004565b1515156200032c57600080fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614151515620003c857600080fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200046257805160ff191683800117855562000493565b8280016001018555821562000493579182015b828111156200049257825182559160200191906001019062000475565b5b509050620004a29190620004a6565b5090565b620004cb91905b80821115620004c7576000816000905550600101620004ad565b5090565b90565b61462080620004de6000396000f300608060405260043610610267576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806301ffc9a71461026c57806306fdde03146102d0578063081812fc14610360578063095ea7b3146103cd5780630a0fac2b1461041a5780630af61ed1146104755780630f505a01146104a857806311b059c61461053357806313bbae9b1461058a57806322c9283f146105cd57806323b11d8d1461060057806323b872dd1461064357806329710388146106b05780632f8f175c1461070b5780633d7bed991461079057806340c10f19146107f357806342842e0e14610858578063463dcf0a146108c55780634dad167d146109345780634e4fbee11461096757806350bb4e7f1461097e57806357cd650d14610a295780635a36f4f314610ad45780635b79142014610b355780636352211e14610bb05780636b6ee87514610c1d57806370a0823114610c8a57806384bcd93e14610ce157806395d89b4114610d42578063983b2d5614610dd25780639865027514610e155780639f13c4c714610e2c578063a22cb46514610e83578063aa271e1a14610ed2578063b7b02dd514610f2d578063b88d4fde14610f60578063be116c3b14611013578063c87b56dd14611056578063caf0887d146110fc578063ce8c0b7c14611155578063cef812fa14611188578063d1c2babb146111bb578063d673c93b1461120a578063e024e4eb14611283578063e7a33822146112b6578063e9398cb71461131b578063e985e9c51461134e578063f04303e3146113c9578063f25ebdad1461144a578063fa27e070146114a5578063fed2063c14611508575b600080fd5b34801561027857600080fd5b506102b660048036038101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19169060200190929190505050611593565b604051808215151515815260200191505060405180910390f35b3480156102dc57600080fd5b506102e56115fa565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561032557808201518184015260208101905061030a565b50505050905090810190601f1680156103525780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561036c57600080fd5b5061038b6004803603810190808035906020019092919050505061169c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b3480156103d957600080fd5b50610418600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506116ed565b005b34801561042657600080fd5b5061045b600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611832565b604051808215151515815260200191505060405180910390f35b34801561048157600080fd5b5061048a61194f565b60405180826000191660001916815260200191505060405180910390f35b3480156104b457600080fd5b50610519600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035600019169060200190929190803590602001909291908035600019169060200190929190505050611976565b604051808215151515815260200191505060405180910390f35b34801561053f57600080fd5b5061056c6004803603810190808035906020019092919080356000191690602001909291905050506119d5565b60405180826000191660001916815260200191505060405180910390f35b34801561059657600080fd5b506105cb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611b0c565b005b3480156105d957600080fd5b506105e2611b7a565b60405180826000191660001916815260200191505060405180910390f35b34801561060c57600080fd5b50610641600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611ba1565b005b34801561064f57600080fd5b506106ae600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611cb7565b005b3480156106bc57600080fd5b506106f1600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611cbc565b604051808215151515815260200191505060405180910390f35b34801561071757600080fd5b50610776600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611d12565b604051808215151515815260200191505060405180910390f35b34801561079c57600080fd5b506107f1600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611d84565b005b3480156107ff57600080fd5b5061083e600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611f2e565b604051808215151515815260200191505060405180910390f35b34801561086457600080fd5b506108c3600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611f58565b005b3480156108d157600080fd5b5061091a600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190929190505050611f79565b604051808215151515815260200191505060405180910390f35b34801561094057600080fd5b50610949612030565b60405180826000191660001916815260200191505060405180910390f35b34801561097357600080fd5b5061097c612057565b005b34801561098a57600080fd5b50610a0f600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f016020809104026020016040519081016040528093929190818152602001838380828437820191505050505050919291929050505061206d565b604051808215151515815260200191505060405180910390f35b348015610a3557600080fd5b50610aba600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080356000191690602001909291908035906020019092919080356000191690602001909291905050506120a2565b604051808215151515815260200191505060405180910390f35b348015610ae057600080fd5b50610b1b600480360381019080803590602001909291908035600019169060200190929190803560001916906020019092919050505061211a565b604051808215151515815260200191505060405180910390f35b348015610b4157600080fd5b50610b96600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612144565b604051808215151515815260200191505060405180910390f35b348015610bbc57600080fd5b50610bdb600480360381019080803590602001909291905050506121d8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610c2957600080fd5b50610c4860048036038101908080359060200190929190505050612256565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610c9657600080fd5b50610ccb600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612293565b6040518082815260200191505060405180910390f35b348015610ced57600080fd5b50610d286004803603810190808035906020019092919080356000191690602001909291908035600019169060200190929190505050612317565b604051808215151515815260200191505060405180910390f35b348015610d4e57600080fd5b50610d57612371565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610d97578082015181840152602081019050610d7c565b50505050905090810190601f168015610dc45780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610dde57600080fd5b50610e13600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612413565b005b348015610e2157600080fd5b50610e2a612433565b005b348015610e3857600080fd5b50610e6560048036038101908080359060200190929190803560001916906020019092919050505061243e565b60405180826000191660001916815260200191505060405180910390f35b348015610e8f57600080fd5b50610ed0600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050612475565b005b348015610ede57600080fd5b50610f13600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506125b1565b604051808215151515815260200191505060405180910390f35b348015610f3957600080fd5b50610f426125ce565b60405180826000191660001916815260200191505060405180910390f35b348015610f6c57600080fd5b50611011600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506125f5565b005b34801561101f57600080fd5b50611054600480360381019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061261d565b005b34801561106257600080fd5b5061108160048036038101908080359060200190929190505050612729565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156110c15780820151818401526020810190506110a6565b50505050905090810190601f1680156110ee5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561110857600080fd5b5061113b6004803603810190808035906020019092919080359060200190929190803590602001909291905050506127f2565b604051808215151515815260200191505060405180910390f35b34801561116157600080fd5b5061116a61284c565b60405180826000191660001916815260200191505060405180910390f35b34801561119457600080fd5b5061119d612873565b60405180826000191660001916815260200191505060405180910390f35b3480156111c757600080fd5b506111f0600480360381019080803590602001909291908035906020019092919050505061289a565b604051808215151515815260200191505060405180910390f35b34801561121657600080fd5b50611269600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035906020019092919080359060200190929190505050612936565b604051808215151515815260200191505060405180910390f35b34801561128f57600080fd5b506112986129a9565b60405180826000191660001916815260200191505060405180910390f35b3480156112c257600080fd5b50611301600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506129d0565b604051808215151515815260200191505060405180910390f35b34801561132757600080fd5b50611330612a29565b60405180826000191660001916815260200191505060405180910390f35b34801561135a57600080fd5b506113af600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612a50565b604051808215151515815260200191505060405180910390f35b3480156113d557600080fd5b50611430600480360381019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080356000191690602001909291908035600019169060200190929190505050612ae4565b604051808215151515815260200191505060405180910390f35b34801561145657600080fd5b5061148b600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612b57565b604051808215151515815260200191505060405180910390f35b3480156114b157600080fd5b50611506600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612b74565b005b34801561151457600080fd5b50611579600480360381019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291908035600019169060200190929190803560001916906020019092919080359060200190929190505050612d14565b604051808215151515815260200191505060405180910390f35b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060058054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156116925780601f1061166757610100808354040283529160200191611692565b820191906000526020600020905b81548152906001019060200180831161167557829003601f168201915b5050505050905090565b60006116a782612d42565b15156116b257600080fd5b6002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006116f8826121d8565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415151561173557600080fd5b8073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16148061177557506117748133612a50565b5b151561178057600080fd5b826002600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b60008173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614806118b75750600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b806119485750600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b9050919050565b7fa91efd13169e3bceace525b23b7f968b3cc611248271e35f04c5c917311fc7f760010281565b6000843373ffffffffffffffffffffffffffffffffffffffff16611999826121d8565b73ffffffffffffffffffffffffffffffffffffffff161415156119bb57600080fd5b6119c9873388888888612db4565b91505095945050505050565b6000806009600085815260200190815260200160002060007f82f1bb612577f02f2d28d75a6004227778388d11803f2c7faa961f947a84c84760010260001916600019168152602001908152602001600020546001900490506000811480611a6757507f82f1bb612577f02f2d28d75a6004227778388d11803f2c7faa961f947a84c847600102600019168360001916145b80611a9c57507f3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c600102600019168360001916145b15611ad5576009600085815260200190815260200160002060008460001916600019168152602001908152602001600020549150611b05565b60096000828152602001908152602001600020600084600019166000191681526020019081526020016000205491505b5092915050565b611b1533612b57565b1515611b2057600080fd5b611b3481600c612e5d90919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f7fd9388eed61d6c8286637fdf1afc25624585cab358450328dd43b0c7aeed95b60405160405180910390a250565b7f4eba03e4695ef490bd0d99b2e8fa2d0aa4c54ddfc1a74b32febd9142981e717660010281565b611baa33612b57565b1515611bb557600080fd5b600d60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515611c0e57600080fd5b6001600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167fb6a7032fe3eb4e07207181a752f893754c0a19f7188c7be0221a456cbec6ee5c426040518082815260200191505060405180910390a250565b600080fd5b6000600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b600082611d1e81611832565b1515611d2957600080fd5b83838173ffffffffffffffffffffffffffffffffffffffff16611d4b826121d8565b73ffffffffffffffffffffffffffffffffffffffff16141515611d6d57600080fd5b611d78878787612f0d565b93505050509392505050565b80611d8e81611832565b1515611d9957600080fd5b600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151515611e2f57600080fd5b6001600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f03eb2e619f22c50c782751f77c71c7cad6ce3840c208a3a65974cfee0bc54bbf426040518082815260200191505060405180910390a3505050565b6000611f39336125b1565b1515611f4457600080fd5b611f4e8383613011565b6001905092915050565b611f7483838360206040519081016040528060008152506125f5565b505050565b600083611f8581611832565b1515611f9057600080fd5b84848173ffffffffffffffffffffffffffffffffffffffff16611fb2826121d8565b73ffffffffffffffffffffffffffffffffffffffff16141515611fd457600080fd5b86858173ffffffffffffffffffffffffffffffffffffffff16611ff6826121d8565b73ffffffffffffffffffffffffffffffffffffffff1614151561201857600080fd5b61202288886130b7565b955050505050509392505050565b7ff3f6170cfbf7600c536f76f63bd1f6cd1df950659eea69fca42323a7b891853860010281565b61206b33600c61343590919063ffffffff16565b565b6000612078336125b1565b151561208357600080fd5b61208d8484613011565b61209783836134e4565b600190509392505050565b6000856120ae81611832565b15156120b957600080fd5b86868173ffffffffffffffffffffffffffffffffffffffff166120db826121d8565b73ffffffffffffffffffffffffffffffffffffffff161415156120fd57600080fd5b61210b8a8a8a8a8a8a612db4565b93505050509695505050505050565b6000612125336125b1565b151561213057600080fd5b61213b848484613524565b90509392505050565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000806001600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561224d57600080fd5b80915050919050565b6000600b600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156122d057600080fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000833373ffffffffffffffffffffffffffffffffffffffff1661233a826121d8565b73ffffffffffffffffffffffffffffffffffffffff1614151561235c57600080fd5b61236785858561357b565b9150509392505050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156124095780601f106123de57610100808354040283529160200191612409565b820191906000526020600020905b8154815290600101906020018083116123ec57829003601f168201915b5050505050905090565b61241c336125b1565b151561242757600080fd5b61243081613614565b50565b61243c3361366e565b565b6000600a60008481526020019081526020016000206000836000191660001916815260200190815260200160002054905092915050565b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141515156124b057600080fd5b80600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051808215151515815260200191505060405180910390a35050565b60006125c78260086136c890919063ffffffff16565b9050919050565b7f5fbb821d7c8660396e9025a6eae37db36accc5621c22f0bc3e7f6ce9ea20a9b860010281565b612600848484611cb7565b61260c8484848461375c565b151561261757600080fd5b50505050565b61262633612b57565b151561263157600080fd5b600d60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16151561268957600080fd5b600d60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81549060ff02191690558073ffffffffffffffffffffffffffffffffffffffff167f955981272de9a405d530a29cab23dda64b892b32e1c7a778cd699baf367b537b426040518082815260200191505060405180910390a250565b606061273482612d42565b151561273f57600080fd5b600760008381526020019081526020016000208054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156127e65780601f106127bb576101008083540402835291602001916127e6565b820191906000526020600020905b8154815290600101906020018083116127c957829003601f168201915b50505050509050919050565b6000833373ffffffffffffffffffffffffffffffffffffffff16612815826121d8565b73ffffffffffffffffffffffffffffffffffffffff1614151561283757600080fd5b61284285858561397e565b9150509392505050565b7f3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c60010281565b7f82f1bb612577f02f2d28d75a6004227778388d11803f2c7faa961f947a84c84760010281565b6000823373ffffffffffffffffffffffffffffffffffffffff166128bd826121d8565b73ffffffffffffffffffffffffffffffffffffffff161415156128df57600080fd5b823373ffffffffffffffffffffffffffffffffffffffff16612900826121d8565b73ffffffffffffffffffffffffffffffffffffffff1614151561292257600080fd5b61292c85856130b7565b9250505092915050565b60008461294281611832565b151561294d57600080fd5b85858173ffffffffffffffffffffffffffffffffffffffff1661296f826121d8565b73ffffffffffffffffffffffffffffffffffffffff1614151561299157600080fd5b61299c87878761397e565b9350505050949350505050565b7fa0aa0714617b83af6568cf05c25404b309565ed9fdda7f53f4f6f60105eb033760010281565b6000813373ffffffffffffffffffffffffffffffffffffffff166129f3826121d8565b73ffffffffffffffffffffffffffffffffffffffff16141515612a1557600080fd5b612a20843385612f0d565b91505092915050565b7fb275e7ea4f8ae6075626a6bc37c558f4265ba49512523cf4d68c05b249cf20b960010281565b6000600460008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600084612af081611832565b1515612afb57600080fd5b85858173ffffffffffffffffffffffffffffffffffffffff16612b1d826121d8565b73ffffffffffffffffffffffffffffffffffffffff16141515612b3f57600080fd5b612b4a87878761357b565b9350505050949350505050565b6000612b6d82600c6136c890919063ffffffff16565b9050919050565b80612b7e81611832565b1515612b8957600080fd5b600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161515612c1e57600080fd5b600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81549060ff02191690558173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f53f4fdbf046e2ed867f0f8d1cc7d5063ce080d58e9ae6d57f16c668514664c34426040518082815260200191505060405180910390a3505050565b6000612d1f336125b1565b1515612d2a57600080fd5b612d378686868686613ccc565b905095945050505050565b6000806001600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415915050919050565b6000612de4857fa0aa0714617b83af6568cf05c25404b309565ed9fdda7f53f4f6f60105eb03376001028661357b565b50612e16857ff3f6170cfbf7600c536f76f63bd1f6cd1df950659eea69fca42323a7b89185386001028560010261357b565b50612e45857f5fbb821d7c8660396e9025a6eae37db36accc5621c22f0bc3e7f6ce9ea20a9b86001028461357b565b50612e51878787612f0d565b90509695505050505050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614151515612e9957600080fd5b612ea382826136c8565b151515612eaf57600080fd5b60018260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b600080600b600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515612f6657600080fd5b83600b600084815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550612fc430858585613d75565b1515612fcf57600080fd5b7fba34121df90b0e77cf350d3550142d4cd66df49d5ac6c50c9560399f8820a061826040518082815260200191505060405180910390a1600190509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415151561304d57600080fd5b6130578282613efb565b808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b6000806000806000808688141515156130cf57600080fd5b6130d8876121d8565b73ffffffffffffffffffffffffffffffffffffffff166130f7896121d8565b73ffffffffffffffffffffffffffffffffffffffff1614151561311957600080fd5b6000600b60008a815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161480156131bb57506000600b600089815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16145b15156131c657600080fd5b6009600089815260200190815260200160002060007f82f1bb612577f02f2d28d75a6004227778388d11803f2c7faa961f947a84c847600102600019166000191681526020019081526020016000205494506009600088815260200190815260200160002060007f82f1bb612577f02f2d28d75a6004227778388d11803f2c7faa961f947a84c84760010260001916600019168152602001908152602001600020549350600060010284600019161415151561328157600080fd5b8360001916886001026000191614806132a1575083600019168560001916145b15156132ac57600080fd5b6009600089815260200190815260200160002060007f3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c60010260001916600019168152602001908152602001600020546001900492506009600088815260200190815260200160002060007f3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c6001026000191660001916815260200190815260200160002054600190049150818301905060006001026009600089815260200190815260200160002060007f3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c60010260001916600019168152602001908152602001600020816000191690555080600102600960008a815260200190815260200160002060007f3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c600102600019166000191681526020019081526020016000208160001916905550613426613420886121d8565b88614055565b60019550505050505092915050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415151561347157600080fd5b61347b82826136c8565b151561348657600080fd5b60008260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6134ed82612d42565b15156134f857600080fd5b8060076000848152602001908152602001600020908051906020019061351f929190614507565b505050565b600061352f84612d42565b15151561353b57600080fd5b8160096000868152602001908152602001600020600085600019166000191681526020019081526020016000208160001916905550600190509392505050565b600080600b600086815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156135d457600080fd5b81600a6000868152602001908152602001600020600085600019166000191681526020019081526020016000208160001916905550600190509392505050565b613628816008612e5d90919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f660405160405180910390a250565b61368281600861343590919063ffffffff16565b8073ffffffffffffffffffffffffffffffffffffffff167fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669260405160405180910390a250565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415151561370557600080fd5b8260000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60008061377e8573ffffffffffffffffffffffffffffffffffffffff166141ad565b151561378d5760019150613975565b8473ffffffffffffffffffffffffffffffffffffffff1663150b7a02338887876040518563ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015613882578082015181840152602081019050613867565b50505050905090810190601f1680156138af5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156138d157600080fd5b505af11580156138e5573d6000803e3d6000fd5b505050506040513d60208110156138fb57600080fd5b8101908080519060200190929190505050905063150b7a027c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505b50949350505050565b60008060008061398d87612d42565b801561399f575061399d86612d42565b155b15156139aa57600080fd5b6000600b600089815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515613a0257600080fd5b60006001026009600088815260200190815260200160002060007f3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c600102600019166000191681526020019081526020016000205460001916141515613a6757600080fd5b60006001026009600088815260200190815260200160002060007f82f1bb612577f02f2d28d75a6004227778388d11803f2c7faa961f947a84c847600102600019166000191681526020019081526020016000205460001916141515613acc57600080fd5b6009600088815260200190815260200160002060007f3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c60010260001916600019168152602001908152602001600020546001900492508285101515613b3057600080fd5b8483039150816001026009600089815260200190815260200160002060007f3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c600102600019166000191681526020019081526020016000208160001916905550846001026009600088815260200190815260200160002060007f3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c6001026000191660001916815260200190815260200160002081600019169055506009600088815260200190815260200160002060007f82f1bb612577f02f2d28d75a6004227778388d11803f2c7faa961f947a84c84760010260001916600019168152602001908152602001600020549050600060010281600019161415613c54578660010290505b806009600088815260200190815260200160002060007f82f1bb612577f02f2d28d75a6004227778388d11803f2c7faa961f947a84c847600102600019166000191681526020019081526020016000208160001916905550613cbe613cb8886121d8565b87613011565b600193505050509392505050565b6000613cfc857fa91efd13169e3bceace525b23b7f968b3cc611248271e35f04c5c917311fc7f760010286613524565b50613d2b857fb275e7ea4f8ae6075626a6bc37c558f4265ba49512523cf4d68c05b249cf20b960010285613524565b50613d5d857f3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c60010284600102613524565b50613d688686613011565b6001905095945050505050565b6000808473ffffffffffffffffffffffffffffffffffffffff16638f3de2828786866040518463ffffffff167c0100000000000000000000000000000000000000000000000000000000028152600401808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018281526020019350505050602060405180830381600087803b158015613e4f57600080fd5b505af1158015613e63573d6000803e3d6000fd5b505050506040513d6020811015613e7957600080fd5b81019080805190602001909291905050509050638f3de2827c0100000000000000000000000000000000000000000000000000000000027bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b600073ffffffffffffffffffffffffffffffffffffffff166001600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16141515613f6957600080fd5b816001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061400e6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546141c090919063ffffffff16565b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b61405e81612d42565b151561406957600080fd5b6009600082815260200190815260200160002060007f82f1bb612577f02f2d28d75a6004227778388d11803f2c7faa961f947a84c84760010260001916600019168152602001908152602001600020600090556009600082815260200190815260200160002060007f3354b151081a5dc2572c75853a10ef902217550496efb2ffa54494ae9b3ab99c6001026000191660001916815260200190815260200160002060009055600b600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690558173ffffffffffffffffffffffffffffffffffffffff16614165826121d8565b73ffffffffffffffffffffffffffffffffffffffff1614151561418757600080fd5b61419082612293565b60011115151561419f57600080fd5b6141a982826141e1565b5050565b600080823b905060008111915050919050565b60008082840190508381101515156141d757600080fd5b8091505092915050565b6141eb8282614240565b60006007600083815260200190815260200160002080546001816001161561010002031660029004905014151561423c5760076000828152602001908152602001600020600061423b9190614587565b5b5050565b61424a82826142b4565b61425482826143b7565b80600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b8173ffffffffffffffffffffffffffffffffffffffff166142d4826121d8565b73ffffffffffffffffffffffffffffffffffffffff161415156142f657600080fd5b600073ffffffffffffffffffffffffffffffffffffffff166002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff161415156143b35760006002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505b5050565b8173ffffffffffffffffffffffffffffffffffffffff166143d7826121d8565b73ffffffffffffffffffffffffffffffffffffffff161415156143f957600080fd5b61444c6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546144e690919063ffffffff16565b600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555060006001600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000808383111515156144f857600080fd5b82840390508091505092915050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061454857805160ff1916838001178555614576565b82800160010185558215614576579182015b8281111561457557825182559160200191906001019061455a565b5b50905061458391906145cf565b5090565b50805460018160011615610100020316600290046000825580601f106145ad57506145cc565b601f0160209004906000526020600020908101906145cb91906145cf565b5b50565b6145f191905b808211156145ed5760008160009055506001016145d5565b5090565b905600a165627a7a723058206612d2bd34a9f39e3acaf6b4ce17d4d7b72e3ee88f6054f3a0cea45a7e7b27330029

   Swarm Source:
bzzr://6612d2bd34a9f39e3acaf6b4ce17d4d7b72e3ee88f6054f3a0cea45a7e7b2733

 

View All
Block Age transaction Difficulty GasUsed Reward
View All
Block Age UncleNumber Difficulty GasUsed Reward