Back to Home

globalregistrar

Registry
0x2272d8d4dec7...decc6918f1a9
FrontierContract #130Source VerifiedEdit this contract
Deployed August 10, 2015 (10 years ago)Block 63,331

A second deployment of the Ethereum GlobalRegistrar — the early name registry that predated ENS — made on August 10, 2015.

Key Facts

Deployment Block
63,331
Deployment Date
Aug 10, 2015, 10:31 AM
Code Size
2.8 KB
Gas at Deploy
779,965
Transactions by Year
20154
2022303

Description

This contract is a deployment of the GlobalRegistrar, an early Ethereum name registry system that allowed users to claim human-readable names and associate them with Ethereum addresses. It was deployed at block 63,331 on August 10, 2015 by address 0xdd38c62d238be6bb72162afec32ddccedd3a0a51.

The GlobalRegistrar implements three interfaces: NameRegister (basic name-to-address resolution), Registrar (with owner, address, subRegistrar, and content fields per name), and GlobalRegistrar (the full implementation). Names are reserved via the reserve(bytes32 _name) function on a first-come, first-served basis — the contract explicitly notes a TODO for a proper bidding mechanism.

The source code contains several unfinished TODO comments, including a planned auction for short names (12 characters or fewer) and a hall-of-fame in the constructor. This reflects the iterative, draft nature of early Ethereum infrastructure development.

The Linagee Name Registrar at 0x5564886ca2c518d1964e5fcea4f423b41db9f561 (deployed August 8, 2015) is an earlier deployment of equivalent functionality. Both contracts represent the proto-ENS era of Ethereum naming — before the Ethereum Name Service launched in May 2017.

Source Verified

Etherscan verified

Heuristic Analysis

The following characteristics were detected through bytecode analysis and may not be accurate.

Detected Type: Registry

Frontier Era

The initial release of Ethereum. A bare-bones implementation for technical users.

Block span: 01,149,999
July 30, 2015March 14, 2016

Bytecode Overview

Opcodes2,894
Unique Opcodes147
Jump Instructions72
Storage Operations62

Verified Source Available

Source verified on Etherscan.

Show 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;
}

External Links