Bytecode verified via sibling
This contract shares identical runtime bytecode with testVUNK (0x2b5b9de0...) which has been verified through compiler archaeology.
A 1,000 unit rehearsal of the PreVNK token contract, deployed an hour into the team's session on 31 January 2016.
Historical Significance
PreVNK is an uncommon case for the Frontier era: the original Solidity survives from the authors themselves rather than from reconstruction. The FreeMyVunk account published the contract to GitHub at 20:31 UTC on 31 January 2016, nine minutes after the production deployment, and that file still recompiles byte for byte to both the runtime and the creation code of all four deployments in this cluster. The contract also records a problem ERC-20 had not yet solved. It emits a non standard TransferFrom event alongside Transfer, because, as its own comment explains, the standard Transfer event alone did not let an observer rebuild balances from logs.
Context
EIP-20 was still an open issue on the day these went out, and the project README points straight at it. The five deployments were made from the Mist wallet across 96 minutes by three different addresses, iterating on one design. The earlier ones assign to the issuer balance inside issue(), the later ones increment it instead, a one character edit that shows up as a three byte difference in the deployed runtime. The source also carries comments citing Solidity issues 333 and 281, optimizer storage bugs that were live at the time, warning that the statement order inside transferFrom must not be tidied up or the contract breaks.
Token Information
Key Facts
Source Verified
Exact runtime + creation bytecode match. Runtime 1308 bytes, creation 1750 bytes plus 256 bytes of ABI encoded constructor arguments. Compiled with soljson-v0.2.0+commit.4dc2445e, optimizer ON.
Heuristic Analysis
The following characteristics were detected through bytecode analysis and may not be accurate.
Frontier Era
The initial release of Ethereum. A bare-bones implementation for technical users.
Bytecode Overview
Verified Source Available
Source verified through compiler archaeology and exact bytecode matching.
View Verification ProofShow source code (Solidity)
contract Token {
/// @return total amount of tokens
function totalSupply() constant returns (uint256 supply) {}
/// @param _owner The address from which the balance will be retrieved
/// @return The balance
function balanceOf(address _owner) constant returns (uint256 balance) {}
/// @notice send `_value` token to `_to` from `msg.sender`
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
/// @return Whether the transfer was successful or not
function transfer(address _to, uint256 _value) returns (bool success) {}
/// @notice send `_value` token to `_to` from `_from` on the condition it is approved by `_from`
/// @param _from The address of the sender
/// @param _to The address of the recipient
/// @param _value The amount of token to be transferred
/// @return Whether the transfer was successful or not
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {}
/// @notice `msg.sender` approves `_addr` to spend `_value` tokens
/// @param _spender The address of the account able to transfer the tokens
/// @param _value The amount of wei to be approved for transfer
/// @return Whether the approval was successful or not
function approve(address _spender, uint256 _value) returns (bool success) {}
/// @param _owner The address of the account owning tokens
/// @param _spender The address of the account able to transfer the tokens
/// @return Amount of remaining tokens allowed to spent
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {}
/// @param _new_amount The amount of new tokens to issue
/// @return Whether the issuance is successful
function issue(uint256 _new_amount) returns (bool success) {}
/// @param _new_issuer The address that can issue new tokens
/// @return Whether the issuance was successful
function setIssuer(address _new_issuer) returns (bool success) {}
event Transfer(address indexed _from, address indexed _to, uint256 _value);
//TransferFrom event is not standard yet (wrt ERC20), but is required to recreate state when only using events.
event TransferFrom(address indexed _from, address indexed _to, uint256 _value);
event Approval(address indexed _owner, address indexed _spender, uint256 _value);
}
contract PreVNK is Token {
address issuer;
string public name;
string public symbol;
uint8 public decimals;
modifier ifissuer { if(issuer == tx.origin) _ }
function PreVNK(uint256 _initial_amount, string _name, string _symbol, uint8 _decimals) {
balances[msg.sender] = _initial_amount;
total_supply = _initial_amount;
issuer = tx.origin;
name = _name;
symbol = _symbol;
decimals = _decimals;
}
function issue(uint256 _new_amount) ifissuer returns (bool success) {
balances[issuer] = _new_amount;
total_supply += _new_amount;
return true;
}
function setIssuer(address _new_issuer) ifissuer returns (bool success) {
issuer = _new_issuer;
return true;
}
function transfer(address _to, uint256 _value) returns (bool success) {
//Default assumes totalSupply can't be over max (2^256 - 1).
//If your token leaves out totalSupply and can issue more tokens as time goes on, you need to check if it doesn't wrap.
//Replace the if with this one instead.
//if (balances[msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
if (balances[msg.sender] >= _value && _value > 0) {
balances[msg.sender] -= _value;
balances[_to] += _value;
Transfer(msg.sender, _to, _value);
return true;
} else { return false; }
}
//NOTE: This function will throw errors wrt changing storage where it should not, due to the optimizer errors, IF not careful.
//As it is now, it works for both earlier and newer solc versions. (NO need to change anything)
//In the future, the TransferFrom event will be moved to just before "return true;" in order to make it more elegant (once the new solc version is out of develop).
//If you want to move parts of this function around and it breaks, you'll need at least:
//Over commit: https://github.com/ethereum/solidity/commit/67c855c583042ddee6261a9921239a3afd086c14 (last successfully working commit)
//See issue for details: https://github.com/ethereum/solidity/issues/333 & issue: https://github.com/ethereum/solidity/issues/281
function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
//same as above. Replace this line with the following if you want to protect against wrapping uints.
//if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && balances[_to] + _value > balances[_to]) {
if (balances[_from] >= _value && allowed[_from][msg.sender] >= _value && _value > 0) {
balances[_to] += _value;
TransferFrom(_from, _to, _value);
balances[_from] -= _value;
allowed[_from][msg.sender] -= _value;
return true;
} else { return false; }
}
function balanceOf(address _owner) constant returns (uint256 balance) {
return balances[_owner];
}
function approve(address _spender, uint256 _value) returns (bool success) {
allowed[msg.sender][_spender] = _value;
Approval(msg.sender, _spender, _value);
return true;
}
function allowance(address _owner, address _spender) constant returns (uint256 remaining) {
return allowed[_owner][_spender];
}
function totalSupply() constant returns (uint256 _total) {
return total_supply;
}
mapping (address => uint256) balances;
mapping (address => mapping (address => uint256)) allowed;
uint256 total_supply;
}External Links
Related contracts
TestIssue
Same deployerThe last rehearsal of the PreVNK token, deployed 13 minutes before the production contract with a supply of 5,000.
0x610f1d...87f701January 31, 2016token
Same eraAn early ERC-20-like token deployed in Ethereum's first week, built directly from the example in the official Ethereum Frontier Guide documentation.
0x8374f5...46609aAugust 7, 2015token
Same eraA second deployment of the FirstCoin tutorial token by the same creator, 11 blocks after the original — both derived from the official Ethereum Frontier Guide e
0x3b4446...295f52August 7, 2015Contract 0xd958b5...ec4c9f
Same eraEthereum.org tutorial Coin contract deployed on Frontier day 1. Contains a bug: balance(address) ignores its argument and returns msg.sender balance.
0xd958b5...ec4c9fAugust 7, 2015NameRegistry
Same eraFixed-fee name registry from Day 9 of Ethereum (Aug 8, 2015). Reserve names for 69 ETH, resolve addresses. A precursor to ENS.
0xa1a111...b8af00August 8, 2015token
Same eraEarly tutorial-derived coin contract compiled with Solidity v0.1.1, deployed 9 days after Ethereum Frontier launch.
0x3c401b...da1634August 8, 2015