ETH Price: $1,947.74 (+1.06%)
Gas: 0.13 Gwei

Transaction Decoder

Block:
9394570 at Feb-01-2020 05:09:39 AM +UTC
Transaction Fee:
0.000506844 ETH $0.99
Gas Used:
253,422 Gas / 2 Gwei

Emitted Events:

133 CodexCoin.Transfer( from=[Receiver] 0xd8b93107d820d294cd8082a15c65261ee9d30790, to=0xBe25eE3619472545418Acb609B0CE6cA6F69bdfB, value=20000000000000000000 )
134 CodexRecordProxy.0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef( 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef, 0x0000000000000000000000000000000000000000000000000000000000000000, 0x00000000000000000000000030a0ce8008a53f0c75cb4a0cb201314093d41603, 0x000000000000000000000000000000000000000000000000000000000006d806 )
135 CodexRecordProxy.0x9573133e4bf0477d257d5e746e10de577953ee706da897be78cf668a64c16a16( 0x9573133e4bf0477d257d5e746e10de577953ee706da897be78cf668a64c16a16, 000000000000000000000000000000000000000000000000000000000006d806, 0000000000000000000000000000000000000000000000000000000000000040, 000000000000000000000000000000000000000000000000000000000000001f, 636f6465783a3a35653335303739346335303338363138373162656438653100 )
136 0xd8b93107d820d294cd8082a15c65261ee9d30790.( )

Account State Difference:

  Address   Before After State Difference Code
0x4e57529d...e4C632bAF
27.637406670628653907 Eth
Nonce: 436070
27.636899826628653907 Eth
Nonce: 436071
0.000506844
(Spark Pool)
26.727808719589107309 Eth26.728315563589107309 Eth0.000506844
0x8853B058...FA43d2a79
0xf226e38c...0035436ee

Execution Trace

0xd8b93107d820d294cd8082a15c65261ee9d30790.ee5301d5( )
  • 0x029c8f8668c2f89379e23ba27c6af9847a1ceec7.c5ae44de( )
    • CodexRecordProxy.STATICCALL( )
      • CodexRecord.DELEGATECALL( )
      • 0x029c8f8668c2f89379e23ba27c6af9847a1ceec7.STATICCALL( )
      • CodexCoin.transfer( _to=0xBe25eE3619472545418Acb609B0CE6cA6F69bdfB, _value=20000000000000000000 ) => ( True )
      • 0x029c8f8668c2f89379e23ba27c6af9847a1ceec7.b3c2f627( )
      • CodexRecordProxy.ee5301d5( )
        • CodexRecord.mint( )
          File 1 of 3: CodexCoin
          pragma solidity 0.4.24;
          
          // File: contracts/library/Ownable.sol
          
          /**
           * @title Ownable
           * @dev The Ownable contract has an owner address, and provides basic authorization control
           * functions, this simplifies the implementation of "user permissions".
           */
          contract Ownable {
            address public owner;
          
          
            event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
          
          
            /**
             * @dev The Ownable constructor sets the original `owner` of the contract to the sender
             * account.
             */
            constructor() public {
              owner = msg.sender;
            }
          
            /**
             * @dev Throws if called by any account other than the owner.
             */
            modifier onlyOwner() {
              require(msg.sender == owner);
              _;
            }
          
            /**
             * @dev Allows the current owner to transfer control of the contract to a newOwner.
             * @param newOwner The address to transfer ownership to.
             */
            function transferOwnership(address newOwner) public onlyOwner {
              require(newOwner != address(0));
              emit OwnershipTransferred(owner, newOwner);
              owner = newOwner;
            }
          
          }
          
          // File: contracts/library/Pausable.sol
          
          /**
           * @title Pausable
           * @dev Base contract which allows children to implement an emergency stop mechanism.
           */
          contract Pausable is Ownable {
            event Pause();
            event Unpause();
          
            bool public paused = false;
          
          
            /**
             * @dev Modifier to make a function callable only when the contract is not paused.
             */
            modifier whenNotPaused() {
              require(!paused);
              _;
            }
          
            /**
             * @dev Modifier to make a function callable only when the contract is paused.
             */
            modifier whenPaused() {
              require(paused);
              _;
            }
          
            /**
             * @dev called by the owner to pause, triggers stopped state
             */
            function pause() onlyOwner whenNotPaused public {
              paused = true;
              emit Pause();
            }
          
            /**
             * @dev called by the owner to unpause, returns to normal state
             */
            function unpause() onlyOwner whenPaused public {
              paused = false;
              emit Unpause();
            }
          }
          
          // File: contracts/library/SafeMath.sol
          
          /**
           * @title SafeMath
           * @dev Math operations with safety checks that throw on error
           */
          library SafeMath {
          
            /**
            * @dev Multiplies two numbers, throws on overflow.
            */
            function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
              if (a == 0) {
                return 0;
              }
              c = a * b;
              assert(c / a == b);
              return c;
            }
          
            /**
            * @dev Integer division of two numbers, truncating the quotient.
            */
            function div(uint256 a, uint256 b) internal pure returns (uint256) {
              // assert(b > 0); // Solidity automatically throws when dividing by 0
              uint256 c = a / b;
              // assert(a == b * c + a % b); // There is no case in which this doesn't hold
              return c;
            }
          
            /**
            * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
            */
            function sub(uint256 a, uint256 b) internal pure returns (uint256) {
              assert(b <= a);
              return a - b;
            }
          
            /**
            * @dev Adds two numbers, throws on overflow.
            */
            function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
              c = a + b;
              assert(c >= a);
              return c;
            }
          }
          
          // File: contracts/ERC20/ERC20Basic.sol
          
          /**
           * @title ERC20Basic
           * @dev Simpler version of ERC20 interface
           * @dev see https://github.com/ethereum/EIPs/issues/179
           */
          contract ERC20Basic {
            function totalSupply() public view returns (uint256);
            function balanceOf(address who) public view returns (uint256);
            function transfer(address to, uint256 value) public returns (bool);
            event Transfer(address indexed from, address indexed to, uint256 value);
          }
          
          // File: contracts/ERC20/BasicToken.sol
          
          /**
           * @title Basic token
           * @dev Basic version of StandardToken, with no allowances.
           */
          contract BasicToken is ERC20Basic {
            using SafeMath for uint256;
          
            mapping(address => uint256) balances;
          
            uint256 totalSupply_;
          
            /**
            * @dev total number of tokens in existence
            */
            function totalSupply() public view returns (uint256) {
              return totalSupply_;
            }
          
            /**
            * @dev transfer token for a specified address
            * @param _to The address to transfer to.
            * @param _value The amount to be transferred.
            */
            function transfer(address _to, uint256 _value) public returns (bool) {
              require(_to != address(0));
              require(_value <= balances[msg.sender]);
          
              // SafeMath.sub will throw if there is not enough balance.
              balances[msg.sender] = balances[msg.sender].sub(_value);
              balances[_to] = balances[_to].add(_value);
              emit Transfer(msg.sender, _to, _value);
              return true;
            }
          
            /**
            * @dev Gets the balance of the specified address.
            * @param _owner The address to query the the balance of.
            * @return An uint256 representing the amount owned by the passed address.
            */
            function balanceOf(address _owner) public view returns (uint256 balance) {
              return balances[_owner];
            }
          }
          
          // File: contracts/ERC20/ERC20.sol
          
          /**
           * @title ERC20 interface
           * @dev see https://github.com/ethereum/EIPs/issues/20
           */
          contract ERC20 is ERC20Basic {
            function allowance(address owner, address spender) public view returns (uint256);
            function transferFrom(address from, address to, uint256 value) public returns (bool);
            function approve(address spender, uint256 value) public returns (bool);
            event Approval(address indexed owner, address indexed spender, uint256 value);
          }
          
          // File: contracts/ERC20/StandardToken.sol
          
          /**
           * @title Standard ERC20 token
           *
           * @dev Implementation of the basic standard token.
           * @dev https://github.com/ethereum/EIPs/issues/20
           * @dev Based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
           */
          contract StandardToken is ERC20, BasicToken {
          
            mapping (address => mapping (address => uint256)) internal allowed;
          
          
            /**
             * @dev Transfer tokens from one address to another
             * @param _from address The address which you want to send tokens from
             * @param _to address The address which you want to transfer to
             * @param _value uint256 the amount of tokens to be transferred
             */
            function transferFrom(address _from, address _to, uint256 _value) public returns (bool) {
              require(_to != address(0));
              require(_value <= balances[_from]);
              require(_value <= allowed[_from][msg.sender]);
          
              balances[_from] = balances[_from].sub(_value);
              balances[_to] = balances[_to].add(_value);
              allowed[_from][msg.sender] = allowed[_from][msg.sender].sub(_value);
              emit Transfer(_from, _to, _value);
              return true;
            }
          
            /**
             * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
             *
             * Beware that changing an allowance with this method brings the risk that someone may use both the old
             * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
             * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
             * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
             * @param _spender The address which will spend the funds.
             * @param _value The amount of tokens to be spent.
             */
            function approve(address _spender, uint256 _value) public returns (bool) {
              allowed[msg.sender][_spender] = _value;
              emit Approval(msg.sender, _spender, _value);
              return true;
            }
          
            /**
             * @dev Function to check the amount of tokens that an owner allowed to a spender.
             * @param _owner address The address which owns the funds.
             * @param _spender address The address which will spend the funds.
             * @return A uint256 specifying the amount of tokens still available for the spender.
             */
            function allowance(address _owner, address _spender) public view returns (uint256) {
              return allowed[_owner][_spender];
            }
          
            /**
             * @dev Increase the amount of tokens that an owner allowed to a spender.
             *
             * approve should be called when allowed[_spender] == 0. To increment
             * allowed value is better to use this function to avoid 2 calls (and wait until
             * the first transaction is mined)
             * From MonolithDAO Token.sol
             * @param _spender The address which will spend the funds.
             * @param _addedValue The amount of tokens to increase the allowance by.
             */
            function increaseApproval(address _spender, uint _addedValue) public returns (bool) {
              allowed[msg.sender][_spender] = allowed[msg.sender][_spender].add(_addedValue);
              emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
              return true;
            }
          
            /**
             * @dev Decrease the amount of tokens that an owner allowed to a spender.
             *
             * approve should be called when allowed[_spender] == 0. To decrement
             * allowed value is better to use this function to avoid 2 calls (and wait until
             * the first transaction is mined)
             * From MonolithDAO Token.sol
             * @param _spender The address which will spend the funds.
             * @param _subtractedValue The amount of tokens to decrease the allowance by.
             */
            function decreaseApproval(address _spender, uint _subtractedValue) public returns (bool) {
              uint oldValue = allowed[msg.sender][_spender];
              if (_subtractedValue > oldValue) {
                allowed[msg.sender][_spender] = 0;
              } else {
                allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
              }
          
              emit Approval(msg.sender, _spender, allowed[msg.sender][_spender]);
              return true;
            }
          
          }
          
          // File: contracts/ERC20/PausableToken.sol
          
          /**
           * @title Pausable token
           * @dev StandardToken modified with pausable transfers.
           **/
          contract PausableToken is StandardToken, Pausable {
          
            function transfer(
              address _to,
              uint256 _value
            )
              public
              whenNotPaused
              returns (bool)
            {
              return super.transfer(_to, _value);
            }
          
            function transferFrom(
              address _from,
              address _to,
              uint256 _value
            )
              public
              whenNotPaused
              returns (bool)
            {
              return super.transferFrom(_from, _to, _value);
            }
          
            function approve(
              address _spender,
              uint256 _value
            )
              public
              whenNotPaused
              returns (bool)
            {
              return super.approve(_spender, _value);
            }
          
            function increaseApproval(
              address _spender,
              uint _addedValue
            )
              public
              whenNotPaused
              returns (bool success)
            {
              return super.increaseApproval(_spender, _addedValue);
            }
          
            function decreaseApproval(
              address _spender,
              uint _subtractedValue
            )
              public
              whenNotPaused
              returns (bool success)
            {
              return super.decreaseApproval(_spender, _subtractedValue);
            }
          }
          
          // File: contracts/CodexCoin.sol
          
          contract CodexCoin is PausableToken {
          
            /* solium-disable uppercase */
            uint8 constant public decimals = 18;
          
            string constant public name = "CodexCoin";
          
            string constant public symbol = "CODX";
            /* solium-enable */
          
            constructor(uint256 _totalSupply) public {
              totalSupply_ = _totalSupply;
              balances[msg.sender] = totalSupply_;
            }
          
            /**
             * @dev Reclaim all ERC20Basic compatible tokens
             * @param token ERC20Basic The address of the token contract
             */
            function reclaimToken(ERC20Basic token) external onlyOwner {
              uint256 balance = token.balanceOf(this);
              token.transfer(owner, balance);
            }
          }

          File 2 of 3: CodexRecordProxy
          pragma solidity 0.4.24;
          
          // File: contracts/ERC165/ERC165.sol
          
          /**
           * @dev A standard for detecting smart contract interfaces.
           * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
           */
          contract ERC165 {
          
            // bytes4(keccak256('supportsInterface(bytes4)'));
            bytes4 constant INTERFACE_ERC165 = 0x01ffc9a7;
          
            /**
             * @dev Checks if the smart contract includes a specific interface.
             * @param _interfaceID The interface identifier, as specified in ERC-165.
             */
            function supportsInterface(bytes4 _interfaceID) public pure returns (bool) {
              return _interfaceID == INTERFACE_ERC165;
            }
          }
          
          // File: contracts/ERC721/ERC721Basic.sol
          
          /**
           * @title ERC721 Non-Fungible Token Standard basic interface
           * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
           */
          contract ERC721Basic {
            // 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 constant INTERFACE_ERC721 = 0x80ac58cd;
          
            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 indexed _approved);
          
            function balanceOf(address _owner) public view returns (uint256 _balance);
            function ownerOf(uint256 _tokenId) public view returns (address _owner);
          
            // Note: This is not in the official ERC-721 standard so it's not included in the interface hash
            function exists(uint256 _tokenId) public view returns (bool _exists);
          
            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;
          }
          
          // File: contracts/ERC721/ERC721.sol
          
          /**
           * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
           * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
           */
          contract ERC721Enumerable is ERC721Basic {
            // bytes4(keccak256('totalSupply()')) ^
            // bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^
            // bytes4(keccak256('tokenByIndex(uint256)'));
            bytes4 constant INTERFACE_ERC721_ENUMERABLE = 0x780e9d63;
          
            function totalSupply() public view returns (uint256);
            function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256 _tokenId);
            function tokenByIndex(uint256 _index) public view returns (uint256);
          }
          
          
          /**
           * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
           * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
           */
          contract ERC721Metadata is ERC721Basic {
            // bytes4(keccak256('name()')) ^
            // bytes4(keccak256('symbol()')) ^
            // bytes4(keccak256('tokenURI(uint256)'));
            bytes4 constant INTERFACE_ERC721_METADATA = 0x5b5e139f;
          
            function name() public view returns (string _name);
            function symbol() public view returns (string _symbol);
            function tokenURI(uint256 _tokenId) public view returns (string);
          }
          
          
          /**
           * @title ERC-721 Non-Fungible Token Standard, full implementation interface
           * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
           */
          /* solium-disable-next-line no-empty-blocks */
          contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata {
          }
          
          // File: contracts/library/ProxyOwnable.sol
          
          /**
           * @title ProxyOwnable
           * @dev Essentially the Ownable contract, renamed for the purposes of separating it from the
           *  DelayedOwnable contract (the owner of the token contract).
           */
          contract ProxyOwnable {
            address public proxyOwner;
          
            event ProxyOwnershipTransferred(address indexed previousOwner, address indexed newOwner);
          
            /**
             * @dev The Ownable constructor sets the original `proxyOwner` of the contract to the sender
             * account.
             */
            constructor() public {
              proxyOwner = msg.sender;
            }
          
            /**
             * @dev Throws if called by any account other than the owner.
             */
            modifier onlyOwner() {
              require(msg.sender == proxyOwner);
              _;
            }
          
            /**
             * @dev Allows the current owner to transfer control of the contract to a newOwner.
             * @param _newOwner The address to transfer ownership to.
             */
            function transferProxyOwnership(address _newOwner) public onlyOwner {
              require(_newOwner != address(0));
          
              emit ProxyOwnershipTransferred(proxyOwner, _newOwner);
          
              proxyOwner = _newOwner;
            }
          }
          
          // File: contracts/CodexRecordProxy.sol
          
          /**
           * @title CodexRecordProxy, a proxy contract for token storage
           * @dev This allows the token owner to optionally upgrade the token in the future
           *  if there are changes needed in the business logic. See the upgradeTo function
           *  for caveats.
           * Based on MIT licensed code from
           *  https://github.com/zeppelinos/labs/tree/master/upgradeability_using_inherited_storage
           */
          contract CodexRecordProxy is ProxyOwnable {
            event Upgraded(string version, address indexed implementation);
          
            string public version;
            address public implementation;
          
            constructor(address _implementation) public {
              upgradeTo("1", _implementation);
            }
          
            /**
             * @dev Fallback function. Any transaction sent to this contract that doesn't match the
             *  upgradeTo signature will fallback to this function, which in turn will use
             *  DELEGATECALL to delegate the transaction data to the implementation.
             */
            function () payable public {
              address _implementation = implementation;
          
              // solium-disable-next-line security/no-inline-assembly
              assembly {
                let ptr := mload(0x40)
                calldatacopy(ptr, 0, calldatasize)
                let result := delegatecall(gas, _implementation, ptr, calldatasize, 0, 0)
                let size := returndatasize
                returndatacopy(ptr, 0, size)
          
                switch result
                case 0 { revert(ptr, size) }
                default { return(ptr, size) }
              }
            }
          
            /**
             * @dev Since name is passed into the ERC721 token constructor, it's not stored in the CodexRecordProxy
             *  contract. Thus, we call into the contract directly to retrieve its value.
             * @return string The name of the token
             */
            function name() external view returns (string) {
              ERC721Metadata tokenMetadata = ERC721Metadata(implementation);
          
              return tokenMetadata.name();
            }
          
            /**
             * @dev Since symbol is passed into the ERC721 token constructor, it's not stored in the CodexRecordProxy
             *  contract. Thus, we call into the contract directly to retrieve its value.
             * @return string The symbol of token
             */
            function symbol() external view returns (string) {
              ERC721Metadata tokenMetadata = ERC721Metadata(implementation);
          
              return tokenMetadata.symbol();
            }
          
            /**
             * @dev Upgrades the CodexRecordProxy to point at a new implementation. Only callable by the owner.
             *  Only upgrade the token after extensive testing has been done. The storage is append only.
             *  The new token must inherit from the previous token so the shape of the storage is maintained.
             * @param _version The version of the token
             * @param _implementation The address at which the implementation is available
             */
            function upgradeTo(string _version, address _implementation) public onlyOwner {
              require(
                keccak256(abi.encodePacked(_version)) != keccak256(abi.encodePacked(version)),
                "The version cannot be the same");
          
              require(
                _implementation != implementation,
                "The implementation cannot be the same");
          
              require(
                _implementation != address(0),
                "The implementation cannot be the 0 address");
          
              version = _version;
              implementation = _implementation;
          
              emit Upgraded(version, implementation);
            }
          }

          File 3 of 3: CodexRecord
          pragma solidity 0.4.24;
          
          // File: contracts/ERC20/ERC20Basic.sol
          
          /**
           * @title ERC20Basic
           * @dev Simpler version of ERC20 interface
           * @dev see https://github.com/ethereum/EIPs/issues/179
           */
          contract ERC20Basic {
            function totalSupply() public view returns (uint256);
            function balanceOf(address who) public view returns (uint256);
            function transfer(address to, uint256 value) public returns (bool);
            event Transfer(address indexed from, address indexed to, uint256 value);
          }
          
          // File: contracts/ERC20/ERC20.sol
          
          /**
           * @title ERC20 interface
           * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
           */
          contract ERC20 is ERC20Basic {
            function allowance(address owner, address spender) public view returns (uint256);
            function transferFrom(address from, address to, uint256 value) public returns (bool);
            function approve(address spender, uint256 value) public returns (bool);
            event Approval(address indexed owner, address indexed spender, uint256 value);
          }
          
          // File: contracts/ERC721/ERC721Basic.sol
          
          /**
           * @title ERC721 Non-Fungible Token Standard basic interface
           * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
           */
          contract ERC721Basic {
            // 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 constant INTERFACE_ERC721 = 0x80ac58cd;
          
            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 indexed _approved);
          
            function balanceOf(address _owner) public view returns (uint256 _balance);
            function ownerOf(uint256 _tokenId) public view returns (address _owner);
          
            // Note: This is not in the official ERC-721 standard so it's not included in the interface hash
            function exists(uint256 _tokenId) public view returns (bool _exists);
          
            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;
          }
          
          // File: contracts/ERC721/ERC721.sol
          
          /**
           * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
           * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
           */
          contract ERC721Enumerable is ERC721Basic {
            // bytes4(keccak256('totalSupply()')) ^
            // bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^
            // bytes4(keccak256('tokenByIndex(uint256)'));
            bytes4 constant INTERFACE_ERC721_ENUMERABLE = 0x780e9d63;
          
            function totalSupply() public view returns (uint256);
            function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256 _tokenId);
            function tokenByIndex(uint256 _index) public view returns (uint256);
          }
          
          
          /**
           * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
           * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
           */
          contract ERC721Metadata is ERC721Basic {
            // bytes4(keccak256('name()')) ^
            // bytes4(keccak256('symbol()')) ^
            // bytes4(keccak256('tokenURI(uint256)'));
            bytes4 constant INTERFACE_ERC721_METADATA = 0x5b5e139f;
          
            function name() public view returns (string _name);
            function symbol() public view returns (string _symbol);
            function tokenURI(uint256 _tokenId) public view returns (string);
          }
          
          
          /**
           * @title ERC-721 Non-Fungible Token Standard, full implementation interface
           * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
           */
          /* solium-disable-next-line no-empty-blocks */
          contract ERC721 is ERC721Basic, ERC721Enumerable, ERC721Metadata {
          }
          
          // File: contracts/ERC165/ERC165.sol
          
          /**
           * @dev A standard for detecting smart contract interfaces.
           * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
           */
          contract ERC165 {
          
            // bytes4(keccak256('supportsInterface(bytes4)'));
            bytes4 constant INTERFACE_ERC165 = 0x01ffc9a7;
          
            /**
             * @dev Checks if the smart contract includes a specific interface.
             * @param _interfaceID The interface identifier, as specified in ERC-165.
             */
            function supportsInterface(bytes4 _interfaceID) public pure returns (bool) {
              return _interfaceID == INTERFACE_ERC165;
            }
          }
          
          // File: contracts/library/AddressUtils.sol
          
          /**
           * @title Utility library of inline functions on addresses
           */
          library AddressUtils {
          
            /**
             * @notice Returns whether there is code in the target address
             * @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 addr address address to check
             * @return whether there is code in the target address
             */
            function isContract(address addr) internal view returns (bool) {
              uint256 size;
          
              // solium-disable-next-line security/no-inline-assembly
              assembly { size := extcodesize(addr) }
          
              return size > 0;
            }
          }
          
          // File: contracts/library/SafeMath.sol
          
          /**
           * @title SafeMath
           * @dev Math operations with safety checks that throw on error
           */
          library SafeMath {
          
            /**
            * @dev Multiplies two numbers, throws on overflow.
            */
            function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
              // Gas optimization: this is cheaper than asserting 'a' not being zero, but the
              // benefit is lost if 'b' is also tested.
              // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
              if (a == 0) {
                return 0;
              }
          
              c = a * b;
              assert(c / a == b);
              return c;
            }
          
            /**
            * @dev Integer division of two numbers, truncating the quotient.
            */
            function div(uint256 a, uint256 b) internal pure returns (uint256) {
              // assert(b > 0); // Solidity automatically throws when dividing by 0
              // uint256 c = a / b;
              // assert(a == b * c + a % b); // There is no case in which this doesn't hold
              return a / b;
            }
          
            /**
            * @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
            */
            function sub(uint256 a, uint256 b) internal pure returns (uint256) {
              assert(b <= a);
              return a - b;
            }
          
            /**
            * @dev Adds two numbers, throws on overflow.
            */
            function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
              c = a + b;
              assert(c >= a);
              return c;
            }
          }
          
          // File: contracts/ERC721/ERC721Receiver.sol
          
          /**
           * @title ERC721 token receiver interface
           * @dev Interface for any contract that wants to support safeTransfers
           *  from ERC721 asset contracts.
           */
          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 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. Returns other than the magic value MUST result in the
             *  transaction being reverted.
             *  Note: the contract address is always the message sender.
             * @param _from The sending address
             * @param _tokenId The NFT identifier which is being transfered
             * @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);
          }
          
          // File: contracts/ERC721/ERC721BasicToken.sol
          
          /**
           * @title ERC721 Non-Fungible Token Standard basic implementation
           * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
           */
          contract ERC721BasicToken is ERC721Basic, ERC165 {
            using SafeMath for uint256;
            using AddressUtils for address;
          
            // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
            // which can be also obtained as `ERC721Receiver(0).onERC721Received.selector`
            bytes4 constant ERC721_RECEIVED = 0x150b7a02;
          
            // Mapping from token ID to owner
            mapping (uint256 => address) internal tokenOwner;
          
            // Mapping from token ID to approved address
            mapping (uint256 => address) internal tokenApprovals;
          
            // Mapping from owner to number of owned token
            mapping (address => uint256) internal ownedTokensCount;
          
            // Mapping from owner to operator approvals
            mapping (address => mapping (address => bool)) internal operatorApprovals;
          
            /**
             * @dev Guarantees msg.sender is owner of the given token
             * @param _tokenId uint256 ID of the token to validate its ownership belongs to msg.sender
             */
            modifier onlyOwnerOf(uint256 _tokenId) {
              require(ownerOf(_tokenId) == msg.sender);
              _;
            }
          
            /**
             * @dev Checks if the smart contract includes a specific interface.
             * @param _interfaceID The interface identifier, as specified in ERC-165.
             */
            function supportsInterface(bytes4 _interfaceID) public pure returns (bool) {
              return super.supportsInterface(_interfaceID) || _interfaceID == INTERFACE_ERC721;
            }
          
            /**
            * @dev Gets the balance of the specified address
            * @param _owner address to query the balance of
            * @return uint256 representing the amount owned by the passed address
            */
            function balanceOf(address _owner) public view returns (uint256) {
              require(_owner != address(0));
              return ownedTokensCount[_owner];
            }
          
            /**
             * @dev Gets the owner of the specified token ID
             * @param _tokenId uint256 ID of the token to query the owner of
             * @return owner address currently marked as the owner of the given token ID
             */
            function ownerOf(uint256 _tokenId) public view returns (address) {
              address owner = tokenOwner[_tokenId];
              require(owner != address(0));
              return owner;
            }
          
            /**
             * @dev Returns whether the specified token exists
             * @param _tokenId uint256 ID of the token to query the existance of
             * @return whether the token exists
             */
            function exists(uint256 _tokenId) public view returns (bool) {
              address owner = tokenOwner[_tokenId];
              return owner != address(0);
            }
          
            /**
             * @dev Approves another address to transfer the given token ID
             * @dev The zero address indicates there is no approved address.
             * @dev There can only be one approved address per token at a given time.
             * @dev Can only be called by the token owner or an approved operator.
             * @param _to address to be approved for the given token ID
             * @param _tokenId uint256 ID of the token to be approved
             */
            function approve(address _to, uint256 _tokenId) public {
              address owner = ownerOf(_tokenId);
              require(_to != owner);
              require(msg.sender == owner || isApprovedForAll(owner, msg.sender));
          
              if (getApproved(_tokenId) != address(0) || _to != address(0)) {
                tokenApprovals[_tokenId] = _to;
                emit Approval(owner, _to, _tokenId);
              }
            }
          
            /**
             * @dev Gets the approved address for a token ID, or zero if no address set
             * @param _tokenId uint256 ID of the token to query the approval of
             * @return address currently approved for a the given token ID
             */
            function getApproved(uint256 _tokenId) public view returns (address) {
              return tokenApprovals[_tokenId];
            }
          
            /**
             * @dev Sets or unsets the approval of a given operator
             * @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 representing the status of the approval to be set
             */
            function setApprovalForAll(address _to, bool _approved) public {
              require(_to != msg.sender);
              operatorApprovals[msg.sender][_to] = _approved;
              emit ApprovalForAll(msg.sender, _to, _approved);
            }
          
            /**
             * @dev Tells whether an operator is approved by a given owner
             * @param _owner owner address which you want to query the approval of
             * @param _operator operator address which you want to query the approval of
             * @return bool whether the given operator is approved by the given owner
             */
            function isApprovedForAll(address _owner, address _operator) public view returns (bool) {
              return operatorApprovals[_owner][_operator];
            }
          
            /**
             * @dev Transfers the ownership of a given token ID to another address
             * @dev Usage of this method is discouraged, use `safeTransferFrom` whenever possible
             * @dev Requires the msg sender to be the owner, approved, or operator
             * @param _from current owner of the token
             * @param _to address to receive the ownership of the given token ID
             * @param _tokenId uint256 ID of the token to be transferred
             */
            function transferFrom(
              address _from,
              address _to,
              uint256 _tokenId
            )
              public
            {
              internalTransferFrom(
                _from,
                _to,
                _tokenId);
            }
          
            /**
             * @dev Safely transfers the ownership of a given token ID to another address
             * @dev If the target address is a contract, it must implement `onERC721Received`,
             *  which is called upon a safe transfer, and return the magic value
             *  `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
             *  the transfer is reverted.
             * @dev Requires the msg sender to be the owner, approved, or operator
             * @param _from current owner of the token
             * @param _to address to receive the ownership of the given token ID
             * @param _tokenId uint256 ID of the token to be transferred
             */
            function safeTransferFrom(
              address _from,
              address _to,
              uint256 _tokenId
            )
              public
            {
              internalSafeTransferFrom(
                _from,
                _to,
                _tokenId,
                "");
            }
          
            /**
             * @dev Safely transfers the ownership of a given token ID to another address
             * @dev If the target address is a contract, it must implement `onERC721Received`,
             *  which is called upon a safe transfer, and return the magic value
             *  `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
             *  the transfer is reverted.
             * @dev Requires the msg sender to be the owner, approved, or operator
             * @param _from current owner of the token
             * @param _to address to receive the ownership of the given token ID
             * @param _tokenId uint256 ID of the token to be transferred
             * @param _data bytes data to send along with a safe transfer check
             */
            function safeTransferFrom(
              address _from,
              address _to,
              uint256 _tokenId,
              bytes _data
            )
              public
            {
              internalSafeTransferFrom(
                _from,
                _to,
                _tokenId,
                _data);
            }
          
            function internalTransferFrom(
              address _from,
              address _to,
              uint256 _tokenId
            )
              internal
            {
              address owner = ownerOf(_tokenId);
              require(_from == owner);
              require(_to != address(0));
          
              address sender = msg.sender;
          
              require(
                sender == owner || isApprovedForAll(owner, sender) || getApproved(_tokenId) == sender,
                "Not authorized to transfer"
              );
          
              // Resetting the approved address if it's set
              if (tokenApprovals[_tokenId] != address(0)) {
                tokenApprovals[_tokenId] = address(0);
              }
          
              tokenOwner[_tokenId] = _to;
              ownedTokensCount[_from] = ownedTokensCount[_from].sub(1);
              ownedTokensCount[_to] = ownedTokensCount[_to].add(1);
          
              emit Transfer(_from, _to, _tokenId);
            }
          
            function internalSafeTransferFrom(
              address _from,
              address _to,
              uint256 _tokenId,
              bytes _data
            )
              internal
            {
              internalTransferFrom(_from, _to, _tokenId);
          
              require(
                checkAndCallSafeTransfer(
                  _from,
                  _to,
                  _tokenId,
                  _data)
              );
            }
          
            /**
             * @dev Internal function to invoke `onERC721Received` on a target address
             * @dev The call is not executed if the target address is not a contract
             * @param _from address representing the previous owner of the given token ID
             * @param _to target address that will receive the tokens
             * @param _tokenId uint256 ID of the token to be transferred
             * @param _data bytes optional data to send along with the call
             * @return whether the call correctly returned the expected magic value
             */
            function 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);
            }
          }
          
          // File: contracts/ERC721/ERC721Token.sol
          
          /**
           * @title Full ERC721 Token
           * This implementation includes all the required and some optional functionality of the ERC721 standard
           * Moreover, it includes approve all functionality using operator terminology
           * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md
           */
          contract ERC721Token is ERC721, ERC721BasicToken {
            // Token name
            string internal name_;
          
            // Token symbol
            string internal symbol_;
          
            // Mapping from owner to list of owned token IDs
            mapping (address => uint256[]) internal ownedTokens;
          
            // Mapping from token ID to index of the owner tokens list
            mapping(uint256 => uint256) internal ownedTokensIndex;
          
            // Array with all token ids, used for enumeration
            uint256[] internal allTokens;
          
            // Optional mapping for token URIs
            mapping(uint256 => string) internal tokenURIs;
          
            /**
            * @dev Constructor function
            */
            constructor(string _name, string _symbol) public {
              name_ = _name;
              symbol_ = _symbol;
            }
          
            /**
              * @dev Checks if the smart contract includes a specific interface.
              * @param _interfaceID The interface identifier, as specified in ERC-165.
              */
            function supportsInterface(bytes4 _interfaceID) public pure returns (bool) {
              return super.supportsInterface(_interfaceID) || _interfaceID == INTERFACE_ERC721_ENUMERABLE || _interfaceID == INTERFACE_ERC721_METADATA;
            }
          
            /**
             * @dev Gets the token name
             * @return string representing the token name
             */
            function name() public view returns (string) {
              return name_;
            }
          
            /**
             * @dev Gets the token symbol
             * @return string representing the token symbol
             */
            function symbol() public view returns (string) {
              return symbol_;
            }
          
            /**
             * @dev Returns an URI for a given token ID
             * @dev Throws if the token ID does not exist. May return an empty string.
             * @param _tokenId uint256 ID of the token to query
             */
            function tokenURI(uint256 _tokenId) public view returns (string) {
              require(exists(_tokenId));
              return tokenURIs[_tokenId];
            }
          
            /**
             * @dev Gets the token ID at a given index of the tokens list of the requested owner
             * @param _owner address owning the tokens list to be accessed
             * @param _index uint256 representing the index to be accessed of the requested tokens list
             * @return uint256 token ID at the given index of the tokens list owned by the requested address
             */
            function tokenOfOwnerByIndex(address _owner, uint256 _index) public view returns (uint256) {
              require(_index < balanceOf(_owner));
              return ownedTokens[_owner][_index];
            }
          
            /**
             * @dev Gets the total amount of tokens stored by the contract
             * @return uint256 representing the total amount of tokens
             */
            function totalSupply() public view returns (uint256) {
              return allTokens.length;
            }
          
            /**
             * @dev Gets the token ID at a given index of all the tokens in this contract
             * @dev Reverts if the index is greater or equal to the total number of tokens
             * @param _index uint256 representing the index to be accessed of the tokens list
             * @return uint256 token ID at the given index of the tokens list
             */
            function tokenByIndex(uint256 _index) public view returns (uint256) {
              require(_index < totalSupply());
              return allTokens[_index];
            }
          
            function internalTransferFrom(
              address _from,
              address _to,
              uint256 _tokenId
            )
              internal
            {
              super.internalTransferFrom(_from, _to, _tokenId);
          
              uint256 removeTokenIndex = ownedTokensIndex[_tokenId];
              uint256 lastTokenIndex = ownedTokens[_from].length.sub(1);
              uint256 lastToken = ownedTokens[_from][lastTokenIndex];
          
              ownedTokens[_from][removeTokenIndex] = lastToken;
              ownedTokens[_from].length--;
              ownedTokensIndex[lastToken] = removeTokenIndex;
          
              ownedTokens[_to].push(_tokenId);
              ownedTokensIndex[_tokenId] = ownedTokens[_to].length - 1;
            }
          
            /**
             * @dev Internal function to set the token URI for a given token
             * @dev Reverts if the token ID does not exist
             * @param _tokenId uint256 ID of the token to set its URI
             * @param _uri string URI to assign
             */
            function _setTokenURI(uint256 _tokenId, string _uri) internal {
              require(exists(_tokenId));
              tokenURIs[_tokenId] = _uri;
            }
          }
          
          // File: contracts/CodexRecordMetadata.sol
          
          /**
           * @title CodexRecordMetadata
           * @dev Storage, mutators, and modifiers for CodexRecord metadata.
           */
          contract CodexRecordMetadata is ERC721Token {
            struct CodexRecordData {
              bytes32 nameHash;
              bytes32 descriptionHash;
              bytes32[] fileHashes;
            }
          
            event Modified(
              address indexed _from,
              uint256 _tokenId,
              bytes32 _newNameHash,
              bytes32 _newDescriptionHash,
              bytes32[] _newFileHashes,
              bytes _data
            );
          
            // Mapping from token ID to token data
            mapping(uint256 => CodexRecordData) internal tokenData;
          
            // Global tokenURIPrefix prefix. The token ID will be appended to the uri when accessed
            //  via the tokenURI method
            string public tokenURIPrefix;
          
            /**
             * @dev Updates token metadata hashes to whatever is passed in
             * @param _tokenId uint256 The token ID
             * @param _newNameHash bytes32 The new sha3 hash of the name
             * @param _newDescriptionHash bytes32 The new sha3 hash of the description
             * @param _newFileHashes bytes32[] The new sha3 hashes of the files associated with the token
             * @param _data (optional) bytes Additional data that will be emitted with the Modified event
             */
            function modifyMetadataHashes(
              uint256 _tokenId,
              bytes32 _newNameHash,
              bytes32 _newDescriptionHash,
              bytes32[] _newFileHashes,
              bytes _data
            )
              public
              onlyOwnerOf(_tokenId)
            {
              // nameHash is only overridden if it's not a blank string, since name is a
              //  required value. Emptiness is determined if the first element is the null-byte
              if (!bytes32IsEmpty(_newNameHash)) {
                tokenData[_tokenId].nameHash = _newNameHash;
              }
          
              // descriptionHash can always be overridden since it's an optional value
              //  (e.g. you can "remove" a description by setting it to a blank string)
              tokenData[_tokenId].descriptionHash = _newDescriptionHash;
          
              // fileHashes is only overridden if it has one or more value, since at
              //  least one file (i.e. mainImage) is required
              bool containsNullHash = false;
              for (uint i = 0; i < _newFileHashes.length; i++) {
                if (bytes32IsEmpty(_newFileHashes[i])) {
                  containsNullHash = true;
                  break;
                }
              }
              if (_newFileHashes.length > 0 && !containsNullHash) {
                tokenData[_tokenId].fileHashes = _newFileHashes;
              }
          
              emit Modified(
                msg.sender,
                _tokenId,
                tokenData[_tokenId].nameHash,
                tokenData[_tokenId].descriptionHash,
                tokenData[_tokenId].fileHashes,
                _data
              );
            }
          
            /**
             * @dev Gets the token given a token ID.
             * @param _tokenId token ID
             * @return CodexRecordData token data for the given token ID
             */
            function getTokenById(
              uint256 _tokenId
            )
              public
              view
              returns (bytes32 nameHash, bytes32 descriptionHash, bytes32[] fileHashes)
            {
              return (
                tokenData[_tokenId].nameHash,
                tokenData[_tokenId].descriptionHash,
                tokenData[_tokenId].fileHashes
              );
            }
          
            /**
             * @dev Returns an URI for a given token ID
             * @dev Throws if the token ID does not exist.
             *
             * @dev To save on gas, we will host a standard metadata endpoint for each token.
             *  For Collector privacy, specific token metadata is stored off chain, which means
             *  the metadata returned by this endpoint cannot include specific details about
             *  the physical asset the token represents unless the Collector has made it public.
             *
             * @dev This metadata will be a JSON blob that includes:
             *  name - Codex Record
             *  description - Information about the Provider that is hosting the off-chain metadata
             *  imageUri - A generic Codex Record image
             *
             * @param _tokenId uint256 ID of the token to query
             */
            function tokenURI(
              uint256 _tokenId
            )
              public
              view
              returns (string)
            {
              bytes memory prefix = bytes(tokenURIPrefix);
              if (prefix.length == 0) {
                return "";
              }
          
              // Rather than store a string representation of _tokenId, we just convert it on the fly
              // since this is just a 'view' function (i.e., there's no gas cost if called off chain)
              bytes memory tokenId = uint2bytes(_tokenId);
              bytes memory output = new bytes(prefix.length + tokenId.length);
          
              // Index counters
              uint256 i;
              uint256 outputIndex = 0;
          
              // Copy over the prefix into the new bytes array
              for (i = 0; i < prefix.length; i++) {
                output[outputIndex++] = prefix[i];
              }
          
              // Copy over the tokenId into the new bytes array
              for (i = 0; i < tokenId.length; i++) {
                output[outputIndex++] = tokenId[i];
              }
          
              return string(output);
            }
          
            /**
             * @dev Based on MIT licensed code @ https://github.com/oraclize/ethereum-api
             * @dev Converts an incoming uint256 to a dynamic byte array
             */
            function uint2bytes(uint256 i) internal pure returns (bytes) {
              if (i == 0) {
                return "0";
              }
          
              uint256 j = i;
              uint256 length;
              while (j != 0) {
                length++;
                j /= 10;
              }
          
              bytes memory bstr = new bytes(length);
              uint256 k = length - 1;
              j = i;
              while (j != 0) {
                bstr[k--] = byte(48 + j % 10);
                j /= 10;
              }
          
              return bstr;
            }
          
            /**
             * @dev Returns whether or not a bytes32 array is empty (all null-bytes)
             * @param _data bytes32 The array to check
             * @return bool Whether or not the array is empty
             */
            function bytes32IsEmpty(bytes32 _data) internal pure returns (bool) {
              for (uint256 i = 0; i < 32; i++) {
                if (_data[i] != 0x0) {
                  return false;
                }
              }
          
              return true;
            }
          }
          
          // File: contracts/ERC900/ERC900.sol
          
          /**
           * @title ERC900 Simple Staking Interface
           * @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-900.md
           */
          contract ERC900 {
            event Staked(address indexed user, uint256 amount, uint256 total, bytes data);
            event Unstaked(address indexed user, uint256 amount, uint256 total, bytes data);
          
            function stake(uint256 amount, bytes data) public;
            function stakeFor(address user, uint256 amount, bytes data) public;
            function unstake(uint256 amount, bytes data) public;
            function totalStakedFor(address addr) public view returns (uint256);
            function totalStaked() public view returns (uint256);
            function token() public view returns (address);
            function supportsHistory() public pure returns (bool);
          
            // NOTE: Not implementing the optional functions
            // function lastStakedFor(address addr) public view returns (uint256);
            // function totalStakedForAt(address addr, uint256 blockNumber) public view returns (uint256);
            // function totalStakedAt(uint256 blockNumber) public view returns (uint256);
          }
          
          // File: contracts/CodexStakeContractInterface.sol
          
          contract CodexStakeContractInterface is ERC900 {
          
            function stakeForDuration(
              address user,
              uint256 amount,
              uint256 lockInDuration,
              bytes data)
              public;
          
            function spendCredits(
              address user,
              uint256 amount)
              public;
          
            function creditBalanceOf(
              address user)
              public
              view
              returns (uint256);
          }
          
          // File: contracts/library/DelayedOwnable.sol
          
          /**
           * @title DelayedOwnable
           * @dev The DelayedOwnable contract has an owner address, and provides basic authorization control
           *  functions, this simplifies the implementation of "user permissions".
           * @dev This is different than the original Ownable contract because intializeOwnable
           *  must be specifically called after creation to create an owner.
           */
          contract DelayedOwnable {
            address public owner;
            bool public isInitialized = false;
          
            event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
          
            /**
             * @dev Throws if called by any account other than the owner.
             */
            modifier onlyOwner() {
              require(msg.sender == owner);
              _;
            }
          
            function initializeOwnable(address _owner) external {
              require(
                !isInitialized,
                "The owner has already been set");
          
              isInitialized = true;
              owner = _owner;
            }
          
            /**
             * @dev Allows the current owner to transfer control of the contract to a newOwner.
             * @param _newOwner The address to transfer ownership to.
             */
            function transferOwnership(address _newOwner) public onlyOwner {
              require(_newOwner != address(0));
          
              emit OwnershipTransferred(owner, _newOwner);
          
              owner = _newOwner;
            }
          }
          
          // File: contracts/library/DelayedPausable.sol
          
          /**
           * @title Pausable
           * @dev Base contract which allows children to implement an emergency stop mechanism.
           */
          contract DelayedPausable is DelayedOwnable {
            event Pause();
            event Unpause();
          
            bool public paused = false;
          
          
            /**
             * @dev Modifier to make a function callable only when the contract is not paused.
             */
            modifier whenNotPaused() {
              require(!paused);
              _;
            }
          
            /**
             * @dev Modifier to make a function callable only when the contract is paused.
             */
            modifier whenPaused() {
              require(paused);
              _;
            }
          
            /**
             * @dev called by the owner to pause, triggers stopped state
             */
            function pause() onlyOwner whenNotPaused public {
              paused = true;
              emit Pause();
            }
          
            /**
             * @dev called by the owner to unpause, returns to normal state
             */
            function unpause() onlyOwner whenPaused public {
              paused = false;
              emit Unpause();
            }
          }
          
          // File: contracts/CodexRecordFees.sol
          
          /**
           * @title CodexRecordFees
           * @dev Storage, mutators, and modifiers for fees when using the token.
           *  This also includes the DelayedPausable contract for the onlyOwner modifier.
           */
          contract CodexRecordFees is CodexRecordMetadata, DelayedPausable {
          
            // Implementation of the ERC20 Codex Protocol Token, used for fees in the contract
            ERC20 public codexCoin;
          
            // Implementation of the ERC900 Codex Protocol Stake Container,
            //  used to calculate discounts on fees
            CodexStakeContractInterface public codexStakeContract;
          
            // Address where all contract fees are sent, i.e., the Community Fund
            address public feeRecipient;
          
            // Fee to create new tokens. 10^18 = 1 token
            uint256 public creationFee = 0;
          
            // Fee to transfer tokens. 10^18 = 1 token
            uint256 public transferFee = 0;
          
            // Fee to modify tokens. 10^18 = 1 token
            uint256 public modificationFee = 0;
          
            modifier canPayFees(uint256 _baseFee) {
              if (feeRecipient != address(0) && _baseFee > 0) {
                bool feePaid = false;
          
                if (codexStakeContract != address(0)) {
                  uint256 discountCredits = codexStakeContract.creditBalanceOf(msg.sender);
          
                  // Regardless of what the baseFee is, all transactions can be paid by using exactly one credit
                  if (discountCredits > 0) {
                    codexStakeContract.spendCredits(msg.sender, 1);
                    feePaid = true;
                  }
                }
          
                if (!feePaid) {
                  require(
                    codexCoin.transferFrom(msg.sender, feeRecipient, _baseFee),
                    "Insufficient funds");
                }
              }
          
              _;
            }
          
            /**
             * @dev Sets the address of the ERC20 token used for fees in the contract.
             *  Fees are in the smallest denomination, e.g., 10^18 is 1 token.
             * @param _codexCoin ERC20 The address of the ERC20 Codex Protocol Token
             * @param _feeRecipient address The address where the fees are sent
             * @param _creationFee uint256 The new creation fee.
             * @param _transferFee uint256 The new transfer fee.
             * @param _modificationFee uint256 The new modification fee.
             */
            function setFees(
              ERC20 _codexCoin,
              address _feeRecipient,
              uint256 _creationFee,
              uint256 _transferFee,
              uint256 _modificationFee
            )
              external
              onlyOwner
            {
              codexCoin = _codexCoin;
              feeRecipient = _feeRecipient;
              creationFee = _creationFee;
              transferFee = _transferFee;
              modificationFee = _modificationFee;
            }
          
            function setStakeContract(CodexStakeContractInterface _codexStakeContract) external onlyOwner {
              codexStakeContract = _codexStakeContract;
            }
          }
          
          // File: contracts/CodexRecordCore.sol
          
          /**
           * @title CodexRecordCore
           * @dev Core functionality of the token, namely minting.
           */
          contract CodexRecordCore is CodexRecordFees {
          
            /**
             * @dev This event is emitted when a new token is minted and allows providers
             *  to discern which Minted events came from transactions they submitted vs
             *  transactions submitted by other platforms, as well as providing information
             *  about what metadata record the newly minted token should be associated with.
             */
            event Minted(uint256 _tokenId, bytes _data);
          
            /**
             * @dev Sets the global tokenURIPrefix for use when returning token metadata.
             *  Only callable by the owner.
             * @param _tokenURIPrefix string The new tokenURIPrefix
             */
            function setTokenURIPrefix(string _tokenURIPrefix) external onlyOwner {
              tokenURIPrefix = _tokenURIPrefix;
            }
          
            /**
             * @dev Creates a new token
             * @param _to address The address the token will get transferred to after minting
             * @param _nameHash bytes32 The sha3 hash of the name
             * @param _descriptionHash bytes32 The sha3 hash of the description
             * @param _data (optional) bytes Additional data that will be emitted with the Minted event
             */
            function mint(
              address _to,
              bytes32 _nameHash,
              bytes32 _descriptionHash,
              bytes32[] _fileHashes,
              bytes _data
            )
              public
            {
              // All new tokens will be the last entry in the array
              uint256 newTokenId = allTokens.length;
              internalMint(_to, newTokenId);
          
              // Add metadata to the newly created token
              tokenData[newTokenId] = CodexRecordData({
                nameHash: _nameHash,
                descriptionHash: _descriptionHash,
                fileHashes: _fileHashes
              });
          
              emit Minted(newTokenId, _data);
            }
          
            function internalMint(address _to, uint256 _tokenId) internal {
              require(_to != address(0));
          
              tokenOwner[_tokenId] = _to;
              ownedTokensCount[_to] = ownedTokensCount[_to].add(1);
          
              ownedTokensIndex[_tokenId] = ownedTokens[_to].length;
              ownedTokens[_to].push(_tokenId);
          
              allTokens.push(_tokenId);
          
              emit Transfer(address(0), _to, _tokenId);
            }
          }
          
          // File: contracts/CodexRecordAccess.sol
          
          /**
           * @title CodexRecordAccess
           * @dev Override contract functions
           */
          contract CodexRecordAccess is CodexRecordCore {
          
            /**
             * @dev Make mint() pausable
             */
            function mint(
              address _to,
              bytes32 _nameHash,
              bytes32 _descriptionHash,
              bytes32[] _fileHashes,
              bytes _data
            )
              public
              whenNotPaused
              canPayFees(creationFee)
            {
              return super.mint(
                _to,
                _nameHash,
                _descriptionHash,
                _fileHashes,
                _data);
            }
          
            /**
             * @dev Make trasferFrom() pausable
             */
            function transferFrom(
              address _from,
              address _to,
              uint256 _tokenId
            )
              public
              whenNotPaused
              canPayFees(transferFee)
            {
              return super.transferFrom(
                _from,
                _to,
                _tokenId);
            }
          
            /**
             * @dev Make safeTrasferFrom() pausable
             */
            function safeTransferFrom(
              address _from,
              address _to,
              uint256 _tokenId
            )
              public
              whenNotPaused
              canPayFees(transferFee)
            {
              return super.safeTransferFrom(
                _from,
                _to,
                _tokenId);
            }
          
            /**
             * @dev Make safeTrasferFrom() pausable
             */
            function safeTransferFrom(
              address _from,
              address _to,
              uint256 _tokenId,
              bytes _data
            )
              public
              whenNotPaused
              canPayFees(transferFee)
            {
              return super.safeTransferFrom(
                _from,
                _to,
                _tokenId,
                _data
              );
            }
          
            /**
             * @dev Make modifyMetadataHashes() pausable
             */
            function modifyMetadataHashes(
              uint256 _tokenId,
              bytes32 _newNameHash,
              bytes32 _newDescriptionHash,
              bytes32[] _newFileHashes,
              bytes _data
            )
              public
              whenNotPaused
              canPayFees(modificationFee)
            {
              return super.modifyMetadataHashes(
                _tokenId,
                _newNameHash,
                _newDescriptionHash,
                _newFileHashes,
                _data);
            }
          }
          
          // File: contracts/CodexRecord.sol
          
          /**
           * @title CodexRecord, an ERC721 token for arts & collectables
           * @dev Developers should never interact with this smart contract directly!
           *  All transactions/calls should be made through CodexRecordProxy. Storage will be maintained
           *  in that smart contract so that the governing body has the ability
           *  to upgrade the contract in the future in the event of an emergency or new functionality.
           */
          contract CodexRecord is CodexRecordAccess {
            /**
             * @dev Constructor function
             */
            constructor() public ERC721Token("Codex Record", "CR") { }
          
            /**
             * @dev Reclaim all ERC20Basic compatible tokens
             * @param token ERC20Basic The address of the token contract
             */
            function reclaimToken(ERC20Basic token) external onlyOwner {
              uint256 balance = token.balanceOf(this);
              token.transfer(owner, balance);
            }
          }