Coinmonks
Published in

Coinmonks

A literal airdrop: But Handshake isn’t conducting psychological warfare, just giving away free stuff to bootstrap the network

Understanding the Handshake Airdrop and Reserved Names

Money & Names

Free Stuff

Collecting Keys

$ curl https://api.github.com/users/pinheadmz/gpg_keys
[
{
...
"public_key": "xsFNBFtrHssBEADlPQQ+eaXmIg/lDxCUuwJDnF0BXVoTKeqDIrDLx/2qFA6Dj6AcUWsrVNPxvvSMr2i5LgMFrFvjbrXoo7jsZO5a4AUuXragJzI6UKaKD5HxQR/6L6zXsOmGHhLMCAUwaIyl7wqOUrDaJbAbmr/S38yEhEkztVuxN8YbrZ6WpgEVMPfZsNdyUPEOEHUcRSwJGVGnn2CEPdUavFYIGYgGFxJBhy/xcRtgDrKyMhXa8qdj5IPksfGiSGC69PkbG2vT6Dy+Lmc2QhSv3cRn+rYnY8jdN9ADKY7um4XKwvlzkVld6MGDYJG/EB53Q+rAu+qbUhPrGOKRdC7hnangsALi6dwEq1XDk1n/Snp4/WR3oADFxo5WAGls+i+vxtQul3U+h67xyPRBaW/FZjgN8gNL97nIqMPa7HHDxBsobmrVYnbNnhiA84qXHDc/vgcSFlMjJ9il05m6JIvwpMCN+QaR2s5G0MW6lhY6qmBezBMwyy7eSMvRiAGpUg/KDTzqKj+x87VkYPb6YMoa/FHkV+dne/1Alb1Kp9+tvGe/FSjPBOPbXK+F1uRMC46O2lOpsAPo0DntI85c7/RlXUBlXk8En+FYies/a+vBNgEtZsmBVxGD77i+ThM7MOk+oGY8yON25OQOYXIoBT8FLGzUofM/LF5yERtcIf5lm48XNBOWhQr+xQARAQAB"
}
]
$ node> const {PGPMessage} = require('bcrypto/lib/pgp')
> PGPMessage.fromBase64('xsFNBFtrHssBEADlPQQ+eaXmIg/lDxCUuwJD...')
{ packets: [ { type: 'PUBLIC_KEY', body: [Object] } ] }

The Money Tree

$ gpg --quick-generate-key Alice rsa4096
$ gpg --armor --output alice_pub.asc --export Alice
$ gpg --armor --output alice_prv.asc --export-secret-keys Alice
$ ./extract-publickey alice_pub.ascKey ID:
351d404712461946
Public key (base64):
BF1keZABEAD2++nDebPDr9M4HpJB+cf5Sn6GEXOej8PZ6D3k3wY3MQxlNkBW6caADsMVsDT1hSNJPzUVY+p+cRA5Aou34NWvRd+OtDDJyHfXy9tbMCMxjV0FDweMfGWinbhfV3WKTl6xecKNBapBzgyKz5ZJK048U/zPXd8cEihmEPsnMiHno8m3uH2XQSusWp6SqYKvBh6Bi3zuWIx7uzuRyS1pwOOe7Go76bU189O7OA9S2rh/6xhX2Fp0WyJiGds7L2Fy1+e43YHB529HhYhFw8jPmPHc1HVP19OSW5YT4BnZDfkhydPLICZwrwYpNxnB/mj7mEu447+/ahFBV7YnH2KBmk/4azePkk1ItqvVP9I1TEYrF7H5wtYsSmqK7/LAG/18sUI17d8F40ZlsPvWq5yr67AikbMaItrSq+eoedbZPWB+AQk1kKCXG1MEVLH3zejHboxXVzqAOen7shrG0TGfjn6N48pLJnkCqOtmI5XMkSibKT1JWH1Vgmm0Z36XwSaeG+d4ryCnZDsPhb3d3UPvvvAy3BHGAyyV8VqCWnmQaqKbLgVnltY8omDIwkz9AYs/d7rhP8Ld6DGbrkcZMNbxu8idwjokhiHr+VBGgkWJxQdfT/ndwIbWedpSAF+19MuhfM9x2VuIEpAYGmA1PEKt6r4+XM3qnA4D+/39n1UAYRFIuQARAQAB
$ faucet-tool createaddress -n regtest...

Address:
rs1qk2hh6xrmmnpsc8pt08tr8uwdqdxp0yuyv6hzsu
$ echo "[]" > sponsors.json
$ echo "[]" > creators.json
$ echo "[]" > hn-keys.json
$ echo "" > strongset.asc
[
[
1, // GitHub User ID #
"Alice", // GitHub username
[] // No SSH keys for Alice
]
]
[
[
1, // GitHub User ID #
"Alice", // GitHub username
[
[
1, // User ID #
-1, // Parent Key ID
"351d404712461946", // Key ID
"BF1keZABEAD2++nDebPDr9M4Hp...", // Raw key as PGP packet
[["alice@alice.com", 1]] // Email, verified (bool)
]
]
]
]
[
{
"email": "bob@bob.com",
"github": "Bob"
"address": "rs1qk2hh6xrmmnpsc8pt08tr8uwdqdxp0yuyv6hzsu",
"shares": 1
}
]

Hash Hash Hashy Hash

$ scripts/merkelize-airdrop regtest/jsonValid github users: 1
Valid github keys: 2
Invalid github users: 0
Invalid github keys: 0
Valid strongset members: 0
Invalid strongset members: 0
Valid hackernews users: 0
Invalid hackernews users: 0
Wrote buckets (size=0.0004901885986328125mb).
Wrote merkle tree with 2 keys and 1 leaves.
Checksum: fb92f890ab91ad36dda17f28f114f771ecb76b0cae0b154f2415a4a2b1be68b7
Tree Root: ee8bff349dec24a8378f38fbed35bba5cd0ebde2d5f256101ffbadac93920744
Leaves: 1
Keys: 2
Max Keys: 2
Depth: 0
Subdepth: 1
Faucet: 1
Shares: 1
Reward: 476000000000000
$ scripts/merkelize-faucet regtest/jsonValid sponsor addresses: 0
Valid creator addresses: 0
Valid participant addresses: 1
Wrote merkle tree with 1 leaves.
Checksum: 06d55ac651d4c5b2264ad62c60c9633079709c9bbfff1ffd6e0172616964be32
Tree Root: 1d592d73c49f0aa50b2ef857c343700be0d00ebe13167a7cebd633d3bae682d8
Leaves: 1
Depth: 0
Participants: 1
Faucet Total: 476000000000000
Shares: 1
Sponsors: 0
Creators: 0
External Total: 0

Prove It

$ bin/hs-airdrop rs1qk2hh6xrmmnpsc8pt08tr8uwdqdxp0yuyv6hzsuAttempting to create proof.
This may take a bit...
Creating proof from leaf...
JSON:
{
"index": 0,
"proof": [],
"subindex": 0,
"subproof": [],
"key": {
"type": "ADDRESS",
"version": 0,
"address": "b2af7d187bdcc30c1c2b79d633f1cd034c179384",
"value": 476000000000000,
"sponsor": false
},
"version": 0,
"address": "b2af7d187bdcc30c1c2b79d633f1cd034c179384",
"fee": 100000000,
"signature": ""
}
Base64 (pass this to $ hsd-rpc sendrawairdrop):
AAAAAAAAACAEABSyr30Ye9zDDBwredYz8c0DTBeThADA6WLrsAEAAAAUsq99GHvcwwwcK3nWM/HNA0wXk4T+AOH1BQA=
$ hsd-rpc --network=regtest sendrawairdrop AAAAAAAAACAEABSyr30Ye9zDDBwredYz8c0DTBeThADA6WLrsAEAAAAUsq99GHvcwwwcK3nWM/HNA0wXk4T+AOH1BQA=9a2771031b305533b1015f2b1860079daa6243c873a51abf4735621c4c16007e
$ bin/hs-airdrop regtest/pgp/alice_prv.asc 351d404712461946 rs1qy9uplxpt5cur32rw3zmyf8e7tp87w8slly2fms 0.5Attempting to create proof.
This may take a bit...
Decrypting nonce...
Finding merkle leaf...
Creating proof from leaf...
JSON:
{
"index": 0,
"proof": [],
"subindex": 1,
"subproof": [
"9de514887afa96c585e8a27161c7bba420703e25a280aa67c57ffc8980816311"
],
"key": {
"type": "GOO",
"C1": "0f6d9..."
},
"version": 0,
"address": "21781f982ba63838a86e88b6449f3e584fe71e1f",
"fee": 500000,
"signature": "4933fd82aa8aa7fb900a2..."
}
Base64 (pass this to $ hsd-rpc sendrawairdrop):
AAAAAAABAZ3lFIh6+pbFheiicWHHu6QgcD4looCqZ8V//ImAgWMR/QEBA...
$ hsd-rpc --network=regtest sendrawairdrop AAAAAAABAZ3lFIh6+pb...

Confirm

$ hsd-rpc --network=regtest generatetoaddress 1 rs1q30ppv5gyrwpy4wyk0v6uzawxygdtvrpux8yrg2[
"022882f6566671742c524cb485109a4d8ef51861e09f286d651d927cfe6630ee"
]
$ hsd-cli --network=regtest block 022882f6566671742c524cb485109a4d8ef51861e09f286d651d927cfe6630ee...
"outputs": [
{
"value": 2100500000,
"address": "rs1q30ppv5gyrwpy4wyk0v6uzawxygdtvrpux8yrg2",
"covenant": {
"type": 0,
"action": "NONE",
"items": []
}
},
{
"value": 475999900000000,
"address": "rs1qk2hh6xrmmnpsc8pt08tr8uwdqdxp0yuyv6hzsu",
"covenant": {
"type": 0,
"action": "NONE",
"items": []
}
},
{
"value": 4370322008,
"address": "rs1qy9uplxpt5cur32rw3zmyf8e7tp87w8slly2fms",
"covenant": {
"type": 0,
"action": "NONE",
"items": []
}
}
]
...

Reserved Names

Look at Me, I’m the ICANN Now

$ hsw-rpc --network=regtest createclaim bitcoin{
"name": "bitcoin",
"target": "bitcoin.com.",
"value": 566471548,
"size": 5120,
"fee": 25600,
"address": "rs1q7ywfylsgt3fj4n6fz7q8k8j0wz43lcws2ee2ya",
"txt": "hns-regtest:aakpchespyefyuzkz5erpad3dzhxbky74hip2adei6z7736u6qcacthqpeg2ncko7nnwpepv76f6sn3ywjlerdorw7dacaaaadrg5xku"
}
$ dnssec-keygen -f KSK -a RSASHA256 -n ZONE bitcoin.comGenerating key pair...
Kbitcoin.com.+008+37177
$ dnssec-keygen -a RSASHA256 -n ZONE bitcoin.comGenerating key pair...
Kbitcoin.com.+008+27510
$ORIGIN bitcoin.com.
$TTL 172800
@ IN SOA com. admin.email ( 2007120710 1d 2h 4w 1h )
$INCLUDE /work/guide/keys/Kbitcoin.com.+008+37177.key
$INCLUDE /work/guide/keys/Kbitcoin.com.+008+27510.key
bitcoin.com. IN TXT "hns-regtest:aakpchespyefyuzkz5erpad3dzhxbky74hip2adei6z7736u6qcacthqpeg2ncko7nnwpepv76f6sn3ywjlerdorw7dacaaaadrg5xku"
$ dnssec-signzone -o bitcoin.com bitcoin.com.zone
172800 TXT "hns-regtest:aakpchespyefyuzkz5erpad3dzhxbky74hip2adei6z7736u6qcacthqpeg2ncko7nnwpepv76f6sn3ywjlerdorw7dacaaaadrg5xku"
172800 RRSIG TXT 8 2 172800 (
20190926203106 20190827203106 17421 bitcoin.com.
wE/Ky5yH9bG2DAmOp1d0oSOA2OpsrmxQjv8w
OvnNkYC65Vo38eBDj64wSU2x1tgO91TBepj1
rLj3Df2owMYv3A+Ciu/qXXCRSM/2krcltXis
guV7tLltBQLsiPtVs1wEr8vCWcaZP4yd1lo4
1Bmvi0YajOsxV7NNWJloTPJfdNM= )
$ dnssec-dsfromkey -2 Kbitcoin.com.+008+37177.keybitcoin.com. IN DS 17421 8 2 78D60AF13E97693AC2F32B591FD3D60D34E151016F8692475617FBCD03CDCBE1

Claim That Name

$ node> const bns = require('bns')undefined> bns.Ownership.Proof.fromString(
fs.readFileSync('/work/guide/zones/ownership-bitcoin.zone')
.toString('ascii')
).toBase64()
'AwMAADAAAQACowAAiAEAAwgDAQABnt9Z4x3v0DvnkBY0Hx17RTi3Ac...'
hsd-rpc --network=regtest sendrawclaim AwMAADAAAQACowAAiAEAAwgD...

Confirm

$ hsd-rpc --network=regtest generatetoaddress 1 rs1q30ppv5gyrwpy4wyk0v6uzawxygdtvrpux8yrg2[
"908eb35fab448ec928126dc7b451b27798b5f611bc50b5bfc081a7d18add04e0"
]
$ hsd-cli --network=regtest block 908eb35fab448ec928126dc7b451b27798b5f611bc50b5bfc081a7d18add04e0...
"outputs": [
{
"value": 2000025600,
"address": "rs1q30ppv5gyrwpy4wyk0v6uzawxygdtvrpux8yrg2",
"covenant": {
"type": 0,
"action": "NONE",
"items": []
}
},
{
"value": 566445948,
"address": "rs1q7ywfylsgt3fj4n6fz7q8k8j0wz43lcws2ee2ya",
"covenant": {
"type": 1,
"action": "CLAIM",
"items": [
"f82f54fe3a9daa86316dc706e74b31d57ce6b21a12104cdfbd3f90b627847105",
"0c000000",
"626974636f696e",
"01", "47b3ffefd4f404014cf0790da6894efb5b6791f5ff8be93778b256488dd1b7c6",
"01000000"
]
}
}
]
...

🍺 Conclusion🍺

Get Best Software Deals Directly In Your Inbox

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store