Transaction Hash:
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 | ||
---|---|---|---|---|---|
0x30741289...14E723851 | (HTX 21) |
22.721389007635762135 Eth
Nonce: 45280
|
22.719861227635762135 Eth
Nonce: 45281
| 0.00152778 | |
0x44607358...80c8b16cF
Miner
| 0.319966003464694777 Eth | 0.320572491589559428 Eth | 0.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
File 2 of 4: MultiSigWallet
File 3 of 4: HXTZLogic
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}"},"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}"}}