___ /\__\ /:/__/_ /::\/\__\ \/\::/ / /:/ / \/__/
Handshake Protocol Summary
This guide is intended for developers with a working knowledge of the Bitcoin protocol and its general consensus parameters. All values below describe mainnet parameters. Testnet, regtest, and simnet may differ. Links reference the
hsd codebase at the time of writing, just before main net launch.
Block interval time: 10 minutes
PoW difficulty adjustments are computed after every block, targeting 144 blocks per day.
Hash algorithm: BLAKE2b + SHA3
Hashes in Handshake are Big-Endian.
Segregated Witness: Handshake is 100% SegWit, with witness commitment in the block header.
Block headers: Handshake block headers are 236 bytes and commit to several tree roots:
merkle: Base transaction data
witness: Transaction witness data
tree: Root of the name-resource urkel tree. (updated every 36 blocks, about 4 times a day)
reserved: (Not currently implemented) Will be used for layer 2 expansion.
Proof-of-work hashing involves a reserialization of the block header including a
maskHashdesigned to prevent block withholding attacks.
All coinbase outputs including airdrops and claims require 100 confirmations before they are spendable.
Base unit: dollarydoo
1 HNS = 1,000,000 dollarydoos
Maximum total supply: 2,040,000,000 HNS
Airdrop supply: 1,360,000,000 HNS The airdrop is 2/3 of the entire coin supply.
Initial block subsidy: 2,000 HNS
Block reward halving interval: 170,000 blocks (about 3 1/4 years)
Because Handshake is SegWit-only, there are no output scripts, just addresses (which themselves are witness program version + witness program hash). A witness program can encode a public key or a script hash, but those keys and scripts will appear in transaction inputs as witness stack items.
Handshake also introduces a new field in transaction outputs called a
covenant. All transaction outputs contain a value, an address, and a covenant.
The Handshake name auction system is run by transaction covenants. Currently all covenant types operate on the naming system, but new covenants can be added that don’t affect naming at all. New covenant types can be added by soft fork.
Covenants contain a
type and an array of items. Items include auction details like a name hash, or a blinded bid.
Name covenants are linked together in a chain, in the same way that transaction inputs and outputs transfer value in a chain. In addition, some covenants must identify the correct name hash to be valid. There are rules about the sequence in which covenants can be spent. A transaction can have more than one covenant, but the input and output indexes are linked.
These covenant types negotiate the name auctions:
|From –>||–> To||Purpose|
||Just sending money|
||Start an auction for an available name|
||Bid on an open auction for a name with a blinded value|
||Reveal the amount that was bid on a name|
||Sweep a losing auction bid back to wallet|
||Names in the Alexa top 100,000 are reserved for legacy DNS owners|
||Update the DNS resource for an owned or won name (effectively burns coins)|
Because Handshake uses Vickrey Auctions, the highest bidder pays the second-highest bid. In the event only one bid is submitted, that bidder can recover their entire bid (when they
REGISTER) in essence, paying the second-highest bid of zero.
Once a name has been registered it’s value is locked forever, but the namestate can still be changed.
These covenant types update “owned” names:
|From –>||–> To||Purpose|
||Update the DNS resource|
||Renew name ownership before expiration|
||Initiate ownership transfer to new Handshake address|
||Confirm ownership to new Handshake address|
||burn name. Used when a key is compromised|
Transfers are locked for about two days before
FINALIZE is allowed. At any point during that phase, the original owner can
REVOKE. A revoked name can be re-opened with a new auction after it expires, but the current chain of ownership is terminated.
Names must be renewed within two years or they become available for new auctions again.
When a name is updated with either
UPDATE, the new resource is stored in a temporary data structure in the chain database. Every 36 blocks (about 6 hours) this cache is committed to the urkel tree.
From the whitepaper:
Because our tree is implemented as a series of append-only files, a commission interval is required to prevent history bloat, which may otherwise require the user of the software to compact their history regularly.
Name auctions progress through a series of states based on time (i.e. block depth). The first time a name is seen on chain, it’s state is set to the current block height. This height is saved in the database and used as a reference point for the entire auction process. It can be reset after a name expires. Covenant types will be rejected if they are broadcast during the wrong phase.
|Approx. time||Current state|
|< 37||~6 hours||
|< 720||~5 days||
|< 1,440||~10 days||
When reserved names are claimed on chain, they enter a lockup period of about 30 days. During the
LOCKED phase, a reserved name can be re-claimed. This is to provide solutions to legacy DNS name holders whose keys are compromised.
Legacy DNS names in the Alexa top 100,000 are reserved for their current owners. You can see the list in names.json.
Learn more about the claims list.
Learn about on-chain name claims.
Claims are broadcast to the network in a special type of transaction message, and miners include the proofs in coinbase inputs
RSA-1024 Soft Fork
DNSSEC proofs can be signed with a variety of algorithms. Unfortunately, this includes 1024-bit RSA. Keys of that limited size may be compromised in the near future, much like SHA-1 has already been. For this reason, Handshake is already prepared for a soft fork to prohibit claims of this nature. Names that have already been claimed with a weak key will be prohibited from registering after the soft fork activates. Reserved names can be re-claimed any time before registration.
KSK-2010 Soft Fork
When the Handshake whitepaper was written, one of the systemic vulnerabilities considered was the revocation or compromise of ICANN’s 2010 key-signing-key. Earlier versions of the software included a soft-forkable rule that would prohibit reserved name claims with DNSSEC proofs rooted by KSK-2010. Since then, ICANN has provably revoked the 2010 key, and the soft fork was removed. KSK-2017 is now the only root zone key allowed in Claims on Handshake.
Un-reserved names are not all available immediately when mainnet launches. They become available over the first year, based on a simple algorithm that compares the name’s hash against a 52-week modulus.
The RPC call getnameinfo will return the
week value, indicating when a given name is available.
The entire Handshake auction system is not active until the first fourteen days of network life. In fact, transactions of any kinds are not allowed for the first fourteen days in order to accumulate a secure level of proof-of-work.
Two thirds of the total currency supply is reserved for hundreds of thousands of Internet citizens in the open-source software community. Public keys were collected in various ways and added to a merkle tree, whose root is committed in consensus code, and even referenced in the genesis block. Airdrops are redeemed by submitting a proof to the network.
Airdrop outputs ARE NOT included in the genesis block like other cryptocurrency airdrops. A Handshake airdrop is like a transaction that can be submitted at any time. Miners add the airdrop outputs to the coinbase transactions in new blocks, with the proof encoded in the witness of the corresponding input.
Users who received an airdrop to a public key on an external platform can redeem it with a custom signing tool that has a blinding factor built in to conceal the identity of the recipient. Because users have a wide variety of public key types, airdrop proofs are subject to the same RSA-1024 soft fork described above for name claims.
A portion of the airdrop was made available to users that signed up through a website during 2018. These users generated a main net Handshake address with a faucet tool and submitted it along with meta data. Because these airdrop recipients are recorded by address and not public key, no signature is required to generate their airdrop transactions (of course a signature is required to SPEND from the airdrop, like any other address). Because these transactions can be generated and submitted by any node at any time, their fees are hard-coded, and enforced by consensus rules.
Airdrop double-redeems are prevented by a bitfield in the chain database.
Script OP Codes
Several new OP codes has been added to the redeem script language.
||Get the covenant type (int) from the corresponding tx output and push on to stack|
This extra OP code was added to Handshake to make name updates and transfers more secure. For example, a hot/cold wallet system could be implemented in which “cold” keys handle name transfers but “hot” keys are used for DNS resource updates.
Handshake also implements four additional hash function OP codes. Each of these pop one item off the stack, and return the hash function digest of that blob.
Handshake implements two new sighash types. These can be used in more creative transactions by signing a commit to different combinations of transaction elements.
SIGHASH_NOINPUT is defined in Bitcoin as BIP 118, and enables flexibility in off-chain and layer two protocols. It allows a TX to spend from any output that “solves” the redeem script, instead of specifying one single tx output by
index. It is implemented as a mask
0x40, so it can be combined with other SIGHASH flags like
SIGHASH_SINGLEREVERSE allows for on-chain atomic sales of a name to a coin holder. A specially crafted transaction can be generated by a name owner that commits to one input that signs for their name, and one output that spends coins to their wallet. Another user can add one input that funds the transaction, and the
TRANSFER output to their own address. Note that the buyer must require that the name-owning script checks
OP_TYPE in such a way to prevent the name owner from issuing a
REVOKE before the
FINALIZE can be issued. This sighash type is implemented as