ETH Price: $3,783.18 (+22.43%)
Gas: 10 Gwei

Transaction Decoder

Block:
15961340 at Nov-13-2022 01:16:47 PM +UTC
Transaction Fee:
0.00152778 ETH $5.78
Gas Used:
76,389 Gas / 20 Gwei

Emitted Events:

30 HXTZToken.Transfer( from=[Sender] 0x30741289523c2e4d2a62c7d6722686d14e723851, to=MultiSigWallet, value=79180300000000000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x30741289...14E723851
(HTX 21)
22.721389007635762135 Eth
Nonce: 45280
22.719861227635762135 Eth
Nonce: 45281
0.00152778
0.319966003464694777 Eth0.320572491589559428 Eth0.000606488124864651
0xb1b4D8dF...e7e970D67

Execution Trace

HXTZToken.transfer( to=0x265EAc8035912AecC793947E6A55Cd3284801772, value=79180300000000000000000 ) => ( True )
  • HXTZLogic.transferLogic( sender=0x30741289523c2e4d2A62c7D6722686D14E723851, to=0x265EAc8035912AecC793947E6A55Cd3284801772, value=79180300000000000000000 ) => ( True )
    • HXTZStorage.balanceOf( account=0x30741289523c2e4d2A62c7D6722686D14E723851 ) => ( 825186861999989000000000 )
    • HXTZStorage.balanceOf( account=0x265EAc8035912AecC793947E6A55Cd3284801772 ) => ( 0 )
    • 0x449ee891e9e395aa717e9786eb69dbc3dba6ec61.a293d1e8( )
    • 0x449ee891e9e395aa717e9786eb69dbc3dba6ec61.e6cb9013( )
    • HXTZStorage.setBalance( account=0x30741289523c2e4d2A62c7D6722686D14E723851, amount=746006561999989000000000 )
    • HXTZStorage.setBalance( account=0x265EAc8035912AecC793947E6A55Cd3284801772, amount=79180300000000000000000 )
      File 1 of 4: HXTZToken
      {"Container.sol":{"content":"pragma solidity ^0.5.11;\n\ncontract Container{\n    struct Item{\n        uint256 itemType;\n        uint256 status;\n        address[] addresses;\n    }\n    uint256 MaxItemAdressNum = 255;\n\n    mapping (bytes32 =\u003e Item) private container;\n\n    function itemAddressExists(bytes32 id, address oneAddress) internal view returns(bool){\n        for(uint256 i = 0; i \u003c container[id].addresses.length; i++){\n            if(container[id].addresses[i] == oneAddress)\n                return true;\n        }\n        return false;\n    }\n    function getItemAddresses(bytes32 id) internal view returns(address[] memory){\n        return container[id].addresses;\n    }\n\n    function getItemInfo(bytes32 id) internal view returns(uint256, uint256, uint256){\n        return (container[id].itemType, container[id].status, container[id].addresses.length);\n    }\n\n    function getItemAddressCount(bytes32 id) internal view returns(uint256){\n        return container[id].addresses.length;\n    }\n\n    function setItemInfo(bytes32 id, uint256 itemType, uint256 status) internal{\n        container[id].itemType = itemType;\n        container[id].status = status;\n    }\n\n    function addItemAddress(bytes32 id, address oneAddress) internal{\n        require(!itemAddressExists(id, oneAddress), \"dup address added\");\n        require(container[id].addresses.length \u003c MaxItemAdressNum, \"too many addresses\");\n        container[id].addresses.push(oneAddress);\n    }\n    function removeItemAddresses(bytes32 id) internal{\n        container[id].addresses.length = 0;\n    }\n\n    function removeOneItemAddress(bytes32 id, address oneAddress) internal{\n        for(uint256 i = 0; i \u003c container[id].addresses.length; i++){\n            if(container[id].addresses[i] == oneAddress){\n                container[id].addresses[i] = container[id].addresses[container[id].addresses.length - 1];\n                container[id].addresses.length--;\n                return;\n            }\n        }\n        revert(\"not exist address\");\n    }\n\n    function removeItem(bytes32 id) internal{\n        delete container[id];\n    }\n\n    function replaceItemAddress(bytes32 id, address oneAddress, address anotherAddress) internal{\n        require(!itemAddressExists(id,anotherAddress),\"dup address added\");\n        for(uint256 i = 0; i \u003c container[id].addresses.length; i++){\n            if(container[id].addresses[i] == oneAddress){\n                container[id].addresses[i] = anotherAddress;\n                return;\n            }\n        }\n        revert(\"not exist address\");\n    }\n}"},"HXTZAdmin.sol":{"content":"pragma solidity ^0.5.11;\n\nimport \"./Container.sol\";\n\ncontract HXTZAdmin is Container{\n\n    bytes32 internal constant OWNERHASH = 0x02016836a56b71f0d02689e69e326f4f4c1b9057164ef592671cf0d37c8040c0;\n    bytes32 internal constant OPERATORHASH = 0x46a52cf33029de9f84853745a87af28464c80bf0346df1b32e205fc73319f622;\n    bytes32 internal constant PAUSERHASH = 0x0cc58340b26c619cd4edc70f833d3f4d9d26f3ae7d5ef2965f81fe5495049a4f;\n    bytes32 internal constant STOREHASH = 0xe41d88711b08bdcd7556c5d2d24e0da6fa1f614cf2055f4d7e10206017cd1680;\n    bytes32 internal constant LOGICHASH = 0x397bc5b97f629151e68146caedba62f10b47e426b38db589771a288c0861f182;\n    uint256 internal constant MAXUSERNUM = 255;\n    bytes32[] private classHashArray;\n\n    uint256 internal ownerRequireNum;\n    uint256 internal operatorRequireNum;\n\n    event AdminChanged(string TaskType, string class, address oldAddress, address newAddress);\n    event AdminRequiredNumChanged(string TaskType, string class, uint256 previousNum, uint256 requiredNum);\n    event AdminTaskDropped(bytes32 taskHash);\n\n    function initAdmin(address owner0, address owner1, address owner2) internal{\n        addItemAddress(OWNERHASH, owner0);\n        addItemAddress(OWNERHASH, owner1);\n        addItemAddress(OWNERHASH, owner2);\n        addItemAddress(LOGICHASH, address(0x0));\n        addItemAddress(STOREHASH, address(0x1));\n\n        classHashArray.push(OWNERHASH);\n        classHashArray.push(OPERATORHASH);\n        classHashArray.push(PAUSERHASH);\n        classHashArray.push(STOREHASH);\n        classHashArray.push(LOGICHASH);\n        ownerRequireNum = 2;\n        operatorRequireNum = 2;\n    }\n\n    function classHashExist(bytes32 aHash) private view returns(bool){\n        for(uint256 i = 0; i \u003c classHashArray.length; i++)\n            if(classHashArray[i] == aHash) return true;\n        return false;\n    }\n    function getAdminAddresses(string memory class) public view returns(address[] memory) {\n        bytes32 classHash = getClassHash(class);\n        return getItemAddresses(classHash);\n    }\n    function getOwnerRequiredNum() public view returns(uint256){\n        return ownerRequireNum;\n    }\n    function getOperatorRequiredNum() public view returns(uint256){\n        return operatorRequireNum;\n    }\n\n    function resetRequiredNum(string memory class, uint256 requiredNum)\n        public onlyOwner returns(bool){\n        bytes32 classHash = getClassHash(class);\n        require((classHash == OPERATORHASH) || (classHash == OWNERHASH),\"wrong class\");\n        if (classHash == OWNERHASH)\n            require(requiredNum \u003c= getItemAddressCount(OWNERHASH),\"num larger than existed owners\");\n\n        bytes32 taskHash = keccak256(abi.encodePacked(\"resetRequiredNum\", class, requiredNum));\n        addItemAddress(taskHash, msg.sender);\n\n        if(getItemAddressCount(taskHash) \u003e= ownerRequireNum){\n            removeItem(taskHash);\n            uint256 previousNum = 0;\n            if (classHash == OWNERHASH){\n                previousNum = ownerRequireNum;\n                ownerRequireNum = requiredNum;\n            }\n            else if(classHash == OPERATORHASH){\n                previousNum = operatorRequireNum;\n                operatorRequireNum = requiredNum;\n            }else{\n                revert(\"wrong class\");\n            }\n            emit AdminRequiredNumChanged(\"resetRequiredNum\", class, previousNum, requiredNum);\n        }\n        return true;\n    }\n\n\n    function modifyAddress(string memory class, address oldAddress, address newAddress)\n        internal onlyOwner returns(bool){\n        bytes32 classHash = getClassHash(class);\n        require(!itemAddressExists(classHash,newAddress),\"address existed already\");\n        require(itemAddressExists(classHash,oldAddress),\"address not existed\");\n        bytes32 taskHash = keccak256(abi.encodePacked(\"modifyAddress\", class, oldAddress, newAddress));\n        addItemAddress(taskHash, msg.sender);\n        if(getItemAddressCount(taskHash) \u003e= ownerRequireNum){\n            replaceItemAddress(classHash, oldAddress, newAddress);\n            emit AdminChanged(\"modifyAddress\", class, oldAddress, newAddress);\n            removeItem(taskHash);\n            return true;\n        }\n        return false;\n    }\n\n    function getClassHash(string memory class) private view returns (bytes32){\n        bytes32 classHash = keccak256(abi.encodePacked(class));\n        require(classHashExist(classHash), \"invalid class\");\n        return classHash;\n    }\n\n    function dropAddress(string memory class, address oneAddress)\n        public onlyOwner returns(bool){\n        bytes32 classHash = getClassHash(class);\n        require(classHash != STOREHASH \u0026\u0026 classHash != LOGICHASH, \"wrong class\");\n        require(itemAddressExists(classHash, oneAddress), \"no such address exist\");\n\n        if(classHash == OWNERHASH)\n            require(getItemAddressCount(classHash) \u003e ownerRequireNum, \"insuffience addresses\");\n\n        bytes32 taskHash = keccak256(abi.encodePacked(\"dropAddress\", class, oneAddress));\n        addItemAddress(taskHash, msg.sender);\n        if(getItemAddressCount(taskHash) \u003e= ownerRequireNum){\n            removeOneItemAddress(classHash, oneAddress);\n            emit AdminChanged(\"dropAddress\", class, oneAddress, oneAddress);\n            removeItem(taskHash);\n            return true;\n        }\n        return false;\n\n    }\n\n    function addAddress(string memory class, address oneAddress)\n        public onlyOwner returns(bool){\n        bytes32 classHash = getClassHash(class);\n        require(classHash != STOREHASH \u0026\u0026 classHash != LOGICHASH, \"wrong class\");\n        require(!itemAddressExists(classHash,oneAddress),\"address existed already\");\n\n        bytes32 taskHash = keccak256(abi.encodePacked(\"addAddress\", class, oneAddress));\n        addItemAddress(taskHash, msg.sender);\n        if(getItemAddressCount(taskHash) \u003e= ownerRequireNum){\n            addItemAddress(classHash, oneAddress);\n            emit AdminChanged(\"addAddress\", class, oneAddress, oneAddress);\n            removeItem(taskHash);\n            return true;\n        }\n        return false;\n    }\n\n\n    function dropTask(bytes32 taskHash)\n    public onlyOwner returns (bool){\n        removeItem(taskHash);\n        emit AdminTaskDropped(taskHash);\n        return true;\n    }\n\n    modifier onlyOwner() {\n        require(itemAddressExists(OWNERHASH, msg.sender), \"only use owner to call\");\n        _;\n    }\n\n}"},"HXTZLogic.sol":{"content":"pragma solidity ^0.5.11;\n\nimport \"./SafeMath.sol\";\nimport \"./HXTZStorage.sol\";\n\ncontract HXTZLogic {\n\n    using SafeMath for uint256;\n\n    string public constant name = \"HXTZLogic\";\n\n    uint256 public constant TASKINIT = 0;\n    uint256 public constant TASKPROCESSING = 1;\n    uint256 public constant TASKCANCELLED = 2;\n    uint256 public constant TASKDONE = 3;\n    uint256 public constant MINTTASK = 1;\n    uint256 public constant BURNTASK = 2;\n\n    address private caller;\n    HXTZStorage private store;\n\n    constructor(address aCaller) public{\n        caller = aCaller;\n    }\n\n    modifier onlyCaller(){\n        require(msg.sender == caller, \"only main contract can call\");\n        _;\n    }\n\n    function mintLogic(uint256 value,address to,string calldata proof,\n        bytes32 taskHash, address supportAddress, uint256 requireNum)\n        external onlyCaller returns(uint256){\n        require(to != address(0), \"cannot be burned from zero address\");\n        require(value \u003e 0, \"value need \u003e 0\");\n        require(taskHash == keccak256((abi.encodePacked(to,value,proof))),\"taskHash is wrong\");\n        uint256 status = supportTask(MINTTASK, taskHash, supportAddress, requireNum);\n\n        if( status == TASKDONE){\n            uint256 totalSupply = store.getTotalSupply();\n            uint256 balanceTo = store.balanceOf(to);\n            balanceTo = balanceTo.safeAdd(value);\n            totalSupply = totalSupply.safeAdd(value);\n            store.setBalance(to,balanceTo);\n            store.setTotalSupply(totalSupply);\n        }\n        return status;\n    }\n\n    function burnLogic(address from, uint256 value,string calldata xtzAddress,\n        string calldata proof,bytes32 taskHash, address supportAddress, uint256 requireNum)\n        external onlyCaller returns(uint256){\n\n        uint256 balance = store.balanceOf(from);\n        require(balance \u003e= value,\"sender address not have enough HXTZ\");\n        require(value \u003e 0, \"value need \u003e 0\");\n        require(taskHash == keccak256((abi.encodePacked(from,value,xtzAddress,proof))),\"taskHash is wrong\");\n        uint256 status = supportTask(BURNTASK, taskHash, supportAddress, requireNum);\n\n        if ( status == TASKDONE ){\n            uint256 totalSupply = store.getTotalSupply();\n            totalSupply = totalSupply.safeSub(value);\n            balance = balance.safeSub(value);\n            store.setBalance(from,balance);\n            store.setTotalSupply(totalSupply);\n\n        }\n        return status;\n    }\n\n    function transferLogic(address sender,address to,uint256 value) external onlyCaller returns(bool) {\n        require(to != address(0), \"cannot transfer to address zero\");\n        require(sender != to, \"sender need != to\");\n        require(value \u003e 0, \"value need \u003e 0\");\n        require(address(store) != address(0), \"dataStore address error\");\n\n        uint256 balanceFrom = store.balanceOf(sender);\n        uint256 balanceTo = store.balanceOf(to);\n        require(value \u003c= balanceFrom, \"insufficient funds\");\n        balanceFrom = balanceFrom.safeSub(value);\n        balanceTo = balanceTo.safeAdd(value);\n        store.setBalance(sender,balanceFrom);\n        store.setBalance(to,balanceTo);\n        return true;\n    }\n\n    function transferFromLogic(address sender,address from,address to,uint256 value) external onlyCaller returns(bool) {\n        require(from != address(0), \"cannot transfer from address zero\");\n        require(to != address(0), \"cannot transfer to address zero\");\n        require(value \u003e 0, \"can not tranfer zero Token\");\n        require(from!=to,\"from and to can not be be the same \");\n        require(address(store) != address(0), \"dataStore address error\");\n\n        uint256 balanceFrom = store.balanceOf(from);\n        uint256 balanceTo = store.balanceOf(to);\n        uint256 allowedvalue = store.getAllowed(from,sender);\n\n        require(value \u003c= allowedvalue, \"insufficient allowance\");\n        require(value \u003c= balanceFrom, \"insufficient funds\");\n\n        balanceFrom = balanceFrom.safeSub(value);\n        balanceTo = balanceTo.safeAdd(value);\n        allowedvalue = allowedvalue.safeSub(value);\n\n        store.setBalance(from,balanceFrom);\n        store.setBalance(to,balanceTo);\n        store.setAllowed(from,sender,allowedvalue);\n        return true;\n    }\n\n    function approveLogic(address sender,address spender,uint256 value)  external onlyCaller returns(bool success){\n        require(spender != address(0), \"spender address zero\");\n        require(value \u003e 0, \"value need \u003e 0\");\n        require(address(store) != address(0), \"dataStore address error\");\n\n        store.setAllowed(sender,spender,value);\n        return true;\n    }\n\n    function resetStoreLogic(address storeAddress) external onlyCaller {\n        store = HXTZStorage(storeAddress);\n    }\n\n    function getTotalSupply() public view returns (uint256 supply) {\n        return store.getTotalSupply();\n    }\n\n    function balanceOf(address owner) public view returns (uint256 balance) {\n        return store.balanceOf(owner);\n    }\n\n    function getAllowed(address owner, address spender) public view returns (uint256 remaining){\n        return store.getAllowed(owner,spender);\n    }\n\n    function getStoreAddress() public view returns(address){\n        return address(store);\n    }\n\n    function supportTask(uint256 taskType, bytes32 taskHash, address oneAddress, uint256 requireNum) private returns(uint256){\n        require(!store.supporterExists(taskHash, oneAddress), \"supporter already exists\");\n        (uint256 theTaskType,uint256 theTaskStatus,uint256 theSupporterNum) = store.getTaskInfo(taskHash);\n        require(theTaskStatus \u003c TASKDONE, \"wrong status\");\n\n        if (theTaskStatus != TASKINIT)\n            require(theTaskType == taskType, \"task type not match\");\n        store.addSupporter(taskHash, oneAddress);\n        theSupporterNum++;\n        if(theSupporterNum \u003e= requireNum)\n            theTaskStatus = TASKDONE;\n        else\n            theTaskStatus = TASKPROCESSING;\n        store.setTaskInfo(taskHash, taskType, theTaskStatus);\n        return theTaskStatus;\n    }\n\n    function cancelTask(bytes32 taskHash)  external onlyCaller returns(uint256){\n        (uint256 theTaskType,uint256 theTaskStatus,uint256 theSupporterNum) = store.getTaskInfo(taskHash);\n        require(theTaskStatus == TASKPROCESSING, \"wrong status\");\n        if(theSupporterNum \u003e 0) store.removeAllSupporter(taskHash);\n        theTaskStatus = TASKCANCELLED;\n        store.setTaskInfo(taskHash, theTaskType, theTaskStatus);\n        return theTaskStatus;\n    }\n}"},"HXTZStorage.sol":{"content":"pragma solidity ^0.5.11;\n\nimport \"./Container.sol\";\n\ncontract HXTZStorage is Container{\n\n    string public constant name = \"HXTZStorage\";\n\n    address private caller;\n\n    constructor(address aCaller) public{\n        totalSupply = 0;\n        caller = aCaller;\n    }\n    uint256 public totalSupply;\n\n    mapping (address =\u003e uint256) private balances;\n\n    mapping (address =\u003e mapping (address =\u003e uint256)) private allowed;\n\n    function supporterExists(bytes32 taskHash, address user) public view returns(bool){\n        return itemAddressExists(taskHash, user);\n    }\n\n    function setTaskInfo(bytes32 taskHash, uint256 taskType, uint256 status) external onlyCaller{\n        setItemInfo(taskHash, taskType, status);\n    }\n\n    function getTaskInfo(bytes32 taskHash) public view returns(uint256, uint256, uint256){\n        return getItemInfo(taskHash);\n    }\n\n    function addSupporter(bytes32 taskHash, address oneAddress) external onlyCaller{\n        addItemAddress(taskHash, oneAddress);\n    }\n\n    function removeAllSupporter(bytes32 taskHash) external onlyCaller{\n        removeItemAddresses(taskHash);\n    }\n\n    modifier onlyCaller() {\n        require(msg.sender == caller, \"only use main main contract to call\");\n        _;\n    }\n\n    function getTotalSupply() external view returns(uint256) {\n        return totalSupply;\n    }\n\n    function setTotalSupply(uint256 amount) external onlyCaller {\n        totalSupply = amount;\n    }\n\n    function balanceOf(address account) external view returns(uint256) {\n        return balances[account];\n    }\n\n    function setBalance(address account,uint256 amount) external onlyCaller {\n        require(account != address(0),\"account address error\");\n        balances[account] = amount;\n    }\n\n    function getAllowed(address owner,address spender) external view returns(uint256) {\n        return allowed[owner][spender];\n    }\n\n    function setAllowed(address owner,address spender,uint256 amount) external onlyCaller {\n        require(owner != address(0),\"owner address error\");\n        require(spender != address(0),\"spender address error\");\n        allowed[owner][spender] = amount;\n    }\n}"},"HXTZToken.sol":{"content":"pragma solidity ^0.5.11;\n\nimport \"./IERC20Token.sol\";\nimport \"./HXTZAdmin.sol\";\nimport \"./HXTZLogic.sol\";\nimport \"./HXTZStorage.sol\";\nimport \"./Pausable.sol\";\n\ncontract HXTZToken is IERC20Token,Pausable, HXTZAdmin{\n    string public constant name = \"Huobi XTZ\";\n\n    string public constant symbol = \"HXTZ\";\n\n    uint8 public constant decimals = 18;\n\n    HXTZLogic private logic;\n\n    event Burning(address indexed from, uint256 value, string proof, string  xtzAddress, address burner);\n    event Burned(address indexed from, uint256 value, string proof, string  xtzAddress);\n    event Minting(address indexed to, uint256 value, string proof, address  minter);\n    event Minted(address indexed to, uint256 value, string proof);\n\n    constructor(address owner0, address owner1, address owner2) public{\n        initAdmin(owner0, owner1, owner2);\n    }\n\n\n    function totalSupply() public view returns (uint256 supply) {\n        return logic.getTotalSupply();\n    }\n\n    function balanceOf(address owner) public view returns (uint256 balance) {\n        return logic.balanceOf(owner);\n    }\n\n    function mint(address to, uint256 value, string memory proof,bytes32 taskHash) public whenNotPaused returns(bool){\n        require(itemAddressExists(OPERATORHASH, msg.sender), \"wrong operator\");\n        uint256 status = logic.mintLogic(value,to,proof,taskHash, msg.sender, operatorRequireNum);\n        if (status == 1){\n            emit Minting(to, value, proof, msg.sender);\n        }else if (status == 3) {\n            emit Minting(to, value, proof, msg.sender);\n            emit Minted(to, value, proof);\n            emit Transfer(address(0x0),to,value);\n        }\n        return true;\n    }\n\n\n    function burn(address from,uint256 value,string memory xtzAddress,string memory proof, bytes32 taskHash)\n    public whenNotPaused returns(bool){\n        require(itemAddressExists(OPERATORHASH, msg.sender), \"wrong operator\");\n        uint256 status = logic.burnLogic(from,value,xtzAddress,proof,taskHash, msg.sender, operatorRequireNum);\n        if (status == 1){\n           emit Burning(from, value, proof,xtzAddress, msg.sender);\n        }else if (status == 3) {\n           emit Burning(from, value, proof,xtzAddress,  msg.sender);\n           emit Burned(from, value, proof,xtzAddress);\n           emit Transfer(from, address(0x0),value);\n        }\n        return true;\n    }\n\n    function cancelTask(bytes32 taskHash)  public returns(uint256){\n        require(itemAddressExists(OPERATORHASH, msg.sender), \"wrong operator\");\n        return logic.cancelTask(taskHash);\n    }\n\n    function transfer(address to, uint256 value) public whenNotPaused returns (bool) {\n        bool flag = logic.transferLogic(msg.sender,to,value);\n        require(flag, \"transfer failed\");\n        emit Transfer(msg.sender,to,value);\n        return true;\n    }\n\n    function transferFrom(address from, address to, uint256 value) public whenNotPaused  returns (bool){\n        bool flag = logic.transferFromLogic(msg.sender,from,to,value);\n        require(flag,\"transferFrom failed\");\n        emit Transfer(from, to, value);\n        return true;\n    }\n\n\n    function approve(address spender, uint256 value) public whenNotPaused returns (bool){\n        bool flag = logic.approveLogic(msg.sender,spender,value);\n        require(flag, \"approve failed\");\n        emit Approval(msg.sender, spender, value);\n        return true;\n    }\n\n    function allowance(address owner, address spender) public view returns (uint256 remaining){\n        return logic.getAllowed(owner,spender);\n    }\n\n    function modifyAdminAddress(string memory class, address oldAddress, address newAddress) public whenPaused{\n        require(newAddress != address(0x0), \"wrong address\");\n        bool flag = modifyAddress(class, oldAddress, newAddress);\n        if(flag){\n            bytes32 classHash = keccak256(abi.encodePacked(class));\n            if(classHash == LOGICHASH){\n                logic = HXTZLogic(newAddress);\n            }else if(classHash == STOREHASH){\n                logic.resetStoreLogic(newAddress);\n            }\n        }\n    }\n\n    function getLogicAddress() public view returns(address){\n        return address(logic);\n    }\n\n    function getStoreAddress() public view returns(address){\n        return logic.getStoreAddress();\n    }\n\n    function pause() public{\n        require(itemAddressExists(PAUSERHASH, msg.sender), \"wrong user to pauser\");\n        doPause();\n    }\n\n}"},"IERC20Token.sol":{"content":"pragma solidity ^0.5.11;\n\ncontract IERC20Token {\n    function totalSupply() public view returns (uint256 supply);\n    /// @param owner The address from which the balance will be retrieved\n    /// @return The balance\n    //solium-disable security/enforce-explicit-visibility\n    function balanceOf(address owner) public view returns (uint256 balance);\n\n    /// @notice send `value` token to `to` from `msg.sender`\n    /// @param to The address of the recipient\n    /// @param value The amount of token to be transferred\n    /// @return Whether the transfer was successful or not\n    function transfer(address to, uint256 value) public returns (bool success);\n\n    /// @notice send `value` token to `to` from `from` on the condition it is approved by `from`\n    /// @param from The address of the sender\n    /// @param to The address of the recipient\n    /// @param value The amount of token to be transferred\n    /// @return Whether the transfer was successful or not\n    function transferFrom(address from, address to, uint256 value) public returns (bool success);\n\n    /// @notice `msg.sender` approves `spender` to spend `value` tokens\n    /// @param spender The address of the account able to transfer the tokens\n    /// @param value The amount of tokens to be approved for transfer\n    /// @return Whether the approval was successful or not\n    function approve(address spender, uint256 value) public returns (bool success);\n\n    /// @param owner The address of the account owning tokens\n    /// @param spender The address of the account able to transfer the tokens\n    /// @return Amount of remaining tokens allowed to spent\n    function allowance(address owner, address spender) public view returns (uint256 remaining);\n\n    event Transfer(address indexed from, address indexed to, uint256 value);\n    event Approval(address indexed owner, address indexed spender, uint256 value);\n\n}"},"Pausable.sol":{"content":"pragma solidity ^0.5.11;\n\ncontract Pausable {\n\n    bool private pauseState = true;\n\n    event PauseChangedTo(bool pauseState);\n\n    function doPause() internal {\n        pauseState = !pauseState;\n        emit PauseChangedTo(pauseState);\n    }\n\n    function isPaused() public view returns (bool) {\n        return pauseState;\n    }\n\n    modifier whenPaused() {\n        require(pauseState, \"it is not paused now\");\n        _;\n    }\n\n    modifier whenNotPaused() {\n        require(!pauseState, \"it is paused now\");\n        _;\n    }\n\n}"},"SafeMath.sol":{"content":"// solium-disable linebreak-style\r\npragma solidity ^0.5.11;\r\n\r\nlibrary SafeMath {\r\n    function safeAdd(uint a, uint b) public pure returns (uint c) {\r\n        c = a + b;\r\n        require(c \u003e= a,\"\");\r\n    }\r\n    function safeSub(uint a, uint b) public pure returns (uint c) {\r\n        require(b \u003c= a,\"\");\r\n        c = a - b;\r\n    }\r\n    function safeMul(uint a, uint b) public pure returns (uint c) {\r\n        c = a * b;\r\n        require(a == 0 || c / a == b,\"\");\r\n    }\r\n    function safeDiv(uint a, uint b) public pure returns (uint c) {\r\n        require(b \u003e 0,\"\");\r\n        c = a / b;\r\n    }\r\n}"}}

      File 2 of 4: MultiSigWallet
      pragma solidity ^0.5.0;
      
      
      /// @title Multisignature wallet - Allows multiple parties to agree on transactions before execution.
      /// @author Stefan George - <[email protected]>
      contract MultiSigWallet {
      
          /*
           *  Events
           */
          event Confirmation(address indexed sender, uint indexed transactionId);
          event Revocation(address indexed sender, uint indexed transactionId);
          event Submission(uint indexed transactionId);
          event Execution(uint indexed transactionId);
          event ExecutionFailure(uint indexed transactionId);
          event Deposit(address indexed sender, uint value);
          event OwnerAddition(address indexed owner);
          event OwnerRemoval(address indexed owner);
          event RequirementChange(uint required);
      
          /*
           *  Constants
           */
          uint constant public MAX_OWNER_COUNT = 50;
      
          /*
           *  Storage
           */
          mapping (uint => Transaction) public transactions;
          mapping (uint => mapping (address => bool)) public confirmations;
          mapping (address => bool) public isOwner;
          address[] public owners;
          uint public required;
          uint public transactionCount;
      
          struct Transaction {
              address destination;
              uint value;
              bytes data;
              bool executed;
          }
      
          /*
           *  Modifiers
           */
          modifier onlyWallet() {
              require(msg.sender == address(this));
              _;
          }
      
          modifier ownerDoesNotExist(address owner) {
              require(!isOwner[owner]);
              _;
          }
      
          modifier ownerExists(address owner) {
              require(isOwner[owner]);
              _;
          }
      
          modifier transactionExists(uint transactionId) {
              require(transactions[transactionId].destination != address(0));
              _;
          }
      
          modifier confirmed(uint transactionId, address owner) {
              require(confirmations[transactionId][owner]);
              _;
          }
      
          modifier notConfirmed(uint transactionId, address owner) {
              require(!confirmations[transactionId][owner]);
              _;
          }
      
          modifier notExecuted(uint transactionId) {
              require(!transactions[transactionId].executed);
              _;
          }
      
          modifier notNull(address _address) {
              require(_address != address(0));
              _;
          }
      
          modifier validRequirement(uint ownerCount, uint _required) {
              require(ownerCount <= MAX_OWNER_COUNT
                  && _required <= ownerCount
                  && _required != 0
                  && ownerCount != 0);
              _;
          }
      
          /// @dev Fallback function allows to deposit ether.
          function()
              external
              payable
          {
              if (msg.value > 0)
                  emit Deposit(msg.sender, msg.value);
          }
      
          /*
           * Public functions
           */
          /// @dev Contract constructor sets initial owners and required number of confirmations.
          /// @param _owners List of initial owners.
          /// @param _required Number of required confirmations.
          constructor (address[] memory _owners, uint _required)
            public
            validRequirement(_owners.length, _required)
          {
              for (uint i = 0; i < _owners.length; i++) {
                  require(!isOwner[_owners[i]] && _owners[i] != address(0));
                  isOwner[_owners[i]] = true;
              }
              owners = _owners;
              required = _required;
          }
      
          /// @dev Allows to add a new owner. Transaction has to be sent by wallet.
          /// @param owner Address of new owner.
          function addOwner(address owner)
              public
              onlyWallet
              ownerDoesNotExist(owner)
              notNull(owner)
              validRequirement(owners.length + 1, required)
          {
              isOwner[owner] = true;
              owners.push(owner);
              emit OwnerAddition(owner);
          }
      
          /// @dev Allows to remove an owner. Transaction has to be sent by wallet.
          /// @param owner Address of owner.
          function removeOwner(address owner)
              public
              onlyWallet
              ownerExists(owner)
          {
              isOwner[owner] = false;
              for (uint i = 0; i < owners.length - 1; i++)
                  if (owners[i] == owner) {
                      owners[i] = owners[owners.length - 1];
                      break;
                  }
              owners.length -= 1;
              if (required > owners.length)
                  changeRequirement(owners.length);
              emit OwnerRemoval(owner);
          }
      
          /// @dev Allows to replace an owner with a new owner. Transaction has to be sent by wallet.
          /// @param owner Address of owner to be replaced.
          /// @param newOwner Address of new owner.
          function replaceOwner(address owner, address newOwner)
              public
              onlyWallet
              ownerExists(owner)
              ownerDoesNotExist(newOwner)
          {
              for (uint i = 0; i < owners.length; i++)
                  if (owners[i] == owner) {
                      owners[i] = newOwner;
                      break;
                  }
              isOwner[owner] = false;
              isOwner[newOwner] = true;
              emit OwnerRemoval(owner);
              emit OwnerAddition(newOwner);
          }
      
          /// @dev Allows to change the number of required confirmations. Transaction has to be sent by wallet.
          /// @param _required Number of required confirmations.
          function changeRequirement(uint _required)
              public
              onlyWallet
              validRequirement(owners.length, _required)
          {
              required = _required;
              emit RequirementChange(_required);
          }
      
          /// @dev Allows an owner to submit and confirm a transaction.
          /// @param destination Transaction target address.
          /// @param value Transaction ether value.
          /// @param data Transaction data payload.
          /// @return Returns transaction ID.
          function submitTransaction(address destination, uint value, bytes memory data)
              public
              returns (uint transactionId)
          {
              transactionId = addTransaction(destination, value, data);
              confirmTransaction(transactionId);
          }
      
          /// @dev Allows an owner to confirm a transaction.
          /// @param transactionId Transaction ID.
          function confirmTransaction(uint transactionId)
              public
              ownerExists(msg.sender)
              transactionExists(transactionId)
              notConfirmed(transactionId, msg.sender)
          {
              confirmations[transactionId][msg.sender] = true;
              emit Confirmation(msg.sender, transactionId);
              executeTransaction(transactionId);
          }
      
          /// @dev Allows an owner to revoke a confirmation for a transaction.
          /// @param transactionId Transaction ID.
          function revokeConfirmation(uint transactionId)
              public
              ownerExists(msg.sender)
              confirmed(transactionId, msg.sender)
              notExecuted(transactionId)
          {
              confirmations[transactionId][msg.sender] = false;
              emit Revocation(msg.sender, transactionId);
          }
      
          /// @dev Allows anyone to execute a confirmed transaction.
          /// @param transactionId Transaction ID.
          function executeTransaction(uint transactionId)
              public
              ownerExists(msg.sender)
              confirmed(transactionId, msg.sender)
              notExecuted(transactionId)
          {
              if (isConfirmed(transactionId)) {
                  Transaction storage txn = transactions[transactionId];
                  txn.executed = true;
                  if (external_call(txn.destination, txn.value, txn.data.length, txn.data))
                      emit Execution(transactionId);
                  else {
                      emit ExecutionFailure(transactionId);
                      txn.executed = false;
                  }
              }
          }
      
          // call has been separated into its own function in order to take advantage
          // of the Solidity's code generator to produce a loop that copies tx.data into memory.
          function external_call(address destination, uint value, uint dataLength, bytes memory data) internal returns (bool) {
              bool result;
              assembly {
                  let x := mload(0x40)   // "Allocate" memory for output (0x40 is where "free memory" pointer is stored by convention)
                  let d := add(data, 32) // First 32 bytes are the padded length of data, so exclude that
                  result := call(
                      sub(gas, 34710),   // 34710 is the value that solidity is currently emitting
                                         // It includes callGas (700) + callVeryLow (3, to pay for SUB) + callValueTransferGas (9000) +
                                         // callNewAccountGas (25000, in case the destination address does not exist and needs creating)
                      destination,
                      value,
                      d,
                      dataLength,        // Size of the input (in bytes) - this is what fixes the padding problem
                      x,
                      0                  // Output is ignored, therefore the output size is zero
                  )
              }
              return result;
          }
      
          /// @dev Returns the confirmation status of a transaction.
          /// @param transactionId Transaction ID.
          /// @return Confirmation status.
          function isConfirmed(uint transactionId)
              public
              view
              returns (bool)
          {
              uint count = 0;
              for (uint i = 0; i < owners.length; i++) {
                  if (confirmations[transactionId][owners[i]])
                      count += 1;
                  if (count == required)
                      return true;
              }
          }
      
          /*
           * Internal functions
           */
          /// @dev Adds a new transaction to the transaction mapping, if transaction does not exist yet.
          /// @param destination Transaction target address.
          /// @param value Transaction ether value.
          /// @param data Transaction data payload.
          /// @return Returns transaction ID.
          function addTransaction(address destination, uint value, bytes memory data)
              internal
              notNull(destination)
              returns (uint transactionId)
          {
              transactionId = transactionCount;
              transactions[transactionId] = Transaction({
                  destination: destination,
                  value: value,
                  data: data,
                  executed: false
              });
              transactionCount += 1;
              emit Submission(transactionId);
          }
      
          /*
           * Web3 call functions
           */
          /// @dev Returns number of confirmations of a transaction.
          /// @param transactionId Transaction ID.
          /// @return Number of confirmations.
          function getConfirmationCount(uint transactionId)
              public
              view
              returns (uint count)
          {
              for (uint i = 0; i < owners.length; i++)
                  if (confirmations[transactionId][owners[i]])
                      count += 1;
          }
      
          /// @dev Returns total number of transactions after filers are applied.
          /// @param pending Include pending transactions.
          /// @param executed Include executed transactions.
          /// @return Total number of transactions after filters are applied.
          function getTransactionCount(bool pending, bool executed)
              public
              view
              returns (uint count)
          {
              for (uint i = 0; i < transactionCount; i++)
                  if (   pending && !transactions[i].executed
                      || executed && transactions[i].executed)
                      count += 1;
          }
      
          /// @dev Returns list of owners.
          /// @return List of owner addresses.
          function getOwners()
              public
              view
              returns (address[] memory)
          {
              return owners;
          }
      
          /// @dev Returns array with owner addresses, which confirmed transaction.
          /// @param transactionId Transaction ID.
          /// @return Returns array of owner addresses.
          function getConfirmations(uint transactionId)
              public
              view
              returns (address[] memory _confirmations)
          {
              address[] memory confirmationsTemp = new address[](owners.length);
              uint count = 0;
              uint i;
              for (i = 0; i < owners.length; i++)
                  if (confirmations[transactionId][owners[i]]) {
                      confirmationsTemp[count] = owners[i];
                      count += 1;
                  }
              _confirmations = new address[](count);
              for (i = 0; i < count; i++)
                  _confirmations[i] = confirmationsTemp[i];
          }
      
          /// @dev Returns list of transaction IDs in defined range.
          /// @param from Index start position of transaction array.
          /// @param to Index end position of transaction array.
          /// @param pending Include pending transactions.
          /// @param executed Include executed transactions.
          /// @return Returns array of transaction IDs.
          function getTransactionIds(uint from, uint to, bool pending, bool executed)
              public
              view
              returns (uint[] memory _transactionIds)
          {
              uint[] memory transactionIdsTemp = new uint[](transactionCount);
              uint count = 0;
              uint i;
              for (i = 0; i < transactionCount; i++)
                  if (   pending && !transactions[i].executed
                      || executed && transactions[i].executed)
                  {
                      transactionIdsTemp[count] = i;
                      count += 1;
                  }
              _transactionIds = new uint[](to - from);
              for (i = from; i < to; i++)
                  _transactionIds[i - from] = transactionIdsTemp[i];
          }
      }

      File 3 of 4: HXTZLogic
      {"Container.sol":{"content":"pragma solidity ^0.5.11;\n\ncontract Container{\n    struct Item{\n        uint256 itemType;\n        uint256 status;\n        address[] addresses;\n    }\n    uint256 MaxItemAdressNum = 255;\n\n    mapping (bytes32 =\u003e Item) private container;\n\n    function itemAddressExists(bytes32 id, address oneAddress) internal view returns(bool){\n        for(uint256 i = 0; i \u003c container[id].addresses.length; i++){\n            if(container[id].addresses[i] == oneAddress)\n                return true;\n        }\n        return false;\n    }\n    function getItemAddresses(bytes32 id) internal view returns(address[] memory){\n        return container[id].addresses;\n    }\n\n    function getItemInfo(bytes32 id) internal view returns(uint256, uint256, uint256){\n        return (container[id].itemType, container[id].status, container[id].addresses.length);\n    }\n\n    function getItemAddressCount(bytes32 id) internal view returns(uint256){\n        return container[id].addresses.length;\n    }\n\n    function setItemInfo(bytes32 id, uint256 itemType, uint256 status) internal{\n        container[id].itemType = itemType;\n        container[id].status = status;\n    }\n\n    function addItemAddress(bytes32 id, address oneAddress) internal{\n        require(!itemAddressExists(id, oneAddress), \"dup address added\");\n        require(container[id].addresses.length \u003c MaxItemAdressNum, \"too many addresses\");\n        container[id].addresses.push(oneAddress);\n    }\n    function removeItemAddresses(bytes32 id) internal{\n        container[id].addresses.length = 0;\n    }\n\n    function removeOneItemAddress(bytes32 id, address oneAddress) internal{\n        for(uint256 i = 0; i \u003c container[id].addresses.length; i++){\n            if(container[id].addresses[i] == oneAddress){\n                container[id].addresses[i] = container[id].addresses[container[id].addresses.length - 1];\n                container[id].addresses.length--;\n                return;\n            }\n        }\n        revert(\"not exist address\");\n    }\n\n    function removeItem(bytes32 id) internal{\n        delete container[id];\n    }\n\n    function replaceItemAddress(bytes32 id, address oneAddress, address anotherAddress) internal{\n        require(!itemAddressExists(id,anotherAddress),\"dup address added\");\n        for(uint256 i = 0; i \u003c container[id].addresses.length; i++){\n            if(container[id].addresses[i] == oneAddress){\n                container[id].addresses[i] = anotherAddress;\n                return;\n            }\n        }\n        revert(\"not exist address\");\n    }\n}"},"HXTZLogic.sol":{"content":"pragma solidity ^0.5.11;\n\nimport \"./SafeMath.sol\";\nimport \"./HXTZStorage.sol\";\n\ncontract HXTZLogic {\n\n    using SafeMath for uint256;\n\n    string public constant name = \"HXTZLogic\";\n\n    uint256 public constant TASKINIT = 0;\n    uint256 public constant TASKPROCESSING = 1;\n    uint256 public constant TASKCANCELLED = 2;\n    uint256 public constant TASKDONE = 3;\n    uint256 public constant MINTTASK = 1;\n    uint256 public constant BURNTASK = 2;\n\n    address private caller;\n    HXTZStorage private store;\n\n    constructor(address aCaller) public{\n        caller = aCaller;\n    }\n\n    modifier onlyCaller(){\n        require(msg.sender == caller, \"only main contract can call\");\n        _;\n    }\n\n    function mintLogic(uint256 value,address to,string calldata proof,\n        bytes32 taskHash, address supportAddress, uint256 requireNum)\n        external onlyCaller returns(uint256){\n        require(to != address(0), \"cannot be burned from zero address\");\n        require(value \u003e 0, \"value need \u003e 0\");\n        require(taskHash == keccak256((abi.encodePacked(to,value,proof))),\"taskHash is wrong\");\n        uint256 status = supportTask(MINTTASK, taskHash, supportAddress, requireNum);\n\n        if( status == TASKDONE){\n            uint256 totalSupply = store.getTotalSupply();\n            uint256 balanceTo = store.balanceOf(to);\n            balanceTo = balanceTo.safeAdd(value);\n            totalSupply = totalSupply.safeAdd(value);\n            store.setBalance(to,balanceTo);\n            store.setTotalSupply(totalSupply);\n        }\n        return status;\n    }\n\n    function burnLogic(address from, uint256 value,string calldata xtzAddress,\n        string calldata proof,bytes32 taskHash, address supportAddress, uint256 requireNum)\n        external onlyCaller returns(uint256){\n\n        uint256 balance = store.balanceOf(from);\n        require(balance \u003e= value,\"sender address not have enough HXTZ\");\n        require(value \u003e 0, \"value need \u003e 0\");\n        require(taskHash == keccak256((abi.encodePacked(from,value,xtzAddress,proof))),\"taskHash is wrong\");\n        uint256 status = supportTask(BURNTASK, taskHash, supportAddress, requireNum);\n\n        if ( status == TASKDONE ){\n            uint256 totalSupply = store.getTotalSupply();\n            totalSupply = totalSupply.safeSub(value);\n            balance = balance.safeSub(value);\n            store.setBalance(from,balance);\n            store.setTotalSupply(totalSupply);\n\n        }\n        return status;\n    }\n\n    function transferLogic(address sender,address to,uint256 value) external onlyCaller returns(bool) {\n        require(to != address(0), \"cannot transfer to address zero\");\n        require(sender != to, \"sender need != to\");\n        require(value \u003e 0, \"value need \u003e 0\");\n        require(address(store) != address(0), \"dataStore address error\");\n\n        uint256 balanceFrom = store.balanceOf(sender);\n        uint256 balanceTo = store.balanceOf(to);\n        require(value \u003c= balanceFrom, \"insufficient funds\");\n        balanceFrom = balanceFrom.safeSub(value);\n        balanceTo = balanceTo.safeAdd(value);\n        store.setBalance(sender,balanceFrom);\n        store.setBalance(to,balanceTo);\n        return true;\n    }\n\n    function transferFromLogic(address sender,address from,address to,uint256 value) external onlyCaller returns(bool) {\n        require(from != address(0), \"cannot transfer from address zero\");\n        require(to != address(0), \"cannot transfer to address zero\");\n        require(value \u003e 0, \"can not tranfer zero Token\");\n        require(from!=to,\"from and to can not be be the same \");\n        require(address(store) != address(0), \"dataStore address error\");\n\n        uint256 balanceFrom = store.balanceOf(from);\n        uint256 balanceTo = store.balanceOf(to);\n        uint256 allowedvalue = store.getAllowed(from,sender);\n\n        require(value \u003c= allowedvalue, \"insufficient allowance\");\n        require(value \u003c= balanceFrom, \"insufficient funds\");\n\n        balanceFrom = balanceFrom.safeSub(value);\n        balanceTo = balanceTo.safeAdd(value);\n        allowedvalue = allowedvalue.safeSub(value);\n\n        store.setBalance(from,balanceFrom);\n        store.setBalance(to,balanceTo);\n        store.setAllowed(from,sender,allowedvalue);\n        return true;\n    }\n\n    function approveLogic(address sender,address spender,uint256 value)  external onlyCaller returns(bool success){\n        require(spender != address(0), \"spender address zero\");\n        require(value \u003e 0, \"value need \u003e 0\");\n        require(address(store) != address(0), \"dataStore address error\");\n\n        store.setAllowed(sender,spender,value);\n        return true;\n    }\n\n    function resetStoreLogic(address storeAddress) external onlyCaller {\n        store = HXTZStorage(storeAddress);\n    }\n\n    function getTotalSupply() public view returns (uint256 supply) {\n        return store.getTotalSupply();\n    }\n\n    function balanceOf(address owner) public view returns (uint256 balance) {\n        return store.balanceOf(owner);\n    }\n\n    function getAllowed(address owner, address spender) public view returns (uint256 remaining){\n        return store.getAllowed(owner,spender);\n    }\n\n    function getStoreAddress() public view returns(address){\n        return address(store);\n    }\n\n    function supportTask(uint256 taskType, bytes32 taskHash, address oneAddress, uint256 requireNum) private returns(uint256){\n        require(!store.supporterExists(taskHash, oneAddress), \"supporter already exists\");\n        (uint256 theTaskType,uint256 theTaskStatus,uint256 theSupporterNum) = store.getTaskInfo(taskHash);\n        require(theTaskStatus \u003c TASKDONE, \"wrong status\");\n\n        if (theTaskStatus != TASKINIT)\n            require(theTaskType == taskType, \"task type not match\");\n        store.addSupporter(taskHash, oneAddress);\n        theSupporterNum++;\n        if(theSupporterNum \u003e= requireNum)\n            theTaskStatus = TASKDONE;\n        else\n            theTaskStatus = TASKPROCESSING;\n        store.setTaskInfo(taskHash, taskType, theTaskStatus);\n        return theTaskStatus;\n    }\n\n    function cancelTask(bytes32 taskHash)  external onlyCaller returns(uint256){\n        (uint256 theTaskType,uint256 theTaskStatus,uint256 theSupporterNum) = store.getTaskInfo(taskHash);\n        require(theTaskStatus == TASKPROCESSING, \"wrong status\");\n        if(theSupporterNum \u003e 0) store.removeAllSupporter(taskHash);\n        theTaskStatus = TASKCANCELLED;\n        store.setTaskInfo(taskHash, theTaskType, theTaskStatus);\n        return theTaskStatus;\n    }\n}"},"HXTZStorage.sol":{"content":"pragma solidity ^0.5.11;\n\nimport \"./Container.sol\";\n\ncontract HXTZStorage is Container{\n\n    string public constant name = \"HXTZStorage\";\n\n    address private caller;\n\n    constructor(address aCaller) public{\n        totalSupply = 0;\n        caller = aCaller;\n    }\n    uint256 public totalSupply;\n\n    mapping (address =\u003e uint256) private balances;\n\n    mapping (address =\u003e mapping (address =\u003e uint256)) private allowed;\n\n    function supporterExists(bytes32 taskHash, address user) public view returns(bool){\n        return itemAddressExists(taskHash, user);\n    }\n\n    function setTaskInfo(bytes32 taskHash, uint256 taskType, uint256 status) external onlyCaller{\n        setItemInfo(taskHash, taskType, status);\n    }\n\n    function getTaskInfo(bytes32 taskHash) public view returns(uint256, uint256, uint256){\n        return getItemInfo(taskHash);\n    }\n\n    function addSupporter(bytes32 taskHash, address oneAddress) external onlyCaller{\n        addItemAddress(taskHash, oneAddress);\n    }\n\n    function removeAllSupporter(bytes32 taskHash) external onlyCaller{\n        removeItemAddresses(taskHash);\n    }\n\n    modifier onlyCaller() {\n        require(msg.sender == caller, \"only use main main contract to call\");\n        _;\n    }\n\n    function getTotalSupply() external view returns(uint256) {\n        return totalSupply;\n    }\n\n    function setTotalSupply(uint256 amount) external onlyCaller {\n        totalSupply = amount;\n    }\n\n    function balanceOf(address account) external view returns(uint256) {\n        return balances[account];\n    }\n\n    function setBalance(address account,uint256 amount) external onlyCaller {\n        require(account != address(0),\"account address error\");\n        balances[account] = amount;\n    }\n\n    function getAllowed(address owner,address spender) external view returns(uint256) {\n        return allowed[owner][spender];\n    }\n\n    function setAllowed(address owner,address spender,uint256 amount) external onlyCaller {\n        require(owner != address(0),\"owner address error\");\n        require(spender != address(0),\"spender address error\");\n        allowed[owner][spender] = amount;\n    }\n}"},"SafeMath.sol":{"content":"// solium-disable linebreak-style\r\npragma solidity ^0.5.11;\r\n\r\nlibrary SafeMath {\r\n    function safeAdd(uint a, uint b) public pure returns (uint c) {\r\n        c = a + b;\r\n        require(c \u003e= a,\"\");\r\n    }\r\n    function safeSub(uint a, uint b) public pure returns (uint c) {\r\n        require(b \u003c= a,\"\");\r\n        c = a - b;\r\n    }\r\n    function safeMul(uint a, uint b) public pure returns (uint c) {\r\n        c = a * b;\r\n        require(a == 0 || c / a == b,\"\");\r\n    }\r\n    function safeDiv(uint a, uint b) public pure returns (uint c) {\r\n        require(b \u003e 0,\"\");\r\n        c = a / b;\r\n    }\r\n}"}}

      File 4 of 4: HXTZStorage
      {"Container.sol":{"content":"pragma solidity ^0.5.11;\n\ncontract Container{\n    struct Item{\n        uint256 itemType;\n        uint256 status;\n        address[] addresses;\n    }\n    uint256 MaxItemAdressNum = 255;\n\n    mapping (bytes32 =\u003e Item) private container;\n\n    function itemAddressExists(bytes32 id, address oneAddress) internal view returns(bool){\n        for(uint256 i = 0; i \u003c container[id].addresses.length; i++){\n            if(container[id].addresses[i] == oneAddress)\n                return true;\n        }\n        return false;\n    }\n    function getItemAddresses(bytes32 id) internal view returns(address[] memory){\n        return container[id].addresses;\n    }\n\n    function getItemInfo(bytes32 id) internal view returns(uint256, uint256, uint256){\n        return (container[id].itemType, container[id].status, container[id].addresses.length);\n    }\n\n    function getItemAddressCount(bytes32 id) internal view returns(uint256){\n        return container[id].addresses.length;\n    }\n\n    function setItemInfo(bytes32 id, uint256 itemType, uint256 status) internal{\n        container[id].itemType = itemType;\n        container[id].status = status;\n    }\n\n    function addItemAddress(bytes32 id, address oneAddress) internal{\n        require(!itemAddressExists(id, oneAddress), \"dup address added\");\n        require(container[id].addresses.length \u003c MaxItemAdressNum, \"too many addresses\");\n        container[id].addresses.push(oneAddress);\n    }\n    function removeItemAddresses(bytes32 id) internal{\n        container[id].addresses.length = 0;\n    }\n\n    function removeOneItemAddress(bytes32 id, address oneAddress) internal{\n        for(uint256 i = 0; i \u003c container[id].addresses.length; i++){\n            if(container[id].addresses[i] == oneAddress){\n                container[id].addresses[i] = container[id].addresses[container[id].addresses.length - 1];\n                container[id].addresses.length--;\n                return;\n            }\n        }\n        revert(\"not exist address\");\n    }\n\n    function removeItem(bytes32 id) internal{\n        delete container[id];\n    }\n\n    function replaceItemAddress(bytes32 id, address oneAddress, address anotherAddress) internal{\n        require(!itemAddressExists(id,anotherAddress),\"dup address added\");\n        for(uint256 i = 0; i \u003c container[id].addresses.length; i++){\n            if(container[id].addresses[i] == oneAddress){\n                container[id].addresses[i] = anotherAddress;\n                return;\n            }\n        }\n        revert(\"not exist address\");\n    }\n}"},"HXTZStorage.sol":{"content":"pragma solidity ^0.5.11;\n\nimport \"./Container.sol\";\n\ncontract HXTZStorage is Container{\n\n    string public constant name = \"HXTZStorage\";\n\n    address private caller;\n\n    constructor(address aCaller) public{\n        totalSupply = 0;\n        caller = aCaller;\n    }\n    uint256 public totalSupply;\n\n    mapping (address =\u003e uint256) private balances;\n\n    mapping (address =\u003e mapping (address =\u003e uint256)) private allowed;\n\n    function supporterExists(bytes32 taskHash, address user) public view returns(bool){\n        return itemAddressExists(taskHash, user);\n    }\n\n    function setTaskInfo(bytes32 taskHash, uint256 taskType, uint256 status) external onlyCaller{\n        setItemInfo(taskHash, taskType, status);\n    }\n\n    function getTaskInfo(bytes32 taskHash) public view returns(uint256, uint256, uint256){\n        return getItemInfo(taskHash);\n    }\n\n    function addSupporter(bytes32 taskHash, address oneAddress) external onlyCaller{\n        addItemAddress(taskHash, oneAddress);\n    }\n\n    function removeAllSupporter(bytes32 taskHash) external onlyCaller{\n        removeItemAddresses(taskHash);\n    }\n\n    modifier onlyCaller() {\n        require(msg.sender == caller, \"only use main main contract to call\");\n        _;\n    }\n\n    function getTotalSupply() external view returns(uint256) {\n        return totalSupply;\n    }\n\n    function setTotalSupply(uint256 amount) external onlyCaller {\n        totalSupply = amount;\n    }\n\n    function balanceOf(address account) external view returns(uint256) {\n        return balances[account];\n    }\n\n    function setBalance(address account,uint256 amount) external onlyCaller {\n        require(account != address(0),\"account address error\");\n        balances[account] = amount;\n    }\n\n    function getAllowed(address owner,address spender) external view returns(uint256) {\n        return allowed[owner][spender];\n    }\n\n    function setAllowed(address owner,address spender,uint256 amount) external onlyCaller {\n        require(owner != address(0),\"owner address error\");\n        require(spender != address(0),\"spender address error\");\n        allowed[owner][spender] = amount;\n    }\n}"}}