Contract Address Details

0x7b355c571FEde83F152E9585143306C0d2b53193

BitUnitsPOWR BitUnits Proof of Work Reward (BPOWR) Last Balance Update: Block #9630942
Created by 0x7df2ā€“54dcb9 at 0xb80cā€“16dd1f

Balance

0 ETC

(@ /ETC)

Fetching tokens...

Contract name:
BitUnitsPOWR




Optimization enabled
true
Compiler version
v0.4.24+commit.e67f0147





Contract source code

/**
* Submitted for verification at blockscout.com on 2018-11-02 03:11:08.553407Z
*/
pragma solidity ^0.4.23;
// 'Bitunits Proof of Work Reward'
// Mineable ERC223 Token using Proof Of Work
/**
* Symbol : BPOWR
* Name : BitUnitsPOWR
* Total supply: 61,800,000.00
* Decimals : 18
*/
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 BitUnitsPOWR 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**224;
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 = "BPOWR";
name = "BitUnits Proof of Work Reward";
decimals = 18;
totalSupply = 61800000 * 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 61800000000000000000000000 because of 18 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.bitcoin.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 10 minutes to mine each 'block'
// about 60 ethereum blocks = one BCT epoch
uint epochsMined = _BLOCKS_PER_READJUSTMENT;
// should be 60 times slower than ETC
uint targetBlocksPerDiffPeriod = epochsMined * 60;
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;
}
// 42m 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

[{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":""}],"name":"name","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"lastRewardEthBlockNumber","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getMiningDifficulty","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"success"}],"name":"mint","inputs":[{"type":"uint256","name":"nonce"},{"type":"bytes32","name":"challenge_digest"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":"_supply"}],"name":"totalSupply","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"rewardEra","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint8","name":""}],"name":"decimals","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getMiningTarget","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"getMiningReward","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bytes32","name":""}],"name":"getChallengeNumber","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"maxSupplyForEra","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"tokensMinted","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"address","name":""}],"name":"lastRewardTo","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"balanceOf","inputs":[{"type":"address","name":"who"}],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"epochCount","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"_MAXIMUM_TARGET","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"miningTarget","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"bytes32","name":""}],"name":"challengeNumber","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"string","name":""}],"name":"symbol","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"success"}],"name":"transfer","inputs":[{"type":"address","name":"_to"},{"type":"uint256","name":"_value"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"_BLOCKS_PER_READJUSTMENT","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"lastRewardAmount","inputs":[],"constant":true},{"type":"function","stateMutability":"nonpayable","payable":false,"outputs":[{"type":"bool","name":"success"}],"name":"transfer","inputs":[{"type":"address","name":"_to"},{"type":"uint256","name":"_value"},{"type":"bytes","name":"_data"}],"constant":false},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"latestDifficultyPeriodStarted","inputs":[],"constant":true},{"type":"function","stateMutability":"view","payable":false,"outputs":[{"type":"uint256","name":""}],"name":"_MINIMUM_TARGET","inputs":[],"constant":true},{"type":"constructor","stateMutability":"nonpayable","payable":false,"inputs":[{"type":"uint256","name":"_startBlock"}]},{"type":"fallback","stateMutability":"payable","payable":true},{"type":"event","name":"Mint","inputs":[{"type":"address","name":"from","indexed":true},{"type":"uint256","name":"reward_amount","indexed":false},{"type":"uint256","name":"epochCount","indexed":false},{"type":"bytes32","name":"newChallengeNumber","indexed":false}],"anonymous":false},{"type":"event","name":"Transfer","inputs":[{"type":"address","name":"_from","indexed":true},{"type":"address","name":"_to","indexed":true},{"type":"uint256","name":"_value","indexed":false}],"anonymous":false},{"type":"event","name":"ERC223Transfer","inputs":[{"type":"address","name":"_from","indexed":true},{"type":"address","name":"_to","indexed":true},{"type":"uint256","name":"_value","indexed":false},{"type":"bytes","name":"_data","indexed":false}],"anonymous":false}]
            

Contract Byte Code

0x6080604052600436106101485763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166306fdde03811461014d578063163aa00d146101d757806317da485f146101fe5780631801fbe51461021357806318160ddd146102425780632d38bf7a14610257578063313ce5671461026c57806332e9970814610297578063490203a7146102ac5780634ef37628146102c15780634fa972e1146102d65780636de9f32b146102eb5780636fd396d61461030057806370a0823114610331578063829965cc1461035257806387a2a9d6146103675780638a769d351461037c5780638ae0368b1461039157806395d89b41146103a6578063a9059cbb146103bb578063b5ade81b146103df578063bafedcaa146103f4578063be45fd6214610409578063cb9ae70714610472578063dc6e9cf914610487575b600080fd5b34801561015957600080fd5b5061016261049c565b6040805160208082528351818301528351919283929083019185019080838360005b8381101561019c578181015183820152602001610184565b50505050905090810190601f1680156101c95780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156101e357600080fd5b506101ec61052f565b60408051918252519081900360200190f35b34801561020a57600080fd5b506101ec610535565b34801561021f57600080fd5b5061022e600435602435610553565b604080519115158252519081900360200190f35b34801561024e57600080fd5b506101ec610726565b34801561026357600080fd5b506101ec61072c565b34801561027857600080fd5b50610281610732565b6040805160ff9092168252519081900360200190f35b3480156102a357600080fd5b506101ec61073b565b3480156102b857600080fd5b506101ec610741565b3480156102cd57600080fd5b506101ec610760565b3480156102e257600080fd5b506101ec610766565b3480156102f757600080fd5b506101ec61076c565b34801561030c57600080fd5b50610315610772565b60408051600160a060020a039092168252519081900360200190f35b34801561033d57600080fd5b506101ec600160a060020a0360043516610781565b34801561035e57600080fd5b506101ec61079c565b34801561037357600080fd5b506101ec6107a2565b34801561038857600080fd5b506101ec6107a8565b34801561039d57600080fd5b506101ec6107ae565b3480156103b257600080fd5b506101626107b4565b3480156103c757600080fd5b5061022e600160a060020a0360043516602435610814565b3480156103eb57600080fd5b506101ec61084a565b34801561040057600080fd5b506101ec610850565b34801561041557600080fd5b50604080516020600460443581810135601f810184900484028501840190955284845261022e948235600160a060020a03169460248035953695946064949201919081908401838280828437509497506108569650505050505050565b34801561047e57600080fd5b506101ec61088a565b34801561049357600080fd5b506101ec610890565b60028054604080516020601f60001961010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156105255780601f106104fa57610100808354040283529160200191610525565b820191906000526020600020905b81548152906001019060200180831161050857829003601f168201915b5050505050905090565b60125481565b600061054e600c54600b5461089690919063ffffffff16565b905090565b60008060008060065443101561056857600080fd5b600d54604080516020808201939093526c0100000000000000000000000033028183015260548082018a905282518083039091018152607490910191829052805190928291908401908083835b602083106105d45780518252601f1990920191602091820191016105b5565b5181516020939093036101000a6000190180199091169216919091179052604051920182900390912095505050858414905061060f57600080fd5b600c5483111561061e57600080fd5b600d5460009081526013602052604090208054908490559150811561064257600080fd5b61064a610741565b3360009081526005602052604090205490915061066d908263ffffffff6108b716565b33600090815260056020526040902055601454610690908263ffffffff6108b716565b6014819055600f5410156106a057fe5b6010805473ffffffffffffffffffffffffffffffffffffffff1916331790556011819055436012556106d06108cd565b600854600d54604080518481526020810193909352828101919091525133917fcf6fbb9dcea7d07263ab4f5c3a92f53af33dffc421d9d121e1c74b307e68189d919081900360600190a250600195945050505050565b60045490565b600e5481565b60035460ff1690565b600c5490565b600e5460035460009161054e9160ff16600a0a6032029060020a610896565b600d5490565b600f5481565b60145481565b601054600160a060020a031681565b600160a060020a031660009081526005602052604090205490565b60085481565b600b5481565b600c5481565b600d5481565b60018054604080516020601f600260001961010087891615020190951694909404938401819004810282018101909252828152606093909290918301828280156105255780601f106104fa57610100808354040283529160200191610525565b600060606108218461096c565b156108385761083184848361098c565b9150610843565b610831848483610bea565b5092915050565b60095481565b60115481565b60006108618461096c565b156108785761087184848461098c565b9050610883565b610871848484610bea565b9392505050565b60075481565b600a5481565b60008082116108a457600080fd5b81838115156108af57fe5b049392505050565b818101828110156108c757600080fd5b92915050565b600f546108ea6108db610741565b6014549063ffffffff6108b716565b1180156108f957506027600e54105b1561090857600e805460010190555b610937610928600e5460010160020a60045461089690919063ffffffff16565b6004549063ffffffff610d3f16565b600f5560088054600101908190556009549081151561095257fe5b06151561096157610961610d54565b600019430140600d55565b6000813b818111156109815760019150610986565b600091505b50919050565b6000808361099933610781565b10156109a457600080fd5b6109bd846109b133610781565b9063ffffffff610d3f16565b336000908152600560205260409020556109e6846109da87610781565b9063ffffffff6108b716565b600160a060020a03861660008181526005602090815260408083209490945592517fc0ee0b8a0000000000000000000000000000000000000000000000000000000081523360048201818152602483018a90526060604484019081528951606485015289518c9850959663c0ee0b8a9693958c958c956084909101928601918190849084905b83811015610a84578181015183820152602001610a6c565b50505050905090810190601f168015610ab15780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b158015610ad257600080fd5b505af1158015610ae6573d6000803e3d6000fd5b5050604080518781529051600160a060020a03891693503392507fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9181900360200190a384600160a060020a031633600160a060020a03167f9bfafdc2ae8835972d7b64ef3f8f307165ac22ceffde4a742c52da5487f45fd186866040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610ba4578181015183820152602001610b8c565b50505050905090810190601f168015610bd15780820380516001836020036101000a031916815260200191505b50935050505060405180910390a3506001949350505050565b600082610bf633610781565b1015610c0157600080fd5b610c0e836109b133610781565b33600090815260056020526040902055610c2b836109da86610781565b600160a060020a0385166000818152600560209081526040918290209390935580518681529051919233927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9281900390910190a383600160a060020a031633600160a060020a03167f9bfafdc2ae8835972d7b64ef3f8f307165ac22ceffde4a742c52da5487f45fd185856040518083815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610cfa578181015183820152602001610ce2565b50505050905090810190601f168015610d275780820380516001836020036101000a031916815260200191505b50935050505060405180910390a35060019392505050565b600082821115610d4e57600080fd5b50900390565b6000806000806000806000610d7460075443610d3f90919063ffffffff16565b9650600954955085603c02945084871015610e1257610daa87610d9e87606463ffffffff610ea616565b9063ffffffff61089616565b9350610dcf6103e8610dc386606463ffffffff610d3f16565b9063ffffffff610ecb16565b9250610e0a610dfb84610def6107d0600c5461089690919063ffffffff16565b9063ffffffff610ea616565b600c549063ffffffff610d3f16565b600c55610e73565b610e2785610d9e89606463ffffffff610ea616565b9150610e406103e8610dc384606463ffffffff610d3f16565b9050610e6f610e6082610def6107d0600c5461089690919063ffffffff16565b600c549063ffffffff6108b716565b600c555b43600755600a54600c541015610e8a57600a54600c555b600b54600c541115610e9d57600b54600c555b50505050505050565b818102821580610ec05750818382811515610ebd57fe5b04145b15156108c757600080fd5b600081831115610edc5750806108c7565b50909190505600a165627a7a72305820cfefee89624d0197bd06204371825fac8ec43cd5154c54d1a2412ccbc22a32ac0029