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  }