First deployment of Gavin Wood's ExpRegistrar, a name registry where every name has a standing price that doubles on each sale.
Historical Significance
One of the registry designs Gavin Wood tried on Frontier while working out how naming should be paid for, alongside the fixed fee registrars and the auction based GlobalRegistrar in ethereum/dapp-bin.
Context
Deployed on 12 August 2015 by 0xb7576e9d314df41ec5506494293afb1bd5d3f65d, two and a half hours before ExpRegistrar.sol first appeared in ethereum/dapp-bin at commit 9e306a469a. The committed file has no reverse name support, so the version running here was ahead of the repository. The same account deployed a revised ExpRegistrar at 0x047cdba9627a8686bb24b3a65d87dab7efa53d31 the next morning. The source shown was compiled with Solidity v0.1.1+commit.6ff4cd6 with the optimizer on, and reproduces both the 2933 byte creation code and the 2914 byte runtime exactly.
Key Facts
Description
Names are bought outright instead of auctioned. The first buyer of an unowned name pays at least 1 ether. After that the name always has a price, and anyone who pays it takes the name and sends the money to the previous owner. The price doubles on every sale, so a name that someone else wants gets expensive quickly. Each record holds a resolved address, a sub registrar, a content hash and an owner, and a second mapping keeps a reverse index from an address back to a name that anyone can set for themselves. Only the owner can change a record, through the onlyrecordowner modifier.
Source Verified
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.
Show source code (Solidity)
// Submitted by EthereumHistory (ethereumhistory.com)
// Simple global registrar with fixed-fee reservations.
// @authors:
// Gav Wood <g@ethdev.com>
contract Registrar {
event Changed(string indexed name);
function owner(string _name) constant returns (address o_owner);
function addr(string _name) constant returns (address o_address);
function subRegistrar(string _name) constant returns (address o_subRegistrar);
function content(string _name) constant returns (bytes32 o_content);
function name(address _addr) constant returns (string o_name);
}
contract ExpRegistrar is Registrar {
struct Record {
address addr;
address subRegistrar;
bytes32 content;
address owner;
uint price;
}
modifier onlyrecordowner(string _name) { if (m_record[_name].owner == msg.sender) _ }
function setContent(string _name, bytes32 _content) onlyrecordowner(_name) {
m_record[_name].content = _content;
Changed(_name);
}
function reserve(string _name) {
Record rec = m_record[_name];
if ((rec.owner == 0 && msg.value >= 1 ether) || (rec.owner != 0 && msg.value >= rec.price)) {
if (rec.price > 0)
rec.owner.send(rec.price);
else
rec.price = msg.value;
rec.price *= 2;
rec.owner = msg.sender;
Changed(_name);
}
}
function transfer(string _name, address _newOwner) onlyrecordowner(_name) {
m_record[_name].owner = _newOwner;
Changed(_name);
}
function setAddr(string _name, address _a) onlyrecordowner(_name) {
m_record[_name].addr = _a;
Changed(_name);
}
function setSubRegistrar(string _name, address _registrar) onlyrecordowner(_name) {
m_record[_name].subRegistrar = _registrar;
Changed(_name);
}
function setName(string _name) {
m_reverse[msg.sender] = _name;
}
function record(string _name) constant returns (address o_addr, address o_subRegistrar, bytes32 o_content, address o_owner) {
Record rec = m_record[_name];
o_addr = rec.addr;
o_subRegistrar = rec.subRegistrar;
o_content = rec.content;
o_owner = rec.owner;
}
function addr(string _name) constant returns (address) { return m_record[_name].addr; }
function subRegistrar(string _name) constant returns (address) { return m_record[_name].subRegistrar; }
function content(string _name) constant returns (bytes32) { return m_record[_name].content; }
function owner(string _name) constant returns (address) { return m_record[_name].owner; }
function name(address _addr) constant returns (string) { return m_reverse[_addr]; }
mapping (string => Record) m_record;
mapping (address => string) m_reverse;
}External Links
Related contracts
NameReg
Same deployerFixed fee name registry deployed 7 August 2015, the night before NameRegistry and by the same account. Same 69 ETH fee, no read functions.
0xc076cf...a339a5August 7, 2015NameRegistry
Same deployerFixed-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, 2015ExpRegistrar
Same deployerRevised ExpRegistrar, deployed six minutes before its source was committed to ethereum/dapp-bin. Seeds itself with the names gavofyork and NameReg.
0x047cdb...a53d31August 13, 2015token
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, 2015