LCT Litecoin Classic Token
Featured: Register HENS (.etc) Domain Name Click to register
Overview [ERC-20]
Max Total Supply:
84,000,000
Holders:
1,588
Transfers:
2,700
Profile Summary
Decimals:
8
Official Site:
FILTERED BY TOKEN HOLDER
BALANCE
32,874.42 LCT
VALUE
$0 (~0 ETC)
Contract name:
LCT
Optimization enabled :
false
Compiler version:
v0.4.24+commit.e67f0147
EVM Version:
default
Contract source code
pragma solidity ^0.4.23;

/**
* Symbol      : LCT
* Name        : Litecoin Classic Token
* Total supply: 84,000,000.00
* Decimals    : 8
*/

library SafeMath {
  function add(uint a, uint b) internal pure returns (uint c) {
    c = a + b;
    require(c >= a);
  }

  function sub(uint a, uint b) internal pure returns (uint c) {
    require(b <= a);
    c = a - b;
  }

  function mul(uint a, uint b) internal pure returns (uint c) {
    c = a * b;
    require(a == 0 || c / a == b);
  }

  function div(uint a, uint b) internal pure returns (uint c) {
    require(b > 0);
    c = a / b;
  }
}

library ExtendedMath {
  // return the smaller of the two inputs (a or b)
  function limitLessThan(uint a, uint b) internal pure returns (uint c) {
    if (a > b) return b;
    return a;
  }
}

contract ERC223 {
  uint public totalSupply;

  function balanceOf(address who) public constant returns (uint);
  function name() public constant returns (string _name);
  function symbol() public constant returns (string _symbol);
  function decimals() public constant returns (uint8 _decimals);
  function totalSupply() public constant returns (uint256 _supply);
  function transfer(address to, uint value) public returns (bool ok);
  function transfer(address to, uint value, bytes data) public returns (bool ok);

  event Transfer(address indexed _from, address indexed _to, uint256 _value);
  event ERC223Transfer(address indexed _from, address indexed _to, uint256 _value, bytes _data);
}

contract ContractReceiver {
  function tokenFallback(address _from, uint _value, bytes _data) public;
}

contract LCT is ERC223 {
  using SafeMath for uint;
  using ExtendedMath for uint;

  string public symbol;
  string public name;
  uint8 public decimals;
  uint public totalSupply;
  mapping(address => uint) balances;

  uint private startBlock;
  uint public latestDifficultyPeriodStarted;
  uint public epochCount; // number of 'blocks' mined
  uint public _BLOCKS_PER_READJUSTMENT = 2016;
  uint public  _MINIMUM_TARGET = 2**16;
  uint public  _MAXIMUM_TARGET = 2**234;
  uint public miningTarget;
  bytes32 public challengeNumber;
  uint public rewardEra;
  uint public maxSupplyForEra;
  address public lastRewardTo;
  uint public lastRewardAmount;
  uint public lastRewardEthBlockNumber;
  mapping(bytes32 => bytes32) solutionForChallenge;
  uint public tokensMinted;

  event Mint(address indexed from, uint reward_amount, uint epochCount, bytes32 newChallengeNumber);

  constructor(uint _startBlock) public {
    symbol      = "LCT";
    name        = "Litecoin Classic Token";
    decimals    = 8;
    totalSupply = 84000000 * 10**uint(decimals);

    maxSupplyForEra = totalSupply.div(2);
    miningTarget    = _MAXIMUM_TARGET;
    startBlock      = _startBlock;

    latestDifficultyPeriodStarted = block.number;
    _startNewMiningEpoch();
  }

  function () public payable {
    revert();
  }

  function mint(uint256 nonce, bytes32 challenge_digest) public returns (bool success) {
    // in order to ensure fair launch revert all mining transactions
    // that happen before startBlock
    if (block.number < startBlock) revert();
    // the PoW must contain work that includes a recent ETC block hash (challenge number) and the msg.sender's address to prevent MITM attacks
    bytes32 digest =  keccak256(abi.encodePacked(challengeNumber, msg.sender, nonce));
    // the challenge digest must match the expected
    if (digest != challenge_digest) revert();
    // the digest must be smaller than the target
    if (uint256(digest) > miningTarget) revert();
    // only allow one reward for each challenge
    bytes32 solution = solutionForChallenge[challengeNumber];
    solutionForChallenge[challengeNumber] = digest;
    if (solution != 0x0) revert();  // prevent the same answer from awarding twice

    uint reward_amount = getMiningReward();
    balances[msg.sender] = balances[msg.sender].add(reward_amount);
    tokensMinted = tokensMinted.add(reward_amount);
    // Cannot mint more tokens than there are
    assert(tokensMinted <= maxSupplyForEra);

    // set readonly diagnostics data
    lastRewardTo = msg.sender;
    lastRewardAmount = reward_amount;
    lastRewardEthBlockNumber = block.number;

    _startNewMiningEpoch();
    emit Mint(msg.sender, reward_amount, epochCount, challengeNumber);
    return true;
  }

  // a new 'block' to be mined
  function _startNewMiningEpoch() internal {
    // if max supply for the era will be exceeded next reward round then
    // enter the new era before that happens

    // 40 is the final reward era, almost all tokens minted
    // once the final era is reached, more tokens will not be given out
    // because of the assertion
    if (tokensMinted.add(getMiningReward()) > maxSupplyForEra && rewardEra < 39) {
      rewardEra++;
    }

    // set the next minted supply at which the era will change
    // total supply is 8400000000000000  because of 8 decimal places
    maxSupplyForEra = totalSupply.sub(totalSupply.div(2**(rewardEra + 1)));
    epochCount++;

    // every so often, readjust difficulty. Dont readjust when deploying
    if (epochCount % _BLOCKS_PER_READJUSTMENT == 0) {
      _reAdjustDifficulty();
    }

    // make the latest ETC block hash a part of the next challenge for PoW
    // to prevent pre-mining future blocks
    // do this last since this is a protection mechanism in the mint() function
    challengeNumber = blockhash(block.number - 1);
  }

  //https://en.Litecoin.it/wiki/Difficulty#What_is_the_formula_for_difficulty.3F
  //as of 2017 the bitcoin difficulty was up to 17 zeroes, it was only 8 in the early days
  // readjust the target by 5 percent
  function _reAdjustDifficulty() internal {
    uint blocksSinceLastDifficultyPeriod = block.number.sub(latestDifficultyPeriodStarted);
    // assume 360 ETC blocks per hour
    // we want miners to spend 2.5 minutes to mine each 'block'
    // about 15 ethereum blocks = one LCT epoch
    uint epochsMined = _BLOCKS_PER_READJUSTMENT;
    // should be 15 times slower than ETC
    uint targetBlocksPerDiffPeriod = epochsMined * 15;

    if (blocksSinceLastDifficultyPeriod < targetBlocksPerDiffPeriod) {
      // make it harder
      uint excess_block_pct = targetBlocksPerDiffPeriod.mul(100).div(blocksSinceLastDifficultyPeriod);
      uint excess_block_pct_extra = excess_block_pct.sub(100).limitLessThan(1000);
      miningTarget = miningTarget.sub(miningTarget.div(2000).mul(excess_block_pct_extra));
    } else {
      // make it easier
      uint shortage_block_pct = blocksSinceLastDifficultyPeriod.mul(100).div(targetBlocksPerDiffPeriod);
      uint shortage_block_pct_extra = shortage_block_pct.sub(100).limitLessThan(1000);
      miningTarget = miningTarget.add(miningTarget.div(2000).mul(shortage_block_pct_extra));
    }

    latestDifficultyPeriodStarted = block.number;

    if (miningTarget < _MINIMUM_TARGET) {
      miningTarget = _MINIMUM_TARGET;
    }

    if (miningTarget > _MAXIMUM_TARGET) {
      miningTarget = _MAXIMUM_TARGET;
    }
  }

  function getChallengeNumber() public constant returns (bytes32) {
    return challengeNumber;
  }

  function getMiningDifficulty() public constant returns (uint) {
    return _MAXIMUM_TARGET.div(miningTarget);
  }

  function getMiningTarget() public constant returns (uint) {
    return miningTarget;
  }

  // 84m coins total
  // reward begins at 50 and is cut in half every reward era (as tokens are mined)
  function getMiningReward() public constant returns (uint) {
    return (50 * 10**uint(decimals)).div(2**rewardEra);
  }

  // ERC223 functionality
  function name() public constant returns (string) {
    return name;
  }

  function symbol() public constant returns (string) {
    return symbol;
  }

  function decimals() public constant returns (uint8) {
    return decimals;
  }

  function totalSupply() public constant returns (uint256 _supply) {
    return totalSupply;
  }

  function balanceOf(address who) public constant returns (uint) {
    return balances[who];
  }

  function transfer(address _to, uint _value, bytes _data) public returns (bool success) {
    if (isContract(_to)) {
      return transferToContract(_to, _value, _data);
    } else {
      return transferToAddress(_to, _value, _data);
    }
  }

  function transfer(address _to, uint _value) public returns (bool success) {
    bytes memory empty;
    if (isContract(_to)) {
      return transferToContract(_to, _value, empty);
    } else {
      return transferToAddress(_to, _value, empty);
    }
  }

  function isContract(address _addr) private view returns (bool) {
    uint length;
    assembly {
      length := extcodesize(_addr)
    }
    if (length > 0) {
      return true;
    } else {
      return false;
    }
  }

  function transferToAddress(address _to, uint _value, bytes _data) private returns (bool success) {
    if (balanceOf(msg.sender) < _value) revert();
    balances[msg.sender] = balanceOf(msg.sender).sub(_value);
    balances[_to] = balanceOf(_to).add(_value);
    emit Transfer(msg.sender, _to, _value);
    emit ERC223Transfer(msg.sender, _to, _value, _data);
    return true;
  }

  function transferToContract(address _to, uint _value, bytes _data) private returns (bool success) {
    if (balanceOf(msg.sender) < _value) revert();
    balances[msg.sender] = balanceOf(msg.sender).sub(_value);
    balances[_to] = balanceOf(_to).add(_value);
    ContractReceiver reciever = ContractReceiver(_to);
    reciever.tokenFallback(msg.sender, _value, _data);
    emit Transfer(msg.sender, _to, _value);
    emit ERC223Transfer(msg.sender, _to, _value, _data);
    return true;
  }
}
Contract ABI
[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastRewardEthBlockNumber","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getMiningDifficulty","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"nonce","type":"uint256"},{"name":"challenge_digest","type":"bytes32"}],"name":"mint","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"_supply","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"rewardEra","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getMiningTarget","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getMiningReward","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getChallengeNumber","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxSupplyForEra","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokensMinted","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastRewardTo","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"epochCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_MAXIMUM_TARGET","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"miningTarget","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"challengeNumber","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"_BLOCKS_PER_READJUSTMENT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastRewardAmount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"},{"name":"_data","type":"bytes"}],"name":"transfer","outputs":[{"name":"success","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"latestDifficultyPeriodStarted","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_MINIMUM_TARGET","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_startBlock","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":false,"name":"reward_amount","type":"uint256"},{"indexed":false,"name":"epochCount","type":"uint256"},{"indexed":false,"name":"newChallengeNumber","type":"bytes32"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_from","type":"address"},{"indexed":true,"name":"_to","type":"address"},{"indexed":false,"name":"_value","type":"uint256"},{"indexed":false,"name":"_data","type":"bytes"}],"name":"ERC223Transfer","type":"event"}]