账户
0xA8...2c76
0xA8...2c76

0xA8...2c76

$500
此合同的源代码已经过验证!
合同元数据
编译器
0.5.16+commit.9c3226ce
语言
Solidity
合同源代码
文件 1 的 1:ERC721ConverterWithCSPLCard.sol
// Copyright (c) 2018-2020 double jump.tokyo inc.
pragma solidity 0.5.16;

interface IERC721Converter /* is IERC721TokenReceiver */{
    function draftAliceToken(uint256 _aliceTokenId, uint256 _bobTokenId) external;
    function draftBobToken(uint256 _BobTokenId, uint256 _aliceTokenId) external;
    function getAliceTokenID(uint256 _bobTokenId) external view returns(uint256);
    function getBobTokenID(uint256 _aliceTokenId) external view returns(uint256);
    function convertFromAliceToBob(uint256 _tokenId) external;
    function convertFromBobToAlice(uint256 _tokenId) external;
}

library Roles {
    struct Role {
        mapping (address => bool) bearer;
    }

    function add(Role storage role, address account) internal {
        require(!has(role, account), "role already has the account");
        role.bearer[account] = true;
    }

    function remove(Role storage role, address account) internal {
        require(has(role, account), "role dosen't have the account");
        role.bearer[account] = false;
    }

    function has(Role storage role, address account) internal view returns (bool) {
        return role.bearer[account];
    }
}

interface IERC721TokenReceiver {
    /// @notice Handle the receipt of an NFT
    /// @dev The ERC721 smart contract calls this function on the recipient
    ///  after a `transfer`. This function MAY throw to revert and reject the
    ///  transfer. Return of other than the magic value MUST result in the
    ///  transaction being reverted.
    ///  Note: the contract address is always the message sender.
    /// @param _operator The address which called `safeTransferFrom` function
    /// @param _from The address which previously owned the token
    /// @param _tokenId The NFT identifier which is being transferred
    /// @param _data Additional data with no specified format
    /// @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    ///  unless throwing
    function onERC721Received(
        address _operator,
        address _from,
        uint256 _tokenId,
        bytes calldata _data
    )
        external
        returns(bytes4);
}

interface IERC165 {
    function supportsInterface(bytes4 interfaceID) external view returns (bool);
}

/// @title ERC-165 Standard Interface Detection
/// @dev See https://eips.ethereum.org/EIPS/eip-165
contract ERC165 is IERC165 {
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () internal {
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    function supportsInterface(bytes4 interfaceId) external view returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    function _registerInterface(bytes4 interfaceId) internal {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

interface IERC173 /* is ERC165 */ {
    /// @dev This emits when ownership of a contract changes.
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /// @notice Get the address of the owner
    /// @return The address of the owner.
    function owner() external view returns (address);

    /// @notice Set the address of the new owner of the contract
    /// @param _newOwner The address of the new owner of the contract
    function transferOwnership(address _newOwner) external;
}

contract ERC173 is IERC173, ERC165  {
    address private _owner;

    constructor() public {
        _registerInterface(0x7f5828d0);
        _transferOwnership(msg.sender);
    }

    modifier onlyOwner() {
        require(msg.sender == owner(), "Must be owner");
        _;
    }

    function owner() public view returns (address) {
        return _owner;
    }

    function transferOwnership(address _newOwner) public onlyOwner() {
        _transferOwnership(_newOwner);
    }

    function _transferOwnership(address _newOwner) internal {
        address previousOwner = owner();
	_owner = _newOwner;
        emit OwnershipTransferred(previousOwner, _newOwner);
    }
}

contract ERC721Holder is IERC721TokenReceiver {
    function onERC721Received(address, address, uint256, bytes memory) public returns (bytes4) {
        return this.onERC721Received.selector;
    }
}

contract Operatable is ERC173 {
    using Roles for Roles.Role;

    event OperatorAdded(address indexed account);
    event OperatorRemoved(address indexed account);

    event Paused(address account);
    event Unpaused(address account);

    bool private _paused;
    Roles.Role private operators;

    constructor() public {
        operators.add(msg.sender);
        _paused = false;
    }

    modifier onlyOperator() {
        require(isOperator(msg.sender), "Must be operator");
        _;
    }

    modifier whenNotPaused() {
        require(!_paused, "Pausable: paused");
        _;
    }

    modifier whenPaused() {
        require(_paused, "Pausable: not paused");
        _;
    }

    function transferOwnership(address _newOwner) public onlyOperator() {
        _transferOwnership(_newOwner);
    }

    function isOperator(address account) public view returns (bool) {
        return operators.has(account);
    }

    function addOperator(address account) public onlyOperator() {
        operators.add(account);
        emit OperatorAdded(account);
    }

    function removeOperator(address account) public onlyOperator() {
        operators.remove(account);
        emit OperatorRemoved(account);
    }

    function paused() public view returns (bool) {
        return _paused;
    }

    function pause() public onlyOperator() whenNotPaused() {
        _paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public onlyOperator() whenPaused() {
        _paused = false;
        emit Unpaused(msg.sender);
    }

    function withdrawEther() public onlyOperator() {
        msg.sender.transfer(address(this).balance);
    }

}

interface ICSPLCard {
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
}

interface IERC721Mintable {
    function exist(uint256 _tokenId) external view returns (bool);
    function mint(address _owner, uint256 _tokenId) external;
    function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
}

contract ERC721ConverterWithCSPLCard is IERC721Converter, ERC721Holder, Operatable {
    ICSPLCard public Alice;
    IERC721Mintable public Bob;

    mapping (uint256 => uint256) private _idMapAliceToBob;
    mapping (uint256 => uint256) private _idMapBobToAlice;

    constructor() public {}

    function updateAlice(address _newAlice) external onlyOperator() {
        Alice = ICSPLCard(_newAlice);
    }

    function updateBob(address _newBob) external onlyOperator() {
        Bob = IERC721Mintable(_newBob);
    }

    function draftAliceTokens(uint256[] memory _aliceTokenIds, uint256[] memory _bobTokenIds) public onlyOperator() {
        require(_aliceTokenIds.length == _bobTokenIds.length);
        for (uint256 i = 0; i < _aliceTokenIds.length; i++) {
            draftAliceToken(_aliceTokenIds[i], _bobTokenIds[i]);
        }
    }

    function draftBobTokens(uint256[] memory _bobTokenIds, uint256[] memory _aliceTokenIds) public onlyOperator() {
        require(_aliceTokenIds.length == _bobTokenIds.length);
        for (uint256 i = 0; i < _aliceTokenIds.length; i++) {
            draftBobToken(_bobTokenIds[i], _aliceTokenIds[i]);
        }
    }

    function draftAliceToken(uint256 _aliceTokenId, uint256 _bobTokenId) public onlyOperator() {
        require(_idMapAliceToBob[_aliceTokenId] == 0, "_aliceTokenId is already assignd");
        require(_idMapBobToAlice[_bobTokenId] == 0, "_bobTokenId is already assignd");

        _idMapAliceToBob[_aliceTokenId] = _bobTokenId;
        _idMapBobToAlice[_bobTokenId] = _aliceTokenId;
    }

    function draftBobToken(uint256 _bobTokenId, uint256 _aliceTokenId) public onlyOperator() {
        require(_idMapBobToAlice[_bobTokenId] == 0, "_bobTokenId is already assignd");
        require(_idMapAliceToBob[_aliceTokenId] == 0, "_aliceTokenId is already assignd");

        _idMapBobToAlice[_bobTokenId] = _aliceTokenId;
        _idMapAliceToBob[_aliceTokenId] = _bobTokenId;
    }

    function getBobTokenID(uint256 _aliceTokenId) public view returns(uint256) {
        return _idMapAliceToBob[_aliceTokenId];
    }

    function getAliceTokenID(uint256 _bobTokenId) public view returns(uint256) {
        return _idMapBobToAlice[_bobTokenId];
    }

    function convertFromAliceToBob(uint256 _tokenId) public whenNotPaused() {
        Alice.safeTransferFrom(msg.sender, address(this), _tokenId);

        uint256 convertTo = getBobTokenID(_tokenId);
        if (Bob.exist(convertTo)) {
            Bob.safeTransferFrom(address(this), msg.sender, convertTo);
        } else {
            Bob.mint(msg.sender, convertTo);
        }
    }

    function convertFromBobToAlice(uint256 _tokenId) public whenNotPaused() {
        Bob.safeTransferFrom(msg.sender, address(this), _tokenId);

        uint256 convertTo = getAliceTokenID(_tokenId);
        Alice.safeTransferFrom(address(this), msg.sender, convertTo);
    }
}
设置
{
  "compilationTarget": {
    "ERC721ConverterWithCSPLCard.sol": "ERC721ConverterWithCSPLCard"
  },
  "evmVersion": "istanbul",
  "libraries": {},
  "optimizer": {
    "enabled": false,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"OperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"OperatorRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"constant":true,"inputs":[],"name":"Alice","outputs":[{"internalType":"contract ICSPLCard","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"Bob","outputs":[{"internalType":"contract IERC721Mintable","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"convertFromAliceToBob","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"convertFromBobToAlice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_aliceTokenId","type":"uint256"},{"internalType":"uint256","name":"_bobTokenId","type":"uint256"}],"name":"draftAliceToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256[]","name":"_aliceTokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_bobTokenIds","type":"uint256[]"}],"name":"draftAliceTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_bobTokenId","type":"uint256"},{"internalType":"uint256","name":"_aliceTokenId","type":"uint256"}],"name":"draftBobToken","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256[]","name":"_bobTokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_aliceTokenIds","type":"uint256[]"}],"name":"draftBobTokens","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_bobTokenId","type":"uint256"}],"name":"getAliceTokenID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_aliceTokenId","type":"uint256"}],"name":"getBobTokenID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeOperator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newAlice","type":"address"}],"name":"updateAlice","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_newBob","type":"address"}],"name":"updateBob","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[],"name":"withdrawEther","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]