Contract 0x5536B6aAdd29eAf0DB112Bb28046A5FaD3761bD4

 
Ad
Ad
Txn Hash Method
Block
From
To
Value
0x520b5289b20ed0ffc317b7980f4686afdbea32fc7cca38f5b378b1bf7006b1faCreate125794672021-06-06 7:04:3913 days 4 hrs agoENS Name *jackp💰t.eth IN  PixelCons: PXCN Token0 Ether0.00196127113
0x1971492b7fb6c0728f5f0e43cdb43bc1b8ee0c4e4b86ff0aaf55c9eda5835f6aSet Approval For...120384592021-03-14 19:03:3396 days 16 hrs ago0x4ff81761e0e8d3d311163b1b17607165c2d4955f IN  PixelCons: PXCN Token0 Ether0.008310848182
0x0b11cda13afe5819f934c8a873e418fe080210894c7889baaac77a8e79859576Create Collectio...120359372021-03-14 9:40:0797 days 2 hrs ago0x4ff81761e0e8d3d311163b1b17607165c2d4955f IN  PixelCons: PXCN Token0 Ether0.016850106117
0x92298afc4cc223af0fd8e45ef2f4ef84364789f1969c5c7c7be0f35db4744e54Create120282142021-03-13 5:13:1698 days 6 hrs ago0x2293af700392125f9b6fbf6231451d969450ba05 IN  PixelCons: PXCN Token0 Ether0.01054012896
0x3f21fb3dceff5479ad3bc73e1f5b4dc1810c6c492f2bd36bb2c092b360067364Create120280102021-03-13 4:31:2098 days 7 hrs agoENS Name dude.eth IN  PixelCons: PXCN Token0 Ether0.028352384128
0x4553584974764daca646bcd2c8ac0c2e0ac822506e5423c4906335a6330f097cSet Approval For...119813922021-03-05 23:49:11105 days 11 hrs ago0x0507873482d57637e8d975640316b0a6b2ebbfc1 IN  PixelCons: PXCN Token0 Ether0.0041108490
0xe4259769d0e403405ed8077520a57c39436abde26454f058e1d662d9a6147f0cSet Approval For...114587902020-12-15 16:41:43185 days 19 hrs agoENS Name acekennedy.eth IN  PixelCons: PXCN Token0 Ether0.003115103268.2
0xa077dc1118d0e833aa891e0ac9be8e5a9ab57c44271bf985a6f2cfc5f0f140fdCreate113530272020-11-29 10:16:08202 days 1 hr agoENS Name himesa.eth IN  PixelCons: PXCN Token0 Ether0.00190555321313.000001459
0xa909e7e26b6fcfa123441bb3c5b21372a400e89f354919a428197e69aede5972Create113530042020-11-29 10:10:29202 days 1 hr agoENS Name himesa.eth IN  PixelCons: PXCN Token0 Ether0.0023279426713.19
0x58b6b52954f26e9f3f6e12cac55a2271953961120bab9b55e15967ee2fbd7794Create113529802020-11-29 10:04:12202 days 1 hr agoENS Name himesa.eth IN  PixelCons: PXCN Token0 Ether0.00190617721313.000001459
0xead70182848a17c3c27dd684c1c6ca3222663b59a0fcd62a348e89ea52fc111aCreate113529162020-11-29 9:51:04202 days 1 hr agoENS Name himesa.eth IN  PixelCons: PXCN Token0 Ether0.00210005913
0x65eab602ac97d18337e90e88fa813e23e501b163717dd262dad4ba8c19d2afcbCreate113419982020-11-27 17:59:24203 days 17 hrs agoENS Name himesa.eth IN  PixelCons: PXCN Token0 Ether0.0038132926
0x51329f391b66b1673fd92c49f947eff59e1e1f6eb6ace285cb3f0e31267c4ec7Transfer From113411652020-11-27 14:49:39203 days 20 hrs agoENS Name cmyk.eth IN  PixelCons: PXCN Token0 Ether0.0014693091132.700000233
0x3b387553e3a062dfa22d2ecec0f320f048940dfba931ae0c96206997471b9e82Transfer From113405412020-11-27 12:24:43203 days 23 hrs ago0xbbf8212cc72965fedac92b233afeeb099114d2e5 IN  PixelCons: PXCN Token0 Ether0.00270647650123.247921293
0x0bfbfb352d5cba45fab9866daba4ba44e991d14ed8b21fcef94172937158e452Transfer From113404292020-11-27 12:00:09203 days 23 hrs agoENS Name cmyk.eth IN  PixelCons: PXCN Token0 Ether0.00116638626
0xce97f04c04ba7a02db857b82e4370be84a5ec909cc7f137549339201a37abb81Transfer From113404162020-11-27 11:56:16203 days 23 hrs agoENS Name cmyk.eth IN  PixelCons: PXCN Token0 Ether0.00302686826
0x0ac792397bde8a8622143c4291d5043fa2761de3e4e49482bbd989bf7bdf6357Create113396432020-11-27 8:59:28204 days 2 hrs agoENS Name himesa.eth IN  PixelCons: PXCN Token0 Ether0.00489967887827.750000729
0xa522024012f04cde9fe9e19c2720e24f2a6e7868ec6a4f5c158965f80ee65841Create113386882020-11-27 5:33:53204 days 6 hrs agoENS Name himesa.eth IN  PixelCons: PXCN Token0 Ether0.003389070323.1
0xa8b3d5384351a257096f7fee423438ea6ecce2d25db0d126cf8fe2d49388adcfCreate113385482020-11-27 4:59:04204 days 6 hrs agoENS Name cmyk.eth IN  PixelCons: PXCN Token0 Ether0.002924579918.1
0x734dee3de886af85eeb2fdba678a41fce169f8a4925a9d968e77bc9f7c52d0b9Create113385462020-11-27 4:58:52204 days 6 hrs agoENS Name himesa.eth IN  PixelCons: PXCN Token0 Ether0.002655505318.1
0x9ddcc7c68ae8415dc80113ffc3a5f59342e0610c1e752a38d30a10e8adc14ee7Set Approval For...113385082020-11-27 4:52:22204 days 6 hrs agoENS Name cmyk.eth IN  PixelCons: PXCN Token0 Ether0.001009439622.1
0x55e6c2f1ca51f04d76a612bdbea927f7465006353563263780c81718ed3846c9Create113384642020-11-27 4:42:49204 days 7 hrs agoENS Name himesa.eth IN  PixelCons: PXCN Token0 Ether0.00264061821418.000001459
0x8d7524fd39b4612b589e38f7e77525c54f0bf835c5e1ded38c8dcfd610ee3569Create113383252020-11-27 4:14:13204 days 7 hrs agoENS Name cmyk.eth IN  PixelCons: PXCN Token0 Ether0.00475182325523.000001235
0x6b600a031d4bcb7ef2deb431d17e847b99d67d8754577109d70ea7d93c2e6c06Set Approval For...113382612020-11-27 3:58:41204 days 7 hrs agoENS Name himesa.eth IN  PixelCons: PXCN Token0 Ether0.00095919621
0x8796b34faeeeecb8016ec0e5686894271f5471941b1b3ca045dbf26132a6daaaSet Approval For...113377452020-11-27 2:07:32204 days 9 hrs agoENS Name himesa.eth IN  PixelCons: PXCN Token0 Ether0.00132460429
[ Download CSV Export 

OVERVIEW

PixelCons are collectible NFTs featuring minimalist pixel art. This open platform was started in 2018 to allow any artist to easily make digital collectibles within a shared ecosystem. Every PixelCon is unique and its ownership is secured on the Ethereum blockchain.

View more zero value Internal Transactions in Advanced View mode
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
PixelCons

Compiler Version
v0.4.24+commit.e67f0147

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2018-12-02
*/

pragma solidity ^0.4.24;


/**
 * @title ERC721 Non-Fungible Token Standard Basic Interface
 * @dev Based on openzepplin open source ERC721 examples.
 * See (https://github.com/OpenZeppelin/openzeppelin-solidity)
 */
contract ERC721 {

	/**
	 * @dev 0x01ffc9a7 === 
	 *   bytes4(keccak256('supportsInterface(bytes4)'))
	 */
	bytes4 public constant InterfaceId_ERC165 = 0x01ffc9a7;

	/**
	 * @dev 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)'))
	 */
	bytes4 internal constant InterfaceId_ERC721 = 0x80ac58cd;

	/**
	 * @dev 0x780e9d63 ===
	 *   bytes4(keccak256('totalSupply()')) ^
	 *   bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^
	 *   bytes4(keccak256('tokenByIndex(uint256)'))
	 */
	bytes4 internal constant InterfaceId_ERC721Enumerable = 0x780e9d63;

	/**
	 * @dev 0x5b5e139f ===
	 *   bytes4(keccak256('name()')) ^
	 *   bytes4(keccak256('symbol()')) ^
	 *   bytes4(keccak256('tokenURI(uint256)'))
	 */
	bytes4 internal constant InterfaceId_ERC721Metadata = 0x5b5e139f;

	/** @dev A mapping of interface id to whether or not it is supported */
	mapping(bytes4 => bool) internal supportedInterfaces;

	/** @dev Token events */
	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);

	/** @dev Registers ERC-165, ERC-721, ERC-721 Enumerable and ERC-721 Metadata as supported interfaces */
	constructor() public
	{
		registerInterface(InterfaceId_ERC165);
		registerInterface(InterfaceId_ERC721);
		registerInterface(InterfaceId_ERC721Enumerable);
		registerInterface(InterfaceId_ERC721Metadata);
	}

	/** @dev Internal function for registering an interface */
	function registerInterface(bytes4 _interfaceId) internal
	{
		require(_interfaceId != 0xffffffff);
		supportedInterfaces[_interfaceId] = true;
	}

	/** @dev ERC-165 interface implementation */
	function supportsInterface(bytes4 _interfaceId) external view returns(bool)
	{
		return supportedInterfaces[_interfaceId];
	}

	/** @dev ERC-721 interface */
	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;

	/** @dev ERC-721 Enumerable interface */
	function totalSupply() public view returns(uint256 _total);
	function tokenByIndex(uint256 _index) public view returns(uint256 _tokenId);
	function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns(uint256 _tokenId);

	/** @dev ERC-721 Metadata interface */
	function name() public view returns(string _name);
	function symbol() public view returns(string _symbol);
	function tokenURI(uint256 _tokenId) public view returns(string);
}


/**
 * @title PixelCons Core
 * @notice The purpose of this contract is to provide a shared ecosystem of minimal pixel art tokens for everyone to use. All users are treated 
 * equally with the exception of an admin user who only controls the ERC721 metadata function which points to the app website. No fees are 
 * required to interact with this contract beyond base gas fees. Here are a few notes on the basic workings of the contract:
 *    PixelCons [The core ERC721 token of this contract]
 *        -Each PixelCon is unique with an ID that encodes all its pixel data
 *        -PixelCons can be identified by both TokenIDs and TokenIndexes (index requires fewer bits to store)
 *        -A PixelCon can never be destroyed
 *        -Total number of PixelCons is limited to 18,446,744,073,709,551,616 (2^64)
 *        -A single account can only hold 4,294,967,296 PixelCons (2^32)
 *    Collections [Grouping mechanism for associating PixelCons together]
 *        -Collections are identified by an index (zero is invalid)
 *        -Collections can only be created by a user who both created and currently owns all its PixelCons
 *        -Total number of collections is limited to 18,446,744,073,709,551,616 (2^64)
 * For more information about PixelCons, please visit (https://pixelcons.io)
 * @dev This contract follows the ERC721 token standard with additional functions for creating, grouping, etc.
 * See (https://github.com/OpenZeppelin/openzeppelin-solidity)
 * @author PixelCons
 */
contract PixelCons is ERC721 {

	using AddressUtils for address;

	/** @dev Equal to 'bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))' */
	bytes4 private constant ERC721_RECEIVED = 0x150b7a02;


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////// Structs ///////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/** @dev The main PixelCon struct */
	struct PixelCon {
		uint256 tokenId;
		//// ^256bits ////
		address creator;
		uint64 collectionIndex;
		uint32 dateCreated;
	}

	/** @dev A struct linking a token owner with its token index */
	struct TokenLookup {
		address owner;
		uint64 tokenIndex;
		uint32 ownedIndex;
	}


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////// Storage ///////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/**  @dev The address thats allowed to withdraw volunteered funds sent to this contract */
	address internal admin;

	/** @dev The URI template for retrieving token metadata */
	string internal tokenURITemplate;

	////////////////// PixelCon Tokens //////////////////

	/** @dev Mapping from token ID to owner/index */
	mapping(uint256 => TokenLookup) internal tokenLookup;

	/**  @dev Mapping from owner to token indexes */
	mapping(address => uint64[]) internal ownedTokens;

	/**  @dev Mapping from creator to token indexes */
	mapping(address => uint64[]) internal createdTokens;

	/** @dev Mapping from token ID to approved address */
	mapping(uint256 => address) internal tokenApprovals;

	/** @dev Mapping from owner to operator approvals */
	mapping(address => mapping(address => bool)) internal operatorApprovals;

	/** @dev An array containing all PixelCons in existence */
	PixelCon[] internal pixelcons;

	/** @dev An array that mirrors 'pixelcons' in terms of indexing, but stores only name data */
	bytes8[] internal pixelconNames;

	////////////////// Collections //////////////////

	/** @dev Mapping from collection index to token indexes */
	mapping(uint64 => uint64[]) internal collectionTokens;

	/** @dev An array that mirrors 'collectionTokens' in terms of indexing, but stores only name data */
	bytes8[] internal collectionNames;


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	///////////////////////////////////////////////////////////// Events ////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/** @dev PixelCon token events */
	event Create(uint256 indexed _tokenId, address indexed _creator, uint64 _tokenIndex, address _to);
	event Rename(uint256 indexed _tokenId, bytes8 _newName);

	/**  @dev PixelCon collection events */
	event CreateCollection(address indexed _creator, uint64 indexed _collectionIndex);
	event RenameCollection(uint64 indexed _collectionIndex, bytes8 _newName);
	event ClearCollection(uint64 indexed _collectionIndex);


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////// Modifiers ///////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/**  @dev Small validators for quick validation of function parameters */
	modifier validIndex(uint64 _index) {
		require(_index != uint64(0), "Invalid index");
		_;
	}
	modifier validId(uint256 _id) {
		require(_id != uint256(0), "Invalid ID");
		_;
	}
	modifier validAddress(address _address) {
		require(_address != address(0), "Invalid address");
		_;
	}


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////// PixelCons Core ///////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/**
	 * @notice Contract constructor
	 */
	constructor() public
	{
		//admin defaults to the contract creator
		admin = msg.sender;

		//fill zero index pixelcon collection
		collectionNames.length++;
	}

	/**
	 * @notice Get the current admin
	 * @return The current admin
	 */
	function getAdmin() public view returns(address)
	{
		return admin;
	}

	/**
	 * @notice Withdraw all volunteered funds to `(_to)`
	 * @param _to Address to withdraw the funds to
	 */
	function adminWithdraw(address _to) public
	{
		require(msg.sender == admin, "Only the admin can call this function");
		_to.transfer(address(this).balance);
	}

	/**
	 * @notice Change the admin to `(_to)`
	 * @param _newAdmin New admin address
	 */
	function adminChange(address _newAdmin) public
	{
		require(msg.sender == admin, "Only the admin can call this function");
		admin = _newAdmin;
	}

	/**
	 * @notice Change the token URI template
	 * @param _newTokenURITemplate New token URI template
	 */
	function adminSetTokenURITemplate(string _newTokenURITemplate) public
	{
		require(msg.sender == admin, "Only the admin can call this function");
		tokenURITemplate = _newTokenURITemplate;
	}

	////////////////// PixelCon Tokens //////////////////

	/**
	 * @notice Create PixelCon `(_tokenId)`
	 * @dev Throws if the token ID already exists
	 * @param _to Address that will own the PixelCon
	 * @param _tokenId ID of the PixelCon to be creates
	 * @param _name PixelCon name (not required)
	 * @return The index of the new PixelCon
	 */
	function create(address _to, uint256 _tokenId, bytes8 _name) public payable validAddress(_to) validId(_tokenId) returns(uint64)
	{
		TokenLookup storage lookupData = tokenLookup[_tokenId];
		require(pixelcons.length < uint256(2 ** 64) - 1, "Max number of PixelCons has been reached");
		require(lookupData.owner == address(0), "PixelCon already exists");

		//get created timestamp (zero as date indicates null)
		uint32 dateCreated = 0;
		if (now < uint256(2 ** 32)) dateCreated = uint32(now);

		//create PixelCon token and set owner
		uint64 index = uint64(pixelcons.length);
		lookupData.tokenIndex = index;
		pixelcons.length++;
		pixelconNames.length++;
		PixelCon storage pixelcon = pixelcons[index];
		pixelcon.tokenId = _tokenId;
		pixelcon.creator = msg.sender;
		pixelcon.dateCreated = dateCreated;
		pixelconNames[index] = _name;
		uint64[] storage createdList = createdTokens[msg.sender];
		uint createdListIndex = createdList.length;
		createdList.length++;
		createdList[createdListIndex] = index;
		addTokenTo(_to, _tokenId);

		emit Create(_tokenId, msg.sender, index, _to);
		emit Transfer(address(0), _to, _tokenId);
		return index;
	}

	/**
	 * @notice Rename PixelCon `(_tokenId)`
	 * @dev Throws if the caller is not the owner and creator of the token
	 * @param _tokenId ID of the PixelCon to rename
	 * @param _name New name
	 * @return The index of the PixelCon
	 */
	function rename(uint256 _tokenId, bytes8 _name) public validId(_tokenId) returns(uint64)
	{
		require(isCreatorAndOwner(msg.sender, _tokenId), "Sender is not the creator and owner");

		//update name
		TokenLookup storage lookupData = tokenLookup[_tokenId];
		pixelconNames[lookupData.tokenIndex] = _name;

		emit Rename(_tokenId, _name);
		return lookupData.tokenIndex;
	}

	/**
	 * @notice Check if PixelCon `(_tokenId)` exists
	 * @param _tokenId ID of the PixelCon to query the existence of
	 * @return True if the PixelCon exists
	 */
	function exists(uint256 _tokenId) public view validId(_tokenId) returns(bool)
	{
		address owner = tokenLookup[_tokenId].owner;
		return owner != address(0);
	}

	/**
	 * @notice Get the creator of PixelCon `(_tokenId)`
	 * @dev Throws if PixelCon does not exist
	 * @param _tokenId ID of the PixelCon to query the creator of
	 * @return Creator address for PixelCon
	 */
	function creatorOf(uint256 _tokenId) public view validId(_tokenId) returns(address)
	{
		TokenLookup storage lookupData = tokenLookup[_tokenId];
		require(lookupData.owner != address(0), "PixelCon does not exist");

		return pixelcons[lookupData.tokenIndex].creator;
	}

	/**
	 * @notice Get the total number of PixelCons created by `(_creator)`
	 * @param _creator Address to query the total of
	 * @return Total number of PixelCons created by given address
	 */
	function creatorTotal(address _creator) public view validAddress(_creator) returns(uint256)
	{
		return createdTokens[_creator].length;
	}

	/**
	 * @notice Enumerate PixelCon created by `(_creator)`
	 * @dev Throws if index is out of bounds
	 * @param _creator Creator address
	 * @param _index Counter less than `creatorTotal(_creator)`
	 * @return PixelCon ID for the `(_index)`th PixelCon created by `(_creator)`
	 */
	function tokenOfCreatorByIndex(address _creator, uint256 _index) public view validAddress(_creator) returns(uint256)
	{
		require(_index < createdTokens[_creator].length, "Index is out of bounds");
		PixelCon storage pixelcon = pixelcons[createdTokens[_creator][_index]];
		return pixelcon.tokenId;
	}

	/**
	 * @notice Get all details of PixelCon `(_tokenId)`
	 * @dev Throws if PixelCon does not exist
	 * @param _tokenId ID of the PixelCon to get details for
	 * @return PixelCon details
	 */
	function getTokenData(uint256 _tokenId) public view validId(_tokenId)
	returns(uint256 _tknId, uint64 _tknIdx, uint64 _collectionIdx, address _owner, address _creator, bytes8 _name, uint32 _dateCreated)
	{
		TokenLookup storage lookupData = tokenLookup[_tokenId];
		require(lookupData.owner != address(0), "PixelCon does not exist");

		PixelCon storage pixelcon = pixelcons[lookupData.tokenIndex];
		return (pixelcon.tokenId, lookupData.tokenIndex, pixelcon.collectionIndex, lookupData.owner,
			pixelcon.creator, pixelconNames[lookupData.tokenIndex], pixelcon.dateCreated);
	}

	/**
	 * @notice Get all details of PixelCon #`(_tokenIndex)`
	 * @dev Throws if PixelCon does not exist
	 * @param _tokenIndex Index of the PixelCon to get details for
	 * @return PixelCon details
	 */
	function getTokenDataByIndex(uint64 _tokenIndex) public view
	returns(uint256 _tknId, uint64 _tknIdx, uint64 _collectionIdx, address _owner, address _creator, bytes8 _name, uint32 _dateCreated)
	{
		require(_tokenIndex < totalSupply(), "PixelCon index is out of bounds");

		PixelCon storage pixelcon = pixelcons[_tokenIndex];
		TokenLookup storage lookupData = tokenLookup[pixelcon.tokenId];
		return (pixelcon.tokenId, lookupData.tokenIndex, pixelcon.collectionIndex, lookupData.owner,
			pixelcon.creator, pixelconNames[lookupData.tokenIndex], pixelcon.dateCreated);
	}

	/**
	 * @notice Get the index of PixelCon `(_tokenId)`
	 * @dev Throws if PixelCon does not exist
	 * @param _tokenId ID of the PixelCon to query the index of
	 * @return Index of the given PixelCon ID
	 */
	function getTokenIndex(uint256 _tokenId) validId(_tokenId) public view returns(uint64)
	{
		TokenLookup storage lookupData = tokenLookup[_tokenId];
		require(lookupData.owner != address(0), "PixelCon does not exist");

		return lookupData.tokenIndex;
	}

	////////////////// Collections //////////////////

	/**
	 * @notice Create PixelCon collection
	 * @dev Throws if the message sender is not the owner and creator of the given tokens
	 * @param _tokenIndexes Token indexes to group together into a collection
	 * @param _name Name of the collection
	 * @return Index of the new collection
	 */
	function createCollection(uint64[] _tokenIndexes, bytes8 _name) public returns(uint64)
	{
		require(collectionNames.length < uint256(2 ** 64) - 1, "Max number of collections has been reached");
		require(_tokenIndexes.length > 1, "Collection must contain more than one PixelCon");

		//loop through given indexes to add to collection and check additional requirements
		uint64 collectionIndex = uint64(collectionNames.length);
		uint64[] storage collection = collectionTokens[collectionIndex];
		collection.length = _tokenIndexes.length;
		for (uint i = 0; i < _tokenIndexes.length; i++) {
			uint64 tokenIndex = _tokenIndexes[i];
			require(tokenIndex < totalSupply(), "PixelCon index is out of bounds");

			PixelCon storage pixelcon = pixelcons[tokenIndex];
			require(isCreatorAndOwner(msg.sender, pixelcon.tokenId), "Sender is not the creator and owner of the PixelCons");
			require(pixelcon.collectionIndex == uint64(0), "PixelCon is already in a collection");

			pixelcon.collectionIndex = collectionIndex;
			collection[i] = tokenIndex;
		}
		collectionNames.length++;
		collectionNames[collectionIndex] = _name;

		emit CreateCollection(msg.sender, collectionIndex);
		return collectionIndex;
	}

	/**
	 * @notice Rename collection #`(_collectionIndex)`
	 * @dev Throws if the message sender is not the owner and creator of all collection tokens
	 * @param _collectionIndex Index of the collection to rename
	 * @param _name New name
	 * @return Index of the collection
	 */
	function renameCollection(uint64 _collectionIndex, bytes8 _name) validIndex(_collectionIndex) public returns(uint64)
	{
		require(_collectionIndex < totalCollections(), "Collection does not exist");

		//loop through the collections token indexes and check additional requirements
		uint64[] storage collection = collectionTokens[_collectionIndex];
		require(collection.length > 0, "Collection has been cleared");
		for (uint i = 0; i < collection.length; i++) {
			PixelCon storage pixelcon = pixelcons[collection[i]];
			require(isCreatorAndOwner(msg.sender, pixelcon.tokenId), "Sender is not the creator and owner of the PixelCons");
		}

		//update
		collectionNames[_collectionIndex] = _name;

		emit RenameCollection(_collectionIndex, _name);
		return _collectionIndex;
	}

	/**
	 * @notice Clear collection #`(_collectionIndex)`
	 * @dev Throws if the message sender is not the owner and creator of all collection tokens
	 * @param _collectionIndex Index of the collection to clear out
	 * @return Index of the collection
	 */
	function clearCollection(uint64 _collectionIndex) validIndex(_collectionIndex) public returns(uint64)
	{
		require(_collectionIndex < totalCollections(), "Collection does not exist");

		//loop through the collections token indexes and check additional requirements while clearing pixelcon collection index
		uint64[] storage collection = collectionTokens[_collectionIndex];
		require(collection.length > 0, "Collection is already cleared");
		for (uint i = 0; i < collection.length; i++) {
			PixelCon storage pixelcon = pixelcons[collection[i]];
			require(isCreatorAndOwner(msg.sender, pixelcon.tokenId), "Sender is not the creator and owner of the PixelCons");

			pixelcon.collectionIndex = 0;
		}

		//clear out collection data
		delete collectionNames[_collectionIndex];
		delete collectionTokens[_collectionIndex];

		emit ClearCollection(_collectionIndex);
		return _collectionIndex;
	}

	/**
	 * @notice Check if collection #`(_collectionIndex)` exists
	 * @param _collectionIndex Index of the collection to query the existence of
	 * @return True if collection exists
	 */
	function collectionExists(uint64 _collectionIndex) public view validIndex(_collectionIndex) returns(bool)
	{
		return _collectionIndex < totalCollections();
	}

	/**
	 * @notice Check if collection #`(_collectionIndex)` has been cleared
	 * @dev Throws if the collection index is out of bounds
	 * @param _collectionIndex Index of the collection to query the state of
	 * @return True if collection has been cleared
	 */
	function collectionCleared(uint64 _collectionIndex) public view validIndex(_collectionIndex) returns(bool)
	{
		require(_collectionIndex < totalCollections(), "Collection does not exist");
		return collectionTokens[_collectionIndex].length == uint256(0);
	}

	/**
	 * @notice Get the total number of collections
	 * @return Total number of collections
	 */
	function totalCollections() public view returns(uint256)
	{
		return collectionNames.length;
	}

	/**
	 * @notice Get the collection index of PixelCon `(_tokenId)`
	 * @dev Throws if the PixelCon does not exist
	 * @param _tokenId ID of the PixelCon to query the collection of
	 * @return Collection index of given PixelCon
	 */
	function collectionOf(uint256 _tokenId) public view validId(_tokenId) returns(uint256)
	{
		TokenLookup storage lookupData = tokenLookup[_tokenId];
		require(lookupData.owner != address(0), "PixelCon does not exist");

		return pixelcons[tokenLookup[_tokenId].tokenIndex].collectionIndex;
	}

	/**
	 * @notice Get the total number of PixelCons in collection #`(_collectionIndex)`
	 * @dev Throws if the collection does not exist
	 * @param _collectionIndex Collection index to query the total of
	 * @return Total number of PixelCons in the collection
	 */
	function collectionTotal(uint64 _collectionIndex) public view validIndex(_collectionIndex) returns(uint256)
	{
		require(_collectionIndex < totalCollections(), "Collection does not exist");
		return collectionTokens[_collectionIndex].length;
	}

	/**
	 * @notice Get the name of collection #`(_collectionIndex)`
	 * @dev Throws if the collection does not exist
	 * @param _collectionIndex Collection index to query the name of
	 * @return Collection name
	 */
	function getCollectionName(uint64 _collectionIndex) public view validIndex(_collectionIndex) returns(bytes8)
	{
		require(_collectionIndex < totalCollections(), "Collection does not exist");
		return collectionNames[_collectionIndex];
	}

	/**
	 * @notice Enumerate PixelCon in collection #`(_collectionIndex)`
	 * @dev Throws if the collection does not exist or index is out of bounds
	 * @param _collectionIndex Collection index
	 * @param _index Counter less than `collectionTotal(_collection)`
	 * @return PixelCon ID for the `(_index)`th PixelCon in collection #`(_collectionIndex)`
	 */
	function tokenOfCollectionByIndex(uint64 _collectionIndex, uint256 _index) public view validIndex(_collectionIndex) returns(uint256)
	{
		require(_collectionIndex < totalCollections(), "Collection does not exist");
		require(_index < collectionTokens[_collectionIndex].length, "Index is out of bounds");
		PixelCon storage pixelcon = pixelcons[collectionTokens[_collectionIndex][_index]];
		return pixelcon.tokenId;
	}

	////////////////// Web3 Only //////////////////

	/**
	 * @notice Get the indexes of all PixelCons owned by `(_owner)`
	 * @dev This function is for web3 calls only, as it returns a dynamic array
	 * @param _owner Owner address
	 * @return PixelCon indexes
	 */
	function getForOwner(address _owner) public view validAddress(_owner) returns(uint64[])
	{
		return ownedTokens[_owner];
	}

	/**
	 * @notice Get the indexes of all PixelCons created by `(_creator)`
	 * @dev This function is for web3 calls only, as it returns a dynamic array
	 * @param _creator Creator address 
	 * @return PixelCon indexes
	 */
	function getForCreator(address _creator) public view validAddress(_creator) returns(uint64[])
	{
		return createdTokens[_creator];
	}

	/**
	 * @notice Get the indexes of all PixelCons in collection #`(_collectionIndex)`
	 * @dev This function is for web3 calls only, as it returns a dynamic array
	 * @param _collectionIndex Collection index
	 * @return PixelCon indexes
	 */
	function getForCollection(uint64 _collectionIndex) public view validIndex(_collectionIndex) returns(uint64[])
	{
		return collectionTokens[_collectionIndex];
	}

	/**
	 * @notice Get the basic data for the given PixelCon indexes
	 * @dev This function is for web3 calls only, as it returns a dynamic array
	 * @param _tokenIndexes List of PixelCon indexes
	 * @return All PixelCon basic data
	 */
	function getBasicData(uint64[] _tokenIndexes) public view returns(uint256[], bytes8[], address[], uint64[])
	{
		uint256[] memory tokenIds = new uint256[](_tokenIndexes.length);
		bytes8[] memory names = new bytes8[](_tokenIndexes.length);
		address[] memory owners = new address[](_tokenIndexes.length);
		uint64[] memory collectionIdxs = new uint64[](_tokenIndexes.length);

		for (uint i = 0; i < _tokenIndexes.length; i++)	{
			uint64 tokenIndex = _tokenIndexes[i];
			require(tokenIndex < totalSupply(), "PixelCon index is out of bounds");

			tokenIds[i] = pixelcons[tokenIndex].tokenId;
			names[i] = pixelconNames[tokenIndex];
			owners[i] = tokenLookup[pixelcons[tokenIndex].tokenId].owner;
			collectionIdxs[i] = pixelcons[tokenIndex].collectionIndex;
		}
		return (tokenIds, names, owners, collectionIdxs);
	}

	/**
	 * @notice Get the names of all PixelCons
	 * @dev This function is for web3 calls only, as it returns a dynamic array
	 * @return The names of all PixelCons in existence
	 */
	function getAllNames() public view returns(bytes8[])
	{
		return pixelconNames;
	}

	/**
	 * @notice Get the names of all PixelCons from index `(_startIndex)` to `(_endIndex)`
	 * @dev This function is for web3 calls only, as it returns a dynamic array
	 * @return The names of the PixelCons in the given range
	 */
	function getNamesInRange(uint64 _startIndex, uint64 _endIndex) public view returns(bytes8[])
	{
		require(_startIndex <= totalSupply(), "Start index is out of bounds");
		require(_endIndex <= totalSupply(), "End index is out of bounds");
		require(_startIndex <= _endIndex, "End index is less than the start index");

		uint64 length = _endIndex - _startIndex;
		bytes8[] memory names = new bytes8[](length);
		for (uint i = 0; i < length; i++)	{
			names[i] = pixelconNames[_startIndex + i];
		}
		return names;
	}

	/**
	 * @notice Get details of collection #`(_collectionIndex)`
	 * @dev This function is for web3 calls only, as it returns a dynamic array
	 * @param _collectionIndex Index of the collection to get the data of
	 * @return Collection name and included PixelCon indexes
	 */
	function getCollectionData(uint64 _collectionIndex) public view validIndex(_collectionIndex) returns(bytes8, uint64[])
	{
		require(_collectionIndex < totalCollections(), "Collection does not exist");
		return (collectionNames[_collectionIndex], collectionTokens[_collectionIndex]);
	}

	/**
	 * @notice Get the names of all collections
	 * @dev This function is for web3 calls only, as it returns a dynamic array
	 * @return The names of all PixelCon collections in existence
	 */
	function getAllCollectionNames() public view returns(bytes8[])
	{
		return collectionNames;
	}

	/**
	 * @notice Get the names of all collections from index `(_startIndex)` to `(_endIndex)`
	 * @dev This function is for web3 calls only, as it returns a dynamic array
	 * @return The names of the collections in the given range
	 */
	function getCollectionNamesInRange(uint64 _startIndex, uint64 _endIndex) public view returns(bytes8[])
	{
		require(_startIndex <= totalCollections(), "Start index is out of bounds");
		require(_endIndex <= totalCollections(), "End index is out of bounds");
		require(_startIndex <= _endIndex, "End index is less than the start index");

		uint64 length = _endIndex - _startIndex;
		bytes8[] memory names = new bytes8[](length);
		for (uint i = 0; i < length; i++)	{
			names[i] = collectionNames[_startIndex + i];
		}
		return names;
	}


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////// ERC-721 Implementation ///////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/**
	 * @notice Get the balance of `(_owner)`
	 * @param _owner Owner address
	 * @return Owner balance
	 */
	function balanceOf(address _owner) public view validAddress(_owner) returns(uint256)
	{
		return ownedTokens[_owner].length;
	}

	/**
	 * @notice Get the owner of PixelCon `(_tokenId)`
	 * @dev Throws if PixelCon does not exist
	 * @param _tokenId ID of the token
	 * @return Owner of the given PixelCon
	 */
	function ownerOf(uint256 _tokenId) public view validId(_tokenId) returns(address)
	{
		address owner = tokenLookup[_tokenId].owner;
		require(owner != address(0), "PixelCon does not exist");
		return owner;
	}

	/**
	 * @notice Approve `(_to)` to transfer PixelCon `(_tokenId)` (zero indicates no approved address)
	 * @dev Throws if not called by the owner or an approved operator
	 * @param _to Address to be approved
	 * @param _tokenId ID of the token to be approved
	 */
	function approve(address _to, uint256 _tokenId) public validId(_tokenId)
	{
		address owner = tokenLookup[_tokenId].owner;
		require(_to != owner, "Cannot approve PixelCon owner");
		require(msg.sender == owner || operatorApprovals[owner][msg.sender], "Sender does not have permission to approve address");

		tokenApprovals[_tokenId] = _to;
		emit Approval(owner, _to, _tokenId);
	}

	/**
	 * @notice Get the approved address for PixelCon `(_tokenId)`
	 * @dev Throws if the PixelCon does not exist
	 * @param _tokenId ID of the token
	 * @return Address currently approved for the given PixelCon
	 */
	function getApproved(uint256 _tokenId) public view validId(_tokenId) returns(address)
	{
		address owner = tokenLookup[_tokenId].owner;
		require(owner != address(0), "PixelCon does not exist");
		return tokenApprovals[_tokenId];
	}

	/**
	 * @notice Set or unset the approval of operator `(_to)`
	 * @dev An operator is allowed to transfer all tokens of the sender on their behalf
	 * @param _to Operator address to set the approval
	 * @param _approved Flag for setting approval
	 */
	function setApprovalForAll(address _to, bool _approved) public validAddress(_to)
	{
		require(_to != msg.sender, "Cannot approve self");
		operatorApprovals[msg.sender][_to] = _approved;
		emit ApprovalForAll(msg.sender, _to, _approved);
	}

	/**
	 * @notice Get if `(_operator)` is an approved operator for owner `(_owner)`
	 * @param _owner Owner address 
	 * @param _operator Operator address
	 * @return True if the given operator is approved by the given owner
	 */
	function isApprovedForAll(address _owner, address _operator) public view validAddress(_owner) validAddress(_operator) returns(bool)
	{
		return operatorApprovals[_owner][_operator];
	}

	/**
	 * @notice Transfer the ownership of PixelCon `(_tokenId)` to `(_to)` (try to use 'safeTransferFrom' instead)
	 * @dev Throws if the sender is not the owner, approved, or operator
	 * @param _from Current owner
	 * @param _to Address to receive the PixelCon
	 * @param _tokenId ID of the PixelCon to be transferred
	 */
	function transferFrom(address _from, address _to, uint256 _tokenId) public validAddress(_from) validAddress(_to) validId(_tokenId)
	{
		require(isApprovedOrOwner(msg.sender, _tokenId), "Sender does not have permission to transfer PixelCon");
		clearApproval(_from, _tokenId);
		removeTokenFrom(_from, _tokenId);
		addTokenTo(_to, _tokenId);

		emit Transfer(_from, _to, _tokenId);
	}

	/**
	 * @notice Safely transfer the ownership of PixelCon `(_tokenId)` to `(_to)`
	 * @dev Throws if receiver is a contract that does not respond or the sender is not the owner, approved, or operator
	 * @param _from Current owner
	 * @param _to Address to receive the PixelCon
	 * @param _tokenId ID of the PixelCon to be transferred
	 */
	function safeTransferFrom(address _from, address _to, uint256 _tokenId) public
	{
		//requirements are checked in 'transferFrom' function
		safeTransferFrom(_from, _to, _tokenId, "");
	}

	/**
	 * @notice Safely transfer the ownership of PixelCon `(_tokenId)` to `(_to)`
	 * @dev Throws if receiver is a contract that does not respond or the sender is not the owner, approved, or operator
	 * @param _from Current owner
	 * @param _to Address to receive the PixelCon
	 * @param _tokenId ID of the PixelCon to be transferred
	 * @param _data Data to send along with a safe transfer check
	 */
	function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) public
	{
		//requirements are checked in 'transferFrom' function
		transferFrom(_from, _to, _tokenId);
		require(checkAndCallSafeTransfer(_from, _to, _tokenId, _data), "Transfer was not safe");
	}


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	//////////////////////////////////////////////// ERC-721 Enumeration Implementation /////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/**
	 * @notice Get the total number of PixelCons in existence
	 * @return Total number of PixelCons in existence
	 */
	function totalSupply() public view returns(uint256)
	{
		return pixelcons.length;
	}

	/**
	 * @notice Get the ID of PixelCon #`(_tokenIndex)`
	 * @dev Throws if index is out of bounds
	 * @param _tokenIndex Counter less than `totalSupply()`
	 * @return `_tokenIndex`th PixelCon ID
	 */
	function tokenByIndex(uint256 _tokenIndex) public view returns(uint256)
	{
		require(_tokenIndex < totalSupply(), "PixelCon index is out of bounds");
		return pixelcons[_tokenIndex].tokenId;
	}

	/**
	 * @notice Enumerate PixelCon assigned to owner `(_owner)`
	 * @dev Throws if the index is out of bounds
	 * @param _owner Owner address
	 * @param _index Counter less than `balanceOf(_owner)`
	 * @return PixelCon ID for the `(_index)`th PixelCon in owned by `(_owner)`
	 */
	function tokenOfOwnerByIndex(address _owner, uint256 _index) public view validAddress(_owner) returns(uint256)
	{
		require(_index < ownedTokens[_owner].length, "Index is out of bounds");
		PixelCon storage pixelcon = pixelcons[ownedTokens[_owner][_index]];
		return pixelcon.tokenId;
	}


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////// ERC-721 Metadata Implementation //////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/**
	 * @notice Get the name of this contract token
	 * @return Contract token name
	 */
	function name() public view returns(string)
	{
		return "PixelCons";
	}

	/**
	 * @notice Get the symbol for this contract token
	 * @return Contract token symbol
	 */
	function symbol() public view returns(string)
	{
		return "PXCN";
	}

	/**
	 * @notice Get a distinct Uniform Resource Identifier (URI) for PixelCon `(_tokenId)`
	 * @dev Throws if the given PixelCon does not exist
	 * @return PixelCon URI
	 */
	function tokenURI(uint256 _tokenId) public view returns(string)
	{
		TokenLookup storage lookupData = tokenLookup[_tokenId];
		require(lookupData.owner != address(0), "PixelCon does not exist");
		PixelCon storage pixelcon = pixelcons[lookupData.tokenIndex];
		bytes8 pixelconName = pixelconNames[lookupData.tokenIndex];

		//Available values: <tokenId>, <tokenIndex>, <name>, <owner>, <creator>, <dateCreated>, <collectionIndex>

		//start with the token URI template and replace in the appropriate values
		string memory finalTokenURI = tokenURITemplate;
		finalTokenURI = StringUtils.replace(finalTokenURI, "<tokenId>", StringUtils.toHexString(_tokenId, 32));
		finalTokenURI = StringUtils.replace(finalTokenURI, "<tokenIndex>", StringUtils.toHexString(uint256(lookupData.tokenIndex), 8));
		finalTokenURI = StringUtils.replace(finalTokenURI, "<name>", StringUtils.toHexString(uint256(pixelconName), 8));
		finalTokenURI = StringUtils.replace(finalTokenURI, "<owner>", StringUtils.toHexString(uint256(lookupData.owner), 20));
		finalTokenURI = StringUtils.replace(finalTokenURI, "<creator>", StringUtils.toHexString(uint256(pixelcon.creator), 20));
		finalTokenURI = StringUtils.replace(finalTokenURI, "<dateCreated>", StringUtils.toHexString(uint256(pixelcon.dateCreated), 8));
		finalTokenURI = StringUtils.replace(finalTokenURI, "<collectionIndex>", StringUtils.toHexString(uint256(pixelcon.collectionIndex), 8));

		return finalTokenURI;
	}


	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////// Utils ////////////////////////////////////////////////////////////////////////
	/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	/**
	 * @notice Check whether the given editor is the current owner and original creator of a given token ID
	 * @param _address Address to check for
	 * @param _tokenId ID of the token to be edited
	 * @return True if the editor is approved for the given token ID, is an operator of the owner, or is the owner of the token
	 */
	function isCreatorAndOwner(address _address, uint256 _tokenId) internal view returns(bool)
	{
		TokenLookup storage lookupData = tokenLookup[_tokenId];
		address owner = lookupData.owner;
		address creator = pixelcons[lookupData.tokenIndex].creator;

		return (_address == owner && _address == creator);
	}

	/**
	 * @notice Check whether the given spender can transfer a given token ID
	 * @dev Throws if the PixelCon does not exist
	 * @param _address Address of the spender to query
	 * @param _tokenId ID of the token to be transferred
	 * @return True if the spender is approved for the given token ID, is an operator of the owner, or is the owner of the token
	 */
	function isApprovedOrOwner(address _address, uint256 _tokenId) internal view returns(bool)
	{
		address owner = tokenLookup[_tokenId].owner;
		require(owner != address(0), "PixelCon does not exist");
		return (_address == owner || tokenApprovals[_tokenId] == _address || operatorApprovals[owner][_address]);
	}

	/**
	 * @notice Clear current approval of a given token ID
	 * @dev Throws if the given address is not indeed the owner of the token
	 * @param _owner Owner of the token
	 * @param _tokenId ID of the token to be transferred
	 */
	function clearApproval(address _owner, uint256 _tokenId) internal
	{
		require(tokenLookup[_tokenId].owner == _owner, "Incorrect PixelCon owner");
		if (tokenApprovals[_tokenId] != address(0)) {
			tokenApprovals[_tokenId] = address(0);
		}
	}

	/**
	 * @notice Add a token ID to the list of a given address
	 * @dev Throws if the receiver address has hit ownership limit or the PixelCon already has an owner
	 * @param _to Address representing the new owner of the given token ID
	 * @param _tokenId ID of the token to be added to the tokens list of the given address
	 */
	function addTokenTo(address _to, uint256 _tokenId) internal
	{
		uint64[] storage ownedList = ownedTokens[_to];
		TokenLookup storage lookupData = tokenLookup[_tokenId];
		require(ownedList.length < uint256(2 ** 32) - 1, "Max number of PixelCons per owner has been reached");
		require(lookupData.owner == address(0), "PixelCon already has an owner");
		lookupData.owner = _to;

		//update ownedTokens references
		uint ownedListIndex = ownedList.length;
		ownedList.length++;
		lookupData.ownedIndex = uint32(ownedListIndex);
		ownedList[ownedListIndex] = lookupData.tokenIndex;
	}

	/**
	 * @notice Remove a token ID from the list of a given address
	 * @dev Throws if the given address is not indeed the owner of the token
	 * @param _from Address representing the previous owner of the given token ID
	 * @param _tokenId ID of the token to be removed from the tokens list of the given address
	 */
	function removeTokenFrom(address _from, uint256 _tokenId) internal
	{
		uint64[] storage ownedList = ownedTokens[_from];
		TokenLookup storage lookupData = tokenLookup[_tokenId];
		require(lookupData.owner == _from, "From address is incorrect");
		lookupData.owner = address(0);

		//update ownedTokens references
		uint64 replacementTokenIndex = ownedList[ownedList.length - 1];
		delete ownedList[ownedList.length - 1];
		ownedList.length--;
		if (lookupData.ownedIndex < ownedList.length) {
			//we just removed the last token index in the array, but if this wasn't the one to remove, then swap it with the one to remove 
			ownedList[lookupData.ownedIndex] = replacementTokenIndex;
			tokenLookup[pixelcons[replacementTokenIndex].tokenId].ownedIndex = lookupData.ownedIndex;
		}
		lookupData.ownedIndex = 0;
	}

	/**
	 * @notice Invoke `onERC721Received` on a target address (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 ID of the token to be transferred
	 * @param _data Optional data to send along with the call
	 * @return True if the call correctly returned the expected value
	 */
	function checkAndCallSafeTransfer(address _from, address _to, uint256 _tokenId, bytes _data) internal returns(bool)
	{
		if (!_to.isContract()) return true;

		bytes4 retval = ERC721Receiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data);
		return (retval == ERC721_RECEIVED);
	}
}


/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers from ERC721 asset contracts.
 * See (https://github.com/OpenZeppelin/openzeppelin-solidity)
 */
contract ERC721Receiver {

	/**
	 * @dev Magic value to be returned upon successful reception of an NFT.
	 * Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`,
	 * which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
	 */
	bytes4 internal constant ERC721_RECEIVED = 0x150b7a02;

	/**
	 * @notice Handle the receipt of an NFT
	 * @dev The ERC721 smart contract calls this function on the recipient
	 * after a `safetransfer`. This function MAY throw to revert and reject the
	 * transfer. Return of other than the magic value MUST result in the
	 * transaction being reverted.
	 * Note: the 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);
}


/**
 * @title AddressUtils Library
 * @dev Utility library of inline functions on addresses.
 * See (https://github.com/OpenZeppelin/openzeppelin-solidity)
 */
library AddressUtils {

	/**
	 * 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.
		assembly { size := extcodesize(_account) }
		return size > 0;
	}
}


/**
 * @title StringUtils Library
 * @dev Utility library of inline functions on strings. 
 * These functions are very expensive and are only intended for web3 calls
 * @author PixelCons
 */
library StringUtils {

	/**
	 * @dev Replaces the given key with the given value in the given string
	 * @param _str String to find and replace in
	 * @param _key Value to search for
	 * @param _value Value to replace key with
	 * @return The replaced string
	 */
	function replace(string _str, string _key, string _value) internal pure returns(string)
	{
		bytes memory bStr = bytes(_str);
		bytes memory bKey = bytes(_key);
		bytes memory bValue = bytes(_value);

		uint index = indexOf(bStr, bKey);
		if (index < bStr.length) {
			bytes memory rStr = new bytes((bStr.length + bValue.length) - bKey.length);

			uint i;
			for (i = 0; i < index; i++) rStr[i] = bStr[i];
			for (i = 0; i < bValue.length; i++) rStr[index + i] = bValue[i];
			for (i = 0; i < bStr.length - (index + bKey.length); i++) rStr[index + bValue.length + i] = bStr[index + bKey.length + i];

			return string(rStr);
		}
		return string(bStr);
	}

	/**
	 * @dev Converts a given number into a string with hex representation
	 * @param _num Number to convert
	 * @param _byteSize Size of the number in bytes
	 * @return The hex representation as string
	 */
	function toHexString(uint256 _num, uint _byteSize) internal pure returns(string)
	{
		bytes memory s = new bytes(_byteSize * 2 + 2);
		s[0] = 0x30;
		s[1] = 0x78;
		for (uint i = 0; i < _byteSize; i++) {
			byte b = byte(uint8(_num / (2 ** (8 * (_byteSize - 1 - i)))));
			byte hi = byte(uint8(b) / 16);
			byte lo = byte(uint8(b) - 16 * uint8(hi));
			s[2 + 2 * i] = char(hi);
			s[3 + 2 * i] = char(lo);
		}
		return string(s);
	}

	/**
	 * @dev Gets the ascii hex character for the given value (0-15)
	 * @param _b Byte to get ascii code for
	 * @return The ascii hex character
	 */
	function char(byte _b) internal pure returns(byte c)
	{
		if (_b < 10) return byte(uint8(_b) + 0x30);
		else return byte(uint8(_b) + 0x57);
	}

	/**
	 * @dev Gets the index of the key string in the given string
	 * @param _str String to search in
	 * @param _key Value to search for
	 * @return The index of the key in the string (string length if not found)
	 */
	function indexOf(bytes _str, bytes _key) internal pure returns(uint)
	{
		for (uint i = 0; i < _str.length - (_key.length - 1); i++) {
			bool matchFound = true;
			for (uint j = 0; j < _key.length; j++) {
				if (_str[i + j] != _key[j]) {
					matchFound = false;
					break;
				}
			}
			if (matchFound) {
				return i;
			}
		}
		return _str.length;
	}
}

Contract Security Audit

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":"_tokenIndex","type":"uint64"}],"name":"getTokenDataByIndex","outputs":[{"name":"_tknId","type":"uint256"},{"name":"_tknIdx","type":"uint64"},{"name":"_collectionIdx","type":"uint64"},{"name":"_owner","type":"address"},{"name":"_creator","type":"address"},{"name":"_name","type":"bytes8"},{"name":"_dateCreated","type":"uint32"}],"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":true,"inputs":[{"name":"_creator","type":"address"}],"name":"creatorTotal","outputs":[{"name":"","type":"uint256"}],"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":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"InterfaceId_ERC165","outputs":[{"name":"","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_collectionIndex","type":"uint64"}],"name":"collectionTotal","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getTokenIndex","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"view","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":true,"inputs":[{"name":"_collectionIndex","type":"uint64"},{"name":"_index","type":"uint256"}],"name":"tokenOfCollectionByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenIndex","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_creator","type":"address"},{"name":"_index","type":"uint256"}],"name":"tokenOfCreatorByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_collectionIndex","type":"uint64"},{"name":"_name","type":"bytes8"}],"name":"renameCollection","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"getForOwner","outputs":[{"name":"","type":"uint64[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_startIndex","type":"uint64"},{"name":"_endIndex","type":"uint64"}],"name":"getNamesInRange","outputs":[{"name":"","type":"bytes8[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"creatorOf","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_startIndex","type":"uint64"},{"name":"_endIndex","type":"uint64"}],"name":"getCollectionNamesInRange","outputs":[{"name":"","type":"bytes8[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalCollections","outputs":[{"name":"","type":"uint256"}],"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":"_collectionIndex","type":"uint64"}],"name":"getCollectionData","outputs":[{"name":"","type":"bytes8"},{"name":"","type":"uint64[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getAdmin","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":"_name","type":"bytes8"}],"name":"rename","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_collectionIndex","type":"uint64"}],"name":"collectionCleared","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newAdmin","type":"address"}],"name":"adminChange","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_tokenId","type":"uint256"},{"name":"_name","type":"bytes8"}],"name":"create","outputs":[{"name":"","type":"uint64"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_collectionIndex","type":"uint64"}],"name":"clearCollection","outputs":[{"name":"","type":"uint64"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"}],"name":"adminWithdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getAllCollectionNames","outputs":[{"name":"","type":"bytes8[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_collectionIndex","type":"uint64"}],"name":"getForCollection","outputs":[{"name":"","type":"uint64[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"getTokenData","outputs":[{"name":"_tknId","type":"uint256"},{"name":"_tknIdx","type":"uint64"},{"name":"_collectionIdx","type":"uint64"},{"name":"_owner","type":"address"},{"name":"_creator","type":"address"},{"name":"_name","type":"bytes8"},{"name":"_dateCreated","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newTokenURITemplate","type":"string"}],"name":"adminSetTokenURITemplate","outputs":[],"payable":false,"stateMutability":"nonpayable","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":true,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"collectionOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenIndexes","type":"uint64[]"},{"name":"_name","type":"bytes8"}],"name":"createCollection","outputs":[{"name":"","type":"uint64"}],"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":true,"inputs":[{"name":"_creator","type":"address"}],"name":"getForCreator","outputs":[{"name":"","type":"uint64[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_collectionIndex","type":"uint64"}],"name":"collectionExists","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_tokenIndexes","type":"uint64[]"}],"name":"getBasicData","outputs":[{"name":"","type":"uint256[]"},{"name":"","type":"bytes8[]"},{"name":"","type":"address[]"},{"name":"","type":"uint64[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_collectionIndex","type":"uint64"}],"name":"getCollectionName","outputs":[{"name":"","type":"bytes8"}],"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":true,"inputs":[],"name":"getAllNames","outputs":[{"name":"","type":"bytes8[]"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_tokenId","type":"uint256"},{"indexed":true,"name":"_creator","type":"address"},{"indexed":false,"name":"_tokenIndex","type":"uint64"},{"indexed":false,"name":"_to","type":"address"}],"name":"Create","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_tokenId","type":"uint256"},{"indexed":false,"name":"_newName","type":"bytes8"}],"name":"Rename","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_creator","type":"address"},{"indexed":true,"name":"_collectionIndex","type":"uint64"}],"name":"CreateCollection","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_collectionIndex","type":"uint64"},{"indexed":false,"name":"_newName","type":"bytes8"}],"name":"RenameCollection","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_collectionIndex","type":"uint64"}],"name":"ClearCollection","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"}]

60806040523480156200001157600080fd5b50620000467f01ffc9a7000000000000000000000000000000000000000000000000000000006401000000006200010e810204565b6200007a7f80ac58cd000000000000000000000000000000000000000000000000000000006401000000006200010e810204565b620000ae7f780e9d63000000000000000000000000000000000000000000000000000000006401000000006200010e810204565b620000e27f5b5e139f000000000000000000000000000000000000000000000000000000006401000000006200010e810204565b60018054600160a060020a03191633178155600b80549162000107919083016200017b565b50620001db565b7fffffffff0000000000000000000000000000000000000000000000000000000080821614156200013e57600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152602081905260409020805460ff19166001179055565b815481835581811115620001b2576003016004900481600301600490048360005260206000209182019101620001b29190620001b7565b505050565b620001d891905b80821115620001d45760008155600101620001be565b5090565b90565b6151cb80620001eb6000396000f3006080604052600436106102375763ffffffff60e060020a60003504166301ffc9a7811461023c578063062401c21461027257806306fdde03146102f0578063081812fc1461037a57806308702682146103ae578063095ea7b3146103e157806318160ddd1461040757806319fa8f501461041c57806323b872dd1461044e57806326a50862146104785780632f745c59146104995780633a663c80146104bd57806342842e0e146104f15780634aeabcb61461051b5780634f558e791461053f5780634f6ccce7146105575780634fc092751461056f57806350ff9a5b1461059357806357643118146105c15780635835068114610632578063589a174314610659578063602c4f051461067157806361d9db2d146106985780636352211e146106ad5780636bb2a9a8146106c55780636e9960c31461074a57806370a082311461075f57806375d28011146107805780638a153c28146107a557806395d89b41146107c65780639e5f4dbd146107db5780639fee49ba146107fc578063a05d821b14610820578063a22cb46514610841578063a28835b614610867578063ace8116d14610888578063ad7321541461089d578063b09afec1146108be578063b2f42210146108d6578063b88d4fde1461092f578063c7778baa1461099e578063c82a94a1146109b6578063c87b56dd14610a17578063d4aa25cc14610a2f578063d694f10914610a50578063e2b3190314610a71578063e8545f1b14610be9578063e985e9c514610c27578063fb825e5f14610c4e575b600080fd5b34801561024857600080fd5b5061025e600160e060020a031960043516610c63565b604080519115158252519081900360200190f35b34801561027e57600080fd5b506102936001604060020a0360043516610c86565b604080519788526001604060020a0396871660208901529490951686850152600160a060020a03928316606087015291166080850152600160c060020a03191660a084015263ffffffff90911660c0830152519081900360e00190f35b3480156102fc57600080fd5b50610305610dbe565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561033f578181015183820152602001610327565b50505050905090810190601f16801561036c5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561038657600080fd5b50610392600435610df6565b60408051600160a060020a039092168252519081900360200190f35b3480156103ba57600080fd5b506103cf600160a060020a0360043516610ebc565b60408051918252519081900360200190f35b3480156103ed57600080fd5b50610405600160a060020a0360043516602435610f2a565b005b34801561041357600080fd5b506103cf611107565b34801561042857600080fd5b5061043161110d565b60408051600160e060020a03199092168252519081900360200190f35b34801561045a57600080fd5b50610405600160a060020a0360043581169060243516604435611131565b34801561048457600080fd5b506103cf6001604060020a0360043516611302565b3480156104a557600080fd5b506103cf600160a060020a03600435166024356113c5565b3480156104c957600080fd5b506104d5600435611506565b604080516001604060020a039092168252519081900360200190f35b3480156104fd57600080fd5b50610405600160a060020a03600435811690602435166044356115c7565b34801561052757600080fd5b506103cf6001604060020a03600435166024356115e8565b34801561054b57600080fd5b5061025e600435611726565b34801561056357600080fd5b506103cf60043561178f565b34801561057b57600080fd5b506103cf600160a060020a0360043516602435611804565b34801561059f57600080fd5b506104d56001604060020a0360043516600160c060020a0319602435166118ed565b3480156105cd57600080fd5b506105e2600160a060020a0360043516611ba7565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561061e578181015183820152602001610606565b505050509050019250505060405180910390f35b34801561063e57600080fd5b506105e26001604060020a0360043581169060243516611c95565b34801561066557600080fd5b50610392600435611ec2565b34801561067d57600080fd5b506105e26001604060020a0360043581169060243516611fb1565b3480156106a457600080fd5b506103cf6121d1565b3480156106b957600080fd5b506103926004356121d7565b3480156106d157600080fd5b506106e66001604060020a0360043516612286565b60408051600160c060020a031984168152602080820183815284519383019390935283519192916060840191858101910280838360005b8381101561073557818101518382015260200161071d565b50505050905001935050505060405180910390f35b34801561075657600080fd5b5061039261240b565b34801561076b57600080fd5b506103cf600160a060020a036004351661241a565b34801561078c57600080fd5b506104d5600435600160c060020a031960243516612488565b3480156107b157600080fd5b5061025e6001604060020a0360043516612615565b3480156107d257600080fd5b506103056126d9565b3480156107e757600080fd5b50610405600160a060020a0360043516612710565b6104d5600160a060020a0360043516602435600160c060020a0319604435166127c7565b34801561082c57600080fd5b506104d56001604060020a0360043516612bac565b34801561084d57600080fd5b50610405600160a060020a03600435166024351515612e76565b34801561087357600080fd5b50610405600160a060020a0360043516612f95565b34801561089457600080fd5b506105e2613057565b3480156108a957600080fd5b506105e26001604060020a03600435166130df565b3480156108ca57600080fd5b506102936004356131a2565b3480156108e257600080fd5b506040805160206004803580820135601f810184900484028501840190955284845261040594369492936024939284019190819084018382808284375094975061331d9650505050505050565b34801561093b57600080fd5b50604080516020601f60643560048181013592830184900484028501840190955281845261040594600160a060020a0381358116956024803590921695604435953695608494019181908401838280828437509497506133b89650505050505050565b3480156109aa57600080fd5b506103cf60043561342b565b3480156109c257600080fd5b50604080516020600480358082013583810280860185019096528085526104d59536959394602494938501929182918501908490808284375094975050509235600160c060020a031916935061352e92505050565b348015610a2357600080fd5b5061030560043561395c565b348015610a3b57600080fd5b506105e2600160a060020a0360043516613d47565b348015610a5c57600080fd5b5061025e6001604060020a0360043516613e0a565b348015610a7d57600080fd5b5060408051602060048035808201358381028086018501909652808552610ac695369593946024949385019291829185019084908082843750949750613e769650505050505050565b6040518080602001806020018060200180602001858103855289818151815260200191508051906020019060200280838360005b83811015610b12578181015183820152602001610afa565b50505050905001858103845288818151815260200191508051906020019060200280838360005b83811015610b51578181015183820152602001610b39565b50505050905001858103835287818151815260200191508051906020019060200280838360005b83811015610b90578181015183820152602001610b78565b50505050905001858103825286818151815260200191508051906020019060200280838360005b83811015610bcf578181015183820152602001610bb7565b505050509050019850505050505050505060405180910390f35b348015610bf557600080fd5b50610c0a6001604060020a036004351661414a565b60408051600160c060020a03199092168252519081900360200190f35b348015610c3357600080fd5b5061025e600160a060020a0360043581169060243516614235565b348015610c5a57600080fd5b506105e2614306565b600160e060020a0319811660009081526020819052604090205460ff165b919050565b6000806000806000806000806000610c9c611107565b6001604060020a038b1610610ce9576040805160e560020a62461bcd02815260206004820152601f60248201526000805160206150c0833981519152604482015290519081900360640190fd5b600880546001604060020a038c16908110610d0057fe5b600091825260208083206002909202909101805480845260039092526040909220805460018401546009805495975092955092936001604060020a0360a060020a80840482169590810490911693600160a060020a03938416939091169185908110610d6857fe5b90600052602060002090600491828204019190066008029054906101000a900460c060020a0287600101601c9054906101000a900463ffffffff1698509850985098509850985098505050919395979092949650565b60408051808201909152600981527f506978656c436f6e73000000000000000000000000000000000000000000000060208201525b90565b60008082801515610e3f576040805160e560020a62461bcd02815260206004820152600a6024820152600080516020615120833981519152604482015290519081900360640190fd5b600084815260036020526040902054600160a060020a03169150811515610e9e576040805160e560020a62461bcd0281526020600482015260176024820152600080516020615180833981519152604482015290519081900360640190fd5b505050600090815260066020526040902054600160a060020a031690565b600081600160a060020a0381161515610f0d576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206150e0833981519152604482015290519081900360640190fd5b5050600160a060020a031660009081526005602052604090205490565b600081801515610f72576040805160e560020a62461bcd02815260206004820152600a6024820152600080516020615120833981519152604482015290519081900360640190fd5b600083815260036020526040902054600160a060020a0390811692508416821415610fe7576040805160e560020a62461bcd02815260206004820152601d60248201527f43616e6e6f7420617070726f766520506978656c436f6e206f776e6572000000604482015290519081900360640190fd5b33600160a060020a03831614806110215750600160a060020a038216600090815260076020908152604080832033845290915290205460ff165b151561109d576040805160e560020a62461bcd02815260206004820152603260248201527f53656e64657220646f6573206e6f742068617665207065726d697373696f6e2060448201527f746f20617070726f766520616464726573730000000000000000000000000000606482015290519081900360840190fd5b600083815260066020526040808220805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0388811691821790925591518693918616917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a450505050565b60085490565b7f01ffc9a70000000000000000000000000000000000000000000000000000000081565b82600160a060020a0381161515611180576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206150e0833981519152604482015290519081900360640190fd5b82600160a060020a03811615156111cf576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206150e0833981519152604482015290519081900360640190fd5b82801515611215576040805160e560020a62461bcd02815260206004820152600a6024820152600080516020615120833981519152604482015290519081900360640190fd5b61121f338561436d565b151561129b576040805160e560020a62461bcd02815260206004820152603460248201527f53656e64657220646f6573206e6f742068617665207065726d697373696f6e2060448201527f746f207472616e7366657220506978656c436f6e000000000000000000000000606482015290519081900360840190fd5b6112a5868561443b565b6112af86856144f5565b6112b9858561472f565b8385600160a060020a031687600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6000816001604060020a0381161515611353576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615160833981519152604482015290519081900360640190fd5b61135b6121d1565b6001604060020a038416106113a8576040805160e560020a62461bcd0281526020600482015260196024820152600080516020615140833981519152604482015290519081900360640190fd5b50506001604060020a03166000908152600a602052604090205490565b60008083600160a060020a0381161515611417576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206150e0833981519152604482015290519081900360640190fd5b600160a060020a0385166000908152600460205260409020548410611486576040805160e560020a62461bcd02815260206004820152601660248201527f496e646578206973206f7574206f6620626f756e647300000000000000000000604482015290519081900360640190fd5b600160a060020a0385166000908152600460205260409020805460089190869081106114ae57fe5b90600052602060002090600491828204019190066008029054906101000a90046001604060020a03166001604060020a03168154811015156114ec57fe5b600091825260209091206002909102015495945050505050565b6000808280151561154f576040805160e560020a62461bcd02815260206004820152600a6024820152600080516020615120833981519152604482015290519081900360640190fd5b60008481526003602052604090208054909250600160a060020a031615156115af576040805160e560020a62461bcd0281526020600482015260176024820152600080516020615180833981519152604482015290519081900360640190fd5b505460a060020a90046001604060020a031692915050565b6115e383838360206040519081016040528060008152506133b8565b505050565b600080836001604060020a038116151561163a576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615160833981519152604482015290519081900360640190fd5b6116426121d1565b6001604060020a0386161061168f576040805160e560020a62461bcd0281526020600482015260196024820152600080516020615140833981519152604482015290519081900360640190fd5b6001604060020a0385166000908152600a602052604090205484106116fe576040805160e560020a62461bcd02815260206004820152601660248201527f496e646578206973206f7574206f6620626f756e647300000000000000000000604482015290519081900360640190fd5b6001604060020a0385166000908152600a60205260409020805460089190869081106114ae57fe5b6000808280151561176f576040805160e560020a62461bcd02815260206004820152600a6024820152600080516020615120833981519152604482015290519081900360640190fd5b505050600090815260036020526040902054600160a060020a0316151590565b6000611799611107565b82106117dd576040805160e560020a62461bcd02815260206004820152601f60248201526000805160206150c0833981519152604482015290519081900360640190fd5b60088054839081106117eb57fe5b9060005260206000209060020201600001549050919050565b60008083600160a060020a0381161515611856576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206150e0833981519152604482015290519081900360640190fd5b600160a060020a03851660009081526005602052604090205484106118c5576040805160e560020a62461bcd02815260206004820152601660248201527f496e646578206973206f7574206f6620626f756e647300000000000000000000604482015290519081900360640190fd5b600160a060020a0385166000908152600560205260409020805460089190869081106114ae57fe5b6000808080856001604060020a0381161515611941576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615160833981519152604482015290519081900360640190fd5b6119496121d1565b6001604060020a03881610611996576040805160e560020a62461bcd0281526020600482015260196024820152600080516020615140833981519152604482015290519081900360640190fd5b6001604060020a0387166000908152600a60205260408120805490955011611a08576040805160e560020a62461bcd02815260206004820152601b60248201527f436f6c6c656374696f6e20686173206265656e20636c65617265640000000000604482015290519081900360640190fd5b600092505b8354831015611af75760088484815481101515611a2657fe5b90600052602060002090600491828204019190066008029054906101000a90046001604060020a03166001604060020a0316815481101515611a6457fe5b90600052602060002090600202019150611a82338360000154614903565b1515611aec576040805160e560020a62461bcd028152602060048201526034602482015260008051602061510083398151915260448201527f6e6572206f662074686520506978656c436f6e73000000000000000000000000606482015290519081900360840190fd5b600190920191611a0d565b85600b886001604060020a0316815481101515611b1057fe5b90600052602060002090600491828204019190066008026101000a8154816001604060020a03021916908360c060020a90040217905550866001604060020a03167f7a2598b6ea001b660b6a3a5220b528a1837bdfe8e7937b151843c9814e7a25f6876040518082600160c060020a031916600160c060020a031916815260200191505060405180910390a2509495945050505050565b606081600160a060020a0381161515611bf8576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206150e0833981519152604482015290519081900360640190fd5b600160a060020a03831660009081526004602090815260409182902080548351818402810184019094528084529091830182828015611c8857602002820191906000526020600020906000905b82829054906101000a90046001604060020a03166001604060020a031681526020019060080190602082600701049283019260010382029150808411611c455790505b5050505050915050919050565b6060600060606000611ca5611107565b6001604060020a0387161115611d05576040805160e560020a62461bcd02815260206004820152601c60248201527f537461727420696e646578206973206f7574206f6620626f756e647300000000604482015290519081900360640190fd5b611d0d611107565b6001604060020a0386161115611d6d576040805160e560020a62461bcd02815260206004820152601a60248201527f456e6420696e646578206973206f7574206f6620626f756e6473000000000000604482015290519081900360640190fd5b6001604060020a038086169087161115611df7576040805160e560020a62461bcd02815260206004820152602660248201527f456e6420696e646578206973206c657373207468616e2074686520737461727460448201527f20696e6465780000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8585039250826001604060020a0316604051908082528060200260200182016040528015611e2f578160200160208202803883390190505b509150600090505b826001604060020a0316811015611eb557600980546001604060020a0388168301908110611e6157fe5b90600052602060002090600491828204019190066008029054906101000a900460c060020a028282815181101515611e9557fe5b600160c060020a0319909216602092830290910190910152600101611e37565b8193505b50505092915050565b60008082801515611f0b576040805160e560020a62461bcd02815260206004820152600a6024820152600080516020615120833981519152604482015290519081900360640190fd5b60008481526003602052604090208054909250600160a060020a03161515611f6b576040805160e560020a62461bcd0281526020600482015260176024820152600080516020615180833981519152604482015290519081900360640190fd5b815460088054909160a060020a90046001604060020a0316908110611f8c57fe5b6000918252602090912060029091020160010154600160a060020a0316949350505050565b6060600060606000611fc16121d1565b6001604060020a0387161115612021576040805160e560020a62461bcd02815260206004820152601c60248201527f537461727420696e646578206973206f7574206f6620626f756e647300000000604482015290519081900360640190fd5b6120296121d1565b6001604060020a0386161115612089576040805160e560020a62461bcd02815260206004820152601a60248201527f456e6420696e646578206973206f7574206f6620626f756e6473000000000000604482015290519081900360640190fd5b6001604060020a038086169087161115612113576040805160e560020a62461bcd02815260206004820152602660248201527f456e6420696e646578206973206c657373207468616e2074686520737461727460448201527f20696e6465780000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8585039250826001604060020a031660405190808252806020026020018201604052801561214b578160200160208202803883390190505b509150600090505b826001604060020a0316811015611eb557600b80546001604060020a038816830190811061217d57fe5b90600052602060002090600491828204019190066008029054906101000a900460c060020a0282828151811015156121b157fe5b600160c060020a0319909216602092830290910190910152600101612153565b600b5490565b60008082801515612220576040805160e560020a62461bcd02815260206004820152600a6024820152600080516020615120833981519152604482015290519081900360640190fd5b600084815260036020526040902054600160a060020a0316915081151561227f576040805160e560020a62461bcd0281526020600482015260176024820152600080516020615180833981519152604482015290519081900360640190fd5b5092915050565b60006060826001604060020a03811615156122d9576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615160833981519152604482015290519081900360640190fd5b6122e16121d1565b6001604060020a0385161061232e576040805160e560020a62461bcd0281526020600482015260196024820152600080516020615140833981519152604482015290519081900360640190fd5b600b80546001604060020a03861690811061234557fe5b600091825260208083206004830401546001604060020a0388168452600a8252604093849020805485518185028101850190965280865260039094166008026101000a90910460c060020a0293909290918391908301828280156123fa57602002820191906000526020600020906000905b82829054906101000a90046001604060020a03166001604060020a0316815260200190600801906020826007010492830192600103820291508084116123b75790505b505050505090509250925050915091565b600154600160a060020a031690565b600081600160a060020a038116151561246b576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206150e0833981519152604482015290519081900360640190fd5b5050600160a060020a031660009081526004602052604090205490565b600080838015156124d1576040805160e560020a62461bcd02815260206004820152600a6024820152600080516020615120833981519152604482015290519081900360640190fd5b6124db3386614903565b1515612545576040805160e560020a62461bcd028152602060048201526023602482015260008051602061510083398151915260448201527f6e65720000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b60008581526003602052604090208054600980549294508692909160a060020a90046001604060020a031690811061257957fe5b90600052602060002090600491828204019190066008026101000a8154816001604060020a03021916908360c060020a90040217905550847fd3d90f94542b3ca93f1a474e55393834e376ebbac7df618dcf7f9327c57d6c5e856040518082600160c060020a031916600160c060020a031916815260200191505060405180910390a2505460a060020a90046001604060020a03169392505050565b6000816001604060020a0381161515612666576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615160833981519152604482015290519081900360640190fd5b61266e6121d1565b6001604060020a038416106126bb576040805160e560020a62461bcd0281526020600482015260196024820152600080516020615140833981519152604482015290519081900360640190fd5b50506001604060020a03166000908152600a60205260409020541590565b60408051808201909152600481527f5058434e00000000000000000000000000000000000000000000000000000000602082015290565b600154600160a060020a03163314612798576040805160e560020a62461bcd02815260206004820152602560248201527f4f6e6c79207468652061646d696e2063616e2063616c6c20746869732066756e60448201527f6374696f6e000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6001805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0392909216919091179055565b600080808080808089600160a060020a038116151561281e576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206150e0833981519152604482015290519081900360640190fd5b89801515612864576040805160e560020a62461bcd02815260206004820152600a6024820152600080516020615120833981519152604482015290519081900360640190fd5b60008b81526003602052604090206008549098506001604060020a03116128fb576040805160e560020a62461bcd02815260206004820152602860248201527f4d6178206e756d626572206f6620506978656c436f6e7320686173206265656e60448201527f2072656163686564000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8754600160a060020a03161561295b576040805160e560020a62461bcd02815260206004820152601760248201527f506978656c436f6e20616c726561647920657869737473000000000000000000604482015290519081900360640190fd5b60009650640100000000421015612970574296505b6008805489547bffffffffffffffff0000000000000000000000000000000000000000191660a060020a6001604060020a03831602178a558154909750906129bb9060018301614f7f565b5060098054906129ce9060018301614fab565b50600880546001604060020a0388169081106129e657fe5b600091825260209091206002909102018b81556001810180543373ffffffffffffffffffffffffffffffffffffffff19909116177bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e060020a63ffffffff8b1602179055600980549196508b916001604060020a038916908110612a6457fe5b60009182526020808320600483040180546001604060020a0360039094166008026101000a938402191660c060020a909504929092029390931790553381526005909152604090208054909450925082612ac18560018301614fab565b50858484815481101515612ad157fe5b90600052602060002090600491828204019190066008026101000a8154816001604060020a0302191690836001604060020a03160217905550612b148c8c61472f565b604080516001604060020a0388168152600160a060020a038e166020820152815133928e927f5ada7cc76c691909522f79b403dee86482e43a5064fb2d5849c685ab7d40be20929081900390910190a36040518b90600160a060020a038e16906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a450939a9950505050505050505050565b6000808080846001604060020a0381161515612c00576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615160833981519152604482015290519081900360640190fd5b612c086121d1565b6001604060020a03871610612c55576040805160e560020a62461bcd0281526020600482015260196024820152600080516020615140833981519152604482015290519081900360640190fd5b6001604060020a0386166000908152600a60205260408120805490955011612cc7576040805160e560020a62461bcd02815260206004820152601d60248201527f436f6c6c656374696f6e20697320616c726561647920636c6561726564000000604482015290519081900360640190fd5b600092505b8354831015612ddd5760088484815481101515612ce557fe5b90600052602060002090600491828204019190066008029054906101000a90046001604060020a03166001604060020a0316815481101515612d2357fe5b90600052602060002090600202019150612d41338360000154614903565b1515612dab576040805160e560020a62461bcd028152602060048201526034602482015260008051602061510083398151915260448201527f6e6572206f662074686520506978656c436f6e73000000000000000000000000606482015290519081900360840190fd5b600180830180547bffffffffffffffff0000000000000000000000000000000000000000191690559290920191612ccc565b600b80546001604060020a038816908110612df457fe5b60009182526020808320600483040180546001604060020a0360086003909516949094026101000a8402191690559088168252600a905260408120612e3891614fdf565b6040516001604060020a038716907fde081b46744cc92faa6c6d642ed219cefffea3d48bb6886384897031160b9a6190600090a25093949350505050565b81600160a060020a0381161515612ec5576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206150e0833981519152604482015290519081900360640190fd5b600160a060020a038316331415612f26576040805160e560020a62461bcd02815260206004820152601360248201527f43616e6e6f7420617070726f76652073656c6600000000000000000000000000604482015290519081900360640190fd5b336000818152600760209081526040808320600160a060020a03881680855290835292819020805460ff1916871515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a3505050565b600154600160a060020a0316331461301d576040805160e560020a62461bcd02815260206004820152602560248201527f4f6e6c79207468652061646d696e2063616e2063616c6c20746869732066756e60448201527f6374696f6e000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b604051600160a060020a03821690303180156108fc02916000818181858888f19350505050158015613053573d6000803e3d6000fd5b5050565b6060600b8054806020026020016040519081016040528092919081815260200182805480156130d557602002820191906000526020600020906000905b82829054906101000a900460c060020a02600160c060020a031916815260200190600801906020826007010492830192600103820291508084116130945790505b5050505050905090565b6060816001604060020a0381161515613130576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615160833981519152604482015290519081900360640190fd5b6001604060020a0383166000908152600a602090815260409182902080548351818402810184019094528084529091830182828015611c8857600091825260209182902080546001604060020a03168452908202830192909160089101808411611c4557509498975050505050505050565b60008080808080808080898015156131f2576040805160e560020a62461bcd02815260206004820152600a6024820152600080516020615120833981519152604482015290519081900360640190fd5b60008b81526003602052604090208054909350600160a060020a03161515613252576040805160e560020a62461bcd0281526020600482015260176024820152600080516020615180833981519152604482015290519081900360640190fd5b825460088054909160a060020a90046001604060020a031690811061327357fe5b6000918252602090912060029091020180548454600183015460098054949650929360a060020a8084046001604060020a03908116959184041693600160a060020a03908116931691859081106132c657fe5b90600052602060002090600491828204019190066008029054906101000a900460c060020a0287600101601c9054906101000a900463ffffffff169950995099509950995099509950505050919395979092949650565b600154600160a060020a031633146133a5576040805160e560020a62461bcd02815260206004820152602560248201527f4f6e6c79207468652061646d696e2063616e2063616c6c20746869732066756e60448201527f6374696f6e000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b8051613053906002906020840190615007565b6133c3848484611131565b6133cf8484848461498d565b1515613425576040805160e560020a62461bcd02815260206004820152601560248201527f5472616e7366657220776173206e6f7420736166650000000000000000000000604482015290519081900360640190fd5b50505050565b60008082801515613474576040805160e560020a62461bcd02815260206004820152600a6024820152600080516020615120833981519152604482015290519081900360640190fd5b60008481526003602052604090208054909250600160a060020a031615156134d4576040805160e560020a62461bcd0281526020600482015260176024820152600080516020615180833981519152604482015290519081900360640190fd5b60008481526003602052604090205460088054909160a060020a90046001604060020a031690811061350257fe5b600091825260209091206002909102016001015460a060020a90046001604060020a0316949350505050565b60008060008060008060016801000000000000000003600b805490501015156135c7576040805160e560020a62461bcd02815260206004820152602a60248201527f4d6178206e756d626572206f6620636f6c6c656374696f6e732068617320626560448201527f656e207265616368656400000000000000000000000000000000000000000000606482015290519081900360840190fd5b8751600110613646576040805160e560020a62461bcd02815260206004820152602e60248201527f436f6c6c656374696f6e206d75737420636f6e7461696e206d6f72652074686160448201527f6e206f6e6520506978656c436f6e000000000000000000000000000000000000606482015290519081900360840190fd5b600b546001604060020a0381166000908152600a60205260409020895191965094506136728582614fab565b50600092505b87518310156138ad57878381518110151561368f57fe5b9060200190602002015191506136a3611107565b6001604060020a038316106136f0576040805160e560020a62461bcd02815260206004820152601f60248201526000805160206150c0833981519152604482015290519081900360640190fd5b600880546001604060020a03841690811061370757fe5b90600052602060002090600202019050613725338260000154614903565b151561378f576040805160e560020a62461bcd028152602060048201526034602482015260008051602061510083398151915260448201527f6e6572206f662074686520506978656c436f6e73000000000000000000000000606482015290519081900360840190fd5b600181015460a060020a90046001604060020a03161561381f576040805160e560020a62461bcd02815260206004820152602360248201527f506978656c436f6e20697320616c726561647920696e206120636f6c6c65637460448201527f696f6e0000000000000000000000000000000000000000000000000000000000606482015290519081900360840190fd5b6001810180547bffffffffffffffff0000000000000000000000000000000000000000191660a060020a6001604060020a038816021790558354829085908590811061386757fe5b90600052602060002090600491828204019190066008026101000a8154816001604060020a0302191690836001604060020a031602179055508280600101935050613678565b600b8054906138bf9060018301614fab565b5086600b866001604060020a03168154811015156138d957fe5b90600052602060002090600491828204019190066008026101000a8154816001604060020a03021916908360c060020a90040217905550846001604060020a031633600160a060020a03167f19c41bfdfa6988beb6f4ed9b9b4bc922dfe576b16b8299b466350ebb8f8ff0cd60405160405180910390a350929695505050505050565b600081815260036020526040812080546060929081908490600160a060020a031615156139c1576040805160e560020a62461bcd0281526020600482015260176024820152600080516020615180833981519152604482015290519081900360640190fd5b835460088054909160a060020a90046001604060020a03169081106139e257fe5b9060005260206000209060020201925060098460000160149054906101000a90046001604060020a03166001604060020a0316815481101515613a2157fe5b90600052602060002090600491828204019190066008029054906101000a900460c060020a02915060028054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015613adf5780601f10613ab457610100808354040283529160200191613adf565b820191906000526020600020905b815481529060010190602001808311613ac257829003601f168201915b50505050509050613b30816040805190810160405280600981526020017f3c746f6b656e49643e0000000000000000000000000000000000000000000000815250613b2b896020614afa565b614c9a565b60408051808201909152600c81527f3c746f6b656e496e6465783e000000000000000000000000000000000000000060208201528554919250613b8b91839190613b2b9060a060020a90046001604060020a03166008614afa565b9050613bd9816040805190810160405280600681526020017f3c6e616d653e0000000000000000000000000000000000000000000000000000815250613b2b8560c060020a90046008614afa565b60408051808201909152600781527f3c6f776e65723e0000000000000000000000000000000000000000000000000060208201528554919250613c2d91839190613b2b90600160a060020a03166014614afa565b60408051808201909152600981527f3c63726561746f723e000000000000000000000000000000000000000000000060208201526001850154919250613c8491839190613b2b90600160a060020a03166014614afa565b60408051808201909152600d81527f3c64617465437265617465643e0000000000000000000000000000000000000060208201526001850154919250613cdf91839190613b2b9060e060020a900463ffffffff166008614afa565b60408051808201909152601181527f3c636f6c6c656374696f6e496e6465783e00000000000000000000000000000060208201526001850154919250613d3d91839190613b2b9060a060020a90046001604060020a03166008614afa565b9695505050505050565b606081600160a060020a0381161515613d98576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206150e0833981519152604482015290519081900360640190fd5b600160a060020a03831660009081526005602090815260409182902080548351818402810184019094528084529091830182828015611c8857600091825260209182902080546001604060020a03168452908202830192909160089101808411611c4557509498975050505050505050565b6000816001604060020a0381161515613e5b576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615160833981519152604482015290519081900360640190fd5b613e636121d1565b836001604060020a031610915050919050565b6060806060806060806060806000808a51604051908082528060200260200182016040528015613eb0578160200160208202803883390190505b5095508a51604051908082528060200260200182016040528015613ede578160200160208202803883390190505b5094508a51604051908082528060200260200182016040528015613f0c578160200160208202803883390190505b5093508a51604051908082528060200260200182016040528015613f3a578160200160208202803883390190505b509250600091505b8a51821015614139578a82815181101515613f5957fe5b906020019060200201519050613f6d611107565b6001604060020a03821610613fba576040805160e560020a62461bcd02815260206004820152601f60248201526000805160206150c0833981519152604482015290519081900360640190fd5b600880546001604060020a038316908110613fd157fe5b9060005260206000209060020201600001548683815181101515613ff157fe5b60209081029091010152600980546001604060020a03831690811061401257fe5b90600052602060002090600491828204019190066008029054906101000a900460c060020a02858381518110151561404657fe5b600160c060020a0319909216602092830290910190910152600880546003916000916001604060020a03851690811061407b57fe5b6000918252602080832060029092029091015483528201929092526040019020548451600160a060020a03909116908590849081106140b657fe5b600160a060020a03909216602092830290910190910152600880546001604060020a0383169081106140e457fe5b906000526020600020906002020160010160149054906101000a90046001604060020a0316838381518110151561411757fe5b6001604060020a03909216602092830290910190910152600190910190613f42565b509399929850909650945092505050565b6000816001604060020a038116151561419b576040805160e560020a62461bcd02815260206004820152600d6024820152600080516020615160833981519152604482015290519081900360640190fd5b6141a36121d1565b6001604060020a038416106141f0576040805160e560020a62461bcd0281526020600482015260196024820152600080516020615140833981519152604482015290519081900360640190fd5b600b80546001604060020a03851690811061420757fe5b90600052602060002090600491828204019190066008029054906101000a900460c060020a02915050919050565b600082600160a060020a0381161515614286576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206150e0833981519152604482015290519081900360640190fd5b82600160a060020a03811615156142d5576040805160e560020a62461bcd02815260206004820152600f60248201526000805160206150e0833981519152604482015290519081900360640190fd5b505050600160a060020a03918216600090815260076020908152604080832093909416825291909152205460ff1690565b606060098054806020026020016040519081016040528092919081815260200182805480156130d5576000918252602091829020805460c060020a02600160c060020a03191684529082028301929091600891018084116130945790505050505050905090565b600081815260036020526040812054600160a060020a03168015156143ca576040805160e560020a62461bcd0281526020600482015260176024820152600080516020615180833981519152604482015290519081900360640190fd5b80600160a060020a031684600160a060020a031614806144035750600083815260066020526040902054600160a060020a038581169116145b806144335750600160a060020a0380821660009081526007602090815260408083209388168352929052205460ff165b949350505050565b600081815260036020526040902054600160a060020a038381169116146144ac576040805160e560020a62461bcd02815260206004820152601860248201527f496e636f727265637420506978656c436f6e206f776e65720000000000000000604482015290519081900360640190fd5b600081815260066020526040902054600160a060020a031615613053576000908152600660205260409020805473ffffffffffffffffffffffffffffffffffffffff1916905550565b600160a060020a03808316600081815260046020908152604080832086845260039092528220805491949093911614614578576040805160e560020a62461bcd02815260206004820152601960248201527f46726f6d206164647265737320697320696e636f727265637400000000000000604482015290519081900360640190fd5b815473ffffffffffffffffffffffffffffffffffffffff191682558254839060001981019081106145a557fe5b90600052602060002090600491828204019190066008029054906101000a90046001604060020a031690508260018480549050038154811015156145e557fe5b90600052602060002090600491828204019190066008026101000a8154906001604060020a030219169055828054809190600190036146249190614fab565b508254825460e060020a900463ffffffff16101561470757815483548291859160e060020a90910463ffffffff1690811061465b57fe5b90600052602060002090600491828204019190066008026101000a8154816001604060020a0302191690836001604060020a0316021790555081600001601c9054906101000a900463ffffffff16600360006008846001604060020a03168154811015156146c557fe5b9060005260206000209060020201600001548152602001908152602001600020600001601c6101000a81548163ffffffff021916908363ffffffff1602179055505b5080547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff169055505050565b600160a060020a03821660009081526004602090815260408083208484526003909252822081549192909163ffffffff116147da576040805160e560020a62461bcd02815260206004820152603260248201527f4d6178206e756d626572206f6620506978656c436f6e7320706572206f776e6560448201527f7220686173206265656e20726561636865640000000000000000000000000000606482015290519081900360840190fd5b8154600160a060020a03161561483a576040805160e560020a62461bcd02815260206004820152601d60248201527f506978656c436f6e20616c72656164792068617320616e206f776e6572000000604482015290519081900360640190fd5b50805473ffffffffffffffffffffffffffffffffffffffff1916600160a060020a0385161781558154806148718460018301614fab565b5081547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1660e060020a63ffffffff83160217808355835460a060020a9091046001604060020a0316908490839081106148c357fe5b90600052602060002090600491828204019190066008026101000a8154816001604060020a0302191690836001604060020a031602179055505050505050565b6000818152600360205260408120805460088054600160a060020a0383169285929160a060020a9091046001604060020a031690811061493f57fe5b6000918252602090912060016002909202010154600160a060020a039081169150868116908316148015613d3d575080600160a060020a031686600160a060020a0316149695505050505050565b6000806149a285600160a060020a0316614e2e565b15156149b15760019150614af1565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03898116602485015260448401889052608060648501908152875160848601528751918a169463150b7a0294938c938b938b93909160a490910190602085019080838360005b83811015614a44578181015183820152602001614a2c565b50505050905090810190601f168015614a715780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b158015614a9357600080fd5b505af1158015614aa7573d6000803e3d6000fd5b505050506040513d6020811015614abd57600080fd5b5051600160e060020a031981167f150b7a020000000000000000000000000000000000000000000000000000000014925090505b50949350505050565b606080600080600080866002026002016040519080825280601f01601f191660200182016040528015614b37578160200160208202803883390190505b509450603060f860020a02856000815181101515614b5157fe5b906020010190600160f860020a031916908160001a90535084517f78000000000000000000000000000000000000000000000000000000000000009086906001908110614b9a57fe5b906020010190600160f860020a031916908160001a905350600093505b86841015614c8e5783600188030360080260020a88811515614bd557fe5b0460f860020a02925060108360f860020a900460ff16811515614bf457fe5b0460f860020a0291508160f860020a90046010028360f860020a90040360f860020a029050614c2282614e36565b8585600202600201815181101515614c3657fe5b906020010190600160f860020a031916908160001a905350614c5781614e36565b8585600202600301815181101515614c6b57fe5b906020010190600160f860020a031916908160001a905350600190930192614bb7565b50929695505050505050565b606083838360008481614cad8686614eb2565b92508551831015614e1d5784518451875101036040519080825280601f01601f191660200182016040528015614ced578160200160208202803883390190505b509150600090505b82811015614d4c578581815181101515614d0b57fe5b90602001015160f860020a900460f860020a028282815181101515614d2c57fe5b906020010190600160f860020a031916908160001a905350600101614cf5565b5060005b8351811015614daa578381815181101515614d6757fe5b90602001015160f860020a900460f860020a0282828501815181101515614d8a57fe5b906020010190600160f860020a031916908160001a905350600101614d50565b5060005b84518301865103811015614e155785818651850101815181101515614dcf57fe5b90602001015160f860020a900460f860020a0282828651860101815181101515614df557fe5b906020010190600160f860020a031916908160001a905350600101614dae565b819650614e21565b8596505b5050505050509392505050565b6000903b1190565b60007f0a000000000000000000000000000000000000000000000000000000000000007fff0000000000000000000000000000000000000000000000000000000000000083161015614e9a578160f860020a900460300160f860020a029050610c81565b8160f860020a900460570160f860020a029050610c81565b60008080805b6001855103865103831015614f7457506001905060005b8451811015614f5b578481815181101515614ee657fe5b90602001015160f860020a900460f860020a02600160f860020a03191686828501815181101515614f1357fe5b60209101015160f860020a90819004027fff000000000000000000000000000000000000000000000000000000000000001614614f535760009150614f5b565b600101614ecf565b8115614f6957829350611eb9565b600190920191614eb8565b505092519392505050565b8154818355818111156115e3576002028160020283600052602060002091820191016115e39190615085565b8154818355818111156115e35760030160049004816003016004900483600052602060002091820191016115e391906150a5565b50805460008255600301600490049060005260206000209081019061500491906150a5565b50565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061504857805160ff1916838001178555615075565b82800160010185558215615075579182015b8281111561507557825182559160200191906001019061505a565b506150819291506150a5565b5090565b610df391905b80821115615081576000808255600182015560020161508b565b610df391905b8082111561508157600081556001016150ab5600506978656c436f6e20696e646578206973206f7574206f6620626f756e647300496e76616c69642061646472657373000000000000000000000000000000000053656e646572206973206e6f74207468652063726561746f7220616e64206f77496e76616c696420494400000000000000000000000000000000000000000000436f6c6c656374696f6e20646f6573206e6f7420657869737400000000000000496e76616c696420696e64657800000000000000000000000000000000000000506978656c436f6e20646f6573206e6f74206578697374000000000000000000a165627a7a7230582077ffeec90901ca8892dfe29369dbc8502d147fb5bb835c420d9b2b4b96eb29620029

Swarm Source

bzzr://77ffeec90901ca8892dfe29369dbc8502d147fb5bb835c420d9b2b4b96eb2962
Block Transaction Difficulty Gas Used Reward
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.