A 2017 conceptual token by Constantine Nicholas using block.number as the price variable; non-standard 6-field Transfer event.
Historical Significance
A conceptual on-chain art piece treating block height as the price-determining variable, paired with BDI (block.difficulty). Predates the wider ICO frenzy of late 2017.
Context
Deployed during the early-2017 Homestead era, three months before the late-2017 ICO peak. The author Constantine Nicholas appears only in this trio of contracts, suggesting a one-time conceptual experiment.
Token Information
Key Facts
Description
Block Height Index (BHI) is one of three sibling contracts deployed Feb 20, 2017 by Constantine Nicholas. The contract treats block.number as the price-determining variable, with buy() minting at "price" = msg.value * 10^18 / block.number / Fee.
A fixed Fee fraction (default 1/100) of every buy, sell, transfer, and transferFrom is skimmed to the contract owner. The Transfer event has six fields (from, to, amount, fee_amount, lastBuyPrice, lastSellPrice), not the standard three, which prevents direct Uniswap listing.
Owner-callable functions: transferOwnership, changeFee (floor of 100). No mint, freeze, or drain backdoor. Buy works today; sell is unprofitable at current chain state (sell rate ~780x below buy rate).
Source Verified
Source reconstruction. All 18 selectors and dispatch addresses match; function bodies match the decompiled fee-skim logic. ~21 bytes longer due to solc 0.4.6 helper placement.. Optimizer: ON (200 runs)
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Spurious Dragon Era
Continued DoS protection. State trie clearing.
Bytecode Overview
Verified Source Available
This contract has verified source code.
View Verification ProofShow source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
pragma solidity ^0.4.0;
contract owned {
address public owner;
function owned() {
owner = msg.sender;
}
modifier onlyOwner {
if (msg.sender != owner) throw;
_;
}
function transferOwnership(address newOwner) onlyOwner {
owner = newOwner;
}
}
contract tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData); }
contract BlockHeightIndex is owned {
string public name = "Constantine Nicholas: Block Height Index";
string public symbol = "BHI";
uint8 public decimals = 18;
uint256 public totalSupply;
uint256 public Fee = 100;
uint256 public lastBuyPrice;
uint256 public lastSellPrice;
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance;
event Transfer(address from, address to, uint256 a, uint256 b, uint256 c, uint256 d);
event Buy(address from, address to, uint256 a, uint256 b, uint256 c, uint256 d);
event Sell(address from, address to, uint256 a, uint256 b, uint256 c, uint256 d);
function BlockHeightIndex(uint256 initialSupply) {
balanceOf[msg.sender] = initialSupply;
totalSupply = initialSupply;
}
function transfer(address _to, uint256 _value) {
if (balanceOf[msg.sender] < _value) throw;
if (balanceOf[_to] + _value < balanceOf[_to]) throw;
uint feeAmount = _value / Fee;
if (feeAmount == 0) throw;
balanceOf[msg.sender] -= _value;
balanceOf[_to] += _value - feeAmount;
balanceOf[owner] += feeAmount;
Transfer(msg.sender, _to, _value, feeAmount, lastBuyPrice, lastSellPrice);
}
function approve(address _spender, uint256 _value) returns (bool success) {
allowance[msg.sender][_spender] = _value;
return true;
}
function approveAndCall(address _spender, uint256 _value, bytes _extraData)
returns (bool success) {
allowance[msg.sender][_spender] = _value;
tokenRecipient(_spender).receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
if (balanceOf[_from] < _value) throw;
if (balanceOf[_to] + _value < balanceOf[_to]) throw;
if (_value > allowance[_from][msg.sender]) throw;
uint feeAmount = _value / Fee;
if (feeAmount == 0) throw;
balanceOf[_from] -= _value;
balanceOf[_to] += _value - feeAmount;
balanceOf[owner] += feeAmount;
allowance[_from][msg.sender] -= _value;
Transfer(_from, _to, _value, feeAmount, lastBuyPrice, lastSellPrice);
return true;
}
function changeFee(uint256 _newFee) onlyOwner {
if (_newFee < 100) throw;
Fee = _newFee;
}
function buy() payable {
uint amount = 10**18 * msg.value / block.number;
uint feeAmount = amount / Fee;
if (feeAmount == 0) throw;
balanceOf[msg.sender] += amount - feeAmount;
balanceOf[owner] += feeAmount;
totalSupply += amount;
lastBuyPrice = block.number;
Buy(this, msg.sender, amount, feeAmount, block.number, lastSellPrice);
}
function sell(uint256 amount) payable {
if (msg.value > 0) throw;
if (balanceOf[msg.sender] < amount) throw;
uint feeAmount = amount / Fee;
if (feeAmount == 0) throw;
balanceOf[msg.sender] -= amount;
balanceOf[owner] += feeAmount;
totalSupply = totalSupply - amount + feeAmount;
lastSellPrice = this.balance * 10**18 / totalSupply;
if (!msg.sender.send((amount - feeAmount) * lastSellPrice / 10**18)) throw;
Sell(this, msg.sender, amount, feeAmount, lastBuyPrice, lastSellPrice);
}
function () {
throw;
}
}