An ethereum.org tutorial token deployed with no name and no symbol, that tracks spending against approvals rather than decrementing them.
Historical Significance
Instead of decrementing an allowance as it is drawn, this revision of the tutorial keeps a separate ledger of how much of each approval has been spent and compares against it. The result is the same limit enforced from the opposite direction, and it avoids the write-after-read that made the ERC-20 approve race famous. It is a road the standard did not take, preserved in the contracts that copied the tutorial while it was still there.
This deployment left the name and the symbol empty. Both are set once in the constructor and no function changes them, so the token has no display identity of any kind and never will: a wallet holding it can only ever show its address.
Context
Homestead arrived in March 2016 and the ethereum.org tutorials were rewritten around the transfer and balanceOf names that ERC-20 was standardising. Deploying a token had become a matter of filling in four constructor arguments, and most of the deployments of this period are exactly that.
Token Information
Key Facts
Description
A fixed-supply token supporting transfers and allowance spending, plus approvals that call back into the spending contract. Deployed March 2016 by 0xc0d4b32728acc42b8a610b2a87c867b3ba3810db.
Source Verified
Historian Categories
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Homestead Era
The first planned hard fork. Removed the canary contract, adjusted gas costs.
Bytecode Overview
Verified Source Available
Source verified through compiler archaeology and exact bytecode matching.
View Verification ProofShow source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
contract tokenRecipient { function receiveApproval(address _from, uint256 _value, address _token, bytes _extraData); }
contract MyToken {
/* Public variables of the token */
string public name;
string public symbol;
string public version;
uint8 public decimals;
uint256 public totalSupply;
/* This creates an array with all balances */
mapping (address => uint256) public balanceOf;
mapping (address => mapping (address => uint256)) public allowance;
mapping (address => mapping (address => uint256)) public spentAllowance;
/* This generates a public event on the blockchain that will notify clients */
event Transfer(address indexed from, address indexed to, uint256 value);
/* Initializes contract with initial supply tokens to the creator of the contract */
function MyToken(uint256 initialSupply, string tokenName, uint8 decimalUnits, string tokenSymbol, string versionOfTheCode) {
balanceOf[msg.sender] = 21000000; // Give the creator all initial tokens
totalSupply = initialSupply; // Update total supply
name = tokenName; // Set the name for display purposes
symbol = tokenSymbol; // Set the symbol for display purposes
decimals = decimalUnits; // Amount of decimals for display purposes
version = versionOfTheCode;
}
/* Send coins */
function transfer(address _to, uint256 _value) {
if (balanceOf[msg.sender] < _value) throw; // Check if the sender has enough
if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
balanceOf[msg.sender] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
Transfer(msg.sender, _to, _value); // Notify anyone listening that this transfer took place
}
/* Allow another contract to spend some tokens in your behalf */
function approveAndCall(address _spender, uint256 _value, bytes _extraData) returns (bool success) {
allowance[msg.sender][_spender] = _value;
tokenRecipient spender = tokenRecipient(_spender);
spender.receiveApproval(msg.sender, _value, this, _extraData);
return true;
}
/* A contract attempts to get the coins */
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
if (balanceOf[_from] < _value) throw; // Check if the sender has enough
if (balanceOf[_to] + _value < balanceOf[_to]) throw; // Check for overflows
if (spentAllowance[_from][msg.sender] + _value > allowance[_from][msg.sender]) throw; // Check allowance
balanceOf[_from] -= _value; // Subtract from the sender
balanceOf[_to] += _value; // Add the same to the recipient
spentAllowance[_from][msg.sender] += _value;
Transfer(_from, _to, _value);
return true;
}
/* This unnamed function is called whenever someone tries to send ether to it */
function () {
throw; // Prevents accidental sending of ether
}
}External Links
Related contracts
token
Same deployerMinimal Homestead-era token shell (Mar 14 2016): just a public balanceOf mapping and its compiler-generated getter, with no other functions.
0x38e1da...41a81aMarch 14, 2016token
Same eraBare Homestead-era token (Mar 14 2016): public balanceOf mapping + a single unchecked transfer firing the standard Transfer event.
0xc77f06...494c69March 14, 2016DinastyCoinToken
Same eraHomestead-era transfer-only token, DinastyCoinToken (DCT), fixed supply 200000000 and 6 decimals.
0x3693fd...c11466March 14, 2016sultancoin
Same eraA fixed-supply token with direct transfers only, deployed March 2016.
0x9a11ff...0b797dMarch 15, 2016666๐
Same eraSix hundred and sixty six units, named and ticketed with a ram emoji.
0x7684aa...d0ed06March 16, 2016CampusCoin
Same eraByte-identical deployment of: Standard ethereum.org tutorial token (Homestead, Mar 2016): name/symbol/decimals metadata, a public balanceOf mapping and an overf
0x00f0b1...e6fcd2March 16, 2016