ETH Price: $2,426.63 (-4.99%)

Transaction Decoder

Block:
6512396 at Oct-14-2018 08:08:57 AM +UTC
Transaction Fee:
0.00057903 ETH $1.41
Gas Used:
289,515 Gas / 2 Gwei

Emitted Events:

11 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.0x0f55a3683632a559f1b01a716a8714cdce39fe436680435048b966ad2eab20b5( 0x0f55a3683632a559f1b01a716a8714cdce39fe436680435048b966ad2eab20b5, 0x0000000000000000000000007ad295b46744c9d5e108f7db2ffd74f5977933d5, 000000000000000000000000f9d97698447b9d543dc25b5c71646691e45280bf, 00000000000000000000000000000000000000000000124464a7ae0369a91260 )
12 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.0x0f55a3683632a559f1b01a716a8714cdce39fe436680435048b966ad2eab20b5( 0x0f55a3683632a559f1b01a716a8714cdce39fe436680435048b966ad2eab20b5, 0x000000000000000000000000cf1f24d0ccdc1bcee21ce70a7347381e3eeb5637, 000000000000000000000000f9d97698447b9d543dc25b5c71646691e45280bf, 000000000000000000000000000000000000000000002659fe265e1854180000 )
13 0xa40cb2374b41d317f1618535c9e868db8338b639.0x00d4babaea5e51224a883189c906b7c4e416fbfe0f1e432da219ed132c83c112( 0x00d4babaea5e51224a883189c906b7c4e416fbfe0f1e432da219ed132c83c112, 000000000000000000000000f9d97698447b9d543dc25b5c71646691e45280bf, 0000000000000000000000007ad295b46744c9d5e108f7db2ffd74f5977933d5 )
14 0xa40cb2374b41d317f1618535c9e868db8338b639.0x2ff3e81387f2d7e869305dafe055da8420352467e2002e9bf8e8148676b4f78e( 0x2ff3e81387f2d7e869305dafe055da8420352467e2002e9bf8e8148676b4f78e, 000000000000000000000000f9d97698447b9d543dc25b5c71646691e45280bf, 0000000000000000000000007ad295b46744c9d5e108f7db2ffd74f5977933d5, 0000000000000000000000000000000000000000000000000000000000000002 )
15 0x0b226f16327e21ffdd93782bb776e81e833b3a1f.0xa308990dd75b95c0eac16528d7b5e498162c1ef340a9861030a52670c23ba4b2( 0xa308990dd75b95c0eac16528d7b5e498162c1ef340a9861030a52670c23ba4b2, 000000000000000000000000a40cb2374b41d317f1618535c9e868db8338b639, 0000000000000000000000007ad295b46744c9d5e108f7db2ffd74f5977933d5, 0000000000000000000000000000000000000000000012d5ed9616c8d9dcbf34, 000000000000000000000000000000000000000000000000000000005bc2f999 )
16 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.0x39d2a73d35776663391b17495b1604c7f03a3ea88e0eaf24f5a9ab3bdb3205df( 0x39d2a73d35776663391b17495b1604c7f03a3ea88e0eaf24f5a9ab3bdb3205df, 000000000000000000000000f9d97698447b9d543dc25b5c71646691e45280bf, 00000000000000000000000000000000000000000081bd6e15d878c092dc5c84 )
17 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.0x0f55a3683632a559f1b01a716a8714cdce39fe436680435048b966ad2eab20b5( 0x0f55a3683632a559f1b01a716a8714cdce39fe436680435048b966ad2eab20b5, 0x0000000000000000000000007ad295b46744c9d5e108f7db2ffd74f5977933d5, 000000000000000000000000f9d97698447b9d543dc25b5c71646691e45280bf, 0000000000000000000000000000000000000000000012d5ed9616c8d9dcbf34 )
18 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.0x64e5f79d157518d8cf942b1f32eeeb7d766a32689b49c1cd671cca787ca6f752( 0x64e5f79d157518d8cf942b1f32eeeb7d766a32689b49c1cd671cca787ca6f752, 00f9d97698447b9d543dc25b5c71646691e45280bf0000000000000000000000, 0000000000000000000000000000000000000000600000000000000000000000, 0000000000000000000081bd6e15d878c092dc5c840000000000000000000000, 00000000000000000000000000000000000000000b746f74616c4d696e746564 )
19 0xa40cb2374b41d317f1618535c9e868db8338b639.0x00d4babaea5e51224a883189c906b7c4e416fbfe0f1e432da219ed132c83c112( 0x00d4babaea5e51224a883189c906b7c4e416fbfe0f1e432da219ed132c83c112, 000000000000000000000000f9d97698447b9d543dc25b5c71646691e45280bf, 0000000000000000000000007ad295b46744c9d5e108f7db2ffd74f5977933d5 )
20 0xa40cb2374b41d317f1618535c9e868db8338b639.0x2ff3e81387f2d7e869305dafe055da8420352467e2002e9bf8e8148676b4f78e( 0x2ff3e81387f2d7e869305dafe055da8420352467e2002e9bf8e8148676b4f78e, 000000000000000000000000f9d97698447b9d543dc25b5c71646691e45280bf, 0000000000000000000000007ad295b46744c9d5e108f7db2ffd74f5977933d5, 0000000000000000000000000000000000000000000000000000000000000002 )
21 0x0b226f16327e21ffdd93782bb776e81e833b3a1f.0xa308990dd75b95c0eac16528d7b5e498162c1ef340a9861030a52670c23ba4b2( 0xa308990dd75b95c0eac16528d7b5e498162c1ef340a9861030a52670c23ba4b2, 000000000000000000000000a40cb2374b41d317f1618535c9e868db8338b639, 0000000000000000000000007ad295b46744c9d5e108f7db2ffd74f5977933d5, 0000000000000000000000000000000000000000000012d5ed9616c8d9dcbf34, 000000000000000000000000000000000000000000000000000000005bc2f999 )
22 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.0x64e5f79d157518d8cf942b1f32eeeb7d766a32689b49c1cd671cca787ca6f752( 0x64e5f79d157518d8cf942b1f32eeeb7d766a32689b49c1cd671cca787ca6f752, 00f9d97698447b9d543dc25b5c71646691e45280bf0000000000000000000000, 0000000000000000000000000000000000000000600000000000000000000000, 000000000000000000000b640bc0c916343f1bfe040000000000000000000000, 00000000000000000000000000000000000000000b6d696e6564416d6f756e74 )
23 0xf9d97698447b9d543dc25b5c71646691e45280bf.0xfb5ea274206cca7784aa8533361e64f485bbff9daed1f741e70964349b5bc1b3( 0xfb5ea274206cca7784aa8533361e64f485bbff9daed1f741e70964349b5bc1b3, 0x0000000000000000000000007ad295b46744c9d5e108f7db2ffd74f5977933d5, 00000000000000000000000000000000000000000000009188ee68c57033acd4 )
24 0xa40cb2374b41d317f1618535c9e868db8338b639.0x1f0ebf87408b4170b56ad2d326cd76de0ef9f5ee15e573a18259a5d2af63ff80( 0x1f0ebf87408b4170b56ad2d326cd76de0ef9f5ee15e573a18259a5d2af63ff80, 000000000000000000000000f9d97698447b9d543dc25b5c71646691e45280bf, 0000000000000000000000007ad295b46744c9d5e108f7db2ffd74f5977933d5, 0000000000000000000000000000000000000000000000000000000000000002, 00000000000000000000000000000000000000000000124464a7ae0369a91260, 00000000000000000000000000000000000000000000009188ee68c57033acd4, 000000000000000000000000000000000000000000000000000000005bc2f999 )
25 0xa40cb2374b41d317f1618535c9e868db8338b639.0x00d4babaea5e51224a883189c906b7c4e416fbfe0f1e432da219ed132c83c112( 0x00d4babaea5e51224a883189c906b7c4e416fbfe0f1e432da219ed132c83c112, 000000000000000000000000f9d97698447b9d543dc25b5c71646691e45280bf, 000000000000000000000000cf1f24d0ccdc1bcee21ce70a7347381e3eeb5637 )
26 0xa40cb2374b41d317f1618535c9e868db8338b639.0x2ff3e81387f2d7e869305dafe055da8420352467e2002e9bf8e8148676b4f78e( 0x2ff3e81387f2d7e869305dafe055da8420352467e2002e9bf8e8148676b4f78e, 000000000000000000000000f9d97698447b9d543dc25b5c71646691e45280bf, 000000000000000000000000cf1f24d0ccdc1bcee21ce70a7347381e3eeb5637, 0000000000000000000000000000000000000000000000000000000000000000 )
27 0xf9d97698447b9d543dc25b5c71646691e45280bf.0xd0ed88a3f042c6bbb1e3ea406079b5f2b4b198afccaa535d837f4c63abbc4de6( 0xd0ed88a3f042c6bbb1e3ea406079b5f2b4b198afccaa535d837f4c63abbc4de6, 0x0000000000000000000000007ad295b46744c9d5e108f7db2ffd74f5977933d5, 0x000000000000000000000000cf1f24d0ccdc1bcee21ce70a7347381e3eeb5637, 0000000000000000000000000000000000000000000000056bc75e2d63100000 )
28 0xf9d97698447b9d543dc25b5c71646691e45280bf.0xd0ed88a3f042c6bbb1e3ea406079b5f2b4b198afccaa535d837f4c63abbc4de6( 0xd0ed88a3f042c6bbb1e3ea406079b5f2b4b198afccaa535d837f4c63abbc4de6, 0x0000000000000000000000007ad295b46744c9d5e108f7db2ffd74f5977933d5, 0x000000000000000000000000cf1f24d0ccdc1bcee21ce70a7347381e3eeb5637, 0000000000000000000000000000000000000000000000056bc75e2d63100000 )
29 BwinToken.Transfer( from=[Sender] 0x7ad295b46744c9d5e108f7db2ffd74f5977933d5, to=0xCf1F24d0cCdc1bcEe21ce70A7347381e3EEB5637, value=100000000000000000000 )

Account State Difference:

  Address   Before After State Difference Code
0x09C8f2ad...23De49E28
0x0B226f16...e833B3A1f
0x7ad295B4...5977933D5
0.09101683110625 Eth
Nonce: 14
0.09043780110625 Eth
Nonce: 15
0.00057903
(F2Pool Old)
2,616.467071661392960155 Eth2,616.467650691392960155 Eth0.00057903

Execution Trace

BwinToken.transfer( to=0xCf1F24d0cCdc1bcEe21ce70A7347381e3EEB5637, value=100000000000000000000 ) => ( True )
  • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
  • 0xf9d97698447b9d543dc25b5c71646691e45280bf.12a837b4( )
    • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
    • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.70a08231( )
    • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
    • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
    • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
    • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.70a08231( )
    • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
    • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.70a08231( )
    • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.e30443bc( )
    • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
    • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.70a08231( )
    • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.e30443bc( )
    • 0xa40cb2374b41d317f1618535c9e868db8338b639.a4238d31( )
      • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
      • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
      • 0x0b226f16327e21ffdd93782bb776e81e833b3a1f.6386c1c7( )
      • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
      • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
      • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
      • 0x0b226f16327e21ffdd93782bb776e81e833b3a1f.8a6bc85a( )
      • 0xf9d97698447b9d543dc25b5c71646691e45280bf.70a08231( )
        • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
        • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.70a08231( )
        • 0x0b226f16327e21ffdd93782bb776e81e833b3a1f.b440f7ff( )
        • 0xf9d97698447b9d543dc25b5c71646691e45280bf.ba91d87b( )
          • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
          • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.CALL( )
          • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.CALL( )
          • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.1f6b28bf( )
          • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
          • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
          • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.1f6b28bf( )
          • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.CALL( )
          • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.1f8d1d50( )
          • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
          • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.70a08231( )
          • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.e30443bc( )
          • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.7c2da7aa( )
          • 0xa40cb2374b41d317f1618535c9e868db8338b639.a4238d31( )
            • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
            • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
            • 0x0b226f16327e21ffdd93782bb776e81e833b3a1f.6386c1c7( )
            • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
            • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
            • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
            • 0x0b226f16327e21ffdd93782bb776e81e833b3a1f.8a6bc85a( )
            • 0xf9d97698447b9d543dc25b5c71646691e45280bf.70a08231( )
              • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
              • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.70a08231( )
              • 0x0b226f16327e21ffdd93782bb776e81e833b3a1f.b440f7ff( )
              • 0x09c8f2ad800aee0d8e4606838e53ddb23de49e28.7c2da7aa( )
              • 0xa40cb2374b41d317f1618535c9e868db8338b639.a4238d31( )
                • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
                • 0x68839de2adaaf20d1241d0a21bd1a73c03e61e57.693ec85e( )
                • 0x0b226f16327e21ffdd93782bb776e81e833b3a1f.6386c1c7( )
                  pragma solidity ^0.4.13;
                  
                  contract ERC20Basic {
                    function totalSupply() public view returns (uint256);
                    function balanceOf(address who) public view returns (uint256);
                    function transfer(address to, uint256 value) public returns (bool);
                    event Transfer(address indexed from, address indexed to, uint256 value);
                  }
                  
                  contract ERC20 is ERC20Basic {
                    function allowance(address owner, address spender) public view returns (uint256);
                    function transferFrom(address from, address to, uint256 value) public returns (bool);
                    function approve(address spender, uint256 value) public returns (bool);
                    event Approval(address indexed owner, address indexed spender, uint256 value);
                  }
                  
                  contract ContractReceiver {
                  
                      struct TKN {
                          address sender;
                          uint value;
                          bytes data;
                          bytes4 sig;
                      }
                  
                      function tokenFallback(address _from, uint _value, bytes _data) public pure {
                          TKN memory tkn;
                          tkn.sender = _from;
                          tkn.value = _value;
                          tkn.data = _data;
                          uint32 u = uint32(_data[3]) + (uint32(_data[2]) << 8) + (uint32(_data[1]) << 16) + (uint32(_data[0]) << 24);
                          tkn.sig = bytes4(u);
                  
                          /* tkn variable is analogue of msg variable of Ether transaction
                          *  tkn.sender is person who initiated this token transaction   (analogue of msg.sender)
                          *  tkn.value the number of tokens that were sent   (analogue of msg.value)
                          *  tkn.data is data of token transaction   (analogue of msg.data)
                          *  tkn.sig is 4 bytes signature of function
                          *  if data of token transaction is a function execution
                          */
                      }
                  }
                  
                  contract Ownable {
                    address public owner;
                  
                  
                    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
                  
                  
                    /**
                     * @dev The Ownable constructor sets the original `owner` of the contract to the sender
                     * account.
                     */
                    function Ownable() public {
                      owner = msg.sender;
                    }
                  
                    /**
                     * @dev Throws if called by any account other than the owner.
                     */
                    modifier onlyOwner() {
                      require(msg.sender == owner);
                      _;
                    }
                  
                    /**
                     * @dev Allows the current owner to transfer control of the contract to a newOwner.
                     * @param newOwner The address to transfer ownership to.
                     */
                    function transferOwnership(address newOwner) public onlyOwner {
                      require(newOwner != address(0));
                      emit OwnershipTransferred(owner, newOwner);
                      owner = newOwner;
                    }
                  
                  }
                  
                  contract CrowdsaleFront is Ownable{
                      //Crowdsale public provider;
                      using SafeMath for uint256;
                      mapping (address => uint256) internal userAmounts;
                      mapping (address => uint256) internal rewardPayed;
                      BwinCommons internal commons;
                      function setCommons(address _addr) public onlyOwner {
                          commons = BwinCommons(_addr);
                      }
                      // fallback function can be used to buy tokens
                      function () public payable {
                          buyTokens(msg.sender, 0, 999);
                      }
                  
                      // low level token purchase function
                      function buyTokens(address beneficiary, address _parent, uint256 _top) public payable returns(bool){
                        bool ret;
                        uint256 tokens;
                        (ret, tokens) = Crowdsale(commons.get("Crowdsale")).buyTokens.value(msg.value)(beneficiary, beneficiary, _parent, _top);
                        userAmounts[beneficiary] = userAmounts[beneficiary].add(tokens);
                        require(ret);
                      }
                  
                      function getTokensFromBuy(address _addr) public view returns (uint256){
                        return userAmounts[_addr];
                      }
                      function rewardPayedOf(address _user) public view returns (uint256) {
                        return rewardPayed[_user];
                      }
                      function rewardPay(address _user, uint256 amount) public {
                        require(msg.sender == commons.get("Crowdsale"));
                        rewardPayed[_user] = rewardPayed[_user].add(amount);
                      }
                  
                      // @return true if crowdsale event has ended
                      function hasEnded() public view returns (bool){
                          return Crowdsale(commons.get("Crowdsale")).hasEnded();
                      }
                  
                  }
                  
                  contract InterestHolder is Ownable{
                    using SafeMath for uint256;
                    BwinCommons internal commons;
                    function setCommons(address _addr) public onlyOwner {
                        commons = BwinCommons(_addr);
                    }
                    bool public locked = true;
                    event ReceiveBalanceUpdate(address _addr,address _user);
                    event ReceiveBalanceUpdateUserType(address _addr,address _user,uint256 _type);
                    function receiveBalanceUpdate(address _user) external returns (bool) {
                      emit ReceiveBalanceUpdate(msg.sender, _user);
                      Token token = Token(commons.get("Token"));
                      User user = User(commons.get("User"));
                      if (msg.sender == address(token)){
                        uint256 _type;
                        (,,_type) = user.getUserInfo(_user);
                        emit ReceiveBalanceUpdateUserType(msg.sender, _user, _type);
                        if (_type == 0){
                            return true;
                        }
                        process(_user,_type);
                        return true;
                      }
                      return false;
                    }
                    event ProcessLx(address _addr,address _user, uint256 _type,uint256 lastBalance, uint256 iAmount, uint256 lastTime);
                    function process(address _user, uint256 _type) internal{
                      Token token = Token(commons.get("Token"));
                      User user = User(commons.get("User"));
                      uint256 _value = compute(_user, _type);
                      uint256 balance = token.balanceOf(_user);
                      user.setInterestor(_user,balance.add(_value),now);
                      if(_value > 0){
                        token.mintForWorker(_user,_value);
                        emit ProcessLx(msg.sender, _user, _type, balance, _value, now);
                      }
                    }
                    event GetLx(address _addr,address _user,uint256 _type);
                  
                    function compute(address _user, uint256 _type) internal view returns (uint256) {
                      User user = User(commons.get("User"));
                      uint256 lastBalance = 0;
                      uint256 lastTime = 0;
                      bool exist;
                      (lastBalance,lastTime,exist) = user.getInterestor(_user);
                      uint256 _value = 0;
                      if (exist && lastTime > 0){
                          uint256 times = now.sub(lastTime);
                          if (_type == 1){
                              _value = lastBalance.div(10000).mul(5).div(86400).mul(times);
                          }else if(_type == 2){
                              _value = lastBalance.div(10000).mul(8).div(86400).mul(times);
                          }
                      }
                      return _value;
                    }
                    function getLx() external returns (uint256) {
                      User user = User(commons.get("User"));
                      uint256 _type;
                      (,,_type) = user.getUserInfo(msg.sender);
                      emit GetLx(msg.sender, msg.sender, _type);
                      if (_type == 0){
                          return 0;
                      }
                      return compute(msg.sender, _type);
                    }
                  }
                  
                  contract TokenHolder is Ownable{
                    using SafeMath for uint256;
                  
                    BwinCommons internal commons;
                    function setCommons(address _addr) public onlyOwner {
                        commons = BwinCommons(_addr);
                    }
                    bool locked = true;
                    mapping (address => uint256) lockedAmount;
                    event ReceiveLockedAmount(address _addr, address _user, uint256 _amount);
                    function receiveLockedAmount(address _user, uint256 _amount) external returns (bool) {
                      address cds = commons.get("Crowdsale");
                      if (msg.sender == address(cds)){
                        lockedAmount[_user] = lockedAmount[_user].add(_amount);
                        emit ReceiveLockedAmount(msg.sender, _user, _amount);
                        return true;
                      }
                      return false;
                    }
                  
                    function balanceOf(address _user) public view returns (uint256) {
                      return lockedAmount[_user];
                    }
                    function balance() public view returns (uint256) {
                      return lockedAmount[msg.sender];
                    }
                  
                    function setLock(bool _locked) public onlyOwner{
                      locked = _locked;
                    }
                  
                    function withDrawlocked() public view returns (bool) {
                        return locked;
                    }
                  
                    function withDrawable() public view returns (bool) {
                      User user = User(commons.get("User"));
                      uint256 _type;
                      (,,_type) = user.getUserInfo(msg.sender);
                      return !locked && (_type > 0) && lockedAmount[msg.sender] > 0;
                    }
                  
                    function withDraw() external {
                      assert(!locked);//用户必须是种子钱包
                      BwinToken token = BwinToken(commons.get("BwinToken"));
                      User user = User(commons.get("User"));
                      uint256 _type;
                      (,,_type) = user.getUserInfo(msg.sender);
                      assert(_type > 0);
                      uint _value = lockedAmount[msg.sender];
                      lockedAmount[msg.sender] = 0;
                      token.transfer(msg.sender,_value);
                    }
                  
                  }
                  
                  contract Destructible is Ownable {
                  
                    function Destructible() public payable { }
                  
                    /**
                     * @dev Transfers the current balance to the owner and terminates the contract.
                     */
                    function destroy() onlyOwner public {
                      selfdestruct(owner);
                    }
                  
                    function destroyAndSend(address _recipient) onlyOwner public {
                      selfdestruct(_recipient);
                    }
                  }
                  
                  contract EtherHolder is Destructible{
                    using SafeMath for uint256;
                    bool locked = false;
                  
                    BwinCommons internal commons;
                    function setCommons(address _addr) public onlyOwner {
                        commons = BwinCommons(_addr);
                    }
                    struct Account {
                      address wallet;
                      address parent;
                      uint256 radio;
                      bool exist;
                    }
                    mapping (address => uint256) private userAmounts;
                    uint256 internal _balance;
                    event ProcessFunds(address _topWallet, uint256 _value ,bool isContract);
                  
                    event ReceiveFunds(address _addr, address _user, uint256 _value, uint256 _amount);
                    function receiveFunds(address _user, uint256 _amount) external payable returns (bool) {
                      emit ReceiveFunds(msg.sender, _user, msg.value, _amount);
                      Crowdsale cds = Crowdsale(commons.get("Crowdsale"));
                      User user = User(commons.get("User"));
                      assert(msg.value == _amount);
                      if (msg.sender == address(cds)){
                          address _topWallet;
                          uint _percent=0;
                          bool _contract;
                          uint256 _topValue = 0;
                          bool _topOk;
                          uint256 _totalShares = 0;
                          uint256 _totalSharePercent = 0;
                          bool _shareRet;
                          if(user.hasUser(_user)){
                            (_topWallet,_percent,_contract) = user.getTopInfoDetail(_user);
                            assert(_percent <= 1000);
                            (_topValue,_topOk) = processFunds(_topWallet,_amount,_percent,_contract);
                          }else{
                            _topOk = true;
                          }
                          (_totalShares,_totalSharePercent,_shareRet) = processShares(_amount.sub(_topValue));
                          assert(_topOk && _shareRet);
                          assert(_topValue.add(_totalShares) <= _amount);
                          assert(_totalSharePercent <= 1000);
                          _balance = _balance.add(_amount);
                          return true;
                      }
                      return false;
                    }
                    event ProcessShares(uint256 _amount, uint i, uint256 _percent, bool _contract,address _wallet);
                    function processShares(uint256 _amount) internal returns(uint256,uint256,bool){
                        uint256 _sended = 0;
                        uint256 _sharePercent = 0;
                        User user = User(commons.get("User"));
                        for(uint i=0;i<user.getShareHolderCount();i++){
                          address _wallet;
                          uint256 _percent;
                          bool _contract;
                          emit ProcessShares(_amount, i, _percent, _contract,_wallet);
                          assert(_percent <= 1000);
                          (_wallet,_percent,_contract) = user.getShareHolder(i);
                          uint256 _value;
                          bool _valueOk;
                          (_value,_valueOk) = processFunds(_wallet,_amount,_percent,_contract);
                          _sharePercent = _sharePercent.add(_percent);
                          _sended = _sended.add(_value);
                        }
                        return (_sended,_sharePercent,true);
                    }
                    function getAmount(uint256 _amount, uint256 _percent) internal pure returns(uint256){
                        uint256 _value = _amount.div(1000).mul(_percent);
                        return _value;
                    }
                    function processFunds(address _topWallet, uint256 _amount ,uint256 _percent, bool isContract) internal returns(uint,bool) {
                        uint256 _value = getAmount(_amount, _percent);
                        userAmounts[_topWallet] = userAmounts[_topWallet].add(_value);
                        emit ProcessFunds(_topWallet,_value,isContract);
                        return (_value,true);
                    }
                  
                    function balanceOf(address _user) public view returns (uint256) {
                      return userAmounts[_user];
                    }
                  
                    function balanceOfme() public view returns (uint256) {
                      return userAmounts[msg.sender];
                    }
                  
                    function withDrawlocked() public view returns (bool) {
                        return locked;
                    }
                    function getBalance() public view returns (uint256, uint256) {
                      return (address(this).balance,_balance);
                    }
                    function lock(bool _locked) public onlyOwner{
                      locked = _locked;
                    }
                    event WithDraw(address caller, uint256 _amount);
                  
                    function withDraw(uint256 _amount) external {
                      assert(!locked);
                      assert(userAmounts[msg.sender] >= _amount);
                      userAmounts[msg.sender] = userAmounts[msg.sender].sub(_amount);
                      _balance = _balance.sub(_amount);
                      msg.sender.transfer(_amount);
                      emit WithDraw(msg.sender, _amount);
                    }
                    function destroy() onlyOwner public {
                      selfdestruct(owner);
                    }
                  }
                  
                  library SafeMath {
                  
                    /**
                    * @dev Multiplies two numbers, throws on overflow.
                    */
                    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
                      if (a == 0) {
                        return 0;
                      }
                      uint256 c = a * b;
                      assert(c / a == b);
                      return c;
                    }
                  
                    /**
                    * @dev Integer division of two numbers, truncating the quotient.
                    */
                    function div(uint256 a, uint256 b) internal pure returns (uint256) {
                      // assert(b > 0); // Solidity automatically throws 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 Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
                    */
                    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
                      assert(b <= a);
                      return a - b;
                    }
                  
                    /**
                    * @dev Adds two numbers, throws on overflow.
                    */
                    function add(uint256 a, uint256 b) internal pure returns (uint256) {
                      uint256 c = a + b;
                      assert(c >= a);
                      return c;
                    }
                  }
                  
                  contract RBAC {
                    using Roles for Roles.Role;
                  
                    mapping (string => Roles.Role) private roles;
                  
                    event RoleAdded(address addr, string roleName);
                    event RoleRemoved(address addr, string roleName);
                  
                    /**
                     * A constant role name for indicating admins.
                     */
                    string public constant ROLE_ADMIN = "admin";
                  
                    /**
                     * @dev constructor. Sets msg.sender as admin by default
                     */
                    function RBAC()
                      public
                    {
                      addRole(msg.sender, ROLE_ADMIN);
                    }
                  
                    /**
                     * @dev reverts if addr does not have role
                     * @param addr address
                     * @param roleName the name of the role
                     * // reverts
                     */
                    function checkRole(address addr, string roleName)
                      view
                      public
                    {
                      roles[roleName].check(addr);
                    }
                  
                    /**
                     * @dev determine if addr has role
                     * @param addr address
                     * @param roleName the name of the role
                     * @return bool
                     */
                    function hasRole(address addr, string roleName)
                      view
                      public
                      returns (bool)
                    {
                      return roles[roleName].has(addr);
                    }
                  
                    /**
                     * @dev add a role to an address
                     * @param addr address
                     * @param roleName the name of the role
                     */
                    function adminAddRole(address addr, string roleName)
                      onlyAdmin
                      public
                    {
                      addRole(addr, roleName);
                    }
                  
                    /**
                     * @dev remove a role from an address
                     * @param addr address
                     * @param roleName the name of the role
                     */
                    function adminRemoveRole(address addr, string roleName)
                      onlyAdmin
                      public
                    {
                      removeRole(addr, roleName);
                    }
                  
                    /**
                     * @dev add a role to an address
                     * @param addr address
                     * @param roleName the name of the role
                     */
                    function addRole(address addr, string roleName)
                      internal
                    {
                      roles[roleName].add(addr);
                      emit RoleAdded(addr, roleName);
                    }
                  
                    /**
                     * @dev remove a role from an address
                     * @param addr address
                     * @param roleName the name of the role
                     */
                    function removeRole(address addr, string roleName)
                      internal
                    {
                      roles[roleName].remove(addr);
                      emit RoleRemoved(addr, roleName);
                    }
                  
                    /**
                     * @dev modifier to scope access to a single role (uses msg.sender as addr)
                     * @param roleName the name of the role
                     * // reverts
                     */
                    modifier onlyRole(string roleName)
                    {
                      checkRole(msg.sender, roleName);
                      _;
                    }
                  
                    /**
                     * @dev modifier to scope access to admins
                     * // reverts
                     */
                    modifier onlyAdmin()
                    {
                      checkRole(msg.sender, ROLE_ADMIN);
                      _;
                    }
                  
                    /**
                     * @dev modifier to scope access to a set of roles (uses msg.sender as addr)
                     * @param roleNames the names of the roles to scope access to
                     * // reverts
                     *
                     * @TODO - when solidity supports dynamic arrays as arguments to modifiers, provide this
                     *  see: https://github.com/ethereum/solidity/issues/2467
                     */
                    // modifier onlyRoles(string[] roleNames) {
                    //     bool hasAnyRole = false;
                    //     for (uint8 i = 0; i < roleNames.length; i++) {
                    //         if (hasRole(msg.sender, roleNames[i])) {
                    //             hasAnyRole = true;
                    //             break;
                    //         }
                    //     }
                  
                    //     require(hasAnyRole);
                  
                    //     _;
                    // }
                  }
                  
                  contract BwinCommons is RBAC, Destructible {
                      mapping (string => address) internal addresses;
                      mapping (address => string) internal names;
                  
                      event UpdateRegistration(string key, address old, address n);
                  
                      function register(string key, address ad) public onlyAdmin {
                          emit UpdateRegistration(key, addresses[key], ad);
                          addresses[key] = ad;
                          names[ad] = key;
                      }
                  
                      function get(string key) public view returns(address) {
                          return addresses[key];
                      }
                  
                      function remove() public {
                        string memory key = names[msg.sender];
                        delete addresses[key];
                        delete names[msg.sender];
                      }
                  }
                  
                  contract User is RBAC ,Destructible{
                      struct UserInfo {
                          //推荐人
                          address parent;
                          uint256 top;
                          bool exist;
                          uint256 userType;
                      }
                  
                      struct Partner {
                        address addr;
                        uint256 percent;
                        bool exist;
                        bool iscontract;
                      }
                  
                      struct UserBalance{
                          address user;
                          uint256 balance;
                          uint256 lastTime;
                          bool exist;
                      }
                      mapping (address => UserBalance) internal balanceForInterests;
                      uint256[] internal tops;
                      mapping (uint256 => Partner) internal topDefine;
                  
                      uint256[] internal shareHolders;
                      mapping (uint256 => Partner) internal shareHolderInfos;
                      mapping (address => UserInfo) internal tree;
                      BwinCommons internal commons;
                      function setCommons(address _addr) public onlyAdmin {
                          commons = BwinCommons(_addr);
                      }
                  
                  
                      address[] internal users;
                      event SetInterestor(address caller, address _user, uint256 _balance, uint256 _lastTime);
                      event SetShareHolders(address caller, uint256 topId, address _topAddr, uint256 _percent, bool iscontract);
                      event SetTop(address caller, uint256 topId, address _topAddr, uint256 _percent, bool iscontract);
                      event AddUser(address caller, address _parent, uint256 _top);
                      event SetUser(address caller, address _user, address _parent, uint256 _top, uint256 _type);
                      event SetUserType(address caller, address _user, uint _type);
                      event RemoveUser(address caller, uint _index);
                  
                      function setInterestor(address _user, uint256 _balance, uint256 _lastTime) public onlyRole("INTEREST_HOLDER"){
                          balanceForInterests[_user] = UserBalance(_user,_balance,_lastTime,true);
                          emit SetInterestor(msg.sender,_user,_balance,_lastTime);
                      }
                  
                      function getInterestor(address _user) public view returns(uint256,uint256,bool){
                          return (balanceForInterests[_user].balance,balanceForInterests[_user].lastTime,balanceForInterests[_user].exist);
                      }
                      function setShareHolders(uint256 topId, address _topAddr, uint256 _percent, bool iscontract) public onlyAdmin {
                          if (!shareHolderInfos[topId].exist){
                            shareHolders.push(topId);
                          }
                          shareHolderInfos[topId] = Partner(_topAddr, _percent, true, iscontract);
                          emit SetShareHolders(msg.sender,topId,_topAddr,_percent,iscontract);
                      }
                      function getShareHolder(uint256 _index) public view returns(address, uint256, bool){
                          uint256 shareHolderId = shareHolders[_index];
                          return getShareHoldersInfo(shareHolderId);
                      }
                      function getShareHolderCount() public view returns(uint256){
                          return shareHolders.length;
                      }
                      function getShareHoldersInfo(uint256 shareHolderId) public view returns(address, uint256, bool){
                        return (shareHolderInfos[shareHolderId].addr, shareHolderInfos[shareHolderId].percent, shareHolderInfos[shareHolderId].iscontract);
                      }
                  
                      function setTop(uint256 topId, address _topAddr, uint256 _percent, bool iscontract) public onlyAdmin {
                          if (!topDefine[topId].exist){
                            tops.push(topId);
                          }
                          topDefine[topId] = Partner(_topAddr, _percent, true, iscontract);
                          emit SetTop(msg.sender, topId, _topAddr, _percent, iscontract);
                      }
                      function getTopInfoDetail(address _user) public view returns(address, uint256, bool){
                          uint256 _topId;
                          address _wallet;
                          uint256 _percent;
                          bool _contract;
                          (,_topId,) = getUserInfo(_user);
                          (_wallet,_percent,_contract) = getTopInfo(_topId);
                          return (_wallet,_percent,_contract);
                      }
                      function getTopInfo(uint256 topId) public view returns(address, uint256, bool){
                        return (topDefine[topId].addr, topDefine[topId].percent, topDefine[topId].iscontract);
                      }
                      function addUser(address _parent, uint256 _top) public {
                          require(msg.sender != _parent);
                          if (_parent != address(0)) {
                              require(tree[_parent].exist);
                          }
                          require(!hasUser(msg.sender));
                          tree[msg.sender] = UserInfo(_parent, _top, true, 0);
                          users.push(msg.sender);
                          emit AddUser(msg.sender, _parent, _top);
                      }
                  
                      function getUsersCount() public view returns(uint) {
                          return users.length;
                      }
                  
                      function getUserInfo(address _user) public view returns(address, uint256, uint256) {
                          return (tree[_user].parent, tree[_user].top, tree[_user].userType);
                      }
                  
                      function hasUser(address _user) public view returns(bool) {
                          return tree[_user].exist;
                      }
                  
                      function setUser(address _user, address _parent, uint256 _top, uint256 _type) public onlyAdmin {
                        if(!tree[_user].exist){
                          users.push(_user);
                        }
                        tree[_user] = UserInfo(_parent, _top, true, _type);
                        emit SetUser(msg.sender, _user, _parent, _top, _type);
                      }
                  
                      function setUserType(address _user, uint _type) public onlyAdmin {
                          require(hasUser(_user));
                          tree[_user].userType = _type;
                          emit SetUserType(msg.sender, _user, _type);
                      }
                      function indexOfUserInfo(uint _index) public view returns (address) {
                          return users[_index];
                      }
                  
                      function removeUser(uint _index) public onlyAdmin {
                          address _user = indexOfUserInfo(_index);
                          delete users[_index];
                          delete tree[_user];
                          emit RemoveUser(msg.sender, _index);
                      }
                  }
                  
                  contract Pausable is RBAC {
                    event Pause();
                    event Unpause();
                  
                    bool public paused = false;
                  
                  
                    /**
                     * @dev Modifier to make a function callable only when the contract is not paused.
                     */
                    modifier whenNotPaused() {
                      require(!paused);
                      _;
                    }
                  
                    /**
                     * @dev Modifier to make a function callable only when the contract is paused.
                     */
                    modifier whenPaused() {
                      require(paused);
                      _;
                    }
                  
                    /**
                     * @dev called by the owner to pause, triggers stopped state
                     */
                    function pause() onlyAdmin whenNotPaused public {
                      paused = true;
                      emit Pause();
                    }
                  
                    /**
                     * @dev called by the owner to unpause, returns to normal state
                     */
                    function unpause() onlyAdmin whenPaused public {
                      paused = false;
                      emit Unpause();
                    }
                  }
                  
                  contract BwinToken is ERC20, Pausable, Destructible{
                      //Token t;
                  
                      BwinCommons internal commons;
                      function setCommons(address _addr) public onlyOwner {
                          commons = BwinCommons(_addr);
                      }
                      string public constant name = "FFgame Coin";
                      string public constant symbol = "FFC";
                      uint8 public constant decimals = 18;
                      event Transfer(address indexed from, address indexed to, uint256 value);
                      function BwinToken() public {
                        addRole(msg.sender, ROLE_ADMIN);
                      }
                      function totalSupply() public view returns (uint256){
                        Token t = Token(commons.get("Token"));
                        return t.totalSupply();
                      }
                      function balanceOf(address who) public view returns (uint256){
                        Token t = Token(commons.get("Token"));
                        return t.balanceOf(who);
                      }
                      function transfer(address to, uint256 value) public returns (bool){
                        bytes memory empty;
                        Token t = Token(commons.get("Token"));
                        if(t.transfer(msg.sender, to, value,empty)){
                            emit Transfer(msg.sender, to, value);
                            return true;
                        }
                        return false;
                      }
                  
                  
                      function allowance(address owner, address spender) public view returns (uint256){
                        Token t = Token(commons.get("Token"));
                        return t.allowance(owner, spender);
                      }
                      function transferFrom(address from, address to, uint256 value) public returns (bool){
                        Token t = Token(commons.get("Token"));
                        if(t._transferFrom(msg.sender, from, to, value)){
                            emit Transfer(from, to, value);
                            return true;
                        }
                        return false;
                      }
                      function approve(address spender, uint256 value) public returns (bool){
                        Token t = Token(commons.get("Token"));
                        if (t._approve(msg.sender, spender, value)){
                            emit Approval(msg.sender, spender, value);
                            return true;
                        }
                        return false;
                      }
                  
                      function increaseApproval(address _spender, uint _addedValue) public whenNotPaused returns (bool success) {
                        Token t = Token(commons.get("Token"));
                        if(t._increaseApproval(msg.sender, _spender, _addedValue)){
                            emit Approval(msg.sender, _spender, _addedValue);
                            return true;
                        }
                        return false;
                      }
                  
                      function decreaseApproval(address _spender, uint _subtractedValue) public whenNotPaused returns (bool success) {
                        Token t = Token(commons.get("Token"));
                        if (t._decreaseApproval(msg.sender,_spender, _subtractedValue)){
                            emit Approval(msg.sender, _spender, _subtractedValue);
                            return true;
                        }
                        return false;
                      }
                      event Approval(address indexed owner, address indexed spender, uint256 value);
                  
                  }
                  
                  contract Token is RBAC, Pausable{
                      using SafeMath for uint256;
                  
                      BwinCommons internal commons;
                      function setCommons(address _addr) public onlyAdmin {
                          commons = BwinCommons(_addr);
                      }
                      event TokenApproval(address indexed owner, address indexed spender, uint256 value);
                      event TokenTransfer(address indexed from, address indexed to, uint256 value);
                      event MintForSale(address indexed to, uint256 amount);
                      event MintForWorker(address indexed to, uint256 amount);
                      event MintForUnlock(address indexed to, uint256 amount);
                  
                      function Token() public {
                          addRole(msg.sender, ROLE_ADMIN);
                      }
                  
                      function totalSupply() public view returns (uint256) {
                        TokenData td = TokenData(commons.get("TokenData"));
                        return td.totalSupply();
                      }
                      function balanceOf(address _owner) public view returns (uint256) {
                        TokenData td = TokenData(commons.get("TokenData"));
                        return td.balanceOf(_owner);
                      }
                      function _transferFrom(address _sender, address _from, address _to, uint256 _value) external whenNotPaused onlyRole("FRONT_TOKEN_USER") returns (bool) {
                        InterestHolder ih = InterestHolder(commons.get("InterestHolder"));
                        TokenData td = TokenData(commons.get("TokenData"));
                        uint256 _balanceFrom = balanceOf(_from);
                        uint256 _balanceTo = balanceOf(_to);
                        uint256 _allow = allowance(_from, _sender);
                        require(_from != address(0));
                        require(_sender != address(0));
                        require(_to != address(0));
                        require(_value <= _balanceFrom);
                        require(_value <= _allow);
                        td.setBalance(_from,_balanceFrom.sub(_value));
                        td.setBalance(_to,_balanceTo.add(_value));
                        td.setAllowance(_from, _sender, _allow.sub(_value));
                        if(ih != address(0)){
                          ih.receiveBalanceUpdate(_from);
                          ih.receiveBalanceUpdate(_to);
                        }
                        emit TokenTransfer(_from, _to, _value);
                        return true;
                      }
                  
                      function allowance(address _owner, address _spender) public view returns (uint256) {
                        TokenData td = TokenData(commons.get("TokenData"));
                        return td.allowance(_owner,_spender);
                      }
                      function _approve(address _sender, address _spender, uint256 _value) public onlyRole("FRONT_TOKEN_USER")  whenNotPaused returns (bool) {
                        TokenData td = TokenData(commons.get("TokenData"));
                        return td.setAllowance(_sender, _spender, _value);
                      }
                      function _increaseApproval(address _sender, address _spender, uint _addedValue) public onlyRole("FRONT_TOKEN_USER") whenNotPaused returns (bool) {
                        TokenData td = TokenData(commons.get("TokenData"));
                        td.setAllowance(_sender, _spender, allowance(_sender, _spender).add(_addedValue));
                        emit TokenApproval(_sender, _spender, allowance(_sender, _spender));
                        return true;
                      }
                      function _decreaseApproval(address _sender, address _spender, uint _subtractedValue) public onlyRole("FRONT_TOKEN_USER") whenNotPaused returns (bool) {
                        TokenData td = TokenData(commons.get("TokenData"));
                        uint oldValue = allowance(_sender, _spender);
                        if (_subtractedValue > oldValue) {
                            td.setAllowance(_sender, _spender, 0);
                            //allowed[msg.sender][_spender] = 0;
                        } else {
                            td.setAllowance(_sender, _spender, oldValue.sub(_subtractedValue));
                            //allowed[msg.sender][_spender] = oldValue.sub(_subtractedValue);
                        }
                        emit TokenApproval(_sender, _spender, allowance(_sender, _spender));
                        return true;
                      }
                  
                      function unlockAmount(address _to, uint256 _amount) external onlyAdmin returns (bool){
                        TokenData td = TokenData(commons.get("TokenData"));
                        require(td.totalSupply().add(_amount) <= td.TotalCapacity());
                        uint256 unlockedAmount = td.valueOf("unlockedAmount");
                        if(_mint(_to, _amount)){
                            td.setValue("unlockedAmount",unlockedAmount.add(_amount));
                            emit MintForUnlock(_to, _amount);
                            return true;
                        }
                        return false;
                      }
                  
                      function _mint(address _to, uint256 _amount) internal returns (bool) {
                        TokenData td = TokenData(commons.get("TokenData"));
                        InterestHolder ih = InterestHolder(commons.get("InterestHolder"));
                        require(_to != address(0));
                        require(_amount > 0);
                        uint256 totalMinted = td.valueOf("totalMinted");
                        td.setTotal(td.totalSupply().add(_amount));
                        td.setBalance(_to,balanceOf(_to).add(_amount));
                        td.setValue("totalMinted",totalMinted.add(_amount));
                        if(address(ih) != address(0)){
                          ih.receiveBalanceUpdate(_to);
                        }
                        return true;
                      }
                  
                      function mintForSale(address _to, uint256 _amount) external onlyRole("TOKEN_SALE") whenNotPaused returns (bool) {
                        TokenData td = TokenData(commons.get("TokenData"));
                        require(td.totalSupply().add(_amount) <= td.TotalCapacity());
                        uint256 saledAmount = td.valueOf("saledAmount");
                        if(_mint(_to, _amount)){
                            td.setValue("saledAmount",saledAmount.add(_amount));
                            emit MintForSale(_to, _amount);
                            return true;
                        }
                        return false;
                      }
                      function mintForWorker(address _to, uint256 _amount) external onlyRole("TOKEN_WORKER") whenNotPaused returns (bool) {
                        TokenData td = TokenData(commons.get("TokenData"));
                        require(td.totalSupply().add(_amount) <= td.TotalCapacity());
                        uint256 minedAmount = td.valueOf("minedAmount");
                        if(_mint(_to, _amount)){
                          td.setValue("minedAmount",minedAmount.add(_amount));
                          emit MintForWorker(_to, _amount);
                          return true;
                        }
                        return false;
                      }
                      function transfer(address _from, address _to, uint _value, bytes _data) external whenNotPaused onlyRole("FRONT_TOKEN_USER")  returns (bool success) {
                  
                          if (isContract(_to)) {
                              return transferToContract(_from, _to, _value, _data);
                          }else {
                              return transferToAddress(_from, _to, _value);
                          }
                      }
                      //assemble the given address bytecode. If bytecode exists then the _addr is a contract.
                      function isContract(address _addr) internal view returns (bool) {
                          uint length;
                          assembly {
                              //retrieve the size of the code on target address, this needs assembly
                              length := extcodesize(_addr)
                          }
                          return (length > 0);
                      }
                      function _transfer(address _from, address _to, uint256 _value) internal returns (bool) {
                        TokenData td = TokenData(commons.get("TokenData"));
                        InterestHolder ih = InterestHolder(commons.get("InterestHolder"));
                        require(_to != address(0));
                        require(_value <= balanceOf(_from));
                        td.setBalance(_from,balanceOf(_from).sub(_value));
                        td.setBalance(_to,balanceOf(_to).add(_value));
                        if(ih != address(0)){
                          ih.receiveBalanceUpdate(_from);
                          ih.receiveBalanceUpdate(_to);
                        }
                        emit TokenTransfer(_from, _to, _value);
                        return true;
                      }
                  
                      //function that is called when transaction target is an address
                      function transferToAddress(address _from, address _to, uint _value) internal returns (bool success) {
                          require(balanceOf(_from) >= _value);
                          require(_transfer(_from, _to, _value));
                          emit TokenTransfer(_from, _to, _value);
                          return true;
                      }
                  
                      //function that is called when transaction target is a contract
                      function transferToContract(address _from, address _to, uint _value, bytes _data) internal returns (bool success) {
                          require(balanceOf(_from) >= _value);
                          require(_transfer(_from, _to, _value));
                          ContractReceiver receiver = ContractReceiver(_to);
                          receiver.tokenFallback(msg.sender, _value, _data);
                          emit TokenTransfer(msg.sender, _to, _value);
                          return true;
                      }
                  
                  
                  
                  }
                  
                  contract TokenData is RBAC, Pausable{
                    //using SafeMath for uint256;
                    event TokenDataBalance(address sender, address indexed addr, uint256 value);
                    event TokenDataAllowance(address sender, address indexed from, address indexed to, uint256 value);
                    event SetTotalSupply(address _addr, uint256 _total);
                    mapping(address => uint256) internal balances;
                    mapping(string => uint256) internal values;
                  
                    mapping (address => mapping (address => uint256)) internal allowed;
                  
                    address[] internal users;
                  
                    uint256 internal totalSupply_;
                    uint256 internal totalCapacity_;
                  
                    string internal  name_;
                    string internal  symbol_;
                    uint8 internal  decimals_;
                    function TokenData(uint256 _totalSupply, uint256 _totalCapacity) public {
                      addRole(msg.sender, ROLE_ADMIN);
                      totalSupply_ = _totalSupply;
                      totalCapacity_ = _totalCapacity;
                    }
                  
                    BwinCommons internal commons;
                    function setCommons(address _addr) public onlyAdmin {
                        commons = BwinCommons(_addr);
                    }
                    function setTotal(uint256 _total) public onlyRole("TOKEN_DATA_USER") {
                        totalSupply_ = _total;
                        emit SetTotalSupply(msg.sender, _total);
                    }
                    event SetValue(address _addr, string name, uint256 _value);
                  
                    function setValue(string name, uint256 _value) external onlyRole("TOKEN_DATA_USER") {
                        values[name] = _value;
                        emit SetValue(msg.sender, name, _value);
                    }
                  
                    event SetTotalCapacity(address _addr, uint256 _total);
                  
                    function setTotalCapacity(uint256 _total) external onlyRole("TOKEN_DATA_USER") {
                        totalCapacity_ = _total;
                        emit SetTotalCapacity(msg.sender, _total);
                    }
                  
                    function valueOf(string _name) public view returns(uint256){
                        return values[_name];
                    }
                  
                  
                    function TotalCapacity() public view returns (uint256) {
                      return totalCapacity_;
                    }
                  
                    function totalSupply() public view returns (uint256) {
                      return totalSupply_;
                    }
                  
                  
                  
                    function balanceOf(address _owner) public view returns (uint256) {
                      return balances[_owner];
                    }
                  
                    function allowance(address _owner, address _spender) public view returns (uint256) {
                      return allowed[_owner][_spender];
                    }
                  
                  
                  
                    function setBalance(address _addr, uint256 _value) external whenNotPaused onlyRole("TOKEN_DATA_USER") returns (bool) {
                      return _setBalance(_addr, _value);
                    }
                    function setAllowance(address _from, address _to, uint256 _value) external whenNotPaused onlyRole("TOKEN_DATA_USER") returns (bool) {
                      return _setAllowance(_from, _to, _value);
                    }
                  
                    function setBalanceAdmin(address _addr, uint256 _value) external onlyAdmin returns (bool) {
                      return _setBalance(_addr, _value);
                    }
                    function setAllowanceAdmin(address _from, address _to, uint256 _value) external onlyAdmin returns (bool) {
                      return _setAllowance(_from, _to, _value);
                    }
                  
                    function _setBalance(address _addr, uint256 _value) internal returns (bool) {
                      require(_addr != address(0));
                      require(_value >= 0);
                      balances[_addr] = _value;
                      emit TokenDataBalance(msg.sender, _addr, _value);
                      return true;
                    }
                    function _setAllowance(address _from, address _to, uint256 _value) internal returns (bool) {
                      require(_from != address(0));
                      require(_to != address(0));
                      require(_value >= 0);
                      allowed[_from][_to] = _value;
                      emit TokenDataAllowance(msg.sender, _from, _to, _value);
                      return true;
                    }
                  }
                  
                  contract Crowdsale is Ownable, Pausable{
                    using SafeMath for uint256;
                    uint256 public startTime;
                    uint256 public endTime;
                    uint256 public saleCapacity;
                    uint256 public saledAmount;
                    uint256 public rate;
                    uint256 public weiRaised;
                    event TokenPurchase(address payor, address indexed purchaser, address indexed beneficiary, uint256 value, uint256 amount);
                    BwinCommons internal commons;
                    function setCommons(address _addr) public onlyOwner {
                        commons = BwinCommons(_addr);
                    }
                    function buyTokens(address payor, address beneficiary, address _parent, uint256 _top) public  payable returns(bool, uint256);
                    function hasEnded() public view returns (bool){
                        return (now > endTime || saledAmount >= saleCapacity);
                    }
                    modifier onlyFront() {
                        require(msg.sender == address(commons.get("CrowdsaleFront")));
                        _;
                    }
                    function validPurchase() internal view returns (bool) {
                        bool withinPeriod = now >= startTime && now <= endTime;
                        bool withinCapacity = saledAmount <= saleCapacity;
                        return withinPeriod && withinCapacity;
                    }
                  
                    function getTokenAmount(uint256 weiAmount) internal view returns(uint256) {
                        return weiAmount.mul(rate);
                    }
                  }
                  
                  library Roles {
                    struct Role {
                      mapping (address => bool) bearer;
                    }
                  
                    /**
                     * @dev give an address access to this role
                     */
                    function add(Role storage role, address addr)
                      internal
                    {
                      role.bearer[addr] = true;
                    }
                  
                    /**
                     * @dev remove an address' access to this role
                     */
                    function remove(Role storage role, address addr)
                      internal
                    {
                      role.bearer[addr] = false;
                    }
                  
                    /**
                     * @dev check if an address has this role
                     * // reverts
                     */
                    function check(Role storage role, address addr)
                      view
                      internal
                    {
                      require(has(role, addr));
                    }
                  
                    /**
                     * @dev check if an address has this role
                     * @return bool
                     */
                    function has(Role storage role, address addr)
                      view
                      internal
                      returns (bool)
                    {
                      return role.bearer[addr];
                    }
                  }