Contract 0x21bdefb9b43b2e0ba739e76b6d8c9be0476e0509

 

TxHash Block Age From To Value [TxFee]
0x07e65de2e956fe2cafd4b4bb6449162c8314d0cac11f7545a4750a14c02b2e2f72244221 day 11 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.00075446
0x9cbb5428fd579939e6b8d1f6dd290e8309bf5fc77e1a3fa34a608b1e46316c8872244191 day 11 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.009058155
0x654e570b7eaa806db230ba96b6846d5021c34870ff6bbf1bf0e95b738a4dcc2072236301 day 16 hrs ago0x8f482e5fa7ca33d7734447cbb376df6a525fe750  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.00106401
0xa200cde49f6578ce8bd26e32866f033f0ab1aac5cdd12fa80fd31d3ccd1a13ec72196762 days 15 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.001207136
0x29a1dbeeab256d908d628b13956a455da00e8b3f3f856974ac868d8d5f74d9b772196722 days 15 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.011467904
0xe855d376b7ee32be7141e44dd37e2e82ed5bb913f3a3227bfec0149a434055ed72118144 days 12 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.00075414
0xf448f7d20b80e3e79820be15e129708136c76074c84d882dcc06c16286e6049f72118094 days 12 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.004100322
0x032853b3f7498a9bd0e53a3edc14a745c6a52a6fa0f655b853fa2ef776fef33272118024 days 12 hrs ago0x8f482e5fa7ca33d7734447cbb376df6a525fe750  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.00222642
0xf5f10d9b641fe114bb5f4b36837facb1f7f02ac85fc3a6f994af5ce3e9227e9e72117914 days 12 hrs ago0x8f482e5fa7ca33d7734447cbb376df6a525fe750  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.000452697
0xfa16abda7d35cc3108b89bbf4d6bc2de49a3c0b6e2c935fc4c8ed7e0c6027c4572117874 days 12 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.000452484
0xa60d7b3eacd801f12c459179d8c624ee56a8864e44e8fdecb111c4481be32fe972117754 days 12 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.00682715
0xaa3e39f7495e28ccc1111d6277f3cc37c801f16954084cb2eac559dea5d93b1b72116314 days 13 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.00075446
0xa3b4b150c80b8124cf23e6af048105ddabd0e9d40053f34fa17aebda844e2e7f72115884 days 13 hrs ago0x8f482e5fa7ca33d7734447cbb376df6a525fe750  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.0037107
0xe266f2e98e77afec842af3c8ce19506f728a365322ffd77e30164bbd2c27256c72115844 days 13 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.003231135
0xeb62a8a2d0f43fbe7147a69eb465ff99eb1c9d3b29c4190da66216f1a20391c972115754 days 13 hrs ago0x8f482e5fa7ca33d7734447cbb376df6a525fe750  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.000754495
0x83fcc9203557487f4c06cbdfc17bb5ef63d987d724f8976be843343fc6e1e3fc72115684 days 13 hrs ago0x8f482e5fa7ca33d7734447cbb376df6a525fe750  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.0037107
0x46e808262140947eebe59ff4037d350a0f1538b027dc36f95ca67b3ae4b9f9cd72115574 days 13 hrs ago0x8f482e5fa7ca33d7734447cbb376df6a525fe750  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.0037107
0x83111f364d1b3689aab4a8565b372de1ba2918073b5c1abf13994580b20a954272115504 days 13 hrs ago0x8f482e5fa7ca33d7734447cbb376df6a525fe750  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.0037107
0xbf75cc2a46a8fb1b7509c8e91d703a5f00183943e0e1471e460732cf7abaa98072107204 days 18 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.000136345
0x585cd28768e685e4831910d9dd9ca408aa76f0362efbbfc6d8614f461e0e53a172107184 days 18 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.00075414
0xe0d11a1b2acf3a363696007a00f6ccf69b83e4abf3c6c0e55087ddcf51236d4272107084 days 18 hrs ago0x0eadd593e69685a7dd7bebe58d4c79ecb79045c4  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.00504792
0x42066bf4d781712e85e9e5f5cd390c6c0b86d80aa16e65903b582d6da710372672105344 days 19 hrs ago0x8f482e5fa7ca33d7734447cbb376df6a525fe750  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.00014568
0xcc950b5b44369bc6bb61b77ff0d5891cd6e6428ee19c77b021ad09c5201b664772105334 days 19 hrs ago0x8f482e5fa7ca33d7734447cbb376df6a525fe750  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.000147175
0x0984e37f38d98d8497ef10dc7e26d4842aece5329decd59838779e3008ddaa8b72105314 days 19 hrs ago0x8f482e5fa7ca33d7734447cbb376df6a525fe750  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.000147285
0x3fb2d08a43c189caa2a54ad60d7d8db41d4cee26e367585c8e9c4f8433d02c7272105294 days 19 hrs ago0x8f482e5fa7ca33d7734447cbb376df6a525fe750  IN   0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090 Ether0.00014717
[ Download CSV Export 

Latest 6 Internal Transactions Internal Transactions as a result of Contract Execution

Parent TxHash Block Age From To Value
0xfa596a101a3f65111c90b02b03b13cbdf7b341b672dd309dc377b885ad4fc3b172076785 days 11 hrs ago0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090xd7e8ba9c9ba18dfb7602b96e5aa7e93966659f730.016488299373929958 Ether
0xfa596a101a3f65111c90b02b03b13cbdf7b341b672dd309dc377b885ad4fc3b172076785 days 11 hrs ago0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090x920062d455082d2657a8a12722faee39ce80c4e9600 wei
0xfa596a101a3f65111c90b02b03b13cbdf7b341b672dd309dc377b885ad4fc3b172076785 days 11 hrs ago0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090x8f482e5fa7ca33d7734447cbb376df6a525fe750350 wei
0x622d5983364b7c3a6960a2fde6f970d1bffa3894f8bb4408082bd8cc76a3c9a2717977211 days 9 hrs ago0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090xd7e8ba9c9ba18dfb7602b96e5aa7e93966659f730.000000000000052208 Ether
0x622d5983364b7c3a6960a2fde6f970d1bffa3894f8bb4408082bd8cc76a3c9a2717977211 days 9 hrs ago0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090x9994cf142998ca07a30cfc077efbd28e9f0a1b460.00000000000062648 Ether
0x622d5983364b7c3a6960a2fde6f970d1bffa3894f8bb4408082bd8cc76a3c9a2717977211 days 9 hrs ago0x21bdefb9b43b2e0ba739e76b6d8c9be0476e05090x8f482e5fa7ca33d7734447cbb376df6a525fe7500.000000000000365446 Ether
[ Download CSV Export 
Contract Source Code Verified (Exact Match)
Contract Name: BAECore
Compiler Version: v0.5.3+commit.10d17f24
Optimization Enabled: Yes
Runs (Optimizer):  200


Contract Source Code
pragma solidity ^0.5.3;

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;
  }
}

library Address {

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

}

library SafeERC20 {
    function safeTransfer(
      ERC20Basic _token,
      address _to,
      uint256 _value
    )
      internal
    {
      require(_token.transfer(_to, _value));
    }
  
    function safeTransferFrom(
      ERC20 _token,
      address _from,
      address _to,
      uint256 _value
    )
      internal
    {
      require(_token.transferFrom(_from, _to, _value));
    }
  
    function safeApprove(
      ERC20 _token,
      address _spender,
      uint256 _value
    )
      internal
    {
        require(_token.approve(_spender, _value));
    }
}

contract Ownable {
  address public owner;


  event OwnershipRenounced(address indexed previousOwner);
  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 relinquish control of the contract.
   * @notice Renouncing to ownership will leave the contract without an owner.
   * It will not be possible to call the functions with the `onlyOwner`
   * modifier anymore.
   */
  function renounceOwnership() public onlyOwner {
    emit OwnershipRenounced(owner);
    owner = address(0);
  }

  /**
   * @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 {
    _transferOwnership(_newOwner);
  }

  /**
   * @dev Transfers control of the contract to a newOwner.
   * @param _newOwner The address to transfer ownership to.
   */
  function _transferOwnership(address _newOwner) internal {
    require(_newOwner != address(0));
    emit OwnershipTransferred(owner, _newOwner);
    owner = _newOwner;
  }
}

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() public onlyOwner whenNotPaused {
    paused = true;
    emit Pause();
  }

  /**
   * @dev called by the owner to unpause, returns to normal state
   */
  function unpause() public onlyOwner whenPaused {
    paused = false;
    emit Unpause();
  }
}

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);
}
  
contract BasicToken is ERC20Basic {
  using SafeMath for uint256;

  mapping(address => uint256) internal balances;

  uint256 internal 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(_value <= balances[msg.sender]);
    require(_to != address(0));

    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) {
    return balances[_owner];
  }

}

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
  );
}

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(_value <= balances[_from]);
    require(_value <= allowed[_from][msg.sender]);
    require(_to != address(0));

    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,
    uint256 _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,
    uint256 _subtractedValue
  )
    public
    returns (bool)
  {
    uint256 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;
  }

}

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);
  }
}

contract AccessControl is Ownable, Pausable {

    /// @dev The addresses of the accounts (or contracts) that can execute actions within each roles.
    address payable public ceoAddress;
    address payable public cfoAddress;
    address payable public cooAddress;
    address payable public cmoAddress;
    address payable public BAEFeeAddress;
    address payable public owner = msg.sender;

    /// @dev Access modifier for CEO-only functionality
    modifier onlyCEO() {
        require(
            msg.sender == ceoAddress,
            "Only our CEO address can execute this function");
        _;
    }

    /// @dev Access modifier for CFO-only functionality
    modifier onlyCFO() {
        require(
            msg.sender == cfoAddress,
            "Only our CFO can can ll this function");
        _;
    }

    /// @dev Access modifier for COO-only functionality
    modifier onlyCOO() {
        require(
            msg.sender == cooAddress,
            "Only our COO can can ll this function");
        _;
    }

    /// @dev Access modifier for Clevel functions
    modifier onlyCLevelOrOwner() {
        require(
            msg.sender == cooAddress ||
            msg.sender == ceoAddress ||
            msg.sender == cfoAddress ||
            msg.sender == owner,
            "You need to be the owner or a Clevel @BAE to call this function"
        );
        _;
    }
    

    /// @dev Assigns a new address to act as the CEO. Only available to the current CEO.
    /// @param _newCEO The address of the new CEO
    function setCEO(address payable _newCEO) external onlyCEO whenNotPaused {
        require(_newCEO != address(0));
        ceoAddress = _newCEO;
    }

    /// @dev Assigns a new address to act as the CFO. Only available to the current CEO.
    /// @param _newCFO The address of the new CFO
    function setCFO(address payable _newCFO) external onlyCLevelOrOwner whenNotPaused {
        require(_newCFO != address(0));
        cfoAddress = _newCFO;
    }

    /// @dev Assigns a new address to act as the COO. Only available to the current CEO.
    /// @param _newCOO The address of the new COO
    function setCOO(address payable _newCOO) external onlyCLevelOrOwner whenNotPaused {
        require(_newCOO != address(0));
        cooAddress = _newCOO;
    }
     /// @dev Assigns a new address to act as the CMO. 
    /// @param _newCMO The address of the new CMO
    function setCMO(address payable _newCMO) external onlyCLevelOrOwner whenNotPaused {
        require(_newCMO != address(0));
        cmoAddress = _newCMO;
    }

    function getBAEFeeAddress() external view onlyCLevelOrOwner returns (address) {
        return BAEFeeAddress;
    }

    function setBAEFeeAddress(address payable _newAddress) public onlyCLevelOrOwner {
        BAEFeeAddress = _newAddress;
    }

    // Only the CEO, COO, and CFO can execute this function:
    function pause() public onlyCLevelOrOwner whenNotPaused {
        paused = true;
        emit Pause();
    }

    function unpause() public onlyCLevelOrOwner whenPaused {
        paused = false;
        emit Unpause();
    }
}

contract Destructible is AccessControl {

    /**
    * @dev Transfers the current balance to the owner and terminates the contract
    *      onlyOwner needs to be changed to onlyBAE
    */
    function destroy() public onlyCLevelOrOwner whenPaused{
        selfdestruct(owner);
    }

    /**
    * @dev Transfers the current balance to the address and terminates the contract.
    */
    function destroyAndSend(address payable _recipient) public onlyCLevelOrOwner whenPaused {
        selfdestruct(_recipient);
    }
}

contract ArtShop is Destructible {
    using SafeMath for uint256;

    /// @dev this fires everytime an artpiece is created
    event NewArtpiece(uint pieceId, string  name, string artist);
    /// @dev this is set up to track how many changes the url has been changed
    event UrlChange(uint pieceId);

    /// @dev - both baeFeeLevel and royaltyFeeLevel are percentages and the combined should be
    ///        kept below 95% on first sale or 99% on secondary sale :)
    uint8 internal baeFeeLevel;
    uint8 internal royaltyFeeLevel;
    uint8 internal potFeeLevel = 5;

    /// @dev this is used to prevent constant movement of art   
    uint32 public timeUntilAbleToTransfer = 1 hours;

    /// @dev all metadata relating to an artpiece
    /// @dev this is done to prevent the error: Stacktrace too long as per 
    /// @dev https://ethereum.stackexchange.com/questions/7325/stack-too-deep-try-removing-local-variables
    struct ArtpieceMetaData {
        uint8 remainingPrintings;
        uint64 basePrice; ///@dev listing price
        uint256 dateCreatedByTheArtist;
        string notes;
        bool isFirstSale;
        bool physical;
    }

    /// @dev all properties of an artpiece
    struct Artpiece {
        string name; /// @dev - should this change? I don't think so
        string artist; ///@dev artist's name for now - might be good to be an id/hash
        string thumbnailUrl;
        string mainUrl;
        string grade;
        uint64 price; /// @dev current price
        uint8 feeLevel; /// @dev this is the royalty fee
        uint8 baeFeeLevel;
        ArtpieceMetaData metadata;
    }

    Artpiece[] artpieces;

    mapping (uint256 => address) public numArtInAddress;
    mapping (address => uint256) public artCollection;
    mapping (uint256 => address) public artpieceApproved;

    /// @dev contract-specific modifiers on fees
    modifier onlyWithGloballySetFee() {
        require(
            baeFeeLevel > 0,
            "Requires a fee level to be set up"
        );
        require(
            royaltyFeeLevel > 0,
            "Requires a an artist fee level to be set up"
        );
        _;
    }

    /// @dev this is the gloabal fee setter
    /// @dev setBAEFeeLevel should be 35 initially on first sale
    function setBAEFeeLevel(uint8 _newFee) public onlyCLevelOrOwner {
        baeFeeLevel = _newFee;
    }

    function setRoyaltyFeeLevel(uint8 _newFee) public onlyCLevelOrOwner {
        royaltyFeeLevel = _newFee;
    }
    
    function _createArtpiece(
        string memory _name,
        string memory _artist,
        string memory _thumbnailUrl,
        string memory _mainUrl,
        string memory _notes,
        string memory _grade,
        uint256 _dateCreatedByTheArtist,
        uint64 _price,
        uint64 _basePrice,
        uint8 _remainingPrintings,
        bool _physical
        )  
        internal
        onlyWithGloballySetFee
        whenNotPaused
        {
        
        ArtpieceMetaData memory metd = ArtpieceMetaData(
                _remainingPrintings,
                _basePrice,
                _dateCreatedByTheArtist,
                _notes,
                true,
                _physical
        ); 
            
        Artpiece memory newArtpiece = Artpiece(
            _name,
            _artist,
            _thumbnailUrl,
            _mainUrl,
            _grade,
            _price,
            royaltyFeeLevel,
            baeFeeLevel,
            metd
        );
        uint id = artpieces.push(newArtpiece) - 1;

        numArtInAddress[id] = msg.sender;
        artCollection[msg.sender] = artCollection[msg.sender].add(1);
            
        emit NewArtpiece(id, _name, _artist);
    }
}

contract Helpers is ArtShop {
    
        /// @dev modifiers for the ERC721-compliant functions
    modifier onlyOwnerOf(uint _artpieceId) {
        require(msg.sender == numArtInAddress[_artpieceId]);
        _;
    }
    
    /// @dev we use this so we can't delete artpieces once they are on auction
    ///      so people have the feeling they really own the 
    modifier onlyBeforeFirstSale(uint _tokenId) {
        (,,,,bool isFirstSale,) = getArtpieceMeta(_tokenId);
        require(isFirstSale == true);
        _;
    }

    event Printed(uint indexed _id, uint256 indexed _time);
    
    function getArtpieceData(uint _id) public view returns(string memory name, string memory artist, string memory thumbnailUrl, string memory grade, uint64 price) {
        return (
            artpieces[_id].name, 
            artpieces[_id].artist, 
            artpieces[_id].thumbnailUrl, 
            artpieces[_id].grade,
            artpieces[_id].price 
        );
    }
    
    function getArtpieceFeeLevels(uint _id) public view returns(uint8, uint8) {
        return (
            artpieces[_id].feeLevel,
            artpieces[_id].baeFeeLevel
        );
    }
    
    function getArtpieceMeta(uint _id) public view returns(uint8, uint64, uint256, string memory, bool, bool) {
        return (
            artpieces[_id].metadata.remainingPrintings, 
            artpieces[_id].metadata.basePrice, 
            artpieces[_id].metadata.dateCreatedByTheArtist, 
            artpieces[_id].metadata.notes, 
            artpieces[_id].metadata.isFirstSale, 
            artpieces[_id].metadata.physical
        );
    }
    
    function getMainUrl(uint _id) public view onlyOwnerOf(_id) returns(string memory) {
        return artpieces[_id].mainUrl;
    }

    function setArtpieceName(uint _id, string memory _name) public onlyCLevelOrOwner whenNotPaused {
        artpieces[_id].name = _name;
    }

    function setArtist(uint _id, string memory _artist) public onlyCLevelOrOwner whenNotPaused {
        artpieces[_id].artist = _artist;
    }

    function setThumbnailUrl(uint _id, string memory _newThumbnailUrl) public onlyCLevelOrOwner whenNotPaused {
        artpieces[_id].thumbnailUrl = _newThumbnailUrl;
    }

    // this used to be internal
    function setMainUrl(uint _id, string memory _newUrl) public onlyCLevelOrOwner whenNotPaused {
        artpieces[_id].mainUrl = _newUrl;
        emit UrlChange(_id);
    }

    function setGrade(uint _id, string memory _grade) public onlyCLevelOrOwner whenNotPaused returns (bool success) {
        artpieces[_id].grade = _grade;
        return true;
    }

    function setPrice(uint _id, uint64 _price) public onlyCLevelOrOwner whenNotPaused {
        artpieces[_id].price = _price;
    }

    function setArtpieceBAEFee(uint _id, uint8 _newFee) public onlyCLevelOrOwner whenNotPaused {
        artpieces[_id].baeFeeLevel = _newFee;
    }

    function setArtpieceRoyaltyFeeLevel(uint _id, uint8 _newFee) public onlyCLevelOrOwner whenNotPaused {
        artpieces[_id].feeLevel = _newFee;
    }

    function setRemainingPrintings(uint _id, uint8 _remainingPrintings) internal onlyCLevelOrOwner whenNotPaused {
        artpieces[_id].metadata.remainingPrintings = _remainingPrintings;
    }
    
    function setBasePrice(uint _id, uint64 _basePrice) public onlyCLevelOrOwner {
        artpieces[_id].metadata.basePrice = _basePrice;
    }

    function setDateCreateByArtist(uint _id, uint256 _dateCreatedByTheArtist) public onlyCLevelOrOwner {
        artpieces[_id].metadata.dateCreatedByTheArtist = _dateCreatedByTheArtist;
    }

    function setNotes(uint _id, string memory _notes) public onlyCLevelOrOwner {
        artpieces[_id].metadata.notes = _notes;
    }

    function setIsPhysical(uint _id, bool _physical) public onlyCLevelOrOwner {
        artpieces[_id].metadata.physical = _physical;
    }
    
    function getArtpiecesByOwner(address _owner) external view returns(uint[] memory) {
        uint[] memory result = new uint[](artCollection[_owner]);
        uint counter = 0;

        for ( uint i = 0; i < artpieces.length; i++ ) {
            if (numArtInAddress[i] == _owner) {
                result[counter] = i;
                counter = counter.add(1);
            }
        }

        return result;
    }
}

contract BAEToken is PausableToken, AccessControl  {
    using SafeMath for uint256;
    using SafeERC20 for ERC20;

    event Mint(address indexed to, uint256 amount);
    event MintFinished();
    event Burn(address indexed burner, uint256 value);
   
    string public constant name = "BAEToken";
    string public constant symbol = "BAE";
    uint public constant decimals = 6;
    uint public currentAmount = 0; // rate is £1 == 10 BAE based on 100 000 000 = 10,000,000
    uint public totalAllocated = 0;
    bool public mintingFinished = false;
    uint256 public currentIndex = 0;

    /// @dev - holder adresses by index
    mapping(uint => address) public holderAddresses;

    /// @dev total supply assigned to msg.sender directly
    constructor() public {
        totalSupply_ = 0;
    }

    modifier validDestination(address _to)
    {
        require(_to != address(0x0));
        require(_to != address(this)); 
        _;
    }

    modifier canMint() {
        require(
            !mintingFinished,
            "Still minting."
        );
        _;
    }

    modifier hasMintPermission() {
        require(
            msg.sender == owner,
            "Message sender is not owner."
        );
        _;
    }

    modifier onlyWhenNotMinting() {
        require(
            mintingFinished == false,
            "Minting needs to be stopped to execute this function"
        );
        _;
    }

    /** 
     * @dev getter for name
     */
    function getName() public pure returns (string memory) {
        return name;
    }

    /** 
     * @dev getter for token symbol
     */
    function getSymbol() public pure returns (string memory) {
        return symbol;
    }

    /** 
     * @dev getter for totalSupply_
     */
    function getTotalSupply() public view returns (uint) {
        return totalSupply_;
    }

    /** 
     * @dev getter for user amount
     */
    function getBalance() public view returns (uint) {
        return balances[msg.sender];
    }

    /// @dev this is a superuser function to check each wallet amount
    function getUserBalance(address _userAddress) public view onlyCLevelOrOwner returns(uint) {
        return balances[_userAddress];
    }
    
    /** 
     * @dev private 
     */
    function burn(address _who, uint256 _value) public onlyCEO whenNotPaused {
        require(
            _value <= balances[_who],
            "Value is smaller than the value the account in balances has"
        );
        // no need to require value <= totalSupply, since that would imply the
        // sender's balance is greater than the totalSupply, which *should* be an assertion failure

        // BAEholders[_who] = BAEholders[_who].sub(_value);
        totalSupply_ = totalSupply_.sub(_value);
        totalAllocated = totalAllocated.sub(_value);
        balances[_who] = balances[_who].sub(_value);
        emit Burn(_who, _value);
        emit Transfer(_who, address(0), _value);
    }

    /**
    * @dev Function to mint tokens
    * @param _to The address that will receive the minted tokens.
    * @param _amount The amount of tokens to mint.
    * @return A boolean that indicates if the operation was successful.
    */
    function mint(
        address _to,
        uint256 _amount
    )
    public
    canMint
    onlyCLevelOrOwner
    whenNotPaused
    returns (bool) {
        totalSupply_ = totalSupply_.add(_amount);
        totalAllocated = totalAllocated.add(_amount);
        balances[_to] = balances[_to].add(_amount);
        emit Mint(_to, _amount);
        emit Transfer(address(0), _to, _amount);
        return true;
    }

    /**
    * @dev Function to stop minting new tokens.
    * @return True if the operation was successful.
    */
    function finishMinting() 
    public 
    onlyCEO
    canMint
    whenNotPaused
    returns (bool) {
        mintingFinished = true;
        emit MintFinished();
        return true;
    }


    /** ------------------------------------------------------------------------
     *  @dev - Owner can transfer out ERC20 tokens
     *  ------------------------------------------------------------------------ 
    // */    

    /// @dev - we `override` the ability of calling those methods to be allowed only of the owner
    ///        or the C level as the tokens shouldn't have any money properties.
    function transfer(address _to, uint256 _value) public onlyCLevelOrOwner returns (bool) {
        /// @dev call the super function transfer as is
        super.transfer(_to, _value);
        
        /// @dev and add the required
        totalAllocated = totalAllocated.add(_value);
        balances[msg.sender] = balances[msg.sender].sub(_value);
        balances[_to] = balances[_to].add(_value);
        holderAddresses[currentIndex] = _to;
        currentIndex = currentIndex.add(1);
        return true;
    }

    function transferFrom(
        address _from,
        address _to,
        uint256 _value
    )
    public
    onlyCLevelOrOwner
    returns (bool) {
        super.transferFrom(_from, _to, _value);
        totalAllocated = totalAllocated.add(_value);
        balances[_from] = balances[_from].sub(_value);
        balances[_to] = balances[_to].add(_value);
        holderAddresses[currentIndex] = _to;
        currentIndex = currentIndex.add(1);
        return true;
    }


    function approve(address _spender, uint256 _value) public onlyCLevelOrOwner returns (bool) {
        super.approve(_spender, _value);
    }
    

}

contract Payments is BAEToken {
    
    event PotPayout(address indexed _to, uint256 indexed value);

    BAECore public baeInstance;
    
    constructor() public {
        ceoAddress = msg.sender;
    }

    function setBAECoreAddress(address payable _address) public onlyCEO whenPaused {
        BAECore baeCandidate = BAECore(_address);
        baeInstance = baeCandidate;
    }
    
    /// @dev - Update balances - % of ownership
    function addToBAEHolders(address _to) public onlyCLevelOrOwner whenNotPaused {
        mint(_to, currentAmount);
    }
    
    function subToBAEHolders(address _from, address _to, uint _amount) public onlyCLevelOrOwner whenNotPaused {
        transferFrom(_from, _to, _amount);
    }
    
    function setFinalPriceInPounds(uint _finalPrice) public onlyCLevelOrOwner whenNotPaused {
        currentAmount = _finalPrice.mul(10000000);
    }
    
    function withdraw() public onlyCFO {
        cfoAddress.transfer(address(this).balance);
    }
    
    function() external payable { }
}

interface IERC165 {

  /**
  * @notice Query if a contract implements an interface
  * @param interfaceId The interface identifier, as specified in ERC-165
  * @dev Interface identification is specified in ERC-165. This function
  * uses less than 30,000 gas.
  */
  function supportsInterface(bytes4 interfaceId)
    external
    view
    returns (bool);
}

contract IERC721 is IERC165 {

  event Transfer(
    address indexed from,
    address indexed to,
    uint256 indexed tokenId
  );
  event Approval(
    address indexed owner,
    address indexed approved,
    uint256 indexed tokenId
  );
  event ApprovalForAll(
    address indexed owner,
    address indexed operator,
    bool approved
  );

  function balanceOf(address owner) public view returns (uint256 balance);
  function ownerOf(uint256 tokenId) public view returns (address owner);

  function approve(address to, uint256 tokenId) public;
  function getApproved(uint256 tokenId)
    public view returns (address operator);

  function setApprovalForAll(address operator, bool _approved) public;
  function isApprovedForAll(address owner, address operator)
    public view returns (bool);

  function transferFrom(address from, address to, uint256 tokenId) public;
  function safeTransferFrom(address from, address to, uint256 tokenId)
    public;

  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes memory data
  )
    public;
}

contract IERC721Metadata is IERC721 {
  function name() external view returns (string memory);
  function symbol() external view returns (string memory);
  function tokenURI(uint256 tokenId) public view returns (string memory);
}

contract IERC721Enumerable is IERC721 {
  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);
}

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

contract IERC721Full is IERC721, IERC721Enumerable, IERC721Metadata {
}

contract ERC165 is IERC165 {

  bytes4 private constant _InterfaceId_ERC165 = 0x01ffc9a7;
  /**
  * 0x01ffc9a7 ===
  *   bytes4(keccak256('supportsInterface(bytes4)'))
  */

  /**
  * @dev a mapping of interface id to whether or not it's supported
  */
  mapping(bytes4 => bool) internal _supportedInterfaces;

  /**
  * @dev A contract implementing SupportsInterfaceWithLookup
  * implement ERC165 itself
  */
  constructor()
    public
  {
    _registerInterface(_InterfaceId_ERC165);
  }

  /**
  * @dev implement supportsInterface(bytes4) using a lookup table
  */
  function supportsInterface(bytes4 interfaceId)
    external
    view
    returns (bool)
  {
    return _supportedInterfaces[interfaceId];
  }

  /**
  * @dev private method for registering an interface
  */
  function _registerInterface(bytes4 interfaceId)
    internal
  {
    require(interfaceId != 0xffffffff);
    _supportedInterfaces[interfaceId] = true;
  }
}

contract ERC721 is ERC165, IERC721 {
  using SafeMath for uint256;
  using Address for address;

  // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
  // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
  bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

  // Mapping from token ID to owner
  mapping (uint256 => address) private _tokenOwner;

  // Mapping from token ID to approved address
  mapping (uint256 => address) private _tokenApprovals;

  // Mapping from owner to number of owned token
  mapping (address => uint256) private _ownedTokensCount;

  // Mapping from owner to operator approvals
  mapping (address => mapping (address => bool)) private _operatorApprovals;

  bytes4 private constant _InterfaceId_ERC721 = 0x80ac58cd;
  /*
  * 0x80ac58cd ===
  *   bytes4(keccak256('balanceOf(address)')) ^
  *   bytes4(keccak256('ownerOf(uint256)')) ^
  *   bytes4(keccak256('approve(address,uint256)')) ^
  *   bytes4(keccak256('getApproved(uint256)')) ^
  *   bytes4(keccak256('setApprovalForAll(address,bool)')) ^
  *   bytes4(keccak256('isApprovedForAll(address,address)')) ^
  *   bytes4(keccak256('transferFrom(address,address,uint256)')) ^
  *   bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^
  *   bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)'))
  */

  constructor()
    public
  {
    // register the supported interfaces to conform to ERC721 via ERC165
    _registerInterface(_InterfaceId_ERC721);
  }

  /**
  * @dev Gets the balance of the specified address
  * @param owner address to query the balance of
  * @return uint256 representing the amount owned by the passed address
  */
  function balanceOf(address owner) public view returns (uint256) {
    require(owner != address(0));
    return _ownedTokensCount[owner];
  }

  /**
  * @dev Gets the owner of the specified token ID
  * @param tokenId uint256 ID of the token to query the owner of
  * @return owner address currently marked as the owner of the given token ID
  */
  function ownerOf(uint256 tokenId) public view returns (address) {
    address owner = _tokenOwner[tokenId];
    require(owner != address(0));
    return owner;
  }

  /**
  * @dev Approves another address to transfer the given token ID
  * The zero address indicates there is no approved address.
  * There can only be one approved address per token at a given time.
  * Can only be called by the token owner or an approved operator.
  * @param to address to be approved for the given token ID
  * @param tokenId uint256 ID of the token to be approved
  */
  function approve(address to, uint256 tokenId) public {
    address owner = ownerOf(tokenId);
    require(to != owner);
    require(msg.sender == owner || isApprovedForAll(owner, msg.sender));

    _tokenApprovals[tokenId] = to;
    emit Approval(owner, to, tokenId);
  }

  /**
  * @dev Gets the approved address for a token ID, or zero if no address set
  * Reverts if the token ID does not exist.
  * @param tokenId uint256 ID of the token to query the approval of
  * @return address currently approved for the given token ID
  */
  function getApproved(uint256 tokenId) public view returns (address) {
    require(_exists(tokenId));
    return _tokenApprovals[tokenId];
  }

  /**
  * @dev Sets or unsets the approval of a given operator
  * An operator is allowed to transfer all tokens of the sender on their behalf
  * @param to operator address to set the approval
  * @param approved representing the status of the approval to be set
  */
  function setApprovalForAll(address to, bool approved) public {
    require(to != msg.sender);
    _operatorApprovals[msg.sender][to] = approved;
    emit ApprovalForAll(msg.sender, to, approved);
  }

  /**
  * @dev Tells whether an operator is approved by a given owner
  * @param owner owner address which you want to query the approval of
  * @param operator operator address which you want to query the approval of
  * @return bool whether the given operator is approved by the given owner
  */
  function isApprovedForAll(
    address owner,
    address operator
  )
    public
    view
    returns (bool)
  {
    return _operatorApprovals[owner][operator];
  }

  /**
  * @dev Transfers the ownership of a given token ID to another address
  * Usage of this method is discouraged, use `safeTransferFrom` whenever possible
  * Requires the msg sender to be the owner, approved, or operator
  * @param from current owner of the token
  * @param to address to receive the ownership of the given token ID
  * @param tokenId uint256 ID of the token to be transferred
  */
  function transferFrom(
    address from,
    address to,
    uint256 tokenId
  )
    public
  {
    require(_isApprovedOrOwner(msg.sender, tokenId));
    require(to != address(0));

    _clearApproval(from, tokenId);
    _removeTokenFrom(from, tokenId);
    _addTokenTo(to, tokenId);

    emit Transfer(from, to, tokenId);
  }


  /**
  * @dev Safely transfers the ownership of a given token ID to another address
  * If the target address is a contract, it must implement `onERC721Received`,
  * which is called upon a safe transfer, and return the magic value
  * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
  * the transfer is reverted.
  *
  * Requires the msg sender to be the owner, approved, or operator
  * @param from current owner of the token
  * @param to address to receive the ownership of the given token ID
  * @param tokenId uint256 ID of the token to be transferred
  */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId
  )
    public
  {
    // solium-disable-next-line arg-overflow
    safeTransferFrom(from, to, tokenId, "");
  }

  /**
  * @dev Safely transfers the ownership of a given token ID to another address
  * If the target address is a contract, it must implement `onERC721Received`,
  * which is called upon a safe transfer, and return the magic value
  * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise,
  * the transfer is reverted.
  * Requires the msg sender to be the owner, approved, or operator
  * @param from current owner of the token
  * @param to address to receive the ownership of the given token ID
  * @param tokenId uint256 ID of the token to be transferred
  * @param _data bytes data to send along with a safe transfer check
  */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes memory _data
  )
    public
  {
    transferFrom(from, to, tokenId);
    // solium-disable-next-line arg-overflow
    require(_checkAndCallSafeTransfer(from, to, tokenId, _data));
  }

  /**
  * @dev Returns whether the specified token exists
  * @param tokenId uint256 ID of the token to query the existence of
  * @return whether the token exists
  */
  function _exists(uint256 tokenId) internal view returns (bool) {
    address owner = _tokenOwner[tokenId];
    return owner != address(0);
  }

  /**
  * @dev Returns whether the given spender can transfer a given token ID
  * @param spender address of the spender to query
  * @param tokenId uint256 ID of the token to be transferred
  * @return bool whether the msg.sender is approved for the given token ID,
  *  is an operator of the owner, or is the owner of the token
  */
  function _isApprovedOrOwner(
    address spender,
    uint256 tokenId
  )
    internal
    view
    returns (bool)
  {
    address owner = ownerOf(tokenId);
    // Disable solium check because of
    // https://github.com/duaraghav8/Solium/issues/175
    // solium-disable-next-line operator-whitespace
    return (
      spender == owner ||
      getApproved(tokenId) == spender ||
      isApprovedForAll(owner, spender)
    );
  }

  /**
  * @dev Internal function to mint a new token
  * Reverts if the given token ID already exists
  * @param to The address that will own the minted token
  * @param tokenId uint256 ID of the token to be minted by the msg.sender
  */
  function _mint(address to, uint256 tokenId) internal {
    require(to != address(0));
    _addTokenTo(to, tokenId);
    emit Transfer(address(0), to, tokenId);
  }

  /**
  * @dev Internal function to burn a specific token
  * Reverts if the token does not exist
  * @param tokenId uint256 ID of the token being burned by the msg.sender
  */
  function _burn(address owner, uint256 tokenId) internal {
    _clearApproval(owner, tokenId);
    _removeTokenFrom(owner, tokenId);
    emit Transfer(owner, address(0), tokenId);
  }

  /**
  * @dev Internal function to clear current approval of a given token ID
  * Reverts if the given address is not indeed the owner of the token
  * @param owner owner of the token
  * @param tokenId uint256 ID of the token to be transferred
  */
  function _clearApproval(address owner, uint256 tokenId) internal {
    require(ownerOf(tokenId) == owner);
    if (_tokenApprovals[tokenId] != address(0)) {
      _tokenApprovals[tokenId] = address(0);
    }
  }

  /**
  * @dev Internal function to add a token ID to the list of a given address
  * @param to address representing the new owner of the given token ID
  * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
  */
  function _addTokenTo(address to, uint256 tokenId) internal {
    require(_tokenOwner[tokenId] == address(0));
    _tokenOwner[tokenId] = to;
    _ownedTokensCount[to] = _ownedTokensCount[to].add(1);
  }

  /**
  * @dev Internal function to remove a token ID from the list of a given address
  * @param from address representing the previous owner of the given token ID
  * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
  */
  function _removeTokenFrom(address from, uint256 tokenId) internal {
    require(ownerOf(tokenId) == from);
    _ownedTokensCount[from] = _ownedTokensCount[from].sub(1);
    _tokenOwner[tokenId] = address(0);
  }

  /**
  * @dev Internal function to invoke `onERC721Received` on a target address
  * The call is not executed if the target address is not a contract
  * @param from address representing the previous owner of the given token ID
  * @param to target address that will receive the tokens
  * @param tokenId uint256 ID of the token to be transferred
  * @param _data bytes optional data to send along with the call
  * @return whether the call correctly returned the expected magic value
  */
  function _checkAndCallSafeTransfer(
    address from,
    address to,
    uint256 tokenId,
    bytes memory _data
  )
    internal
    returns (bool)
  {
    if (!to.isContract()) {
      return true;
    }
    bytes4 retval = IERC721Receiver(to).onERC721Received(
      msg.sender, from, tokenId, _data);
    return (retval == _ERC721_RECEIVED);
  }
}

contract ERC721Metadata is ERC165, ERC721, IERC721Metadata {
  // Token name
  string internal _name;

  // Token symbol
  string internal _symbol;

  // Optional mapping for token URIs
  mapping(uint256 => string) private _tokenURIs;

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

  /**
  * @dev Constructor function
  */
  constructor(string memory name, string memory symbol) public {
    _name = name;
    _symbol = symbol;

    // register the supported interfaces to conform to ERC721 via ERC165
    _registerInterface(InterfaceId_ERC721Metadata);
  }

  /**
  * @dev Gets the token name
  * @return string representing the token name
  */
  function name() external view returns (string memory) {
    return _name;
  }

  /**
  * @dev Gets the token symbol
  * @return string representing the token symbol
  */
  function symbol() external view returns (string memory) {
    return _symbol;
  }

  /**
  * @dev Returns an URI for a given token ID
  * Throws if the token ID does not exist. May return an empty string.
  * @param tokenId uint256 ID of the token to query
  */
  function tokenURI(uint256 tokenId) public view returns (string memory) {
    require(_exists(tokenId));
    return _tokenURIs[tokenId];
  }

  /**
  * @dev Internal function to set the token URI for a given token
  * Reverts if the token ID does not exist
  * @param tokenId uint256 ID of the token to set its URI
  * @param uri string URI to assign
  */
  function _setTokenURI(uint256 tokenId, string memory uri) internal {
    require(_exists(tokenId));
    _tokenURIs[tokenId] = uri;
  }

  /**
  * @dev Internal function to burn a specific token
  * Reverts if the token does not exist
  * @param owner owner of the token to burn
  * @param tokenId uint256 ID of the token being burned by the msg.sender
  */
  function _burn(address owner, uint256 tokenId) internal {
    super._burn(owner, tokenId);

    // Clear metadata (if any)
    if (bytes(_tokenURIs[tokenId]).length != 0) {
      delete _tokenURIs[tokenId];
    }
  }
}

contract ERC721Enumerable is ERC165, ERC721, IERC721Enumerable {
  // Mapping from owner to list of owned token IDs
  mapping(address => uint256[]) private _ownedTokens;

  // Mapping from token ID to index of the owner tokens list
  mapping(uint256 => uint256) private _ownedTokensIndex;

  // Array with all token ids, used for enumeration
  uint256[] private _allTokens;

  // Mapping from token id to position in the allTokens array
  mapping(uint256 => uint256) private _allTokensIndex;

  bytes4 private constant _InterfaceId_ERC721Enumerable = 0x780e9d63;
  /**
  * 0x780e9d63 ===
  *   bytes4(keccak256('totalSupply()')) ^
  *   bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) ^
  *   bytes4(keccak256('tokenByIndex(uint256)'))
  */

  /**
  * @dev Constructor function
  */
  constructor() public {
    // register the supported interface to conform to ERC721 via ERC165
    _registerInterface(_InterfaceId_ERC721Enumerable);
  }

  /**
  * @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
  * 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];
  }

  /**
  * @dev Internal function to add a token ID to the list of a given address
  * @param to address representing the new owner of the given token ID
  * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
  */
  function _addTokenTo(address to, uint256 tokenId) internal {
    super._addTokenTo(to, tokenId);
    uint256 length = _ownedTokens[to].length;
    _ownedTokens[to].push(tokenId);
    _ownedTokensIndex[tokenId] = length;
  }

  /**
  * @dev Internal function to remove a token ID from the list of a given address
  * @param from address representing the previous owner of the given token ID
  * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
  */
  function _removeTokenFrom(address from, uint256 tokenId) internal {
    super._removeTokenFrom(from, tokenId);

    // To prevent a gap in the array, we store the last token in the index of the token to delete, and
    // then delete the last slot.
    uint256 tokenIndex = _ownedTokensIndex[tokenId];
    uint256 lastTokenIndex = _ownedTokens[from].length.sub(1);
    uint256 lastToken = _ownedTokens[from][lastTokenIndex];

    _ownedTokens[from][tokenIndex] = lastToken;
    // This also deletes the contents at the last position of the array
    _ownedTokens[from].length--;

    // Note that this will handle single-element arrays. In that case, both tokenIndex and lastTokenIndex are going to
    // be zero. Then we can make sure that we will remove tokenId from the ownedTokens list since we are first swapping
    // the lastToken to the first position, and then dropping the element placed in the last position of the list

    _ownedTokensIndex[tokenId] = 0;
    _ownedTokensIndex[lastToken] = tokenIndex;
  }

  /**
  * @dev Internal function to mint a new token
  * Reverts if the given token ID already exists
  * @param to address the beneficiary that will own the minted token
  * @param tokenId uint256 ID of the token to be minted by the msg.sender
  */
  function _mint(address to, uint256 tokenId) internal {
    super._mint(to, tokenId);

    _allTokensIndex[tokenId] = _allTokens.length;
    _allTokens.push(tokenId);
  }

  /**
  * @dev Internal function to burn a specific token
  * Reverts if the token does not exist
  * @param owner owner of the token to burn
  * @param tokenId uint256 ID of the token being burned by the msg.sender
  */
  function _burn(address owner, uint256 tokenId) internal {
    super._burn(owner, tokenId);

    // Reorg all tokens array
    uint256 tokenIndex = _allTokensIndex[tokenId];
    uint256 lastTokenIndex = _allTokens.length.sub(1);
    uint256 lastToken = _allTokens[lastTokenIndex];

    _allTokens[tokenIndex] = lastToken;
    _allTokens[lastTokenIndex] = 0;

    _allTokens.length--;
    _allTokensIndex[tokenId] = 0;
    _allTokensIndex[lastToken] = tokenIndex;
  }
}

contract ERC721Full is ERC721, ERC721Enumerable, ERC721Metadata {
    constructor (string memory name, string memory symbol) public ERC721Metadata(name, symbol) {
        // solhint-disable-previous-line no-empty-blocks
    }
}

contract BAE is ERC721Full, Helpers {
    using SafeMath for uint256;

    /// @dev - extra events on the ERC721 contract
    event Sold(uint indexed _tokenId, address _from, address _to, uint indexed _price);
    event Deleted(uint indexed _tokenId, address _from);
    event PaymentsContractChange(address _prevAddress, address _futureAddress);
    event AuctionContractChange(address _prevAddress, address _futureAddress);

    Payments public tokenInterface;
    mapping (uint => address) artTransApprovals;

   constructor() ERC721Full("BlockchainArtExchange", "BAE") public {}
    
    /// @dev functions affecting ERC20 tokens
    function setPaymentAddress(address payable _newAddress) public onlyCEO whenPaused {
        Payments tokenInterfaceCandidate = Payments(_newAddress);
        tokenInterface = tokenInterfaceCandidate;
    }

  function createArtpiece(
        string memory _name,
        string memory _artist,
        string memory _thumbnailUrl,
        string memory _mainUrl,
        string memory _notes,
        string memory _grade,
        uint256 _dateCreatedByTheArtist,
        uint64 _price,
        uint64 _basePrice,
        uint8 _remainingPrintings,
        bool _physical
    ) 
      public 
    {
        super._createArtpiece(_name, _artist, _thumbnailUrl, _mainUrl, _notes, _grade, _dateCreatedByTheArtist, _price, _basePrice, _remainingPrintings, _physical);
        
        _mint(msg.sender, artpieces.length - 1);
    }
  
    function calculateFees(uint _tokenId) public payable whenNotPaused returns (uint baeFee, uint royaltyFee, uint potFee) {
        /// @dev check this will not bring problems in the future or should we be using SafeMath library.
        uint baeFeeAmount = (uint(artpieces[_tokenId].baeFeeLevel) * msg.value) / 100;
        uint artistFeeAmount = (uint(artpieces[_tokenId].feeLevel) * msg.value) / 100;

        /// @dev any extra money will be added to the pot
        uint potFeeAmount = msg.value - (baeFeeAmount + artistFeeAmount);
        return (baeFeeAmount, artistFeeAmount, potFeeAmount);
    }

    /// @dev - this should be getting the royalty fee so we get the remaining as what is the bae fee
    function payFees(uint256 _baeFee, uint256 _royaltyFee, uint256 _potFee, address payable _seller) public payable whenNotPaused {
        uint totalToPay = _baeFee + _royaltyFee + _potFee;
        require(
            msg.value >= totalToPay,
            "Value must be equal or greater than the cost of the fees"
        );

        BAEFeeAddress.transfer(msg.value.sub(_baeFee));
        _seller.transfer(msg.value.sub(_royaltyFee));

        // we send the value left of the message to the POT contract
        address(tokenInterface).transfer(msg.value);
    }
    
    /// @dev set post-purchase data
    function _postPurchase(address _from, address _to, uint256 _tokenId) internal {
        artCollection[_to] = artCollection[_to].add(1);
        artCollection[_from] = artCollection[_from].sub(1);
        numArtInAddress[_tokenId] = _to;

        if (artpieces[_tokenId].metadata.isFirstSale) {
            artpieces[_tokenId].feeLevel = uint8(96);
            artpieces[_tokenId].baeFeeLevel = uint8(3);
            /// potFeeLevel is calculated from adding up (baeFeeLevel + royaltyFee) - 100
        }
        
        /// @dev we set this as not being the first sale anymore
        artpieces[_tokenId].metadata.isFirstSale = false;

        emit Sold(_tokenId, _from, _to, artpieces[_tokenId].price);
    }
    
    
    /// @dev this method is not part of erc-721 - not yet tested
    function deleteArtpiece(uint256 _tokenId) public onlyCLevelOrOwner whenNotPaused onlyBeforeFirstSale(_tokenId) returns (bool deleted) {
        address _from = numArtInAddress[_tokenId];
        delete numArtInAddress[_tokenId];
        artCollection[_from] = artCollection[_from].sub(1);
        _burn(_from, _tokenId);
        delete artpieces[_tokenId];
        emit Deleted(_tokenId, _from);
        return true;
    }

    /// @dev - we override this so only the CEO can call it.
    function pause() public onlyCEO whenNotPaused {
        super.pause();
    }
}

contract PerishableSimpleAuction is Destructible {
    using SafeMath for uint256;

    event AuctionCreated(uint id, address seller);
    event AuctionWon(uint tokenId, address _who);
    event SellerPaid(bool success, uint amount);
    
    BAECore public baeInstance;
    bool private currentAuction;

    struct Auction {
        uint256 tokenId;
        uint256 startingPrice;
        uint256 finalPrice;
        address payable seller;
        uint8 paid;
    }

    // When someone wins add it to this mapping 
    /// @dev address => uint === winnerAddress => tokenId
    mapping (uint => address) public winners;

    // Map from token ID to their corresponding auction.
    mapping (uint256 => Auction) public tokenIdToAuction;
    mapping (uint256 => uint256) public tokendIdToAuctionId;

    /// @dev auction array
    Auction[20] public auctions;

    /// @dev auction index
    uint public idx = 0;

    /// @dev cut on each auction
    uint256 public baeAuctionFee = 0.01 ether;

    modifier onlyAuctionOwner() {
        require(msg.sender == owner);
        _;
    }
    
    modifier onlyAuctionLord() {
        require(msg.sender == address(baeInstance));
        _;
    }
    
    constructor() public {
        paused = true;
        ceoAddress = msg.sender;
    }
    
    function setIsCurrentAuction(bool _current) external onlyCEO {
        currentAuction = _current;
    }
    
    /// @dev this should be done when paused  as it breaks functionality
    /// @dev changes the current contract interaccting with the auction
    function setBAEAddress(address payable _newAddress) public onlyAuctionOwner whenPaused {
        address currentInstance = address(baeInstance);
        BAECore candidate = BAECore(_newAddress);
        baeInstance = candidate;
        require(address(baeInstance) != address(0) && address(baeInstance) != currentInstance);
    }

    function createAuction(
        uint256 _tokenId,
        uint256 _startingPrice,
        uint256 _finalPrice,
        address payable _seller
    )
        external
        whenNotPaused
        onlyAuctionLord
    {
        if (tokendIdToAuctionId[_tokenId] != 0) {
            require(tokenIdToAuction[_tokenId].paid == 1);
        }
        require(idx <= 20);
        
        Auction memory newAuction = Auction(_tokenId, _startingPrice, _finalPrice, _seller, 0);
        auctions[idx] = newAuction;
        tokenIdToAuction[_tokenId] = newAuction; 
        tokendIdToAuctionId[_tokenId] = idx;
        idx = idx.add(1);
        
        emit AuctionCreated(idx,  _seller);
    }

    /// @dev this function sets who won that auction and allows the token to be marked as approved for sale.
    function hasWon(uint256 _auctionId, address _winner, uint256 _finalBidPrice) external whenNotPaused onlyAuctionLord {
        winners[auctions[_auctionId].tokenId] = _winner;
        auctions[_auctionId].finalPrice = _finalBidPrice;
        emit AuctionWon(auctions[_auctionId].tokenId, _winner);
    }

    function winnerCheckWireDetails(uint _auctionId, address _sender) external view whenNotPaused returns(address payable, uint, uint) {
        /// get the storage variables
        uint finalPrice = auctions[_auctionId].finalPrice;
        uint tokenId = auctions[_auctionId].tokenId;
        address winnerAddress = winners[tokenId];
        address payable seller = auctions[_auctionId].seller;

        /// get winner address and check it is in the winners' mapping
        require(_sender == winnerAddress);
        return (seller, tokenId, finalPrice);
    }
    
    function setPaid(uint _auctionId) external whenNotPaused onlyAuctionLord {
        require(auctions[_auctionId].paid == 0);
        auctions[_auctionId].paid = 1;
        emit SellerPaid(true, auctions[_auctionId].finalPrice);
    }
    
    /** Takes an auctionId to get the tokenId for the auction and returns the address of the winner. */
    function getAuctionWinnerAddress(uint _auctionId) external view whenNotPaused returns(address)  {
        return winners[auctions[_auctionId].tokenId];
    }
    
    function getFinalPrice(uint _auctionId) external view whenNotPaused returns(uint)  {
        return auctions[_auctionId].finalPrice;
    }

    function getAuctionDetails(uint _auctionId) external view whenNotPaused returns (uint, uint, uint, address, uint) {
        return (auctions[_auctionId].tokenId, auctions[_auctionId].startingPrice, auctions[_auctionId].finalPrice, auctions[_auctionId].seller, auctions[_auctionId].paid);
    }
    
    function getCurrentIndex() external view returns (uint) {
        uint val = idx - 1;
                
        if (val > 20) {
            return 0;
        }
        
        return val;
    }
    
    function getTokenIdToAuctionId(uint _tokenId) external view returns (uint) {
        return tokendIdToAuctionId[_tokenId];
    }
    
    function unpause() public onlyAuctionOwner whenPaused {
        require(address(baeInstance) != address(0));

        super.unpause();
    }
    
    function () external payable {
        revert();
    }
}

contract BAECore is BAE {
      using SafeMath for uint256;
 
    /// @dev this will be private so no one can see where it is living and will be deployed by another address
    PerishableSimpleAuction private instanceAuctionAddress;
    
    constructor() public {
        paused = true;
        ceoAddress = msg.sender;
    }

    function setAuctionAddress(address payable _newAddress) public onlyCEO whenPaused {
        PerishableSimpleAuction possibleAuctionInstance = PerishableSimpleAuction(_newAddress);
        instanceAuctionAddress = possibleAuctionInstance;
    }
    
    /// @dev we can also charge straight away by charging an amount and making this function payable
    function createAuction(uint _tokenId, uint _startingPrice, uint _finalPrice) external whenNotPaused {
        require(ownerOf( _tokenId) == msg.sender, "You can't transfer an artpiece which is not yours");
        require(_startingPrice >= artpieces[_tokenId].metadata.basePrice);
        instanceAuctionAddress.createAuction(_tokenId, _startingPrice,_finalPrice, msg.sender);
        
        /// @dev - approve the setWinnerAndPrice callers
        setApprovalForAll(owner, true);
        setApprovalForAll(ceoAddress, true);
        setApprovalForAll(cfoAddress, true);
        setApprovalForAll(cooAddress, true);
    }
    
    function getAuctionDetails(uint _auctionId) public view returns (uint) {
        (uint tokenId,,,,) = instanceAuctionAddress.getAuctionDetails(_auctionId);
        return tokenId;
    }
    
    /// @dev this should be cleared from the array if its called on a second time.
    function setWinnerAndPrice(uint256 _auctionId, address _winner, uint256 _finalPrice, uint256 _currentPrice) external onlyCLevelOrOwner whenNotPaused returns(bool hasWinnerInfo) 
    {   
        (uint tokenId,,,,) = instanceAuctionAddress.getAuctionDetails(_auctionId);
        require(_finalPrice >= uint256(artpieces[tokenId].metadata.basePrice));
        approve(_winner, tokenId);
        instanceAuctionAddress.hasWon(_auctionId, _winner, _finalPrice);
        tokenInterface.setFinalPriceInPounds(_currentPrice);
        return true;
    }
    
    function calculateFees(uint _tokenId, uint _fullAmount) internal view  whenNotPaused returns (uint baeFee, uint royaltyFee, uint potFee) {
        /// @dev check this will not bring problems in the future or should we be using SafeMath library.
        uint baeFeeAmount = (uint(artpieces[_tokenId].baeFeeLevel) * _fullAmount) / 100;
        uint artistFeeAmount = (uint(artpieces[_tokenId].feeLevel) * _fullAmount) / 100;

        /// @dev any extra money will be added to the pot
        uint potFeeAmount = _fullAmount - (baeFeeAmount + artistFeeAmount);
        return (baeFeeAmount, artistFeeAmount, potFeeAmount);
    }

    function payAndWithdraw(uint _auctionId) public payable {
        // calculate the share of each of the stakeholders 
        (address payable seller, uint tokenId, uint finalPrice) = instanceAuctionAddress.winnerCheckWireDetails(_auctionId, msg.sender);
        (uint baeFeeAmount, uint artistFeeAmount,) = calculateFees(tokenId, finalPrice);
        
        // break msg.value it into the rightchunks
        require(msg.value >= finalPrice);
        uint baeFee = msg.value.sub(baeFeeAmount);
        uint artistFee = msg.value.sub(artistFeeAmount);
        
        // do the transfers
        BAEFeeAddress.transfer(msg.value.sub(baeFee));
        seller.transfer(msg.value.sub(artistFee));
        address(tokenInterface).transfer(address(this).balance);
        
        // and when the money is sent, we mark the auccion as completed
        instanceAuctionAddress.setPaid(_auctionId);
        
        // and since it's paid then initiate the transfer mechanism
        transferFrom(seller, msg.sender, tokenId);
    }
    
    function getWinnerAddress(uint _auctionId) public view returns(address)  {
        return instanceAuctionAddress.getAuctionWinnerAddress(_auctionId);
    }
    
    function getHighestBid(uint _auctionId) public view returns(uint)  {
        return instanceAuctionAddress.getFinalPrice(_auctionId);
    }
    
    function getLatestAuctionIndex() public view returns(uint) {
        return instanceAuctionAddress.getCurrentIndex();
    }

    function transferFrom(address _from, address _to, uint256 _tokenId) public whenNotPaused {
        uint auctionId = instanceAuctionAddress.getTokenIdToAuctionId(_tokenId);
        (,,,,uint paid) = (instanceAuctionAddress.getAuctionDetails(auctionId));
        require(paid == 1);
        super.transferFrom(_from, _to, _tokenId);
        _postPurchase(_from, _to, _tokenId);
        
        /// @dev this gets paid even to non artists, if it's a seller he will get the same
        tokenInterface.addToBAEHolders(_from);
    }
    
    function unpause() public onlyCEO whenPaused {
        require(ceoAddress != address(0));
        require(address(instanceAuctionAddress) != address(0));
        require(address(tokenInterface) != address(0));
        require(address(BAEFeeAddress) != address(0));

        super.unpause();
    }
    
    /// @dev - we override this so only the CEO can call it.
    function pause() public onlyCEO whenNotPaused {
        super.pause();
    }
    
    function () external payable {}
}

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":"cfoAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"ceoAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_id","type":"uint256"}],"name":"getMainUrl","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"}],"name":"getArtpiecesByOwner","outputs":[{"name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newFee","type":"uint8"}],"name":"setRoyaltyFeeLevel","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newCMO","type":"address"}],"name":"setCMO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getBAEFeeAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getLatestAuctionIndex","outputs":[{"name":"","type":"uint256"}],"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":"_id","type":"uint256"}],"name":"getArtpieceFeeLevels","outputs":[{"name":"","type":"uint8"},{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newCEO","type":"address"}],"name":"setCEO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_name","type":"string"}],"name":"setArtpieceName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_price","type":"uint64"}],"name":"setPrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newCOO","type":"address"}],"name":"setCOO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"BAEFeeAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"deleteArtpiece","outputs":[{"name":"deleted","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_newUrl","type":"string"}],"name":"setMainUrl","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"_id","type":"uint256"}],"name":"getArtpieceMeta","outputs":[{"name":"","type":"uint8"},{"name":"","type":"uint64"},{"name":"","type":"uint256"},{"name":"","type":"string"},{"name":"","type":"bool"},{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newFee","type":"uint8"}],"name":"setBAEFeeLevel","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"from","type":"address"},{"name":"to","type":"address"},{"name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newCFO","type":"address"}],"name":"setCFO","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_auctionId","type":"uint256"}],"name":"getWinnerAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"}],"name":"calculateFees","outputs":[{"name":"baeFee","type":"uint256"},{"name":"royaltyFee","type":"uint256"},{"name":"potFee","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_newThumbnailUrl","type":"string"}],"name":"setThumbnailUrl","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_notes","type":"string"}],"name":"setNotes","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newAddress","type":"address"}],"name":"setPaymentAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"artpieceApproved","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_physical","type":"bool"}],"name":"setIsPhysical","outputs":[],"payable":false,"stateMutability":"nonpayable","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":"owner","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"},{"name":"_artist","type":"string"},{"name":"_thumbnailUrl","type":"string"},{"name":"_mainUrl","type":"string"},{"name":"_notes","type":"string"},{"name":"_grade","type":"string"},{"name":"_dateCreatedByTheArtist","type":"uint256"},{"name":"_price","type":"uint64"},{"name":"_basePrice","type":"uint64"},{"name":"_remainingPrintings","type":"uint8"},{"name":"_physical","type":"bool"}],"name":"createArtpiece","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"uint256"}],"name":"numArtInAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"destroy","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"timeUntilAbleToTransfer","outputs":[{"name":"","type":"uint32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newAddress","type":"address"}],"name":"setBAEFeeAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"cmoAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_auctionId","type":"uint256"},{"name":"_winner","type":"address"},{"name":"_finalPrice","type":"uint256"},{"name":"_currentPrice","type":"uint256"}],"name":"setWinnerAndPrice","outputs":[{"name":"hasWinnerInfo","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_auctionId","type":"uint256"}],"name":"getHighestBid","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_basePrice","type":"uint64"}],"name":"setBasePrice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_newAddress","type":"address"}],"name":"setAuctionAddress","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"artCollection","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_auctionId","type":"uint256"}],"name":"payAndWithdraw","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_grade","type":"string"}],"name":"setGrade","outputs":[{"name":"success","type":"bool"}],"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":true,"inputs":[],"name":"cooAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_newFee","type":"uint8"}],"name":"setArtpieceRoyaltyFeeLevel","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":"_id","type":"uint256"}],"name":"getArtpieceData","outputs":[{"name":"name","type":"string"},{"name":"artist","type":"string"},{"name":"thumbnailUrl","type":"string"},{"name":"grade","type":"string"},{"name":"price","type":"uint64"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_artist","type":"string"}],"name":"setArtist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_tokenId","type":"uint256"},{"name":"_startingPrice","type":"uint256"},{"name":"_finalPrice","type":"uint256"}],"name":"createAuction","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_newFee","type":"uint8"}],"name":"setArtpieceBAEFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"owner","type":"address"},{"name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_baeFee","type":"uint256"},{"name":"_royaltyFee","type":"uint256"},{"name":"_potFee","type":"uint256"},{"name":"_seller","type":"address"}],"name":"payFees","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"name":"_id","type":"uint256"},{"name":"_dateCreatedByTheArtist","type":"uint256"}],"name":"setDateCreateByArtist","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_auctionId","type":"uint256"}],"name":"getAuctionDetails","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"tokenInterface","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_recipient","type":"address"}],"name":"destroyAndSend","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_tokenId","type":"uint256"},{"indexed":false,"name":"_from","type":"address"},{"indexed":false,"name":"_to","type":"address"},{"indexed":true,"name":"_price","type":"uint256"}],"name":"Sold","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_tokenId","type":"uint256"},{"indexed":false,"name":"_from","type":"address"}],"name":"Deleted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_prevAddress","type":"address"},{"indexed":false,"name":"_futureAddress","type":"address"}],"name":"PaymentsContractChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"_prevAddress","type":"address"},{"indexed":false,"name":"_futureAddress","type":"address"}],"name":"AuctionContractChange","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_id","type":"uint256"},{"indexed":true,"name":"_time","type":"uint256"}],"name":"Printed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"pieceId","type":"uint256"},{"indexed":false,"name":"name","type":"string"},{"indexed":false,"name":"artist","type":"string"}],"name":"NewArtpiece","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"pieceId","type":"uint256"}],"name":"UrlChange","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"}],"name":"OwnershipRenounced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"approved","type":"address"},{"indexed":true,"name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"operator","type":"address"},{"indexed":false,"name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"}]

Contract Creation Code
6080604052600c805460a060020a60ff02191690556012805433600160a060020a03199091161760b060020a60ff0219167605000000000000000000000000000000000000000000001760b860020a63ffffffff021916780e1000000000000000000000000000000000000000000000001790553480156200008057600080fd5b50604080518082018252601581527f426c6f636b636861696e41727445786368616e676500000000000000000000006020808301919091528251808401909352600383527f424145000000000000000000000000000000000000000000000000000000000090830152908181620001207f01ffc9a70000000000000000000000000000000000000000000000000000000064010000000062000239810204565b620001547f80ac58cd0000000000000000000000000000000000000000000000000000000064010000000062000239810204565b620001887f780e9d630000000000000000000000000000000000000000000000000000000064010000000062000239810204565b81516200019d906009906020850190620002a6565b508051620001b390600a906020840190620002a6565b50620001e87f5b5e139f0000000000000000000000000000000000000000000000000000000064010000000062000239810204565b5050600c80547401000000000000000000000000000000000000000033600160a060020a0319928316811760a060020a60ff02191691909117909255600d80549091169091179055506200034b9050565b7fffffffff0000000000000000000000000000000000000000000000000000000080821614156200026957600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000166000908152602081905260409020805460ff19166001179055565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10620002e957805160ff191683800117855562000319565b8280016001018555821562000319579182015b8281111562000319578251825591602001919060010190620002fc565b50620003279291506200032b565b5090565b6200034891905b8082111562000327576000815560010162000332565b90565b615f33806200035b6000396000f3fe608060405260043610610438576000357c0100000000000000000000000000000000000000000000000000000000900480635fa66b321161023b5780639a95ac4b11610140578063cda4beef116100c8578063eab31fc911610097578063eab31fc914611a59578063f20e5e3514611a89578063f2fde38b14611ab3578063f343d68314611ae6578063f5074f4114611afb57610438565b8063cda4beef1461197d578063d939c13a146119b3578063e985e9c5146119e6578063ea0a977314611a2157610438565b8063b3a03a261161010f578063b3a03a26146115a4578063b88d4fde146115d7578063c4d74d50146116aa578063c87b56dd14611899578063cb33420b146118c357610438565b80639a95ac4b1461147d5780639ace64961461149a578063a22cb46514611554578063b047fb501461158f57610438565b80638ab8d19e116101c35780638f288644116101925780638f2886441461139e57806391ef4c7e146113c857806393ac36381461140257806395d89b4114611435578063997f8b0a1461144a57610438565b80638ab8d19e146112fc5780638c267b971461132f5780638d59767c146113445780638da5cb5b1461138957610438565b806379b58a631161020a57806379b58a6314610ef95780638121bfef1461127a57806383197ef0146112a45780638456cb59146112b9578063889f22cb146112ce57610438565b80635fa66b3214610e555780636352211e14610e8757806370a0823114610eb1578063715018a614610ee457610438565b80632ba73c15116103415780634e0a3379116102c95780635387253f116102985780635387253f14610c6f5780635b89a38a14610d295780635c975abb14610de35780635e1e100414610df85780635f4968de14610e2b57610438565b80634e0a337914610bad5780634f6ccce714610be0578063515371a314610c0a57806352238fdd14610c3457610438565b80632f745c59116103105780632f745c5914610a085780632fba521114610a415780633f4ba83a14610b2857806340d7ce1414610b3d57806342842e0e14610b6a57610438565b80632ba73c15146108dc5780632bc334e41461090f5780632c4b4a29146109245780632e584ade1461094e57610438565b80631dc9fc61116103c457806323b872dd1161039357806323b872dd1461072857806327d328721461076b57806327d7874c146107b55780632a1d0b16146107e85780632ba27019146108a257610438565b80631dc9fc611461069e5780632072863b146106cb578063215f02f4146106fe57806321d354fd1461071357610438565b8063095ea7b31161040b578063095ea7b31461057c5780630a0f8168146105b557806311229c53146105ca578063134e89f0146105f457806318160ddd1461067757610438565b806301ffc9a71461043a5780630519ce791461049757806306fdde03146104c8578063081812fc14610552575b005b34801561044657600080fd5b506104836004803603602081101561045d57600080fd5b50357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916611b2e565b604080519115158252519081900360200190f35b3480156104a357600080fd5b506104ac611b62565b60408051600160a060020a039092168252519081900360200190f35b3480156104d457600080fd5b506104dd611b71565b6040805160208082528351818301528351919283929083019185019080838360005b838110156105175781810151838201526020016104ff565b50505050905090810190601f1680156105445780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561055e57600080fd5b506104ac6004803603602081101561057557600080fd5b5035611c08565b34801561058857600080fd5b506104386004803603604081101561059f57600080fd5b50600160a060020a038135169060200135611c3a565b3480156105c157600080fd5b506104ac611ce3565b3480156105d657600080fd5b506104dd600480360360208110156105ed57600080fd5b5035611cf2565b34801561060057600080fd5b506106276004803603602081101561061757600080fd5b5035600160a060020a0316611dcb565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561066357818101518382015260200161064b565b505050509050019250505060405180910390f35b34801561068357600080fd5b5061068c611e8e565b60408051918252519081900360200190f35b3480156106aa57600080fd5b50610438600480360360208110156106c157600080fd5b503560ff16611e94565b3480156106d757600080fd5b50610438600480360360208110156106ee57600080fd5b5035600160a060020a0316611f65565b34801561070a57600080fd5b506104ac612040565b34801561071f57600080fd5b5061068c6120e0565b34801561073457600080fd5b506104386004803603606081101561074b57600080fd5b50600160a060020a0381358116916020810135909116906040013561216f565b34801561077757600080fd5b506107956004803603602081101561078e57600080fd5b503561235c565b6040805160ff938416815291909216602082015281519081900390910190f35b3480156107c157600080fd5b50610438600480360360208110156107d857600080fd5b5035600160a060020a03166123c4565b3480156107f457600080fd5b506104386004803603604081101561080b57600080fd5b8135919081019060408101602082013564010000000081111561082d57600080fd5b82018360208201111561083f57600080fd5b8035906020019184600183028401116401000000008311171561086157600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061245e945050505050565b3480156108ae57600080fd5b50610438600480360360408110156108c557600080fd5b508035906020013567ffffffffffffffff1661253b565b3480156108e857600080fd5b50610438600480360360208110156108ff57600080fd5b5035600160a060020a031661262a565b34801561091b57600080fd5b506104ac612705565b34801561093057600080fd5b506104836004803603602081101561094757600080fd5b5035612714565b34801561095a57600080fd5b506104386004803603604081101561097157600080fd5b8135919081019060408101602082013564010000000081111561099357600080fd5b8201836020820111156109a557600080fd5b803590602001918460018302840111640100000000831117156109c757600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550612940945050505050565b348015610a1457600080fd5b5061068c60048036036040811015610a2b57600080fd5b50600160a060020a038135169060200135612a50565b348015610a4d57600080fd5b50610a6b60048036036020811015610a6457600080fd5b5035612a9d565b604051808760ff1660ff1681526020018667ffffffffffffffff1667ffffffffffffffff168152602001858152602001806020018415151515815260200183151515158152602001828103825285818151815260200191508051906020019080838360005b83811015610ae8578181015183820152602001610ad0565b50505050905090810190601f168015610b155780820380516001836020036101000a031916815260200191505b5097505050505050505060405180910390f35b348015610b3457600080fd5b50610438612c41565b348015610b4957600080fd5b5061043860048036036020811015610b6057600080fd5b503560ff16612d0b565b348015610b7657600080fd5b5061043860048036036060811015610b8d57600080fd5b50600160a060020a03813581169160208101359091169060400135612dc9565b348015610bb957600080fd5b5061043860048036036020811015610bd057600080fd5b5035600160a060020a0316612de5565b348015610bec57600080fd5b5061068c60048036036020811015610c0357600080fd5b5035612ec0565b348015610c1657600080fd5b506104ac60048036036020811015610c2d57600080fd5b5035612ef5565b610c5160048036036020811015610c4a57600080fd5b5035612f8c565b60408051938452602084019290925282820152519081900360600190f35b348015610c7b57600080fd5b5061043860048036036040811015610c9257600080fd5b81359190810190604081016020820135640100000000811115610cb457600080fd5b820183602082011115610cc657600080fd5b80359060200191846001830284011164010000000083111715610ce857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613043945050505050565b348015610d3557600080fd5b5061043860048036036040811015610d4c57600080fd5b81359190810190604081016020820135640100000000811115610d6e57600080fd5b820183602082011115610d8057600080fd5b80359060200191846001830284011164010000000083111715610da257600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955061311b945050505050565b348015610def57600080fd5b506104836131df565b348015610e0457600080fd5b5061043860048036036020811015610e1b57600080fd5b5035600160a060020a03166131ef565b348015610e3757600080fd5b506104ac60048036036020811015610e4e57600080fd5b5035613275565b348015610e6157600080fd5b5061043860048036036040811015610e7857600080fd5b50803590602001351515613290565b348015610e9357600080fd5b506104ac60048036036020811015610eaa57600080fd5b503561335a565b348015610ebd57600080fd5b5061068c60048036036020811015610ed457600080fd5b5035600160a060020a0316613384565b348015610ef057600080fd5b506104386133b7565b348015610f0557600080fd5b506104386004803603610160811015610f1d57600080fd5b810190602081018135640100000000811115610f3857600080fd5b820183602082011115610f4a57600080fd5b80359060200191846001830284011164010000000083111715610f6c57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295949360208101935035915050640100000000811115610fbf57600080fd5b820183602082011115610fd157600080fd5b80359060200191846001830284011164010000000083111715610ff357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561104657600080fd5b82018360208201111561105857600080fd5b8035906020019184600183028401116401000000008311171561107a57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156110cd57600080fd5b8201836020820111156110df57600080fd5b8035906020019184600183028401116401000000008311171561110157600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929594936020810193503591505064010000000081111561115457600080fd5b82018360208201111561116657600080fd5b8035906020019184600183028401116401000000008311171561118857600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092959493602081019350359150506401000000008111156111db57600080fd5b8201836020820111156111ed57600080fd5b8035906020019184600183028401116401000000008311171561120f57600080fd5b91908080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092955050823593505067ffffffffffffffff60208301358116926040810135909116915060ff60608201351690608001351515613418565b34801561128657600080fd5b506104ac6004803603602081101561129d57600080fd5b503561344a565b3480156112b057600080fd5b50610438613465565b3480156112c557600080fd5b50610438613518565b3480156112da57600080fd5b506112e3613583565b6040805163ffffffff9092168252519081900360200190f35b34801561130857600080fd5b506104386004803603602081101561131f57600080fd5b5035600160a060020a03166135aa565b34801561133b57600080fd5b506104ac613659565b34801561135057600080fd5b506104836004803603608081101561136757600080fd5b50803590600160a060020a036020820135169060408101359060600135613668565b34801561139557600080fd5b506104ac613904565b3480156113aa57600080fd5b5061068c600480360360208110156113c157600080fd5b5035613913565b3480156113d457600080fd5b50610438600480360360408110156113eb57600080fd5b508035906020013567ffffffffffffffff16613978565b34801561140e57600080fd5b506104386004803603602081101561142557600080fd5b5035600160a060020a0316613a53565b34801561144157600080fd5b506104dd613ad9565b34801561145657600080fd5b5061068c6004803603602081101561146d57600080fd5b5035600160a060020a0316613b3a565b6104386004803603602081101561149357600080fd5b5035613b4c565b3480156114a657600080fd5b50610483600480360360408110156114bd57600080fd5b813591908101906040810160208201356401000000008111156114df57600080fd5b8201836020820111156114f157600080fd5b8035906020019184600183028401116401000000008311171561151357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613da4945050505050565b34801561156057600080fd5b506104386004803603604081101561157757600080fd5b50600160a060020a0381351690602001351515613e89565b34801561159b57600080fd5b506104ac613f0d565b3480156115b057600080fd5b50610438600480360360408110156115c757600080fd5b508035906020013560ff16613f1c565b3480156115e357600080fd5b50610438600480360360808110156115fa57600080fd5b600160a060020a0382358116926020810135909116916040820135919081019060808101606082013564010000000081111561163557600080fd5b82018360208201111561164757600080fd5b8035906020019184600183028401116401000000008311171561166957600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550613ffd945050505050565b3480156116b657600080fd5b506116d4600480360360208110156116cd57600080fd5b5035614025565b60405180806020018060200180602001806020018667ffffffffffffffff1667ffffffffffffffff16815260200185810385528a818151815260200191508051906020019080838360005b8381101561173757818101518382015260200161171f565b50505050905090810190601f1680156117645780820380516001836020036101000a031916815260200191505b5085810384528951815289516020918201918b019080838360005b8381101561179757818101518382015260200161177f565b50505050905090810190601f1680156117c45780820380516001836020036101000a031916815260200191505b5085810383528851815288516020918201918a019080838360005b838110156117f75781810151838201526020016117df565b50505050905090810190601f1680156118245780820380516001836020036101000a031916815260200191505b50858103825287518152875160209182019189019080838360005b8381101561185757818101518382015260200161183f565b50505050905090810190601f1680156118845780820380516001836020036101000a031916815260200191505b50995050505050505050505060405180910390f35b3480156118a557600080fd5b506104dd600480360360208110156118bc57600080fd5b5035614326565b3480156118cf57600080fd5b50610438600480360360408110156118e657600080fd5b8135919081019060408101602082013564010000000081111561190857600080fd5b82018360208201111561191a57600080fd5b8035906020019184600183028401116401000000008311171561193c57600080fd5b91908080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506143db945050505050565b34801561198957600080fd5b50610438600480360360608110156119a057600080fd5b50803590602081013590604001356144b3565b3480156119bf57600080fd5b50610438600480360360408110156119d657600080fd5b508035906020013560ff16614648565b3480156119f257600080fd5b5061048360048036036040811015611a0957600080fd5b50600160a060020a0381358116916020013516614729565b61043860048036036080811015611a3757600080fd5b5080359060208101359060408101359060600135600160a060020a0316614757565b348015611a6557600080fd5b5061043860048036036040811015611a7c57600080fd5b5080359060200135614884565b348015611a9557600080fd5b5061068c60048036036020811015611aac57600080fd5b5035614939565b348015611abf57600080fd5b5061043860048036036020811015611ad657600080fd5b5035600160a060020a03166149d6565b348015611af257600080fd5b506104ac6149f9565b348015611b0757600080fd5b5061043860048036036020811015611b1e57600080fd5b5035600160a060020a0316614a08565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191660009081526020819052604090205460ff1690565b600e54600160a060020a031681565b60098054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015611bfd5780601f10611bd257610100808354040283529160200191611bfd565b820191906000526020600020905b815481529060010190602001808311611be057829003601f168201915b505050505090505b90565b6000611c1382614ab9565b1515611c1e57600080fd5b50600090815260026020526040902054600160a060020a031690565b6000611c458261335a565b9050600160a060020a038381169082161415611c6057600080fd5b33600160a060020a0382161480611c7c5750611c7c8133614729565b1515611c8757600080fd5b6000828152600260205260408082208054600160a060020a031916600160a060020a0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600d54600160a060020a031681565b6000818152601460205260409020546060908290600160a060020a03163314611d1a57600080fd5b6013805484908110611d2857fe5b60009182526020918290206003600a9092020101805460408051601f6002600019610100600187161502019094169390930492830185900485028101850190915281815292830182828015611dbe5780601f10611d9357610100808354040283529160200191611dbe565b820191906000526020600020905b815481529060010190602001808311611da157829003601f168201915b5050505050915050919050565b6060806015600084600160a060020a0316600160a060020a0316815260200190815260200160002054604051908082528060200260200182016040528015611e1d578160200160208202803883390190505b5090506000805b601354811015611e8557600081815260146020526040902054600160a060020a0386811691161415611e7d57808383815181101515611e5f57fe5b60209081029091010152611e7a82600163ffffffff614ad616565b91505b600101611e24565b50909392505050565b60075490565b600f54600160a060020a0316331480611eb75750600d54600160a060020a031633145b80611ecc5750600e54600160a060020a031633145b80611ee15750601254600160a060020a031633145b1515611f215760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b6012805460ff90921675010000000000000000000000000000000000000000000275ff00000000000000000000000000000000000000000019909216919091179055565b600f54600160a060020a0316331480611f885750600d54600160a060020a031633145b80611f9d5750600e54600160a060020a031633145b80611fb25750601254600160a060020a031633145b1515611ff25760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff161561200957600080fd5b600160a060020a038116151561201e57600080fd5b60108054600160a060020a031916600160a060020a0392909216919091179055565b600f54600090600160a060020a03163314806120665750600d54600160a060020a031633145b8061207b5750600e54600160a060020a031633145b806120905750601254600160a060020a031633145b15156120d05760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b50601154600160a060020a031690565b601954604080517f0d9005ae0000000000000000000000000000000000000000000000000000000081529051600092600160a060020a031691630d9005ae916004808301926020929190829003018186803b15801561213e57600080fd5b505afa158015612152573d6000803e3d6000fd5b505050506040513d602081101561216857600080fd5b5051905090565b600c5460a060020a900460ff161561218657600080fd5b601954604080517f89accba5000000000000000000000000000000000000000000000000000000008152600481018490529051600092600160a060020a0316916389accba5916024808301926020929190829003018186803b1580156121eb57600080fd5b505afa1580156121ff573d6000803e3d6000fd5b505050506040513d602081101561221557600080fd5b5051601954604080517ff20e5e35000000000000000000000000000000000000000000000000000000008152600481018490529051929350600092600160a060020a039092169163f20e5e359160248082019260a092909190829003018186803b15801561228257600080fd5b505afa158015612296573d6000803e3d6000fd5b505050506040513d60a08110156122ac57600080fd5b50608001519050600181146122c057600080fd5b6122cb858585614ae3565b6122d6858585614b71565b601754604080517f84991fa8000000000000000000000000000000000000000000000000000000008152600160a060020a038881166004830152915191909216916384991fa891602480830192600092919082900301818387803b15801561233d57600080fd5b505af1158015612351573d6000803e3d6000fd5b505050505050505050565b60008060138381548110151561236e57fe5b90600052602060002090600a020160050160089054906101000a900460ff1660138481548110151561239c57fe5b90600052602060002090600a020160050160099054906101000a900460ff1691509150915091565b600d54600160a060020a031633146124105760405160e560020a62461bcd02815260040180806020018281038252602e815260200180615e50602e913960400191505060405180910390fd5b600c5460a060020a900460ff161561242757600080fd5b600160a060020a038116151561243c57600080fd5b600d8054600160a060020a031916600160a060020a0392909216919091179055565b600f54600160a060020a03163314806124815750600d54600160a060020a031633145b806124965750600e54600160a060020a031633145b806124ab5750601254600160a060020a031633145b15156124eb5760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff161561250257600080fd5b8060138381548110151561251257fe5b90600052602060002090600a02016000019080519060200190612536929190615c53565b505050565b600f54600160a060020a031633148061255e5750600d54600160a060020a031633145b806125735750600e54600160a060020a031633145b806125885750601254600160a060020a031633145b15156125c85760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff16156125df57600080fd5b806013838154811015156125ef57fe5b90600052602060002090600a020160050160006101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050565b600f54600160a060020a031633148061264d5750600d54600160a060020a031633145b806126625750600e54600160a060020a031633145b806126775750601254600160a060020a031633145b15156126b75760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff16156126ce57600080fd5b600160a060020a03811615156126e357600080fd5b600f8054600160a060020a031916600160a060020a0392909216919091179055565b601154600160a060020a031681565b600f54600090600160a060020a031633148061273a5750600d54600160a060020a031633145b8061274f5750600e54600160a060020a031633145b806127645750601254600160a060020a031633145b15156127a45760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff16156127bb57600080fd5b8160006127c782612a9d565b50945050505081151560011490506127de57600080fd5b60008481526014602090815260408083208054600160a060020a03198116909155600160a060020a031680845260159092529091205461282590600163ffffffff614d6116565b600160a060020a0382166000908152601560205260409020556128488186614d73565b601380548690811061285657fe5b600091825260208220600a90910201906128708282615cd1565b61287e600183016000615cd1565b61288c600283016000615cd1565b61289a600383016000615cd1565b6128a8600483016000615cd1565b60058201805469ffffffffffffffffffff1916905560068201805468ffffffffffffffffff191681556000600784018190556128e76008850182615cd1565b50600301805461ffff19169055505060408051600160a060020a0383168152905186917fbdfa951bad4bf2b0fd50f185e31e2dd8a65886d3c650d38151d30fcaabca46e8919081900360200190a2506001949350505050565b600f54600160a060020a03163314806129635750600d54600160a060020a031633145b806129785750600e54600160a060020a031633145b8061298d5750601254600160a060020a031633145b15156129cd5760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff16156129e457600080fd5b806013838154811015156129f457fe5b90600052602060002090600a02016003019080519060200190612a18929190615c53565b506040805183815290517f6c6e7adf43b1b050caae0d2e59b2e5bd7dea7978e49178adb602129c505ce4c59181900360200190a15050565b6000612a5b83613384565b8210612a6657600080fd5b600160a060020a0383166000908152600560205260409020805483908110612a8a57fe5b9060005260206000200154905092915050565b60008060006060600080601387815481101515612ab657fe5b600091825260209091206006600a9092020101546013805460ff9092169189908110612ade57fe5b90600052602060002090600a020160060160000160019054906101000a900467ffffffffffffffff16601389815481101515612b1657fe5b90600052602060002090600a02016006016001015460138a815481101515612b3a57fe5b90600052602060002090600a020160060160020160138b815481101515612b5d57fe5b600091825260209091206009600a9092020101546013805460ff909216918d908110612b8557fe5b6000918252602091829020600a9190910201600901548354604080516002610100600185161581026000190190941604601f81018690048602820186019092528181529190920460ff169290918591830182828015612c255780601f10612bfa57610100808354040283529160200191612c25565b820191906000526020600020905b815481529060010190602001808311612c0857829003601f168201915b5050505050925095509550955095509550955091939550919395565b600d54600160a060020a03163314612c8d5760405160e560020a62461bcd02815260040180806020018281038252602e815260200180615e50602e913960400191505060405180910390fd5b600c5460a060020a900460ff161515612ca557600080fd5b600d54600160a060020a03161515612cbc57600080fd5b601954600160a060020a03161515612cd357600080fd5b601754600160a060020a03161515612cea57600080fd5b601154600160a060020a03161515612d0157600080fd5b612d09614dbf565b565b600f54600160a060020a0316331480612d2e5750600d54600160a060020a031633145b80612d435750600e54600160a060020a031633145b80612d585750601254600160a060020a031633145b1515612d985760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b6012805460ff90921660a060020a0274ff000000000000000000000000000000000000000019909216919091179055565b6125368383836020604051908101604052806000815250613ffd565b600f54600160a060020a0316331480612e085750600d54600160a060020a031633145b80612e1d5750600e54600160a060020a031633145b80612e325750601254600160a060020a031633145b1515612e725760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff1615612e8957600080fd5b600160a060020a0381161515612e9e57600080fd5b600e8054600160a060020a031916600160a060020a0392909216919091179055565b6000612eca611e8e565b8210612ed557600080fd5b6007805483908110612ee357fe5b90600052602060002001549050919050565b601954604080517f5fe36b81000000000000000000000000000000000000000000000000000000008152600481018490529051600092600160a060020a031691635fe36b81916024808301926020929190829003018186803b158015612f5a57600080fd5b505afa158015612f6e573d6000803e3d6000fd5b505050506040513d6020811015612f8457600080fd5b505192915050565b600c546000908190819060a060020a900460ff1615612faa57600080fd5b6000606434601387815481101515612fbe57fe5b60009182526020909120600a90910201600501546901000000000000000000900460ff1602811515612fec57fe5b049050600060643460138881548110151561300357fe5b60009182526020909120600a909102016005015468010000000000000000900460ff160281151561303057fe5b9297920495505084860134039350915050565b600f54600160a060020a03163314806130665750600d54600160a060020a031633145b8061307b5750600e54600160a060020a031633145b806130905750601254600160a060020a031633145b15156130d05760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff16156130e757600080fd5b806013838154811015156130f757fe5b90600052602060002090600a02016002019080519060200190612536929190615c53565b600f54600160a060020a031633148061313e5750600d54600160a060020a031633145b806131535750600e54600160a060020a031633145b806131685750601254600160a060020a031633145b15156131a85760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b806013838154811015156131b857fe5b90600052602060002090600a02016006016002019080519060200190612536929190615c53565b600c5460a060020a900460ff1681565b600d54600160a060020a0316331461323b5760405160e560020a62461bcd02815260040180806020018281038252602e815260200180615e50602e913960400191505060405180910390fd5b600c5460a060020a900460ff16151561325357600080fd5b60178054600160a060020a031916600160a060020a0392909216919091179055565b601660205260009081526040902054600160a060020a031681565b600f54600160a060020a03163314806132b35750600d54600160a060020a031633145b806132c85750600e54600160a060020a031633145b806132dd5750601254600160a060020a031633145b151561331d5760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b8060138381548110151561332d57fe5b600091825260209091206009600a909202010180549115156101000261ff00199092169190911790555050565b600081815260016020526040812054600160a060020a031680151561337e57600080fd5b92915050565b6000600160a060020a038216151561339b57600080fd5b50600160a060020a031660009081526003602052604090205490565b600c54600160a060020a031633146133ce57600080fd5b600c54604051600160a060020a03909116907ff8df31144d9c2f0f6b59d69b8b98abd5459d07f2742c4df920b25aae33c6482090600090a2600c8054600160a060020a0319169055565b61342b8b8b8b8b8b8b8b8b8b8b8b614ead565b60135461343d90339060001901615388565b5050505050505050505050565b601460205260009081526040902054600160a060020a031681565b600f54600160a060020a03163314806134885750600d54600160a060020a031633145b8061349d5750600e54600160a060020a031633145b806134b25750601254600160a060020a031633145b15156134f25760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff16151561350a57600080fd5b601254600160a060020a0316ff5b600d54600160a060020a031633146135645760405160e560020a62461bcd02815260040180806020018281038252602e815260200180615e50602e913960400191505060405180910390fd5b600c5460a060020a900460ff161561357b57600080fd5b612d096153d7565b60125477010000000000000000000000000000000000000000000000900463ffffffff1681565b600f54600160a060020a03163314806135cd5750600d54600160a060020a031633145b806135e25750600e54600160a060020a031633145b806135f75750601254600160a060020a031633145b15156136375760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b60118054600160a060020a031916600160a060020a0392909216919091179055565b601054600160a060020a031681565b600f54600090600160a060020a031633148061368e5750600d54600160a060020a031633145b806136a35750600e54600160a060020a031633145b806136b85750601254600160a060020a031633145b15156136f85760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff161561370f57600080fd5b601954604080517ff20e5e35000000000000000000000000000000000000000000000000000000008152600481018890529051600092600160a060020a03169163f20e5e359160248083019260a0929190829003018186803b15801561377457600080fd5b505afa158015613788573d6000803e3d6000fd5b505050506040513d60a081101561379e57600080fd5b50516013805491925090829081106137b257fe5b60009182526020909120600a9091020160060154610100900467ffffffffffffffff168410156137e157600080fd5b6137eb8582611c3a565b601954604080517f04b40f6900000000000000000000000000000000000000000000000000000000815260048101899052600160a060020a03888116602483015260448201889052915191909216916304b40f6991606480830192600092919082900301818387803b15801561386057600080fd5b505af1158015613874573d6000803e3d6000fd5b5050601754604080517f0d498b61000000000000000000000000000000000000000000000000000000008152600481018890529051600160a060020a039092169350630d498b61925060248082019260009290919082900301818387803b1580156138de57600080fd5b505af11580156138f2573d6000803e3d6000fd5b5050505060019150505b949350505050565b601254600160a060020a031681565b601954604080517f4b554954000000000000000000000000000000000000000000000000000000008152600481018490529051600092600160a060020a031691634b554954916024808301926020929190829003018186803b158015612f5a57600080fd5b600f54600160a060020a031633148061399b5750600d54600160a060020a031633145b806139b05750600e54600160a060020a031633145b806139c55750601254600160a060020a031633145b1515613a055760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b80601383815481101515613a1557fe5b90600052602060002090600a020160060160000160016101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055505050565b600d54600160a060020a03163314613a9f5760405160e560020a62461bcd02815260040180806020018281038252602e815260200180615e50602e913960400191505060405180910390fd5b600c5460a060020a900460ff161515613ab757600080fd5b60198054600160a060020a031916600160a060020a0392909216919091179055565b600a8054604080516020601f6002600019610100600188161502019095169490940493840181900481028201810190925282815260609390929091830182828015611bfd5780601f10611bd257610100808354040283529160200191611bfd565b60156020526000908152604090205481565b601954604080517f83e2e0a800000000000000000000000000000000000000000000000000000000815260048101849052336024820152905160009283928392600160a060020a03909216916383e2e0a891604480820192606092909190829003018186803b158015613bbe57600080fd5b505afa158015613bd2573d6000803e3d6000fd5b505050506040513d6060811015613be857600080fd5b50805160208201516040909201519094509092509050600080613c0b8484615442565b5091509150823410151515613c1f57600080fd5b6000613c31348463ffffffff614d6116565b90506000613c45348463ffffffff614d6116565b601154909150600160a060020a03166108fc613c67348563ffffffff614d6116565b6040518115909202916000818181858888f19350505050158015613c8f573d6000803e3d6000fd5b50600160a060020a0387166108fc613cad348463ffffffff614d6116565b6040518115909202916000818181858888f19350505050158015613cd5573d6000803e3d6000fd5b50601754604051600160a060020a0390911690303180156108fc02916000818181858888f19350505050158015613d10573d6000803e3d6000fd5b50601954604080517f6d25e48e000000000000000000000000000000000000000000000000000000008152600481018b90529051600160a060020a0390921691636d25e48e9160248082019260009290919082900301818387803b158015613d7757600080fd5b505af1158015613d8b573d6000803e3d6000fd5b50505050613d9a87338861216f565b5050505050505050565b600f54600090600160a060020a0316331480613dca5750600d54600160a060020a031633145b80613ddf5750600e54600160a060020a031633145b80613df45750601254600160a060020a031633145b1515613e345760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff1615613e4b57600080fd5b81601384815481101515613e5b57fe5b90600052602060002090600a02016004019080519060200190613e7f929190615c53565b5060019392505050565b600160a060020a038216331415613e9f57600080fd5b336000818152600460209081526040808320600160a060020a03871680855290835292819020805460ff1916861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b600f54600160a060020a031681565b600f54600160a060020a0316331480613f3f5750600d54600160a060020a031633145b80613f545750600e54600160a060020a031633145b80613f695750601254600160a060020a031633145b1515613fa95760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff1615613fc057600080fd5b80601383815481101515613fd057fe5b90600052602060002090600a020160050160086101000a81548160ff021916908360ff1602179055505050565b61400884848461216f565b614014848484846154fa565b151561401f57600080fd5b50505050565b606080606080600060138681548110151561403c57fe5b90600052602060002090600a020160000160138781548110151561405c57fe5b90600052602060002090600a020160010160138881548110151561407c57fe5b90600052602060002090600a020160020160138981548110151561409c57fe5b90600052602060002090600a020160040160138a8154811015156140bc57fe5b60009182526020918290206005600a909202010154855460408051601f6002600019600186161561010002019094169390930492830185900485028101850190915281815267ffffffffffffffff909216928791908301828280156141625780601f1061413757610100808354040283529160200191614162565b820191906000526020600020905b81548152906001019060200180831161414557829003601f168201915b5050875460408051602060026001851615610100026000190190941693909304601f8101849004840282018401909252818152959a50899450925084019050828280156141f05780601f106141c5576101008083540402835291602001916141f0565b820191906000526020600020905b8154815290600101906020018083116141d357829003601f168201915b5050865460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529599508894509250840190508282801561427e5780601f106142535761010080835404028352916020019161427e565b820191906000526020600020905b81548152906001019060200180831161426157829003601f168201915b5050855460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529598508794509250840190508282801561430c5780601f106142e15761010080835404028352916020019161430c565b820191906000526020600020905b8154815290600101906020018083116142ef57829003601f168201915b505050505091509450945094509450945091939590929450565b606061433182614ab9565b151561433c57600080fd5b6000828152600b602090815260409182902080548351601f6002600019610100600186161502019093169290920491820184900484028101840190945280845290918301828280156143cf5780601f106143a4576101008083540402835291602001916143cf565b820191906000526020600020905b8154815290600101906020018083116143b257829003601f168201915b50505050509050919050565b600f54600160a060020a03163314806143fe5750600d54600160a060020a031633145b806144135750600e54600160a060020a031633145b806144285750601254600160a060020a031633145b15156144685760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff161561447f57600080fd5b8060138381548110151561448f57fe5b90600052602060002090600a02016001019080519060200190612536929190615c53565b600c5460a060020a900460ff16156144ca57600080fd5b336144d48461335a565b600160a060020a03161461451c5760405160e560020a62461bcd028152600401808060200182810382526031815260200180615e7e6031913960400191505060405180910390fd5b601380548490811061452a57fe5b60009182526020909120600a9091020160060154610100900467ffffffffffffffff1682101561455957600080fd5b601954604080517f819c9e4c0000000000000000000000000000000000000000000000000000000081526004810186905260248101859052604481018490523360648201529051600160a060020a039092169163819c9e4c9160848082019260009290919082900301818387803b1580156145d357600080fd5b505af11580156145e7573d6000803e3d6000fd5b50506012546146039250600160a060020a031690506001613e89565b600d5461461a90600160a060020a03166001613e89565b600e5461463190600160a060020a03166001613e89565b600f5461253690600160a060020a03166001613e89565b600f54600160a060020a031633148061466b5750600d54600160a060020a031633145b806146805750600e54600160a060020a031633145b806146955750601254600160a060020a031633145b15156146d55760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff16156146ec57600080fd5b806013838154811015156146fc57fe5b90600052602060002090600a020160050160096101000a81548160ff021916908360ff1602179055505050565b600160a060020a03918216600090815260046020908152604080832093909416825291909152205460ff1690565b600c5460a060020a900460ff161561476e57600080fd5b8383018201348111156147b55760405160e560020a62461bcd028152600401808060200182810382526038815260200180615eaf6038913960400191505060405180910390fd5b601154600160a060020a03166108fc6147d4348863ffffffff614d6116565b6040518115909202916000818181858888f193505050501580156147fc573d6000803e3d6000fd5b50600160a060020a0382166108fc61481a348763ffffffff614d6116565b6040518115909202916000818181858888f19350505050158015614842573d6000803e3d6000fd5b50601754604051600160a060020a03909116903480156108fc02916000818181858888f1935050505015801561487c573d6000803e3d6000fd5b505050505050565b600f54600160a060020a03163314806148a75750600d54600160a060020a031633145b806148bc5750600e54600160a060020a031633145b806148d15750601254600160a060020a031633145b15156149115760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b8060138381548110151561492157fe5b600091825260209091206007600a9092020101555050565b601954604080517ff20e5e350000000000000000000000000000000000000000000000000000000081526004810184905290516000928392600160a060020a039091169163f20e5e359160248082019260a092909190829003018186803b1580156149a357600080fd5b505afa1580156149b7573d6000803e3d6000fd5b505050506040513d60a08110156149cd57600080fd5b50519392505050565b600c54600160a060020a031633146149ed57600080fd5b6149f681615676565b50565b601754600160a060020a031681565b600f54600160a060020a0316331480614a2b5750600d54600160a060020a031633145b80614a405750600e54600160a060020a031633145b80614a555750601254600160a060020a031633145b1515614a955760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff161515614aad57600080fd5b80600160a060020a0316ff5b600090815260016020526040902054600160a060020a0316151590565b8181018281101561337e57fe5b614aed33826156e7565b1515614af857600080fd5b600160a060020a0382161515614b0d57600080fd5b614b17838261573e565b614b2183826157a0565b614b2b82826158a2565b8082600160a060020a031684600160a060020a03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600160a060020a038216600090815260156020526040902054614b9b90600163ffffffff614ad616565b600160a060020a038084166000908152601560205260408082209390935590851681522054614bd190600163ffffffff614d6116565b600160a060020a0384811660009081526015602090815260408083209490945584825260149052919091208054600160a060020a0319169184169190911790556013805482908110614c1f57fe5b600091825260209091206009600a90920201015460ff1615614cb0576060601382815481101515614c4c57fe5b90600052602060002090600a020160050160086101000a81548160ff021916908360ff1602179055506003601382815481101515614c8657fe5b90600052602060002090600a020160050160096101000a81548160ff021916908360ff1602179055505b6000601382815481101515614cc157fe5b60009182526020909120600a90910201600901805460ff19169115159190911790556013805482908110614cf157fe5b60009182526020918290206005600a90920201015460408051600160a060020a038088168252861693810193909352805167ffffffffffffffff9092169284927f23f50d55776d8003622a982ade45a6c7f083116c8dbbcd980f59942f440badb1929181900390910190a3505050565b600082821115614d6d57fe5b50900390565b614d7d82826158e8565b6000818152600b60205260409020546002600019610100600184161502019091160415614dbb576000818152600b60205260408120614dbb91615cd1565b5050565b600f54600160a060020a0316331480614de25750600d54600160a060020a031633145b80614df75750600e54600160a060020a031633145b80614e0c5750601254600160a060020a031633145b1515614e4c5760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff161515614e6457600080fd5b600c805474ff0000000000000000000000000000000000000000191690556040517f7805862f689e2f13df9f062ff482ad3ad112aca9e0847911ed832e158c525b3390600090a1565b601254600060a060020a90910460ff1611614efc5760405160e560020a62461bcd028152600401808060200182810382526021815260200180615ee76021913960400191505060405180910390fd5b6012546000750100000000000000000000000000000000000000000090910460ff1611614f5d5760405160e560020a62461bcd02815260040180806020018281038252602b815260200180615e25602b913960400191505060405180910390fd5b600c5460a060020a900460ff1615614f7457600080fd5b614f7c615d15565b506040805160c08101825260ff8416815267ffffffffffffffff85166020820152908101869052606081018890526001608082015281151560a0820152614fc1615d49565b5060408051610120810182528d815260208082018e90529181018c9052606081018b90526080810189905267ffffffffffffffff871660a082015260125460ff75010000000000000000000000000000000000000000008204811660c084015260a060020a9091041660e0820152610100810183905260138054600181810180845560009384528451805195969495929491938793600a9091027f66de8ffda797e3de9c05e8fc57b3bf0ec28a930d40b0d285d93c06501cf6a090019261508c928492910190615c53565b5060208281015180516150a59260018501920190615c53565b50604082015180516150c1916002840191602090910190615c53565b50606082015180516150dd916003840191602090910190615c53565b50608082015180516150f9916004840191602090910190615c53565b5060a082015160058201805460c085015160e086015167ffffffffffffffff1990921667ffffffffffffffff9485161768ff000000000000000019166801000000000000000060ff928316021769ff00000000000000000019166901000000000000000000928216929092029190911790915561010080850151805160068601805460208085015160ff19909216939096169290921768ffffffffffffffff0019169190951690920291909117835560408101516007850155606081015180519193926151ce92600887019290910190615c53565b5060808201516003909101805460a09093015115156101000261ff001992151560ff19909416939093179190911691909117905550500360008181526014602090815260408083208054600160a060020a031916339081179091558352601590915290205490915061524790600163ffffffff614ad616565b6015600033600160a060020a0316600160a060020a03168152602001908152602001600020819055507fcde99b9efee390265235bbcaf4265100bf0707838094ed6b2c22384636581746818f8f604051808481526020018060200180602001838103835285818151815260200191508051906020019080838360005b838110156152db5781810151838201526020016152c3565b50505050905090810190601f1680156153085780820380516001836020036101000a031916815260200191505b50838103825284518152845160209182019186019080838360005b8381101561533b578181015183820152602001615323565b50505050905090810190601f1680156153685780820380516001836020036101000a031916815260200191505b509550505050505060405180910390a15050505050505050505050505050565b61539282826159a1565b600780546000838152600860205260408120829055600182018355919091527fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c688015550565b600d54600160a060020a031633146154235760405160e560020a62461bcd02815260040180806020018281038252602e815260200180615e50602e913960400191505060405180910390fd5b600c5460a060020a900460ff161561543a57600080fd5b612d096159fc565b600c546000908190819060a060020a900460ff161561546057600080fd5b600060648560138881548110151561547457fe5b60009182526020909120600a90910201600501546901000000000000000000900460ff16028115156154a257fe5b04905060006064866013898154811015156154b957fe5b60009182526020909120600a909102016005015468010000000000000000900460ff16028115156154e657fe5b929892049650508587019094039392505050565b600061550e84600160a060020a0316615aef565b151561551c575060016138fc565b6040517f150b7a020000000000000000000000000000000000000000000000000000000081523360048201818152600160a060020a03888116602485015260448401879052608060648501908152865160848601528651600095928a169463150b7a029490938c938b938b939260a4019060208501908083838e5b838110156155af578181015183820152602001615597565b50505050905090810190601f1680156155dc5780820380516001836020036101000a031916815260200191505b5095505050505050602060405180830381600087803b1580156155fe57600080fd5b505af1158015615612573d6000803e3d6000fd5b505050506040513d602081101561562857600080fd5b50517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f150b7a020000000000000000000000000000000000000000000000000000000014915050949350505050565b600160a060020a038116151561568b57600080fd5b600c54604051600160a060020a038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600c8054600160a060020a031916600160a060020a0392909216919091179055565b6000806156f38361335a565b905080600160a060020a031684600160a060020a0316148061572e575083600160a060020a031661572384611c08565b600160a060020a0316145b806138fc57506138fc8185614729565b81600160a060020a03166157518261335a565b600160a060020a03161461576457600080fd5b600081815260026020526040902054600160a060020a031615614dbb5760009081526002602052604090208054600160a060020a031916905550565b6157aa8282615af7565b600081815260066020908152604080832054600160a060020a038616845260059092528220549091906157e490600163ffffffff614d6116565b600160a060020a0385166000908152600560205260408120805492935090918390811061580d57fe5b90600052602060002001549050806005600087600160a060020a0316600160a060020a031681526020019081526020016000208481548110151561584d57fe5b6000918252602080832090910192909255600160a060020a0387168152600590915260409020805490615884906000198301615dab565b50600093845260066020526040808520859055908452909220555050565b6158ac8282615b80565b600160a060020a039091166000908152600560209081526040808320805460018101825590845282842081018590559383526006909152902055565b6158f28282615c03565b60008181526008602052604081205460075490919061591890600163ffffffff614d6116565b9050600060078281548110151561592b57fe5b906000526020600020015490508060078481548110151561594857fe5b6000918252602082200191909155600780548490811061596457fe5b6000918252602090912001556007805490615983906000198301615dab565b50600093845260086020526040808520859055908452909220555050565b600160a060020a03821615156159b657600080fd5b6159c082826158a2565b6040518190600160a060020a038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600f54600160a060020a0316331480615a1f5750600d54600160a060020a031633145b80615a345750600e54600160a060020a031633145b80615a495750601254600160a060020a031633145b1515615a895760405160e560020a62461bcd02815260040180806020018281038252603f815260200180615de6603f913960400191505060405180910390fd5b600c5460a060020a900460ff1615615aa057600080fd5b600c805474ff0000000000000000000000000000000000000000191660a060020a1790556040517f6985a02210a168e66602d3235cb6db0e70f92b3ba4d376a33c0f3d9434bff62590600090a1565b6000903b1190565b81600160a060020a0316615b0a8261335a565b600160a060020a031614615b1d57600080fd5b600160a060020a038216600090815260036020526040902054615b4790600163ffffffff614d6116565b600160a060020a039092166000908152600360209081526040808320949094559181526001909152208054600160a060020a0319169055565b600081815260016020526040902054600160a060020a031615615ba257600080fd5b60008181526001602081815260408084208054600160a060020a031916600160a060020a0388169081179091558452600390915290912054615be391614ad6565b600160a060020a0390921660009081526003602052604090209190915550565b615c0d828261573e565b615c1782826157a0565b6040518190600090600160a060020a038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f10615c9457805160ff1916838001178555615cc1565b82800160010185558215615cc1579182015b82811115615cc1578251825591602001919060010190615ca6565b50615ccd929150615dcb565b5090565b50805460018160011615610100020316600290046000825580601f10615cf757506149f6565b601f0160209004906000526020600020908101906149f69190615dcb565b6040805160c0810182526000808252602082018190529181018290526060808201526080810182905260a081019190915290565b6101c0604051908101604052806060815260200160608152602001606081526020016060815260200160608152602001600067ffffffffffffffff168152602001600060ff168152602001600060ff168152602001615da6615d15565b905290565b815481835581811115612536576000838152602090206125369181019083015b611c0591905b80821115615ccd5760008155600101615dd156fe596f75206e65656420746f20626520746865206f776e6572206f72206120436c6576656c204042414520746f2063616c6c20746869732066756e6374696f6e5265717569726573206120616e2061727469737420666565206c6576656c20746f206265207365742075704f6e6c79206f75722043454f20616464726573732063616e206578656375746520746869732066756e6374696f6e596f752063616e2774207472616e7366657220616e206172747069656365207768696368206973206e6f7420796f75727356616c7565206d75737420626520657175616c206f722067726561746572207468616e2074686520636f7374206f662074686520666565735265717569726573206120666565206c6576656c20746f20626520736574207570a165627a7a72305820045b0d0a32d16dd230e7ca1f355fd46d44ddc5dacffe327b30b77e752337c8f70029


   Swarm Source:
bzzr://045b0d0a32d16dd230e7ca1f355fd46d44ddc5dacffe327b30b77e752337c8f7
Block Age transaction Difficulty GasUsed Reward
Block Age Uncle Number Difficulty GasUsed Reward
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.