Openname Key-Value Store

Table of Contents

Intro

What this project is

A key-value store on the Bitcoin Blockchain.

What this repo contains

  • code for running a node that participates in the KV store network
    • opennamed
  • code for issuing commands to openname nodes like name lookups and name registrations
    • openname-cli
    • openname python lib

Installation

pip install openname

Debian

Install libzmq-dev

sudo apt-get install libzmq-dev

Design

Design overview

  • validated sequence of operations + rules to interpret them = global consensus / agreed upon view of the system
  • data is simply stored in the blockchain in a defined sequence, and nodes read the blockchain and interpret the sequence of events with a set of defined rules. From this, they build a view of the system that should be in sync. register names by being the first to include the name in a “registration” operation
  • to prevent people from stealing your name, first secretly “preorder” the name, but include a salted hash of the name in the blockchain
  • to associate data with the name, issue an “update” operation by including a hash of the data and storing the data itself in the DHT
  • to lookup the data associated with a name, issue a request to an opennamed node, which will lookup the names entry in the nameset, find the hash associated with the name, then go into the DHT with the hash and get the data associated with it
  • there are many, many possible namespaces
  • each namespace can have a custom pricing scheme

The stack

  • Blockchain: bitcoin
  • Hash storage method: OP_RETURN
  • Data storage method: Kademlia distributed hash table
  • Language: Python
  • Frameworks: Twisted

Name operations

  1. name preorder
  2. name register
  3. name update
  4. name transfer
  5. name renew

Definitions

  • nameset: all the names ever registered on all possible namespaces
  • hash160: a 20-byte ripemd160 hash
  • salt: a random value appended to data in order to prevent reverse-lookups of the hashed data
  • preorder hash: a hash160 of a given name to preorder, a random salt, and the scriptPubKey of the registrant
  • name encoding: a given name converted from base 40 to base 256
  • historical record hash: a hash of a data string generated from a representation of the nameset
  • update hash: a hash of the data to be associated with a given name

Data storage comparison

nulldata in OP_RETURN output = 40 bytes nulldata in multi-sig output = 66 bytes namecoin operation = 520 bytes hash in nulldata, full data in DHT = unlimited bytes

Data encoding

Constraints:

  • 40 bytes available in OP_RETURN
  • 1 byte = 256 values
  • charspace of alphanumerics and a few special chars (-._+) = 40 values
  • 1.5 name characters can fit in each byte

Field lengths

  • magic bytes = 2 bytes
  • name hash = 20 bytes
  • nameLen = 1 byte
  • name = 1 byte - 16 bytes
  • salt = 16 bytes
  • update hash = 20 bytes
  • historical record hash (truncated) = 16 bytes

Transaction Senders/Name Owners

Each transaction operation has a "sender". If any pre-orders or name registrations occur as a result of a given transaction, the "sender" is also considered the "owner" of those pre-orders and/or name registrations.

In a transaction, the sender is established as the funder of the first non-OP_RETURN input.

Fields

Operation Fields
--- ---
usernames what constitutes a valid openname username
user profiles v0.2 v0.2 (current version) of the profile data format guidelines
user profiles v0.3 v0.3 (future version) of the profile data format guidelines
resolvers how openname resolvers should behave
namecoin registration on namecoin

Name Preorder (reserve)

  • magic bytes (2 bytes)
  • operation code (1 byte)
  • preorder hash (20 bytes)
  • consensus hash (16 bytes)

Name Register (claim/reveal)

  • magic bytes (2 bytes)
  • operation code (1 byte)
  • nameLen (1 byte)
  • name (up to 16 bytes)
  • salt (16 bytes)

Name Update

  • magic bytes (2 bytes)
  • operation code (1 byte)
  • nameLen (1 byte)
  • name (up to 16 bytes)
  • update hash (20 bytes)

Name Transfer

  • magic byte (2 byte)
  • operation code (1 byte)
  • nameLen (1 byte)
  • name (up to 16 bytes)

In a name transfer, name ownership is transferred to the recipient of the first non-OP_RETURN output, while name admin rights are given to the recipient of the second non-OP_RETURN output.

Misc.

Example of a transaction with an OP_RETURN and multiple outputs: https://blockchain.info/tx/1ae39745fd3891c16806bba44e6540944d145452ff156cab03076d7c08462e38?show_adv=true

Historical Record Hashes

Historical record hashes (16 bytes) are to potentially be added to name preorders and/or name transfers.

The historical record hash must be a hash of a data string generated from a snapshot of the nameset at some point in the recent past (e.g. the last 12 blocks).

Description
No description provided
Readme GPL-3.0 130 MiB
Languages
Rust 94.6%
Clarity 2.4%
TypeScript 2.3%
Shell 0.5%