contract EXH is ERC20, Ownable {

  using Math for uint;

  /* Public variables of the token */
  //To store name for token
  string public name;

  //To store symbol for token       
  string public symbol;

  //To store decimal places for token
  uint8 public decimals;    

  //To store decimal version for token
  string public version = 'v1.0'; 

  //To store current supply of EXH Token
  uint public totalSupply;

  //flag to indicate whether transfer of EXH Token is allowed or not
  bool public locked;

  //map to store EXH Token balance corresponding to address
  mapping(address => uint) balances;

  //To store spender with allowed amount of EXH Token to spend corresponding to EXH Token holder's account
  mapping (address => mapping (address => uint)) allowed;

  //To handle ERC20 short address attack  
  modifier onlyPayloadSize(uint size) {
     require(msg.data.length >= size + 4);
     _;
  }
  
  // Lock transfer during Sale
  modifier onlyUnlocked() {
    require(!locked || msg.sender == owner);
    _;
  }

  //Contructor to define EXH Token token properties
  function EXH() public {

    // lock the transfer function during Sale
    locked = true;

    //initial token supply is 0
    totalSupply = 0;

    //Name for token set to EXH Token
    name = 'EXH Token';

    // Symbol for token set to 'EXH'
    symbol = 'EXH';
 
    decimals = 18;
  }
 
  //Implementation for transferring EXH Token to provided address 
  function transfer(address _to, uint _value) onlyPayloadSize(2 * 32) public onlyUnlocked returns (bool){

    //Check provided EXH Token should not be 0
    if (_value > 0 && !(_to == address(0))) {
      //deduct EXH Token amount from transaction initiator
      balances[msg.sender] = balances[msg.sender].Sub(_value);
      //Add EXH Token to balace of target account
      balances[_to] = balances[_to].Add(_value);
      //Emit event for transferring EXH Token
      Transfer(msg.sender, _to, _value);
      return true;
    }
    else{
      return false;
    }
  }

  //Transfer initiated by spender 
  function transferFrom(address _from, address _to, uint _value) onlyPayloadSize(3 * 32) public onlyUnlocked returns (bool) {

    //Check provided EXH Token should not be 0
    if (_value > 0 && (_to != address(0) && _from != address(0))) {
      //Get amount of EXH Token for which spender is authorized
      var _allowance = allowed[_from][msg.sender];
      //Add amount of EXH Token in trarget account's balance
      balances[_to] = balances[_to].Add( _value);
      //Deduct EXH Token amount from _from account
      balances[_from] = balances[_from].Sub( _value);
      //Deduct Authorized amount for spender
      allowed[_from][msg.sender] = _allowance.Sub( _value);
      //Emit event for Transfer
      Transfer(_from, _to, _value);
      return true;
    }else{
      return false;
    }
  }

  //Get EXH Token balance for provided address
  function balanceOf(address _owner) public constant returns (uint balance) {
    return balances[_owner];
  }
  
  //Add spender to authorize for spending specified amount of EXH Token 
  function approve(address _spender, uint _value) public returns (bool) {
    require(_spender != address(0));
    allowed[msg.sender][_spender] = _value;
    //Emit event for approval provided to spender
    Approval(msg.sender, _spender, _value);
    return true;
  }

  //Get EXH Token amount that spender can spend from provided owner's account 
  function allowance(address _owner, address _spender) public constant returns (uint remaining) {
    return allowed[_owner][_spender];
  }
  
}
/**
 * Contract "EXH"
 * Purpose: Create EXH token
 */
function approve(address _spender, uint _value) public returns (bool) {
  require(_spender != address(0));
  allowed[msg.sender][_spender] = _value;
  //Emit event for approval provided to spender
  Approval(msg.sender, _spender, _value);
  return true;
}

//Add spender to authorize for spending specified amount of EXH Token 