Bytecode verified via sibling
This contract shares identical runtime bytecode with NameRegister (0x5564886c...) which has been verified through compiler archaeology.
The official Ethereum GlobalRegistrar - a name registry pre-compiled and embedded directly in go-ethereum, deployed on August 22, 2015.
Key Facts
Description
The official Ethereum GlobalRegistrar, deployed at block 51,245 (August 22, 2015) by 0x3d0768da09. This is the canonical name registry pre-compiled by the Ethereum Foundation and embedded as GlobalRegistrarCode in go-ethereum's common/registrar/contracts.go (commit 83ee39448e, June 23, 2015). The deployer used go-ethereum's built-in --registrar deployment tool, which sent the embedded bytecode directly - no independent compilation required. The contract maps bytes32 names to owners, addresses, sub-registrars, and content hashes. It implements the full Registrar interface with 13 functions including reserve, transfer, disown, setAddress, and setContent. Notably, register(bytes32) is a temporary alias returning the sub-registrar address (the canonical subRegistrar() getter is commented out in source with a 'TODO: bring in on next iteration' note). Identical bytecode to the earlier deployment at block 50,466 (0x1392a4f1).
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 on Etherscan.
View on EtherscanShow source code (Solidity)
contract NameRegister {
function addr(bytes32 _name) constant returns (address o_owner) {}
function name(address _owner) constant returns (bytes32 o_name) {}
}
contract Registrar is NameRegister {
event Changed(bytes32 indexed name);
event PrimaryChanged(bytes32 indexed name, address indexed addr);
function owner(bytes32 _name) constant returns (address o_owner) {}
function addr(bytes32 _name) constant returns (address o_address) {}
function subRegistrar(bytes32 _name) constant returns (address o_subRegistrar) {}
function content(bytes32 _name) constant returns (bytes32 o_content) {}
function name(address _owner) constant returns (bytes32 o_name) {}
}
contract GlobalRegistrar is Registrar {
struct Record {
address owner;
address primary;
address subRegistrar;
bytes32 content;
uint value;
uint renewalDate;
}
function Registrar() {
// TODO: Populate with hall-of-fame.
}
function reserve(bytes32 _name) {
// Don't allow the same name to be overwritten.
// TODO: bidding mechanism
if (m_toRecord[_name].owner == 0) {
m_toRecord[_name].owner = msg.sender;
Changed(_name);
}
}
/*
TODO
> 12 chars: free
<= 12 chars: auction:
1. new names are auctioned
- 7 day period to collect all bid bytes32es + deposits
- 1 day period to collect all bids to be considered (validity requires associated deposit to be >10% of bid)
- all valid bids are burnt except highest - difference between that and second highest is returned to winner
2. remember when last auctioned/renewed
3. anyone can force renewal process:
- 7 day period to collect all bid bytes32es + deposits
- 1 day period to collect all bids & full amounts - bids only uncovered if sufficiently high.
- 1% of winner burnt; original owner paid rest.
*/
modifier onlyrecordowner(bytes32 _name) { if (m_toRecord[_name].owner == msg.sender) _ }
function transfer(bytes32 _name, address _newOwner) onlyrecordowner(_name) {
m_toRecord[_name].owner = _newOwner;
Changed(_name);
}
function disown(bytes32 _name) onlyrecordowner(_name) {
if (m_toName[m_toRecord[_name].primary] == _name)
{
PrimaryChanged(_name, m_toRecord[_name].primary);
m_toName[m_toRecord[_name].primary] = "";
}
delete m_toRecord[_name];
Changed(_name);
}
function setAddress(bytes32 _name, address _a, bool _primary) onlyrecordowner(_name) {
m_toRecord[_name].primary = _a;
if (_primary)
{
PrimaryChanged(_name, _a);
m_toName[_a] = _name;
}
Changed(_name);
}
function setSubRegistrar(bytes32 _name, address _registrar) onlyrecordowner(_name) {
m_toRecord[_name].subRegistrar = _registrar;
Changed(_name);
}
function setContent(bytes32 _name, bytes32 _content) onlyrecordowner(_name) {
m_toRecord[_name].content = _content;
Changed(_name);
}
function owner(bytes32 _name) constant returns (address) { return m_toRecord[_name].owner; }
function addr(bytes32 _name) constant returns (address) { return m_toRecord[_name].primary; }
// function subRegistrar(bytes32 _name) constant returns (address) { return m_toRecord[_name].subRegistrar; } // TODO: bring in on next iteration.
function register(bytes32 _name) constant returns (address) { return m_toRecord[_name].subRegistrar; } // only possible for now
function content(bytes32 _name) constant returns (bytes32) { return m_toRecord[_name].content; }
function name(address _owner) constant returns (bytes32 o_name) { return m_toName[_owner]; }
mapping (address => bytes32) m_toName;
mapping (bytes32 => Record) m_toRecord;
}