github.com/inklabsfoundation/inkchain@v0.17.1-0.20181025012015-c3cef8062f19/examples/xc/eth/contracts/XC.sol (about) 1 pragma solidity ^0.4.19; 2 3 import "./XCInterface.sol"; 4 5 import "./Token.sol"; 6 7 import "./XCPlugin.sol"; 8 9 import "./SafeMath.sol"; 10 11 contract XC is XCInterface { 12 13 /** 14 * Contract Administrator 15 * @field status Contract external service status. 16 * @field platformName Current contract platform name. 17 * @field account Current contract administrator. 18 */ 19 struct Admin { 20 21 uint8 status; 22 23 bytes32 platformName; 24 25 address account; 26 } 27 28 Admin private admin; 29 30 uint public lockBalance; 31 32 Token private token; 33 34 XCPlugin private xcPlugin; 35 36 bytes2 private compareSymbol; 37 38 event Lock(bytes32 toPlatform, address toAccount, string value); 39 40 event Unlock(string txid, bytes32 fromPlatform, address fromAccount, string value); 41 42 function XC() public payable { 43 //TODO 44 bytes32 name = "ETH"; 45 //TODO 46 compareSymbol = "+="; 47 48 //TODO totalSupply = 10 * (10 ** 8) * (10 ** 9); 49 lockBalance = 10 * (10 ** 8) * (10 ** 9); 50 51 admin = Admin(0, name, msg.sender); 52 } 53 54 function setStatus(uint8 status) external { 55 56 require(admin.account == msg.sender); 57 58 require(status == 0 || status == 1 || status == 2 || status == 3); 59 60 if (admin.status != status) { 61 62 admin.status = status; 63 } 64 } 65 66 function getStatus() external view returns (uint8) { 67 68 return admin.status; 69 } 70 71 function setPlatformName(bytes32 platformName) external { 72 73 require(admin.account == msg.sender); 74 75 if (admin.platformName != platformName) { 76 77 admin.platformName = platformName; 78 } 79 } 80 81 function getPlatformName() external view returns (bytes32) { 82 83 return admin.platformName; 84 } 85 86 function setAdmin(address account) external { 87 88 require(account != address(0)); 89 90 require(admin.account == msg.sender); 91 92 if (admin.account != account) { 93 94 admin.account = account; 95 } 96 } 97 98 function getAdmin() external view returns (address) { 99 100 return admin.account; 101 } 102 103 function setToken(address account) external { 104 105 require(admin.account == msg.sender); 106 107 if (token != account) { 108 109 token = Token(account); 110 } 111 } 112 113 function getToken() external view returns (address) { 114 115 return token; 116 } 117 118 function setXCPlugin(address account) external { 119 120 require(admin.account == msg.sender); 121 122 if (xcPlugin != account) { 123 124 xcPlugin = XCPlugin(account); 125 } 126 } 127 128 function getXCPlugin() external view returns (address) { 129 130 return xcPlugin; 131 } 132 133 function setCompare(bytes2 symbol) external { 134 135 require(admin.account == msg.sender); 136 137 require(symbol == "+=" || symbol == "-="); 138 139 if (compareSymbol != symbol) { 140 141 compareSymbol = symbol; 142 } 143 } 144 145 function getCompare() external view returns (bytes2){ 146 147 require(admin.account == msg.sender); 148 149 return compareSymbol; 150 } 151 152 function lock(bytes32 toPlatform, address toAccount, uint value) external payable { 153 154 require(admin.status == 2 || admin.status == 3); 155 156 require(xcPlugin.getStatus()); 157 158 require(xcPlugin.existPlatform(toPlatform)); 159 160 require(toAccount != address(0)); 161 162 // require(token.totalSupply >= value && value > 0); 163 require(value > 0); 164 165 //get user approve the contract quota 166 uint allowance = token.allowance(msg.sender, this); 167 168 require(toCompare(allowance, value)); 169 170 //do transferFrom 171 bool success = token.transferFrom(msg.sender, this, value); 172 173 require(success); 174 175 //record the amount of local platform turn out 176 lockBalance = SafeMath.add(lockBalance, value); 177 // require(token.totalSupply >= lockBalance); 178 179 //trigger Lock 180 emit Lock(toPlatform, toAccount, uintAppendToString(value)); 181 } 182 183 //turn in 184 function unlock(string txid, bytes32 fromPlatform, address fromAccount, address toAccount, uint value) external payable { 185 186 require(admin.status == 1 || admin.status == 3); 187 188 require(xcPlugin.getStatus()); 189 190 require(xcPlugin.existPlatform(fromPlatform)); 191 192 require(toAccount != address(0)); 193 194 // require(token.totalSupply >= value && value > 0); 195 require(value > 0); 196 197 //verify args by function xcPlugin.verify 198 bool complete; 199 200 bool verify; 201 202 (complete, verify) = xcPlugin.verifyProposal(fromPlatform, fromAccount, toAccount, value, txid); 203 204 require(verify && !complete); 205 206 //get contracts balance 207 uint balance = token.balanceOf(this); 208 209 //validate the balance of contract were less than amount 210 require(toCompare(balance, value)); 211 212 require(token.transfer(toAccount, value)); 213 214 require(xcPlugin.commitProposal(fromPlatform, txid)); 215 216 lockBalance = SafeMath.sub(lockBalance, value); 217 218 emit Unlock(txid, fromPlatform, fromAccount, uintAppendToString(value)); 219 } 220 221 function withdraw(address account, uint value) external payable { 222 223 require(admin.account == msg.sender); 224 225 require(account != address(0)); 226 227 // require(token.totalSupply >= value && value > 0); 228 require(value > 0); 229 230 uint balance = token.balanceOf(this); 231 232 require(toCompare(SafeMath.sub(balance, lockBalance), value)); 233 234 bool success = token.transfer(account, value); 235 236 require(success); 237 } 238 239 function transfer(address account, uint value) external payable { 240 241 require(admin.account == msg.sender); 242 243 require(account != address(0)); 244 245 require(value > 0 && value >= this.balance); 246 247 this.transfer(account, value); 248 } 249 250 /** 251 * ###################### 252 * # private function # 253 * ###################### 254 */ 255 256 function toCompare(uint f, uint s) internal view returns (bool) { 257 258 if (compareSymbol == "-=") { 259 260 return f > s; 261 } else if (compareSymbol == "+=") { 262 263 return f >= s; 264 } else { 265 266 return false; 267 } 268 } 269 270 function uintAppendToString(uint v) pure internal returns (string){ 271 272 uint length = 100; 273 274 bytes memory reversed = new bytes(length); 275 276 bytes16 sixTeenStr = "0123456789abcdef"; 277 278 uint i = 0; 279 280 while (v != 0) { 281 282 uint remainder = v % 16; 283 284 v = v / 16; 285 286 reversed[i++] = byte(sixTeenStr[remainder]); 287 } 288 289 string memory bytesList = "0000000000000000000000000000000000000000000000000000000000000000"; 290 291 bytes memory str = bytes(bytesList); 292 293 for (uint j = 0; j < i; j++) { 294 295 str[str.length - j - 1] = reversed[i - j - 1]; 296 } 297 298 return string(str); 299 } 300 }