Implement

In this page, we go over the details of actually implementing a Gibbername library in Rust.

πŸ‘¨β€πŸ’» Follow along on GitHub!

In the future, cross-language melprot bindings will make it possible to implement protocol libraries in other languages, including in-browser JavaScript!

For now, though, Rust is the only supported language.

Project setup

The first step of implementing Gibbername is to create a new Rust library with the melprot dependency:

cargo new --lib gibbername
cd gibbername

We'll also be adding some dependencies. These will show up in the Cargo.toml:

cargo add futures-util anyhow gibbercode hex melprot melstructs stdcode tmelcrypt

Looking up names

The easiest part of Gibbername is looking up the names. This consists of three parts:

  • Decoding the Gibbername into a blockchain location identifying the start of the Catena chain. This means a block height and a transaction hash.

  • Obtaining and validating the start transaction by obtaining a snapshot at the given block height, retrieving the start transaction, and making sure that its data field says "gibbername-v1".

  • Traversing the Catena chain, following all the custom-token coins, traverse the Catena chain to the most recent element. We'll then have our binding!

The Gibbername encoding

How can we squeeze a blockchain location β€” which identifies a transaction and its location β€” into a short "gibberish string" like xoxqax-lobteh? After all, unique transaction hashes are very long and unwieldy.

Instead, we encode a unique blockchain location as two numbers: the block height and the transaction position. This position is the 0-indexed position of the transaction within all the transactions in that block sorted by hash.

This lets us represent any transaction in the blockchain uniquely with two smallish numbers. For instance, the transaction with the "smallest" hash in block 100000 would be represented as 100000,0.

We then need to represent this pair of numbers as a friendly Gibbername. Fortunately, we can use gibbercode, a crate that encodes a pair of numbers into a gibberish string using the consonants for the first number and the vowels for the second.

Validating the start transaction

Once we have the blockchain location, we need to retrieve the start transaction. This can be done using melprot's Snapshot::get_transaction_by_posn() function.

The start transaction should have a data field that says "gibbername-v1", as well as one, and just one, output with denomination Denom::NewCustom, and that output must have value 1. This is the way we ensure that a given Gibbername is actually valid.

Traversing the Catena chain

Finally, we can traverse the Catena chain to get the coin containing the final binding:

We can now easily build the gibbername lookup function!

Registering names

Registering names is a little different: we need to send a transaction into the blockchain rather than just reading existing data.

One possible way is to craft a transaction inside our library and send it by directly calling an RPC method on a full node (through something like melprot::Client::raw_rpc()). But this is hard, because we must somehow get hold of $MEL to pay transaction fees (possibly by asking the user to send money to some address?). Furthermore, even once we have $MEL, managing the money and the private keys securing it difficult, security-critical task.

Instead, we ask the user's wallet to send a transaction for us, and we simply wait until the user finishes doing so. In summary, here are the steps to register a new gibbername:

Prompt and wait for the transaction

We can now write a function to send the transaction and wait for it to commit in the blockchain.

When this function is called, the user will be prompted to manually send a transaction with our wallet CLI: melwallet-cli. We will continuously stream incoming transactions until we find the one we sent. We are now able to register a name with an arbitrary binding! πŸš€

Transferring names

Transferring names is left as an exercise to the reader.

Hint: you'll need to construct a wallet to extend the Catena chain and prompt the user, just like with registration. If you're truly stuck, there's always our GitHub example code πŸ˜„

Last updated