Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- NFTLibV1
- Optimization enabled
- true
- Compiler version
- v0.4.26+commit.4563c3fc
- Optimization runs
- 200
- EVM Version
- byzantium
- Verified at
- 2023-04-20T02:37:11.734166Z
Contract source code
// File: openzeppelin-eth/contracts/math/SafeMath.sol pragma solidity ^0.4.24; /** * @title SafeMath * @dev Math operations with safety checks that revert on error */ library SafeMath { /** * @dev Multiplies two numbers, reverts on overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b); return c; } /** * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0); // Solidity only automatically asserts when dividing by 0 uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a); uint256 c = a - b; return c; } /** * @dev Adds two numbers, reverts on overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a); return c; } /** * @dev Divides two numbers and returns the remainder (unsigned integer modulo), * reverts when dividing by zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b != 0); return a % b; } } // File: contracts/crossApproach/lib/HTLCTxLib.sol /* Copyright 2019 Wanchain Foundation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // _ _ _ // __ ____ _ _ __ ___| |__ __ _(_)_ __ __| | _____ __ // \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / / // \ V V / (_| | | | | (__| | | | (_| | | | | | (_| | __/\ V / // \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/ // // pragma solidity ^0.4.26; pragma experimental ABIEncoderV2; library HTLCTxLib { using SafeMath for uint; /** * * ENUMS * */ /// @notice tx info status /// @notice uninitialized,locked,redeemed,revoked enum TxStatus {None, Locked, Redeemed, Revoked, AssetLocked, DebtLocked} /** * * STRUCTURES * */ /// @notice struct of HTLC user mint lock parameters struct HTLCUserParams { bytes32 xHash; /// hash of HTLC random number bytes32 smgID; /// ID of storeman group which user has selected uint tokenPairID; /// token pair id on cross chain uint value; /// exchange token value uint lockFee; /// exchange token value uint lockedTime; /// HTLC lock time } /// @notice HTLC(Hashed TimeLock Contract) tx info struct BaseTx { bytes32 smgID; /// HTLC transaction storeman ID uint lockedTime; /// HTLC transaction locked time uint beginLockedTime; /// HTLC transaction begin locked time TxStatus status; /// HTLC transaction status } /// @notice user tx info struct UserTx { BaseTx baseTx; uint tokenPairID; uint value; uint fee; address userAccount; /// HTLC transaction sender address for the security check while user's revoke } /// @notice storeman tx info struct SmgTx { BaseTx baseTx; uint tokenPairID; uint value; address userAccount; /// HTLC transaction user address for the security check while user's redeem } /// @notice storeman debt tx info struct DebtTx { BaseTx baseTx; bytes32 srcSmgID; /// HTLC transaction sender(source storeman) ID } struct Data { /// @notice mapping of hash(x) to UserTx -- xHash->htlcUserTxData mapping(bytes32 => UserTx) mapHashXUserTxs; /// @notice mapping of hash(x) to SmgTx -- xHash->htlcSmgTxData mapping(bytes32 => SmgTx) mapHashXSmgTxs; /// @notice mapping of hash(x) to DebtTx -- xHash->htlcDebtTxData mapping(bytes32 => DebtTx) mapHashXDebtTxs; } /** * * MANIPULATIONS * */ /// @notice add user transaction info /// @param params parameters for user tx function addUserTx(Data storage self, HTLCUserParams memory params) public { UserTx memory userTx = self.mapHashXUserTxs[params.xHash]; // UserTx storage userTx = self.mapHashXUserTxs[params.xHash]; // require(params.value != 0, "Value is invalid"); require(userTx.baseTx.status == TxStatus.None, "User tx exists"); userTx.baseTx.smgID = params.smgID; userTx.baseTx.lockedTime = params.lockedTime; userTx.baseTx.beginLockedTime = now; userTx.baseTx.status = TxStatus.Locked; userTx.tokenPairID = params.tokenPairID; userTx.value = params.value; userTx.fee = params.lockFee; userTx.userAccount = msg.sender; self.mapHashXUserTxs[params.xHash] = userTx; } /// @notice refund coins from HTLC transaction, which is used for storeman redeem(outbound) /// @param x HTLC random number function redeemUserTx(Data storage self, bytes32 x) external returns(bytes32 xHash) { xHash = sha256(abi.encodePacked(x)); UserTx storage userTx = self.mapHashXUserTxs[xHash]; require(userTx.baseTx.status == TxStatus.Locked, "Status is not locked"); require(now < userTx.baseTx.beginLockedTime.add(userTx.baseTx.lockedTime), "Redeem timeout"); userTx.baseTx.status = TxStatus.Redeemed; return xHash; } /// @notice revoke user transaction /// @param xHash hash of HTLC random number function revokeUserTx(Data storage self, bytes32 xHash) external { UserTx storage userTx = self.mapHashXUserTxs[xHash]; require(userTx.baseTx.status == TxStatus.Locked, "Status is not locked"); require(now >= userTx.baseTx.beginLockedTime.add(userTx.baseTx.lockedTime), "Revoke is not permitted"); userTx.baseTx.status = TxStatus.Revoked; } /// @notice function for get user info /// @param xHash hash of HTLC random number /// @return smgID ID of storeman which user has selected /// @return tokenPairID token pair ID of cross chain /// @return value exchange value /// @return fee exchange fee /// @return userAccount HTLC transaction sender address for the security check while user's revoke function getUserTx(Data storage self, bytes32 xHash) external view returns (bytes32, uint, uint, uint, address) { UserTx storage userTx = self.mapHashXUserTxs[xHash]; return (userTx.baseTx.smgID, userTx.tokenPairID, userTx.value, userTx.fee, userTx.userAccount); } /// @notice add storeman transaction info /// @param xHash hash of HTLC random number /// @param smgID ID of the storeman which user has selected /// @param tokenPairID token pair ID of cross chain /// @param value HTLC transfer value of token /// @param userAccount user account address on the destination chain, which is used to redeem token function addSmgTx(Data storage self, bytes32 xHash, bytes32 smgID, uint tokenPairID, uint value, address userAccount, uint lockedTime) external { SmgTx memory smgTx = self.mapHashXSmgTxs[xHash]; // SmgTx storage smgTx = self.mapHashXSmgTxs[xHash]; require(value != 0, "Value is invalid"); require(smgTx.baseTx.status == TxStatus.None, "Smg tx exists"); smgTx.baseTx.smgID = smgID; smgTx.baseTx.status = TxStatus.Locked; smgTx.baseTx.lockedTime = lockedTime; smgTx.baseTx.beginLockedTime = now; smgTx.tokenPairID = tokenPairID; smgTx.value = value; smgTx.userAccount = userAccount; self.mapHashXSmgTxs[xHash] = smgTx; } /// @notice refund coins from HTLC transaction, which is used for users redeem(inbound) /// @param x HTLC random number function redeemSmgTx(Data storage self, bytes32 x) external returns(bytes32 xHash) { xHash = sha256(abi.encodePacked(x)); SmgTx storage smgTx = self.mapHashXSmgTxs[xHash]; require(smgTx.baseTx.status == TxStatus.Locked, "Status is not locked"); require(now < smgTx.baseTx.beginLockedTime.add(smgTx.baseTx.lockedTime), "Redeem timeout"); smgTx.baseTx.status = TxStatus.Redeemed; return xHash; } /// @notice revoke storeman transaction /// @param xHash hash of HTLC random number function revokeSmgTx(Data storage self, bytes32 xHash) external { SmgTx storage smgTx = self.mapHashXSmgTxs[xHash]; require(smgTx.baseTx.status == TxStatus.Locked, "Status is not locked"); require(now >= smgTx.baseTx.beginLockedTime.add(smgTx.baseTx.lockedTime), "Revoke is not permitted"); smgTx.baseTx.status = TxStatus.Revoked; } /// @notice function for get smg info /// @param xHash hash of HTLC random number /// @return smgID ID of storeman which user has selected /// @return tokenPairID token pair ID of cross chain /// @return value exchange value /// @return userAccount user account address for redeem function getSmgTx(Data storage self, bytes32 xHash) external view returns (bytes32, uint, uint, address) { SmgTx storage smgTx = self.mapHashXSmgTxs[xHash]; return (smgTx.baseTx.smgID, smgTx.tokenPairID, smgTx.value, smgTx.userAccount); } /// @notice add storeman transaction info /// @param xHash hash of HTLC random number /// @param srcSmgID ID of source storeman group /// @param destSmgID ID of the storeman which will take over of the debt of source storeman group /// @param lockedTime HTLC lock time /// @param status Status, should be 'Locked' for asset or 'DebtLocked' for debt function addDebtTx(Data storage self, bytes32 xHash, bytes32 srcSmgID, bytes32 destSmgID, uint lockedTime, TxStatus status) external { DebtTx memory debtTx = self.mapHashXDebtTxs[xHash]; // DebtTx storage debtTx = self.mapHashXDebtTxs[xHash]; require(debtTx.baseTx.status == TxStatus.None, "Debt tx exists"); debtTx.baseTx.smgID = destSmgID; debtTx.baseTx.status = status;//TxStatus.Locked; debtTx.baseTx.lockedTime = lockedTime; debtTx.baseTx.beginLockedTime = now; debtTx.srcSmgID = srcSmgID; self.mapHashXDebtTxs[xHash] = debtTx; } /// @notice refund coins from HTLC transaction /// @param x HTLC random number /// @param status Status, should be 'Locked' for asset or 'DebtLocked' for debt function redeemDebtTx(Data storage self, bytes32 x, TxStatus status) external returns(bytes32 xHash) { xHash = sha256(abi.encodePacked(x)); DebtTx storage debtTx = self.mapHashXDebtTxs[xHash]; // require(debtTx.baseTx.status == TxStatus.Locked, "Status is not locked"); require(debtTx.baseTx.status == status, "Status is not locked"); require(now < debtTx.baseTx.beginLockedTime.add(debtTx.baseTx.lockedTime), "Redeem timeout"); debtTx.baseTx.status = TxStatus.Redeemed; return xHash; } /// @notice revoke debt transaction, which is used for source storeman group /// @param xHash hash of HTLC random number /// @param status Status, should be 'Locked' for asset or 'DebtLocked' for debt function revokeDebtTx(Data storage self, bytes32 xHash, TxStatus status) external { DebtTx storage debtTx = self.mapHashXDebtTxs[xHash]; // require(debtTx.baseTx.status == TxStatus.Locked, "Status is not locked"); require(debtTx.baseTx.status == status, "Status is not locked"); require(now >= debtTx.baseTx.beginLockedTime.add(debtTx.baseTx.lockedTime), "Revoke is not permitted"); debtTx.baseTx.status = TxStatus.Revoked; } /// @notice function for get debt info /// @param xHash hash of HTLC random number /// @return srcSmgID ID of source storeman /// @return destSmgID ID of destination storeman function getDebtTx(Data storage self, bytes32 xHash) external view returns (bytes32, bytes32) { DebtTx storage debtTx = self.mapHashXDebtTxs[xHash]; return (debtTx.srcSmgID, debtTx.baseTx.smgID); } function getLeftTime(uint endTime) private view returns (uint) { if (now < endTime) { return endTime.sub(now); } return 0; } /// @notice function for get debt info /// @param xHash hash of HTLC random number /// @return leftTime the left lock time function getLeftLockedTime(Data storage self, bytes32 xHash) external view returns (uint) { UserTx storage userTx = self.mapHashXUserTxs[xHash]; if (userTx.baseTx.status != TxStatus.None) { return getLeftTime(userTx.baseTx.beginLockedTime.add(userTx.baseTx.lockedTime)); } SmgTx storage smgTx = self.mapHashXSmgTxs[xHash]; if (smgTx.baseTx.status != TxStatus.None) { return getLeftTime(smgTx.baseTx.beginLockedTime.add(smgTx.baseTx.lockedTime)); } DebtTx storage debtTx = self.mapHashXDebtTxs[xHash]; if (debtTx.baseTx.status != TxStatus.None) { return getLeftTime(debtTx.baseTx.beginLockedTime.add(debtTx.baseTx.lockedTime)); } require(false, 'invalid xHash'); } } // File: contracts/interfaces/ISignatureVerifier.sol /* Copyright 2019 Wanchain Foundation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // _ _ _ // __ ____ _ _ __ ___| |__ __ _(_)_ __ __| | _____ __ // \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / / // \ V V / (_| | | | | (__| | | | (_| | | | | | (_| | __/\ V / // \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/ // // pragma solidity 0.4.26; interface ISignatureVerifier { function verify( uint curveId, bytes32 signature, bytes32 groupKeyX, bytes32 groupKeyY, bytes32 randomPointX, bytes32 randomPointY, bytes32 message ) external returns (bool); } // File: contracts/interfaces/ITokenManager.sol /* Copyright 2019 Wanchain Foundation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // _ _ _ // __ ____ _ _ __ ___| |__ __ _(_)_ __ __| | _____ __ // \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / / // \ V V / (_| | | | | (__| | | | (_| | | | | | (_| | __/\ V / // \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/ // // pragma solidity 0.4.26; interface ITokenManager { function getTokenPairInfo(uint id) external view returns (uint origChainID, bytes tokenOrigAccount, uint shadowChainID, bytes tokenShadowAccount); function getTokenPairInfoSlim(uint id) external view returns (uint origChainID, bytes tokenOrigAccount, uint shadowChainID); function getAncestorInfo(uint id) external view returns (bytes account, string name, string symbol, uint8 decimals, uint chainId); function mintToken(address tokenAddress, address to, uint value) external; function burnToken(address tokenAddress, address from, uint value) external; function mapTokenPairType(uint tokenPairID) external view returns (uint8 tokenPairType); // erc1155 function mintNFT(uint tokenCrossType, address tokenAddress, address to, uint[] ids, uint[] values, bytes data) public; function burnNFT(uint tokenCrossType, address tokenAddress, address from, uint[] ids, uint[] values) public; } // File: contracts/interfaces/IStoremanGroup.sol /* Copyright 2019 Wanchain Foundation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // _ _ _ // __ ____ _ _ __ ___| |__ __ _(_)_ __ __| | _____ __ // \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / / // \ V V / (_| | | | | (__| | | | (_| | | | | | (_| | __/\ V / // \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/ // // pragma solidity ^0.4.24; interface IStoremanGroup { function getSelectedSmNumber(bytes32 groupId) external view returns(uint number); function getStoremanGroupConfig(bytes32 id) external view returns(bytes32 groupId, uint8 status, uint deposit, uint chain1, uint chain2, uint curve1, uint curve2, bytes gpk1, bytes gpk2, uint startTime, uint endTime); function getDeposit(bytes32 id) external view returns(uint); function getStoremanGroupStatus(bytes32 id) external view returns(uint8 status, uint startTime, uint endTime); function setGpk(bytes32 groupId, bytes gpk1, bytes gpk2) external; function setInvalidSm(bytes32 groupId, uint[] indexs, uint8[] slashTypes) external returns(bool isContinue); function getThresholdByGrpId(bytes32 groupId) external view returns (uint); function getSelectedSmInfo(bytes32 groupId, uint index) external view returns(address wkAddr, bytes PK, bytes enodeId); function recordSmSlash(address wk) external; } // File: contracts/interfaces/IQuota.sol /* Copyright 2019 Wanchain Foundation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // _ _ _ // __ ____ _ _ __ ___| |__ __ _(_)_ __ __| | _____ __ // \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / / // \ V V / (_| | | | | (__| | | | (_| | | | | | (_| | __/\ V / // \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/ // // pragma solidity 0.4.26; interface IQuota { function userLock(uint tokenId, bytes32 storemanGroupId, uint value) external; function userBurn(uint tokenId, bytes32 storemanGroupId, uint value) external; function smgRelease(uint tokenId, bytes32 storemanGroupId, uint value) external; function smgMint(uint tokenId, bytes32 storemanGroupId, uint value) external; function upgrade(bytes32 storemanGroupId) external; function transferAsset(bytes32 srcStoremanGroupId, bytes32 dstStoremanGroupId) external; function receiveDebt(bytes32 srcStoremanGroupId, bytes32 dstStoremanGroupId) external; function getUserMintQuota(uint tokenId, bytes32 storemanGroupId) external view returns (uint); function getSmgMintQuota(uint tokenId, bytes32 storemanGroupId) external view returns (uint); function getUserBurnQuota(uint tokenId, bytes32 storemanGroupId) external view returns (uint); function getSmgBurnQuota(uint tokenId, bytes32 storemanGroupId) external view returns (uint); function getAsset(uint tokenId, bytes32 storemanGroupId) external view returns (uint asset, uint asset_receivable, uint asset_payable); function getDebt(uint tokenId, bytes32 storemanGroupId) external view returns (uint debt, uint debt_receivable, uint debt_payable); function isDebtClean(bytes32 storemanGroupId) external view returns (bool); } // File: contracts/interfaces/IRC20Protocol.sol /* Copyright 2019 Wanchain Foundation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // _ _ _ // __ ____ _ _ __ ___| |__ __ _(_)_ __ __| | _____ __ // \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / / // \ V V / (_| | | | | (__| | | | (_| | | | | | (_| | __/\ V / // \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/ // // pragma solidity ^0.4.26; interface IRC20Protocol { function transfer(address, uint) external returns (bool); function transferFrom(address, address, uint) external returns (bool); function balanceOf(address _owner) external view returns (uint); } // File: contracts/crossApproach/lib/RapidityTxLib.sol /* Copyright 2019 Wanchain Foundation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // _ _ _ // __ ____ _ _ __ ___| |__ __ _(_)_ __ __| | _____ __ // \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / / // \ V V / (_| | | | | (__| | | | (_| | | | | | (_| | __/\ V / // \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/ // // pragma solidity ^0.4.26; library RapidityTxLib { /** * * ENUMS * */ /// @notice tx info status /// @notice uninitialized,Redeemed enum TxStatus {None, Redeemed} /** * * STRUCTURES * */ struct Data { /// @notice mapping of uniqueID to TxStatus -- uniqueID->TxStatus mapping(bytes32 => TxStatus) mapTxStatus; } /** * * MANIPULATIONS * */ /// @notice add user transaction info /// @param uniqueID Rapidity random number function addRapidityTx(Data storage self, bytes32 uniqueID) internal { TxStatus status = self.mapTxStatus[uniqueID]; require(status == TxStatus.None, "Rapidity tx exists"); self.mapTxStatus[uniqueID] = TxStatus.Redeemed; } } // File: contracts/crossApproach/lib/CrossTypesV1.sol /* Copyright 2019 Wanchain Foundation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // _ _ _ // __ ____ _ _ __ ___| |__ __ _(_)_ __ __| | _____ __ // \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / / // \ V V / (_| | | | | (__| | | | (_| | | | | | (_| | __/\ V / // \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/ // // pragma solidity ^0.4.26; library CrossTypesV1 { using SafeMath for uint; /** * * STRUCTURES * */ struct Data { /// map of the htlc transaction info HTLCTxLib.Data htlcTxData; /// map of the rapidity transaction info RapidityTxLib.Data rapidityTxData; /// quota data of storeman group IQuota quota; /// token manager instance interface ITokenManager tokenManager; /// storemanGroup admin instance interface IStoremanGroup smgAdminProxy; /// storemanGroup fee admin instance address address smgFeeProxy; ISignatureVerifier sigVerifier; /// @notice transaction fee, smgID => fee mapping(bytes32 => uint) mapStoremanFee; /// @notice transaction fee, origChainID => shadowChainID => fee mapping(uint => mapping(uint =>uint)) mapContractFee; /// @notice transaction fee, origChainID => shadowChainID => fee mapping(uint => mapping(uint =>uint)) mapAgentFee; } /** * * MANIPULATIONS * */ // /// @notice convert bytes32 to address // /// @param b bytes32 // function bytes32ToAddress(bytes32 b) internal pure returns (address) { // return address(uint160(bytes20(b))); // high // // return address(uint160(uint256(b))); // low // } /// @notice convert bytes to address /// @param b bytes function bytesToAddress(bytes b) internal pure returns (address addr) { assembly { addr := mload(add(b,20)) } } function transfer(address tokenScAddr, address to, uint value) internal returns(bool) { uint beforeBalance; uint afterBalance; beforeBalance = IRC20Protocol(tokenScAddr).balanceOf(to); // IRC20Protocol(tokenScAddr).transfer(to, value); tokenScAddr.call(bytes4(keccak256("transfer(address,uint256)")), to, value); afterBalance = IRC20Protocol(tokenScAddr).balanceOf(to); return afterBalance == beforeBalance.add(value); } function transferFrom(address tokenScAddr, address from, address to, uint value) internal returns(bool) { uint beforeBalance; uint afterBalance; beforeBalance = IRC20Protocol(tokenScAddr).balanceOf(to); // IRC20Protocol(tokenScAddr).transferFrom(from, to, value); tokenScAddr.call(bytes4(keccak256("transferFrom(address,address,uint256)")), from, to, value); afterBalance = IRC20Protocol(tokenScAddr).balanceOf(to); return afterBalance == beforeBalance.add(value); } } // File: openzeppelin-eth/contracts/introspection/IERC165.sol pragma solidity ^0.4.24; /** * @title IERC165 * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md */ interface IERC165 { /** * @notice Query if a contract implements an interface * @param interfaceId The interface identifier, as specified in ERC-165 * @dev Interface identification is specified in ERC-165. This function * uses less than 30,000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); } // File: openzeppelin-eth/contracts/zos-lib/Initializable.sol pragma solidity ^0.4.24; /** * @title Initializable * * @dev Helper contract to support initializer functions. To use it, replace * the constructor with a function that has the `initializer` modifier. * WARNING: Unlike constructors, initializer functions must be manually * invoked. This applies both to deploying an Initializable contract, as well * as extending an Initializable contract via inheritance. * WARNING: When used with inheritance, manual care must be taken to not invoke * a parent initializer twice, or ensure that all initializers are idempotent, * because this is not dealt with automatically as with constructors. */ contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private initializing; /** * @dev Modifier to use in the initializer function of a contract. */ modifier initializer() { require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); bool wasInitializing = initializing; initializing = true; initialized = true; _; initializing = wasInitializing; } /// @dev Returns true if and only if the function is running in the constructor function isConstructor() private view returns (bool) { // extcodesize checks the size of the code stored in an address, and // address returns the current address. Since the code is still not // deployed when running a constructor, any checks on its code size will // yield zero, making it an effective way to detect if a contract is // under construction or not. uint256 cs; assembly { cs := extcodesize(address) } return cs == 0; } // Reserved storage space to allow for layout changes in the future. uint256[50] private ______gap; } // File: openzeppelin-eth/contracts/token/ERC721/IERC721.sol pragma solidity ^0.4.24; /** * @title ERC721 Non-Fungible Token Standard basic interface * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md */ contract IERC721 is Initializable, IERC165 { event Transfer( address indexed from, address indexed to, uint256 indexed tokenId ); event Approval( address indexed owner, address indexed approved, uint256 indexed tokenId ); event ApprovalForAll( address indexed owner, address indexed operator, bool approved ); function balanceOf(address owner) public view returns (uint256 balance); function ownerOf(uint256 tokenId) public view returns (address owner); function approve(address to, uint256 tokenId) public; function getApproved(uint256 tokenId) public view returns (address operator); function setApprovalForAll(address operator, bool _approved) public; function isApprovedForAll(address owner, address operator) public view returns (bool); function transferFrom(address from, address to, uint256 tokenId) public; function safeTransferFrom(address from, address to, uint256 tokenId) public; function safeTransferFrom( address from, address to, uint256 tokenId, bytes data ) public; } // File: contracts/interfaces/IERC1155.sol /* Copyright 2019 Wanchain Foundation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // _ _ _ // __ ____ _ _ __ ___| |__ __ _(_)_ __ __| | _____ __ // \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / / // \ V V / (_| | | | | (__| | | | (_| | | | | | (_| | __/\ V / // \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/ // // pragma solidity ^0.4.26; //interface IERC1155 is IERC165 { interface IERC1155 { ///** // * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. // */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); ///** // * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all // * transfers. // */ //event TransferBatch(address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ //function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes data) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom(address from, address to, uint256[] ids, uint256[] amounts, bytes data) external; } // File: contracts/crossApproach/lib/NFTLibV1.sol /* Copyright 2019 Wanchain Foundation. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ // _ _ _ // __ ____ _ _ __ ___| |__ __ _(_)_ __ __| | _____ __ // \ \ /\ / / _` | '_ \ / __| '_ \ / _` | | '_ \@/ _` |/ _ \ \ / / // \ V V / (_| | | | | (__| | | | (_| | | | | | (_| | __/\ V / // \_/\_/ \__,_|_| |_|\___|_| |_|\__,_|_|_| |_|\__,_|\___| \_/ // // pragma solidity ^0.4.26; library NFTLibV1 { using SafeMath for uint; using RapidityTxLib for RapidityTxLib.Data; enum TokenCrossType {ERC20, ERC721, ERC1155} /// @notice struct of Rapidity storeman mint lock parameters struct RapidityUserLockNFTParams { bytes32 smgID; /// ID of storeman group which user has selected uint tokenPairID; /// token pair id on cross chain uint[] tokenIDs; /// NFT token Ids uint[] tokenValues; /// NFT token values uint currentChainID; /// current chain ID uint tokenPairContractFee; /// fee of token pair bytes destUserAccount; /// account of shadow chain, used to receive token address smgFeeProxy; /// address of the proxy to store fee for storeman group } /// @notice struct of Rapidity storeman mint lock parameters struct RapiditySmgMintNFTParams { bytes32 uniqueID; /// Rapidity random number bytes32 smgID; /// ID of storeman group which user has selected uint tokenPairID; /// token pair id on cross chain uint[] tokenIDs; /// NFT token Ids uint[] tokenValues; /// NFT token values bytes extData; /// storeman data address destTokenAccount; /// shadow token account address destUserAccount; /// account of shadow chain, used to receive token } /// @notice struct of Rapidity user burn lock parameters struct RapidityUserBurnNFTParams { bytes32 smgID; /// ID of storeman group which user has selected uint tokenPairID; /// token pair id on cross chain uint[] tokenIDs; /// NFT token Ids uint[] tokenValues; /// NFT token values uint currentChainID; /// current chain ID uint tokenPairContractFee; /// fee of token pair address srcTokenAccount; /// shadow token account bytes destUserAccount; /// account of token destination chain, used to receive token address smgFeeProxy; /// address of the proxy to store fee for storeman group } /// @notice struct of Rapidity user burn lock parameters struct RapiditySmgReleaseNFTParams { bytes32 uniqueID; /// Rapidity random number bytes32 smgID; /// ID of storeman group which user has selected uint tokenPairID; /// token pair id on cross chain uint[] tokenIDs; /// NFT token Ids uint[] tokenValues; /// NFT token values address destTokenAccount; /// original token/coin account address destUserAccount; /// account of token original chain, used to receive token } event UserLockNFT(bytes32 indexed smgID, uint indexed tokenPairID, address indexed tokenAccount, string[] keys, bytes[] values); event UserBurnNFT(bytes32 indexed smgID, uint indexed tokenPairID, address indexed tokenAccount, string[] keys, bytes[] values); event SmgMintNFT(bytes32 indexed uniqueID, bytes32 indexed smgID, uint indexed tokenPairID, string[] keys, bytes[] values); event SmgReleaseNFT(bytes32 indexed uniqueID, bytes32 indexed smgID, uint indexed tokenPairID, string[] keys, bytes[] values); function getTokenScAddrAndContractFee(CrossTypesV1.Data storage storageData, uint tokenPairID, uint tokenPairContractFee, uint currentChainID, uint batchLength) public view returns (address, uint) { ITokenManager tokenManager = storageData.tokenManager; uint fromChainID; uint toChainID; bytes memory fromTokenAccount; bytes memory toTokenAccount; (fromChainID,fromTokenAccount,toChainID,toTokenAccount) = tokenManager.getTokenPairInfo(tokenPairID); require(fromChainID != 0, "Token does not exist"); uint contractFee = tokenPairContractFee; address tokenScAddr; if (currentChainID == fromChainID) { if (contractFee == 0) { contractFee = storageData.mapContractFee[fromChainID][toChainID]; } tokenScAddr = CrossTypesV1.bytesToAddress(fromTokenAccount); } else if (currentChainID == toChainID) { if (contractFee == 0) { contractFee = storageData.mapContractFee[toChainID][fromChainID]; } tokenScAddr = CrossTypesV1.bytesToAddress(toTokenAccount); } else { require(false, "Invalid token pair"); } if (contractFee > 0) { contractFee = contractFee.mul(9 + batchLength).div(10); } return (tokenScAddr, contractFee); } /// @notice mintBridge, user lock token on token original chain /// @notice event invoked by user mint lock /// @param storageData Cross storage data /// @param params parameters for user mint lock token on token original chain function userLockNFT(CrossTypesV1.Data storage storageData, RapidityUserLockNFTParams memory params) public { address tokenScAddr; uint contractFee; (tokenScAddr, contractFee) = getTokenScAddrAndContractFee(storageData, params.tokenPairID, params.tokenPairContractFee, params.currentChainID, params.tokenIDs.length); if (contractFee > 0) { params.smgFeeProxy.transfer(contractFee); } uint left = (msg.value).sub(contractFee); uint8 tokenCrossType = storageData.tokenManager.mapTokenPairType(params.tokenPairID); if (tokenCrossType == uint8(TokenCrossType.ERC721)) { for(uint idx = 0; idx < params.tokenIDs.length; ++idx) { IERC721(tokenScAddr).safeTransferFrom(msg.sender, address(this), params.tokenIDs[idx], ""); } } else if(tokenCrossType == uint8(TokenCrossType.ERC1155)) { IERC1155(tokenScAddr).safeBatchTransferFrom(msg.sender, address(this), params.tokenIDs, params.tokenValues, ""); } else{ require(false, "Invalid NFT type"); } if (left != 0) { (msg.sender).transfer(left); } string[] memory keys = new string[](4); bytes[] memory values = new bytes[](4); keys[0] = "tokenIDs:uint256[]"; values[0] = abi.encode(params.tokenIDs); keys[1] = "tokenValues:uint256[]"; values[1] = abi.encode(params.tokenValues); keys[2] = "userAccount:bytes"; values[2] = params.destUserAccount; keys[3] = "contractFee:uint256"; values[3] = abi.encodePacked(contractFee); emit UserLockNFT(params.smgID, params.tokenPairID, tokenScAddr, keys, values); } /// @notice burnBridge, user lock token on token original chain /// @notice event invoked by user burn lock /// @param storageData Cross storage data /// @param params parameters for user burn lock token on token original chain function userBurnNFT(CrossTypesV1.Data storage storageData, RapidityUserBurnNFTParams memory params) public { address tokenScAddr; uint contractFee; (tokenScAddr, contractFee) = getTokenScAddrAndContractFee(storageData, params.tokenPairID, params.tokenPairContractFee, params.currentChainID, params.tokenIDs.length); ITokenManager tokenManager = storageData.tokenManager; uint8 tokenCrossType = tokenManager.mapTokenPairType(params.tokenPairID); require((tokenCrossType == uint8(TokenCrossType.ERC721) || tokenCrossType == uint8(TokenCrossType.ERC1155)), "Invalid NFT type"); ITokenManager(tokenManager).burnNFT(uint(tokenCrossType), tokenScAddr, msg.sender, params.tokenIDs, params.tokenValues); if (contractFee > 0) { params.smgFeeProxy.transfer(contractFee); } uint left = (msg.value).sub(contractFee); if (left != 0) { (msg.sender).transfer(left); } string[] memory keys = new string[](4); bytes[] memory values = new bytes[](4); keys[0] = "tokenIDs:uint256[]"; values[0] = abi.encode(params.tokenIDs); keys[1] = "tokenValues:uint256[]"; values[1] = abi.encode(params.tokenValues); keys[2] = "userAccount:bytes"; values[2] = params.destUserAccount; keys[3] = "contractFee:uint256"; values[3] = abi.encodePacked(contractFee); emit UserBurnNFT(params.smgID, params.tokenPairID, tokenScAddr, keys, values); } /// @notice mintBridge, storeman mint lock token on token shadow chain /// @notice event invoked by user mint lock /// @param storageData Cross storage data /// @param params parameters for storeman mint lock token on token shadow chain function smgMintNFT(CrossTypesV1.Data storage storageData, RapiditySmgMintNFTParams memory params) public { storageData.rapidityTxData.addRapidityTx(params.uniqueID); ITokenManager tokenManager = storageData.tokenManager; uint8 tokenCrossType = tokenManager.mapTokenPairType(params.tokenPairID); require((tokenCrossType == uint8(TokenCrossType.ERC721) || tokenCrossType == uint8(TokenCrossType.ERC1155)), "Invalid NFT type"); ITokenManager(tokenManager).mintNFT(uint(tokenCrossType), params.destTokenAccount, params.destUserAccount, params.tokenIDs, params.tokenValues, params.extData); string[] memory keys = new string[](5); bytes[] memory values = new bytes[](5); keys[0] = "tokenIDs:uint256[]"; values[0] = abi.encode(params.tokenIDs); keys[1] = "tokenValues:uint256[]"; values[1] = abi.encode(params.tokenValues); keys[2] = "tokenAccount:address"; values[2] = abi.encodePacked(params.destTokenAccount); keys[3] = "userAccount:address"; values[3] = abi.encodePacked(params.destUserAccount); keys[4] = "extData:bytes"; values[4] = params.extData; emit SmgMintNFT(params.uniqueID, params.smgID, params.tokenPairID, keys, values); } /// @notice burnBridge, storeman burn lock token on token shadow chain /// @notice event invoked by user burn lock /// @param storageData Cross storage data /// @param params parameters for storeman burn lock token on token shadow chain function smgReleaseNFT(CrossTypesV1.Data storage storageData, RapiditySmgReleaseNFTParams memory params) public { storageData.rapidityTxData.addRapidityTx(params.uniqueID); uint8 tokenCrossType = storageData.tokenManager.mapTokenPairType(params.tokenPairID); if (tokenCrossType == uint8(TokenCrossType.ERC721)) { for(uint idx = 0; idx < params.tokenIDs.length; ++idx) { IERC721(params.destTokenAccount).safeTransferFrom(address(this), params.destUserAccount, params.tokenIDs[idx], ""); } } else if(tokenCrossType == uint8(TokenCrossType.ERC1155)) { IERC1155(params.destTokenAccount).safeBatchTransferFrom(address(this), params.destUserAccount, params.tokenIDs, params.tokenValues, ""); } else { require(false, "Invalid NFT type"); } string[] memory keys = new string[](4); bytes[] memory values = new bytes[](4); keys[0] = "tokenIDs:uint256[]"; values[0] = abi.encode(params.tokenIDs); keys[1] = "tokenValues:uint256[]"; values[1] = abi.encode(params.tokenValues); keys[2] = "tokenAccount:address"; values[2] = abi.encodePacked(params.destTokenAccount); keys[3] = "userAccount:address"; values[3] = abi.encodePacked(params.destUserAccount); emit SmgReleaseNFT(params.uniqueID, params.smgID, params.tokenPairID, keys, values); } }
Contract ABI
[{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"userBurnNFT","inputs":[{"type":"CrossTypesV1.Data storage","name":"storageData"},{"type":"tuple","name":"params","components":[{"type":"bytes32","name":"smgID"},{"type":"uint256","name":"tokenPairID"},{"type":"uint256[]","name":"tokenIDs"},{"type":"uint256[]","name":"tokenValues"},{"type":"uint256","name":"currentChainID"},{"type":"uint256","name":"tokenPairContractFee"},{"type":"address","name":"srcTokenAccount"},{"type":"bytes","name":"destUserAccount"},{"type":"address","name":"smgFeeProxy"}]}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"userLockNFT","inputs":[{"type":"CrossTypesV1.Data storage","name":"storageData"},{"type":"tuple","name":"params","components":[{"type":"bytes32","name":"smgID"},{"type":"uint256","name":"tokenPairID"},{"type":"uint256[]","name":"tokenIDs"},{"type":"uint256[]","name":"tokenValues"},{"type":"uint256","name":"currentChainID"},{"type":"uint256","name":"tokenPairContractFee"},{"type":"bytes","name":"destUserAccount"},{"type":"address","name":"smgFeeProxy"}]}],"constant":false},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"smgReleaseNFT","inputs":[{"type":"CrossTypesV1.Data storage","name":"storageData"},{"type":"tuple","name":"params","components":[{"type":"bytes32","name":"uniqueID"},{"type":"bytes32","name":"smgID"},{"type":"uint256","name":"tokenPairID"},{"type":"uint256[]","name":"tokenIDs"},{"type":"uint256[]","name":"tokenValues"},{"type":"address","name":"destTokenAccount"},{"type":"address","name":"destUserAccount"}]}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""},{"type":"uint256","name":""}],"name":"getTokenScAddrAndContractFee","inputs":[{"type":"CrossTypesV1.Data storage","name":"storageData"},{"type":"uint256","name":"tokenPairID"},{"type":"uint256","name":"tokenPairContractFee"},{"type":"uint256","name":"currentChainID"},{"type":"uint256","name":"batchLength"}],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[],"name":"smgMintNFT","inputs":[{"type":"CrossTypesV1.Data storage","name":"storageData"},{"type":"tuple","name":"params","components":[{"type":"bytes32","name":"uniqueID"},{"type":"bytes32","name":"smgID"},{"type":"uint256","name":"tokenPairID"},{"type":"uint256[]","name":"tokenIDs"},{"type":"uint256[]","name":"tokenValues"},{"type":"bytes","name":"extData"},{"type":"address","name":"destTokenAccount"},{"type":"address","name":"destUserAccount"}]}],"constant":false},{"type":"event","name":"UserLockNFT","inputs":[{"type":"bytes32","name":"smgID","indexed":true},{"type":"uint256","name":"tokenPairID","indexed":true},{"type":"address","name":"tokenAccount","indexed":true},{"type":"string[]","name":"keys","indexed":false},{"type":"bytes[]","name":"values","indexed":false}],"anonymous":false},{"type":"event","name":"UserBurnNFT","inputs":[{"type":"bytes32","name":"smgID","indexed":true},{"type":"uint256","name":"tokenPairID","indexed":true},{"type":"address","name":"tokenAccount","indexed":true},{"type":"string[]","name":"keys","indexed":false},{"type":"bytes[]","name":"values","indexed":false}],"anonymous":false},{"type":"event","name":"SmgMintNFT","inputs":[{"type":"bytes32","name":"uniqueID","indexed":true},{"type":"bytes32","name":"smgID","indexed":true},{"type":"uint256","name":"tokenPairID","indexed":true},{"type":"string[]","name":"keys","indexed":false},{"type":"bytes[]","name":"values","indexed":false}],"anonymous":false},{"type":"event","name":"SmgReleaseNFT","inputs":[{"type":"bytes32","name":"uniqueID","indexed":true},{"type":"bytes32","name":"smgID","indexed":true},{"type":"uint256","name":"tokenPairID","indexed":true},{"type":"string[]","name":"keys","indexed":false},{"type":"bytes[]","name":"values","indexed":false}],"anonymous":false}]
Contract Creation Code
0x61246c610030600b82828239805160001a6073146000811461002057610022565bfe5b5030600052607381538281f300730000000000000000000000000000000000000000301460806040526004361061006a5763ffffffff60e060020a60003504166306528fbc811461006f5780633b73799114610091578063972c12ea146100b1578063c921ea93146100d1578063dbd9a2b5146100fb575b600080fd5b81801561007b57600080fd5b5061008f61008a366004611d25565b61011b565b005b81801561009d57600080fd5b5061008f6100ac366004611d6d565b6105c6565b8180156100bd57600080fd5b5061008f6100cc366004611cdd565b610b07565b6100e46100df366004611db5565b610ffd565b6040516100f29291906121b1565b60405180910390f35b81801561010757600080fd5b5061008f610116366004611c8b565b6111aa565b60008060008060006060806101448989602001518a60a001518b608001518c6040015151610ffd565b60058b015460208b015160405160e060020a6375d2e27d028152939a50919850600160a060020a0316965086916375d2e27d9161018391600401612248565b602060405180830381600087803b15801561019d57600080fd5b505af11580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506101d59190810190611ebb565b935060ff8416600114806101ec575060ff84166002145b15156102165760405160e560020a62461bcd02815260040161020d90612238565b60405180910390fd5b84600160a060020a0316632859c5808560ff1689338c604001518d606001516040518663ffffffff1660e060020a028152600401610258959493929190612256565b600060405180830381600087803b15801561027257600080fd5b505af1158015610286573d6000803e3d6000fd5b5050505060008611156102d357876101000151600160a060020a03166108fc879081150290604051600060405180830381858888f193505050501580156102d1573d6000803e3d6000fd5b505b6102e3348763ffffffff61168216565b9250821561031a57604051339084156108fc029085906000818181858888f19350505050158015610318573d6000803e3d6000fd5b505b60408051600480825260a0820190925290816020015b606081526020019060019003908161033057505060408051600480825260a08201909252919350602082015b606081526020019060019003908161035c5790505090506040805190810160405280601281526020016000805160206124138339815191528152508260008151811015156103a657fe5b9060200190602002018190525087604001516040516020016103c891906121f1565b6040516020818303038152906040528160008151811015156103e657fe5b906020019060200201819052506040805190810160405280601581526020016000805160206123f383398151915281525082600181518110151561042657fe5b90602001906020020181905250876060015160405160200161044891906121f1565b60405160208183030381529060405281600181518110151561046657fe5b906020019060200201819052506040805190810160405280601181526020017f757365724163636f756e743a62797465730000000000000000000000000000008152508260028151811015156104b857fe5b6020908102909101015260e08801518151829060029081106104d657fe5b906020019060200201819052506040805190810160405280601381526020017f636f6e74726163744665653a75696e743235360000000000000000000000000081525082600381518110151561052857fe5b602090810290910181019190915260408051808301899052815180820390930183528101905281518290600390811061055d57fe5b9060200190602002018190525086600160a060020a031688602001518960000151600019167f988781dff960cf5a144a15c9b0c4d1346196e415e64ea7ebd609c6ac0559bbbb85856040516105b39291906121cc565b60405180910390a4505050505050505050565b60008060008060006060806105ef8989602001518a60a001518b608001518c6040015151610ffd565b9097509550600086111561063c578760e00151600160a060020a03166108fc879081150290604051600060405180830381858888f1935050505015801561063a573d6000803e3d6000fd5b505b61064c348763ffffffff61168216565b60058a015460208a015160405160e060020a6375d2e27d028152929750600160a060020a03909116916375d2e27d9161068791600401612248565b602060405180830381600087803b1580156106a157600080fd5b505af11580156106b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106d99190810190611ebb565b935060ff84166001141561078957600092505b8760400151518310156107845786600160a060020a031663b88d4fde33308b604001518781518110151561071c57fe5b906020019060200201516040518463ffffffff1660e060020a0281526004016107479392919061216f565b600060405180830381600087803b15801561076157600080fd5b505af1158015610775573d6000803e3d6000fd5b505050508260010192506106ec565b610839565b60ff84166002141561081e5760408089015160608a015191517f2eb2c2d6000000000000000000000000000000000000000000000000000000008152600160a060020a038a1692632eb2c2d6926107e7923392309291600401612111565b600060405180830381600087803b15801561080157600080fd5b505af1158015610815573d6000803e3d6000fd5b50505050610839565b60405160e560020a62461bcd02815260040161020d90612238565b841561086e57604051339086156108fc029087906000818181858888f1935050505015801561086c573d6000803e3d6000fd5b505b60408051600480825260a0820190925290816020015b606081526020019060019003908161088457505060408051600480825260a08201909252919350602082015b60608152602001906001900390816108b05790505090506040805190810160405280601281526020016000805160206124138339815191528152508260008151811015156108fa57fe5b90602001906020020181905250876040015160405160200161091c91906121f1565b60405160208183030381529060405281600081518110151561093a57fe5b906020019060200201819052506040805190810160405280601581526020016000805160206123f383398151915281525082600181518110151561097a57fe5b90602001906020020181905250876060015160405160200161099c91906121f1565b6040516020818303038152906040528160018151811015156109ba57fe5b906020019060200201819052506040805190810160405280601181526020017f757365724163636f756e743a6279746573000000000000000000000000000000815250826002815181101515610a0c57fe5b6020908102909101015260c0880151815182906002908110610a2a57fe5b906020019060200201819052506040805190810160405280601381526020017f636f6e74726163744665653a75696e7432353600000000000000000000000000815250826003815181101515610a7c57fe5b6020908102909101810191909152604080518083018990528151808203909301835281019052815182906003908110610ab157fe5b9060200190602002018190525086600160a060020a031688602001518960000151600019167f62605e96f2f9cd2d124a846c58ea7d9982610ba45d052c99b14900c37a71868385856040516105b39291906121cc565b600080606080610b278560000151876003016116a090919063ffffffff16565b6005860154604080870151905160e060020a6375d2e27d028152600160a060020a03909216916375d2e27d91610b5f91600401612248565b602060405180830381600087803b158015610b7957600080fd5b505af1158015610b8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610bb19190810190611ebb565b935060ff841660011415610c6957600092505b846060015151831015610c64578460a00151600160a060020a031663b88d4fde308760c00151886060015187815181101515610bfc57fe5b906020019060200201516040518463ffffffff1660e060020a028152600401610c279392919061216f565b600060405180830381600087803b158015610c4157600080fd5b505af1158015610c55573d6000803e3d6000fd5b50505050826001019250610bc4565b610ced565b60ff84166002141561081e578460a00151600160a060020a0316632eb2c2d6308760c00151886060015189608001516040518563ffffffff1660e060020a028152600401610cba9493929190612111565b600060405180830381600087803b158015610cd457600080fd5b505af1158015610ce8573d6000803e3d6000fd5b505050505b60408051600480825260a0820190925290816020015b6060815260200190600190039081610d0357505060408051600480825260a08201909252919350602082015b6060815260200190600190039081610d2f579050509050604080519081016040528060128152602001600080516020612413833981519152815250826000815181101515610d7957fe5b906020019060200201819052508460600151604051602001610d9b91906121f1565b604051602081830303815290604052816000815181101515610db957fe5b906020019060200201819052506040805190810160405280601581526020016000805160206123f3833981519152815250826001815181101515610df957fe5b906020019060200201819052508460800151604051602001610e1b91906121f1565b604051602081830303815290604052816001815181101515610e3957fe5b906020019060200201819052506040805190810160405280601481526020017f746f6b656e4163636f756e743a61646472657373000000000000000000000000815250826002815181101515610e8b57fe5b906020019060200201819052508460a001516040516020018082600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401915050604051602081830303815290604052816002815181101515610eec57fe5b906020019060200201819052506040805190810160405280601381526020017f757365724163636f756e743a6164647265737300000000000000000000000000815250826003815181101515610f3e57fe5b906020019060200201819052508460c001516040516020018082600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401915050604051602081830303815290604052816003815181101515610f9f57fe5b602090810290910181019190915260408087015191870151875191519091907fba98d99dde5738beb90acb291bb9b140abeb4d2f93bd94d7dade6b9d9173bc7390610fed90879087906121cc565b60405180910390a4505050505050565b60008060008060006060806000808d60050160009054906101000a9004600160a060020a0316965086600160a060020a031663b90732768e6040518263ffffffff1660e060020a0281526004016110549190612248565b600060405180830381600087803b15801561106e57600080fd5b505af1158015611082573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110aa9190810190611e2a565b9298509650945092508515156110d55760405160e560020a62461bcd02815260040161020d90612218565b8b9150858b141561111657811515611106576000868152600a8f016020908152604080832088845290915290205491505b61110f846116fc565b9050611168565b848b141561114d57811515611144576000858152600a8f016020908152604080832089845290915290205491505b61110f836116fc565b60405160e560020a62461bcd02815260040161020d90612202565b600082111561119857611195600a6111898460098e0163ffffffff61170316565b9063ffffffff61173816565b91505b9d909c509a5050505050505050505050565b6000806060806111ca8560000151876003016116a090919063ffffffff16565b6005860154604080870151905160e060020a6375d2e27d028152600160a060020a03909216955085916375d2e27d9161120591600401612248565b602060405180830381600087803b15801561121f57600080fd5b505af1158015611233573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112579190810190611ebb565b925060ff83166001148061126e575060ff83166002145b151561128f5760405160e560020a62461bcd02815260040161020d90612238565b83600160a060020a0316639947f9328460ff168760c001518860e0015189606001518a608001518b60a001516040518763ffffffff1660e060020a0281526004016112df969594939291906122af565b600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b505060408051600580825260c0820190925292509050816020015b606081526020019060019003908161132857505060408051600580825260c08201909252919350602082015b606081526020019060019003908161135457905050905060408051908101604052806012815260200160008051602061241383398151915281525082600081518110151561139e57fe5b9060200190602002018190525084606001516040516020016113c091906121f1565b6040516020818303038152906040528160008151811015156113de57fe5b906020019060200201819052506040805190810160405280601581526020016000805160206123f383398151915281525082600181518110151561141e57fe5b90602001906020020181905250846080015160405160200161144091906121f1565b60405160208183030381529060405281600181518110151561145e57fe5b906020019060200201819052506040805190810160405280601481526020017f746f6b656e4163636f756e743a616464726573730000000000000000000000008152508260028151811015156114b057fe5b906020019060200201819052508460c001516040516020018082600160a060020a0316600160a060020a03166c0100000000000000000000000002815260140191505060405160208183030381529060405281600281518110151561151157fe5b906020019060200201819052506040805190810160405280601381526020017f757365724163636f756e743a616464726573730000000000000000000000000081525082600381518110151561156357fe5b906020019060200201819052508460e001516040516020018082600160a060020a0316600160a060020a03166c010000000000000000000000000281526014019150506040516020818303038152906040528160038151811015156115c457fe5b906020019060200201819052506040805190810160405280600d81526020017f657874446174613a62797465730000000000000000000000000000000000000081525082600481518110151561161657fe5b6020908102909101015260a085015181518290600490811061163457fe5b602090810290910181019190915260408087015191870151875191519091907f4858e561d5a7ef18c29b934321d532519ca330e6141f44d4650c35d4481b43ed90610fed90879087906121cc565b6000808383111561169257600080fd5b5050808203805b5092915050565b60008181526020839052604081205460ff16908160018111156116bf57fe5b146116df5760405160e560020a62461bcd02815260040161020d90612228565b50600090815260209190915260409020805460ff19166001179055565b6014015190565b6000808315156117165760009150611699565b5082820282848281151561172657fe5b041461173157600080fd5b9392505050565b60008080831161174757600080fd5b828481151561175257fe5b04949350505050565b60006117318235612397565b6000601f8201831361177857600080fd5b813561178b61178682612344565b61231d565b915081818352602084019350602081019050838560208402820111156117b057600080fd5b60005b838110156117dc57816117c688826117e6565b84525060209283019291909101906001016117b3565b5050505092915050565b600061173182356123a3565b6000601f8201831361180357600080fd5b813561181161178682612365565b9150808252602083016020830185838301111561182d57600080fd5b6118388382846123ac565b50505092915050565b6000601f8201831361185257600080fd5b815161186061178682612365565b9150808252602083016020830185838301111561187c57600080fd5b6118388382846123b8565b6000610100828403121561189a57600080fd5b6118a561010061231d565b905060006118b384846117e6565b82525060206118c4848483016117e6565b60208301525060406118d8848285016117e6565b604083015250606082013567ffffffffffffffff8111156118f857600080fd5b61190484828501611767565b606083015250608082013567ffffffffffffffff81111561192457600080fd5b61193084828501611767565b60808301525060a082013567ffffffffffffffff81111561195057600080fd5b61195c848285016117f2565b60a08301525060c06119708482850161175b565b60c08301525060e06119848482850161175b565b60e08301525092915050565b600060e082840312156119a257600080fd5b6119ac60e061231d565b905060006119ba84846117e6565b82525060206119cb848483016117e6565b60208301525060406119df848285016117e6565b604083015250606082013567ffffffffffffffff8111156119ff57600080fd5b611a0b84828501611767565b606083015250608082013567ffffffffffffffff811115611a2b57600080fd5b611a3784828501611767565b60808301525060a0611a4b8482850161175b565b60a08301525060c0611a5f8482850161175b565b60c08301525092915050565b60006101208284031215611a7e57600080fd5b611a8961012061231d565b90506000611a9784846117e6565b8252506020611aa8848483016117e6565b602083015250604082013567ffffffffffffffff811115611ac857600080fd5b611ad484828501611767565b604083015250606082013567ffffffffffffffff811115611af457600080fd5b611b0084828501611767565b6060830152506080611b14848285016117e6565b60808301525060a0611b28848285016117e6565b60a08301525060c0611b3c8482850161175b565b60c08301525060e082013567ffffffffffffffff811115611b5c57600080fd5b611b68848285016117f2565b60e083015250610100611b7d8482850161175b565b6101008301525092915050565b60006101008284031215611b9d57600080fd5b611ba861010061231d565b90506000611bb684846117e6565b8252506020611bc7848483016117e6565b602083015250604082013567ffffffffffffffff811115611be757600080fd5b611bf384828501611767565b604083015250606082013567ffffffffffffffff811115611c1357600080fd5b611c1f84828501611767565b6060830152506080611c33848285016117e6565b60808301525060a0611c47848285016117e6565b60a08301525060c082013567ffffffffffffffff811115611c6757600080fd5b611970848285016117f2565b600061173182516123a3565b600061173182516123a6565b60008060408385031215611c9e57600080fd5b6000611caa85856117e6565b925050602083013567ffffffffffffffff811115611cc757600080fd5b611cd385828601611887565b9150509250929050565b60008060408385031215611cf057600080fd5b6000611cfc85856117e6565b925050602083013567ffffffffffffffff811115611d1957600080fd5b611cd385828601611990565b60008060408385031215611d3857600080fd5b6000611d4485856117e6565b925050602083013567ffffffffffffffff811115611d6157600080fd5b611cd385828601611a6b565b60008060408385031215611d8057600080fd5b6000611d8c85856117e6565b925050602083013567ffffffffffffffff811115611da957600080fd5b611cd385828601611b8a565b600080600080600060a08688031215611dcd57600080fd5b6000611dd988886117e6565b9550506020611dea888289016117e6565b9450506040611dfb888289016117e6565b9350506060611e0c888289016117e6565b9250506080611e1d888289016117e6565b9150509295509295909350565b60008060008060808587031215611e4057600080fd5b6000611e4c8787611c73565b945050602085015167ffffffffffffffff811115611e6957600080fd5b611e7587828801611841565b9350506040611e8687828801611c73565b925050606085015167ffffffffffffffff811115611ea357600080fd5b611eaf87828801611841565b91505092959194509250565b600060208284031215611ecd57600080fd5b6000611ed98484611c7f565b949350505050565b611eea81612397565b82525050565b6000611efb82612393565b80845260208401935083602082028501611f148561238d565b60005b84811015611f4b578383038852611f2f838351612009565b9250611f3a8261238d565b602098909801979150600101611f17565b50909695505050505050565b6000611f6282612393565b80845260208401935083602082028501611f7b8561238d565b60005b84811015611f4b578383038852611f96838351612009565b9250611fa18261238d565b602098909801979150600101611f7e565b6000611fbd82612393565b808452602084019350611fcf8361238d565b60005b82811015611fff57611fe5868351612108565b611fee8261238d565b602096909601959150600101611fd2565b5093949350505050565b600061201482612393565b8084526120288160208601602086016123b8565b612031816123e8565b9093016020019392505050565b601281527f496e76616c696420746f6b656e20706169720000000000000000000000000000602082015260400190565b601481527f546f6b656e20646f6573206e6f74206578697374000000000000000000000000602082015260400190565b601281527f5261706964697479207478206578697374730000000000000000000000000000602082015260400190565b601081527f496e76616c6964204e4654207479706500000000000000000000000000000000602082015260400190565b6000815260200190565b611eea816123a3565b60a0810161211f8287611ee1565b61212c6020830186611ee1565b818103604083015261213e8185611fb2565b905081810360608301526121528184611fb2565b90508181036080830152612165816120fe565b9695505050505050565b6080810161217d8286611ee1565b61218a6020830185611ee1565b6121976040830184612108565b81810360608301526121a8816120fe565b95945050505050565b604081016121bf8285611ee1565b6117316020830184612108565b604080825281016121dd8185611f57565b90508181036020830152611ed98184611ef0565b602080825281016117318184611fb2565b602080825281016122128161203e565b92915050565b602080825281016122128161206e565b602080825281016122128161209e565b60208082528101612212816120ce565b602081016122128284612108565b60a081016122648288612108565b6122716020830187611ee1565b61227e6040830186611ee1565b81810360608301526122908185611fb2565b905081810360808301526122a48184611fb2565b979650505050505050565b60c081016122bd8289612108565b6122ca6020830188611ee1565b6122d76040830187611ee1565b81810360608301526122e98186611fb2565b905081810360808301526122fd8185611fb2565b905081810360a08301526123118184612009565b98975050505050505050565b60405181810167ffffffffffffffff8111828210171561233c57600080fd5b604052919050565b600067ffffffffffffffff82111561235b57600080fd5b5060209081020190565b600067ffffffffffffffff82111561237c57600080fd5b506020601f91909101601f19160190565b60200190565b5190565b600160a060020a031690565b90565b60ff1690565b82818337506000910152565b60005b838110156123d35781810151838201526020016123bb565b838111156123e2576000848401525b50505050565b601f01601f1916905600746f6b656e56616c7565733a75696e743235365b5d0000000000000000000000746f6b656e4944733a75696e743235365b5d0000000000000000000000000000a265627a7a72305820dbfc9fe16af05d7558f205df2ab532cac97419575e47a2b49497cf5dd09c97176c6578706572696d656e74616cf50037
Deployed ByteCode
0x7397ce40aeb600f3a1e2cac32208fc58c937676688301460806040526004361061006a5763ffffffff60e060020a60003504166306528fbc811461006f5780633b73799114610091578063972c12ea146100b1578063c921ea93146100d1578063dbd9a2b5146100fb575b600080fd5b81801561007b57600080fd5b5061008f61008a366004611d25565b61011b565b005b81801561009d57600080fd5b5061008f6100ac366004611d6d565b6105c6565b8180156100bd57600080fd5b5061008f6100cc366004611cdd565b610b07565b6100e46100df366004611db5565b610ffd565b6040516100f29291906121b1565b60405180910390f35b81801561010757600080fd5b5061008f610116366004611c8b565b6111aa565b60008060008060006060806101448989602001518a60a001518b608001518c6040015151610ffd565b60058b015460208b015160405160e060020a6375d2e27d028152939a50919850600160a060020a0316965086916375d2e27d9161018391600401612248565b602060405180830381600087803b15801561019d57600080fd5b505af11580156101b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506101d59190810190611ebb565b935060ff8416600114806101ec575060ff84166002145b15156102165760405160e560020a62461bcd02815260040161020d90612238565b60405180910390fd5b84600160a060020a0316632859c5808560ff1689338c604001518d606001516040518663ffffffff1660e060020a028152600401610258959493929190612256565b600060405180830381600087803b15801561027257600080fd5b505af1158015610286573d6000803e3d6000fd5b5050505060008611156102d357876101000151600160a060020a03166108fc879081150290604051600060405180830381858888f193505050501580156102d1573d6000803e3d6000fd5b505b6102e3348763ffffffff61168216565b9250821561031a57604051339084156108fc029085906000818181858888f19350505050158015610318573d6000803e3d6000fd5b505b60408051600480825260a0820190925290816020015b606081526020019060019003908161033057505060408051600480825260a08201909252919350602082015b606081526020019060019003908161035c5790505090506040805190810160405280601281526020016000805160206124138339815191528152508260008151811015156103a657fe5b9060200190602002018190525087604001516040516020016103c891906121f1565b6040516020818303038152906040528160008151811015156103e657fe5b906020019060200201819052506040805190810160405280601581526020016000805160206123f383398151915281525082600181518110151561042657fe5b90602001906020020181905250876060015160405160200161044891906121f1565b60405160208183030381529060405281600181518110151561046657fe5b906020019060200201819052506040805190810160405280601181526020017f757365724163636f756e743a62797465730000000000000000000000000000008152508260028151811015156104b857fe5b6020908102909101015260e08801518151829060029081106104d657fe5b906020019060200201819052506040805190810160405280601381526020017f636f6e74726163744665653a75696e743235360000000000000000000000000081525082600381518110151561052857fe5b602090810290910181019190915260408051808301899052815180820390930183528101905281518290600390811061055d57fe5b9060200190602002018190525086600160a060020a031688602001518960000151600019167f988781dff960cf5a144a15c9b0c4d1346196e415e64ea7ebd609c6ac0559bbbb85856040516105b39291906121cc565b60405180910390a4505050505050505050565b60008060008060006060806105ef8989602001518a60a001518b608001518c6040015151610ffd565b9097509550600086111561063c578760e00151600160a060020a03166108fc879081150290604051600060405180830381858888f1935050505015801561063a573d6000803e3d6000fd5b505b61064c348763ffffffff61168216565b60058a015460208a015160405160e060020a6375d2e27d028152929750600160a060020a03909116916375d2e27d9161068791600401612248565b602060405180830381600087803b1580156106a157600080fd5b505af11580156106b5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506106d99190810190611ebb565b935060ff84166001141561078957600092505b8760400151518310156107845786600160a060020a031663b88d4fde33308b604001518781518110151561071c57fe5b906020019060200201516040518463ffffffff1660e060020a0281526004016107479392919061216f565b600060405180830381600087803b15801561076157600080fd5b505af1158015610775573d6000803e3d6000fd5b505050508260010192506106ec565b610839565b60ff84166002141561081e5760408089015160608a015191517f2eb2c2d6000000000000000000000000000000000000000000000000000000008152600160a060020a038a1692632eb2c2d6926107e7923392309291600401612111565b600060405180830381600087803b15801561080157600080fd5b505af1158015610815573d6000803e3d6000fd5b50505050610839565b60405160e560020a62461bcd02815260040161020d90612238565b841561086e57604051339086156108fc029087906000818181858888f1935050505015801561086c573d6000803e3d6000fd5b505b60408051600480825260a0820190925290816020015b606081526020019060019003908161088457505060408051600480825260a08201909252919350602082015b60608152602001906001900390816108b05790505090506040805190810160405280601281526020016000805160206124138339815191528152508260008151811015156108fa57fe5b90602001906020020181905250876040015160405160200161091c91906121f1565b60405160208183030381529060405281600081518110151561093a57fe5b906020019060200201819052506040805190810160405280601581526020016000805160206123f383398151915281525082600181518110151561097a57fe5b90602001906020020181905250876060015160405160200161099c91906121f1565b6040516020818303038152906040528160018151811015156109ba57fe5b906020019060200201819052506040805190810160405280601181526020017f757365724163636f756e743a6279746573000000000000000000000000000000815250826002815181101515610a0c57fe5b6020908102909101015260c0880151815182906002908110610a2a57fe5b906020019060200201819052506040805190810160405280601381526020017f636f6e74726163744665653a75696e7432353600000000000000000000000000815250826003815181101515610a7c57fe5b6020908102909101810191909152604080518083018990528151808203909301835281019052815182906003908110610ab157fe5b9060200190602002018190525086600160a060020a031688602001518960000151600019167f62605e96f2f9cd2d124a846c58ea7d9982610ba45d052c99b14900c37a71868385856040516105b39291906121cc565b600080606080610b278560000151876003016116a090919063ffffffff16565b6005860154604080870151905160e060020a6375d2e27d028152600160a060020a03909216916375d2e27d91610b5f91600401612248565b602060405180830381600087803b158015610b7957600080fd5b505af1158015610b8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610bb19190810190611ebb565b935060ff841660011415610c6957600092505b846060015151831015610c64578460a00151600160a060020a031663b88d4fde308760c00151886060015187815181101515610bfc57fe5b906020019060200201516040518463ffffffff1660e060020a028152600401610c279392919061216f565b600060405180830381600087803b158015610c4157600080fd5b505af1158015610c55573d6000803e3d6000fd5b50505050826001019250610bc4565b610ced565b60ff84166002141561081e578460a00151600160a060020a0316632eb2c2d6308760c00151886060015189608001516040518563ffffffff1660e060020a028152600401610cba9493929190612111565b600060405180830381600087803b158015610cd457600080fd5b505af1158015610ce8573d6000803e3d6000fd5b505050505b60408051600480825260a0820190925290816020015b6060815260200190600190039081610d0357505060408051600480825260a08201909252919350602082015b6060815260200190600190039081610d2f579050509050604080519081016040528060128152602001600080516020612413833981519152815250826000815181101515610d7957fe5b906020019060200201819052508460600151604051602001610d9b91906121f1565b604051602081830303815290604052816000815181101515610db957fe5b906020019060200201819052506040805190810160405280601581526020016000805160206123f3833981519152815250826001815181101515610df957fe5b906020019060200201819052508460800151604051602001610e1b91906121f1565b604051602081830303815290604052816001815181101515610e3957fe5b906020019060200201819052506040805190810160405280601481526020017f746f6b656e4163636f756e743a61646472657373000000000000000000000000815250826002815181101515610e8b57fe5b906020019060200201819052508460a001516040516020018082600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401915050604051602081830303815290604052816002815181101515610eec57fe5b906020019060200201819052506040805190810160405280601381526020017f757365724163636f756e743a6164647265737300000000000000000000000000815250826003815181101515610f3e57fe5b906020019060200201819052508460c001516040516020018082600160a060020a0316600160a060020a03166c01000000000000000000000000028152601401915050604051602081830303815290604052816003815181101515610f9f57fe5b602090810290910181019190915260408087015191870151875191519091907fba98d99dde5738beb90acb291bb9b140abeb4d2f93bd94d7dade6b9d9173bc7390610fed90879087906121cc565b60405180910390a4505050505050565b60008060008060006060806000808d60050160009054906101000a9004600160a060020a0316965086600160a060020a031663b90732768e6040518263ffffffff1660e060020a0281526004016110549190612248565b600060405180830381600087803b15801561106e57600080fd5b505af1158015611082573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526110aa9190810190611e2a565b9298509650945092508515156110d55760405160e560020a62461bcd02815260040161020d90612218565b8b9150858b141561111657811515611106576000868152600a8f016020908152604080832088845290915290205491505b61110f846116fc565b9050611168565b848b141561114d57811515611144576000858152600a8f016020908152604080832089845290915290205491505b61110f836116fc565b60405160e560020a62461bcd02815260040161020d90612202565b600082111561119857611195600a6111898460098e0163ffffffff61170316565b9063ffffffff61173816565b91505b9d909c509a5050505050505050505050565b6000806060806111ca8560000151876003016116a090919063ffffffff16565b6005860154604080870151905160e060020a6375d2e27d028152600160a060020a03909216955085916375d2e27d9161120591600401612248565b602060405180830381600087803b15801561121f57600080fd5b505af1158015611233573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112579190810190611ebb565b925060ff83166001148061126e575060ff83166002145b151561128f5760405160e560020a62461bcd02815260040161020d90612238565b83600160a060020a0316639947f9328460ff168760c001518860e0015189606001518a608001518b60a001516040518763ffffffff1660e060020a0281526004016112df969594939291906122af565b600060405180830381600087803b1580156112f957600080fd5b505af115801561130d573d6000803e3d6000fd5b505060408051600580825260c0820190925292509050816020015b606081526020019060019003908161132857505060408051600580825260c08201909252919350602082015b606081526020019060019003908161135457905050905060408051908101604052806012815260200160008051602061241383398151915281525082600081518110151561139e57fe5b9060200190602002018190525084606001516040516020016113c091906121f1565b6040516020818303038152906040528160008151811015156113de57fe5b906020019060200201819052506040805190810160405280601581526020016000805160206123f383398151915281525082600181518110151561141e57fe5b90602001906020020181905250846080015160405160200161144091906121f1565b60405160208183030381529060405281600181518110151561145e57fe5b906020019060200201819052506040805190810160405280601481526020017f746f6b656e4163636f756e743a616464726573730000000000000000000000008152508260028151811015156114b057fe5b906020019060200201819052508460c001516040516020018082600160a060020a0316600160a060020a03166c0100000000000000000000000002815260140191505060405160208183030381529060405281600281518110151561151157fe5b906020019060200201819052506040805190810160405280601381526020017f757365724163636f756e743a616464726573730000000000000000000000000081525082600381518110151561156357fe5b906020019060200201819052508460e001516040516020018082600160a060020a0316600160a060020a03166c010000000000000000000000000281526014019150506040516020818303038152906040528160038151811015156115c457fe5b906020019060200201819052506040805190810160405280600d81526020017f657874446174613a62797465730000000000000000000000000000000000000081525082600481518110151561161657fe5b6020908102909101015260a085015181518290600490811061163457fe5b602090810290910181019190915260408087015191870151875191519091907f4858e561d5a7ef18c29b934321d532519ca330e6141f44d4650c35d4481b43ed90610fed90879087906121cc565b6000808383111561169257600080fd5b5050808203805b5092915050565b60008181526020839052604081205460ff16908160018111156116bf57fe5b146116df5760405160e560020a62461bcd02815260040161020d90612228565b50600090815260209190915260409020805460ff19166001179055565b6014015190565b6000808315156117165760009150611699565b5082820282848281151561172657fe5b041461173157600080fd5b9392505050565b60008080831161174757600080fd5b828481151561175257fe5b04949350505050565b60006117318235612397565b6000601f8201831361177857600080fd5b813561178b61178682612344565b61231d565b915081818352602084019350602081019050838560208402820111156117b057600080fd5b60005b838110156117dc57816117c688826117e6565b84525060209283019291909101906001016117b3565b5050505092915050565b600061173182356123a3565b6000601f8201831361180357600080fd5b813561181161178682612365565b9150808252602083016020830185838301111561182d57600080fd5b6118388382846123ac565b50505092915050565b6000601f8201831361185257600080fd5b815161186061178682612365565b9150808252602083016020830185838301111561187c57600080fd5b6118388382846123b8565b6000610100828403121561189a57600080fd5b6118a561010061231d565b905060006118b384846117e6565b82525060206118c4848483016117e6565b60208301525060406118d8848285016117e6565b604083015250606082013567ffffffffffffffff8111156118f857600080fd5b61190484828501611767565b606083015250608082013567ffffffffffffffff81111561192457600080fd5b61193084828501611767565b60808301525060a082013567ffffffffffffffff81111561195057600080fd5b61195c848285016117f2565b60a08301525060c06119708482850161175b565b60c08301525060e06119848482850161175b565b60e08301525092915050565b600060e082840312156119a257600080fd5b6119ac60e061231d565b905060006119ba84846117e6565b82525060206119cb848483016117e6565b60208301525060406119df848285016117e6565b604083015250606082013567ffffffffffffffff8111156119ff57600080fd5b611a0b84828501611767565b606083015250608082013567ffffffffffffffff811115611a2b57600080fd5b611a3784828501611767565b60808301525060a0611a4b8482850161175b565b60a08301525060c0611a5f8482850161175b565b60c08301525092915050565b60006101208284031215611a7e57600080fd5b611a8961012061231d565b90506000611a9784846117e6565b8252506020611aa8848483016117e6565b602083015250604082013567ffffffffffffffff811115611ac857600080fd5b611ad484828501611767565b604083015250606082013567ffffffffffffffff811115611af457600080fd5b611b0084828501611767565b6060830152506080611b14848285016117e6565b60808301525060a0611b28848285016117e6565b60a08301525060c0611b3c8482850161175b565b60c08301525060e082013567ffffffffffffffff811115611b5c57600080fd5b611b68848285016117f2565b60e083015250610100611b7d8482850161175b565b6101008301525092915050565b60006101008284031215611b9d57600080fd5b611ba861010061231d565b90506000611bb684846117e6565b8252506020611bc7848483016117e6565b602083015250604082013567ffffffffffffffff811115611be757600080fd5b611bf384828501611767565b604083015250606082013567ffffffffffffffff811115611c1357600080fd5b611c1f84828501611767565b6060830152506080611c33848285016117e6565b60808301525060a0611c47848285016117e6565b60a08301525060c082013567ffffffffffffffff811115611c6757600080fd5b611970848285016117f2565b600061173182516123a3565b600061173182516123a6565b60008060408385031215611c9e57600080fd5b6000611caa85856117e6565b925050602083013567ffffffffffffffff811115611cc757600080fd5b611cd385828601611887565b9150509250929050565b60008060408385031215611cf057600080fd5b6000611cfc85856117e6565b925050602083013567ffffffffffffffff811115611d1957600080fd5b611cd385828601611990565b60008060408385031215611d3857600080fd5b6000611d4485856117e6565b925050602083013567ffffffffffffffff811115611d6157600080fd5b611cd385828601611a6b565b60008060408385031215611d8057600080fd5b6000611d8c85856117e6565b925050602083013567ffffffffffffffff811115611da957600080fd5b611cd385828601611b8a565b600080600080600060a08688031215611dcd57600080fd5b6000611dd988886117e6565b9550506020611dea888289016117e6565b9450506040611dfb888289016117e6565b9350506060611e0c888289016117e6565b9250506080611e1d888289016117e6565b9150509295509295909350565b60008060008060808587031215611e4057600080fd5b6000611e4c8787611c73565b945050602085015167ffffffffffffffff811115611e6957600080fd5b611e7587828801611841565b9350506040611e8687828801611c73565b925050606085015167ffffffffffffffff811115611ea357600080fd5b611eaf87828801611841565b91505092959194509250565b600060208284031215611ecd57600080fd5b6000611ed98484611c7f565b949350505050565b611eea81612397565b82525050565b6000611efb82612393565b80845260208401935083602082028501611f148561238d565b60005b84811015611f4b578383038852611f2f838351612009565b9250611f3a8261238d565b602098909801979150600101611f17565b50909695505050505050565b6000611f6282612393565b80845260208401935083602082028501611f7b8561238d565b60005b84811015611f4b578383038852611f96838351612009565b9250611fa18261238d565b602098909801979150600101611f7e565b6000611fbd82612393565b808452602084019350611fcf8361238d565b60005b82811015611fff57611fe5868351612108565b611fee8261238d565b602096909601959150600101611fd2565b5093949350505050565b600061201482612393565b8084526120288160208601602086016123b8565b612031816123e8565b9093016020019392505050565b601281527f496e76616c696420746f6b656e20706169720000000000000000000000000000602082015260400190565b601481527f546f6b656e20646f6573206e6f74206578697374000000000000000000000000602082015260400190565b601281527f5261706964697479207478206578697374730000000000000000000000000000602082015260400190565b601081527f496e76616c6964204e4654207479706500000000000000000000000000000000602082015260400190565b6000815260200190565b611eea816123a3565b60a0810161211f8287611ee1565b61212c6020830186611ee1565b818103604083015261213e8185611fb2565b905081810360608301526121528184611fb2565b90508181036080830152612165816120fe565b9695505050505050565b6080810161217d8286611ee1565b61218a6020830185611ee1565b6121976040830184612108565b81810360608301526121a8816120fe565b95945050505050565b604081016121bf8285611ee1565b6117316020830184612108565b604080825281016121dd8185611f57565b90508181036020830152611ed98184611ef0565b602080825281016117318184611fb2565b602080825281016122128161203e565b92915050565b602080825281016122128161206e565b602080825281016122128161209e565b60208082528101612212816120ce565b602081016122128284612108565b60a081016122648288612108565b6122716020830187611ee1565b61227e6040830186611ee1565b81810360608301526122908185611fb2565b905081810360808301526122a48184611fb2565b979650505050505050565b60c081016122bd8289612108565b6122ca6020830188611ee1565b6122d76040830187611ee1565b81810360608301526122e98186611fb2565b905081810360808301526122fd8185611fb2565b905081810360a08301526123118184612009565b98975050505050505050565b60405181810167ffffffffffffffff8111828210171561233c57600080fd5b604052919050565b600067ffffffffffffffff82111561235b57600080fd5b5060209081020190565b600067ffffffffffffffff82111561237c57600080fd5b506020601f91909101601f19160190565b60200190565b5190565b600160a060020a031690565b90565b60ff1690565b82818337506000910152565b60005b838110156123d35781810151838201526020016123bb565b838111156123e2576000848401525b50505050565b601f01601f1916905600746f6b656e56616c7565733a75696e743235365b5d0000000000000000000000746f6b656e4944733a75696e743235365b5d0000000000000000000000000000a265627a7a72305820dbfc9fe16af05d7558f205df2ab532cac97419575e47a2b49497cf5dd09c97176c6578706572696d656e74616cf50037