Welcome back! I’m glad you made it to the second of three articles in this “Getting Started” series on developing with Nano Currency. If you are new to Nano and just getting started, I recommend you first build your Nano foundation to understand the terminology and design of Nano before attempting to interact with the network.
Of the three articles in this series, this is the article that I am most excited about. Why? Because this is where you, as a developer, first experience the true and awesome capabilities of the Nano Network. No middlemen. No coordinators. Not even a Software Wallet. In this article we are going to be interacting directly with the Nano Nodes that, together, comprise the totality of the Nano Network.
So other than your time and attention, there is really zero cost to you. At the end of this article, I intend to have you programmatically receiving and sending Nano while maintaining a Nano Account. And, of course, you will be left with some Nano to continue your fast, feeless, and eco-friendly cryptocurrency escapades.
But lastly, before we get really started, I want to set your expectations appropriately.
This article is:
- A lesson on the basics of how to programmatically interact with Nano Nodes
This article is NOT:
- A lesson in secure coding practices
- A lesson in key management
- A lesson in browser security
We previously learned that Nano Nodes are the infrastructure that supports the Nano Network. We learned that the Nano Foundation’s Nano Node is the standard across the Nano Network for Nano Node software. And we learned that anyone can operate a Nano Node.
While running a Nano Node is far beyond the scope of this article, I want you, as a developer to understand the differences between a Public and Private Nano Node. For our purposes here, when I mention a Public Nano Node, I am referencing a Nano Node that you do not operate and is open and available to be accessed over the Internet. When I mention a Private Nano Node, I am referencing a Nano Node that you downloaded, installed, and operate on a private server of some sort.
When should I use a Public Nano Node?
Right now, honestly. If you are just getting started, there is zero reason to go through the process that results in a Nano Node for you to operate and maintain. If you want to code … simply code! There are multiple Public Nano Nodes available to you right now with no registration required of any sort.
Security concerns when relying on a Public Nano Node should also be noted. When we build Nano Blocks to send and receive Nano later in this article, you will notice that we are retrieving our current Nano Account balance from a Public Nano Node. If we are creating a Nano Block of subtype send, we are then subtracting the amount of Nano we want to send, signing that Nano Block, and sending it back to the Public Nano Node to process. What happens if a Public Nano Node lies to you and tells you a less-than-actual amount for your balance? Well, you could end up “sending” a lot more Nano than you expected.
It is safe to send a Nano Block to a Public Nano Node because it is cryptographically secure via a Private Key signature. But we need to be mindful about the information we are querying and trusting, coming from a source that we do not inherently trust. One simple way to combat this, is to query more than one Public Nano Node and compare the information returned. If it does not match, bring in the human to do some investigation.
When should I use a Private Nano Node?
After you get your feet beneath you and make it through this article, if you want to write an application that users will depend upon, then you will want to consider running a Private Nano Node. While the individuals that operate the Public Nano Nodes are doing a fine service to new and hobby developers, there are (to my knowledge) no service agreements available from any of them.
That said, it really isn’t difficult to get a Nano Node up and running and the recommended machine specs will hopefully not break the bank.
“On with it!” you say. Ok, let’s get coding.
There are three unique ways in which you may interact with the Nano Network.
- Observing the Nano Network
- Querying the Nano Network
- Participating in the Nano Network
In this section, we are going to focus on the first, observing the Nano Network. We will not be building Nano Blocks here. Here, we will be passively listening.
For some of you, this section might be as far as you need to go for your first Nano project idea. You want to observe the Nano Network and take an action of some sort if Nano is sent to a particular Nano Address. This is all the crypto bird feeder needed to do (not mine) and the Nano Christmas Tree needed to do (also not mine). This is all I do for my Nano Network visualizers (snow and plinko).
The Nano Node has made available a WebSocket for you to subscribe to, to consume various data from the Nano Network.
Here is our boilerplate code that will get us started. We simply create a new WebSocket object and create the three functions to handle events (learn more about WebSockets). As we progress through the article, each JSFiddle in each section builds on the previous (kind of like a block chain…) but each JSFiddle stands on its own as a complete and executable script (kind of like a state block!). I will not describe line by line each example but will cover the highlights following each JSFiddle.
Did you run the script? At this point we are actually communicating with a Public Nano Node. But what should we say? The Nano Foundation’s Nano Node provides a laundry list of topics, but we are going to focus on just a few. First, let’s test our connection with a WebSocket version of “Hello, World!”. Ping.
If all has gone to plan, we should see a “pong” message back that looks something like this:
Great! Now we know the Nano Node and us are speaking the same language. What else can we do? How about we take the crypto bird feeder approach and listen for transactions on a single Nano Account? How about we listen to the fairly active FreeNanoFaucet.com’s Nano Address?
Eventually, you should see some output like below.
If you are working in JSFiddle, you may not see the fully expanded objects in the results window as I’ve pasted above. You can open up your Brower’s console and view the fully expanded objects there.
So what’s going on here? We can send a message with
topic: “Confirmation” and an array of Nano Accounts to subscribe to confirmations from those Nano Accounts. In short, when a Nano Block gets confirmed by the Nano Network as valid, you will get a WebSocket message telling you so.
I won’t dive too much into the Nano Block output as we briefly reviewed the fields in the first article on building your foundation and we will work more with these fields below when we actually build some Nano Blocks.
Now, I said before, I won’t spend much time talking about security or best practices, but I will offer a word of caution here. If you are taking action on the notification of certain confirmed Nano Blocks, you need to check that you haven’t observed that Nano Block previously. You need to maintain a log of hashes from the
hash field. If you’ve already seen that hash and taken action, skip, simple.
And that’s really about it! Like I said before, there are quite a few other messages you can send through WebSockets (update your subscription, observe votes, subscribe to all Nano Blocks, election information, and more…), but I think our point has been made. You are now able to observe the Nano Network!
And before we leave this section, I want to highlight two working WebSocket examples provided by the Nano Foundation. While I have guided you through the simplest implementation that I could think of, if you want to see a Node.js or a Python example, check out the docs.
Observing the Nano Network is immensely useful. But what if you are looking for specific, on-demand information about the Nano Network? What if you want to know the balance of a Nano Account? What if you want to know information about a specific Nano Block? For this information we will need to query the Nano Network.
While technically the section above on observing is not completely passive (you need to actively subscribe to certain information), I consider it passive as it is a stream or feed of data flowing to you as a listener. I consider the act of querying the Nano Network to be active because we are asking a specific question and expecting a certain type of answer in response.
I think the concept is fairly simple to understand, this is your standard RPC or REST API request. Let’s get right to the code. Here is the boilerplate code that will get us started.
This code is fairly generic and won’t actually do anything for us, yet. The
post function returns a
Promise object that is resolved/rejected on the return or the error of the POST request.
There are a HUGE number of Node RPCs supported by the Nano Foudation’s Nano Node. We will only tackle a few. But as long as you know what the input values are, the POST request format is the same. Now let’s actually query the Public Nano Node we’ve selected and request the account balance of FreeNanoFaucet.com’s Nano Address.
Here we simply follow the documentation for the
account_balance RPC. Pass in an
action value and an
account value. By now, especially if you read through my first article, you might have noticed that I discern between a Nano Account and a Nano Address. I try to be very intentional about this. To me, the Nano Address is the xrb_* or nano_* value. Every Nano Account has a Nano Address, but it also has a Private Key and a Public Key. So when I reference a Nano Address, I mean the string of characters that is the address. But when I reference a Nano Account, I reference the logical thing that is the combination of Public Key, Private Key, and Nano Address. It might seem pedantic… but hey, that’s me. All that said, in the Node RPC reference, whenever an “account” field exists, it is looking for the string of characters that I call the Nano Address.
Ok, off my soap box…
After running the above code, you should see a result similar to this:
requestLimitReset: "Fri Jan 15 2021 00:07:06 GMT-0500 (Eastern Standard Time)",
Our query to a Public Nano Node resulted in us determining the current balance (in raw) and pending balance (Nano (in raw) that has been sent but not yet received by this Nano Account). Both of these values can be confirmed on a Block Explorer like NanoCrawler. We are also given some other information about “requests” that I want to highlight.
Some of the Public Nano Nodes run a Nano RPC proxy. This Nano Community developed proxy was created to enable people that operate their own Nano Node, to have its RPC and WebSocket capabilities accessible publicly, without opening direct connections to the actual Nano Node software. One of the features this proxy offers is tokens. Tokens allow the Node Operator to limit requests to their Nano Node. But it also allows them to potentially monetize access to their Nano Node’s API by allowing people to purchase tokens.
In the output above, we see that this particular Nano Node has set a limit of 5000 requests, of which I have 4936 requests remaining. And my limit will be reset on Friday January 15th 2021 at 00:07:06 EST. Referencing back to my earlier section on Private vs Public Nano Nodes. This is potentially a limiting factor if you choose to rely on a Public Nano Node. Not all the Public Nano Nodes utilize tokens, however. And some Public Nano Nodes do utilize tokens but don’t use this particular proxy software. I try to highlight which Public Nano Nodes use the token system on my Public Nano Node webpage. I personally like the Nano RPC Proxy and its token system. It is easy to view and programmatically parse my limits. It demonstrates an attempt at resiliency of the API against spam. And honestly, for playing around, I won’t ever come close to breaching my allotted tokens.
That ended up being quite a bit of foundation building between terminology and introducing the Nano RPC Proxy. Let’s get back to code! Now that we’ve determined a Nano Account’s balance, let’s query information about a specific Nano Block.
Here we add a new function to query the
block_info RPC. And the response is below:
requestLimitReset: "Fri Jan 15 2021 00:07:06 GMT-0500 (Eastern Standard Time)",
The Nano Block object should be looking rather familiar to you by now!
Now that we can observe and listen real-time to the Nano Network for new Nano Blocks as well as query for specific information on any Nano Address or any Nano Block, I think it is time for the real fun. It is time to begin programmatically receiving and sending Nano!
Our plan for this section is:
Step 0: Request Free Nano from FreeNanoFaucet.com
I said you’d be getting some free Nano, didn’t I? But first, you need to figure out the Nano Address where you want the Nano to be sent.
Your results should look something like this (but unique). The first value is your seed and the second value is the first Nano Address derived from the seed. I recommend NEVER generating a seed or ever really using a seed and Private Keys in JSFiddle. However, we are going to be working with very small amounts of Nano and the risk is (in my assessment) minimal.
Copy your seed and Nano Address to a text document for safe keeping as we work through the rest of this article.
Next, head over to FreeNanoFaucet.com, enter your Nano Address and click “Get Nano!”. Then, to confirm the Nano was sent, head over to NanoCrawler, enter your Nano Address into the search box and hit enter. You should see some “pending” Nano.
Now you could enter your seed into a Software Wallet, but we are here to code, so let’s receive the Nano into your Nano Account programmatically.
Note: There are a few free Nano faucets available. You could also try nano-faucet.org or check out the various options on nanolinks.info.
Step 1: Receive Nano
From here on out, for each JSFiddle, you will need to enter your seed for the seed variable I have defined at the bottom of this script.
Here we add a new function
pending which will query the Nano Node with action
pending and return the hash of any Nano Blocks of subtype
send that are ready to be received by your Nano Account. You should see that you have one Nano Block pending and see an array with a hash that matches the hash you saw above on NanoCrawler.
"Found 1 blocks pending..."
Now let’s take it the next (big) step and actually build the Nano Block of subtype
Results should look similar to this:
"Found 1 blocks pending...""Receiving in address nano_1syhufn6sde8oh4ntox6166jzh4rdtk9uoo9donj9epa597wizonn8kt6nhb from block A8AEB2313F12E6D36B3149FFC3D4E534F1B3603D35FAE7FA4EDDAB3985D02157""Computing work for subtype receive, difficulty: fffffe0000000000 (work being done locally: false)""Processing block with block:"
}"Published receive block: 9C447E554E4ACE2809DF87AE95E54B0F05FF6F53CB8F012E33DB7964AFBB31A5"
And you can see in NanoCrawler that your Nano has been received by your Nano Account!
Congrats! You have created and published your first Nano Block! You have requested Nano from a free Nano faucet and programmatically detected a pending block and programmatically received it. But let’s rewind, quite a bit of new code was added to the last example and I want to walk through most of it. Fortunately, this deep dive on the receive will pay dividends soon when we build other Nano Blocks, as there are quite a few similarities.
Let’s walk through it in order of code execution:
Step 2: Change Representative
As discussed in the first article of this series, each Nano Block contains the full state of a Nano Account, which can really be broken down into two pieces of information, balance and representative. Once you understand this concept, you will realize that it is quite possible for a Nano Account to never publish a change block to change its Representative, even if the Representative changes over time.
In any Nano Block (receive, send, or change) the set Representative for that Nano Account can be changed. A change block is not required to carry out this action. However, the change subtype does exist so that the Representative can be changed without a change in the Nano Account’s balance (via sending or receiving). Most Software Wallets do not provide a way to change a Nano Account’s Representative during a send or receive, but only as a standalone “change” action. I think this is to simplify the user experience.
Again, Nano’s consensus mechanism to include voting and Principal Representatives is mostly out of scope of these “Getting Started” articles. But really that’s ok. You can certainly interact with the Nano Network successfully without fully understanding Open Representative Voting (ORV). You just need to understand that every Nano Account should assign a reliable Representative in order to support the security of the Nano Network.
Ok, now back to the code. Let’s build and process a Nano Block with a subtype of “change”.
"Changing representative of nano_1syhufn6sde8oh4ntox6166jzh4rdtk9uoo9donj9epa597wizonn8kt6nhb to nano_1syhufn6sde8oh4ntox6166jzh4rdtk9uoo9donj9epa597wizonn8kt6nhb""Computing work for subtype change, difficulty: fffffff800000000 (work being done locally: false)""Processing block with block:"
In this example we are doing something that shouldn’t really be done. We are setting ourselves as the Representative for our Nano Account. While this is a perfectly legitimate action, our Nano Account is not associated with a voting Representative Nano Node. The Representative should be set to an established and reliable Representative.
To create and process the Nano Block of subtype
change, we add a new function that takes inputs of the Nano Address, the new Representative Address, and the Nano Account’s private key. The only unique quality of a
change block is that the value of the
link field is all zeros.
Step 3: Send Nano
We have received Nano and we have changed the Nano Account’s Representative. All that’s left is to send Nano! So that we can keep playing around with our free Nano, let’s demonstrate a send by doing something useless and send some Nano right back to our Nano Address.
"Sending 0.0001 Nano from address nano_1syhufn6sde8oh4ntox6166jzh4rdtk9uoo9donj9epa597wizonn8kt6nhb to nano_1syhufn6sde8oh4ntox6166jzh4rdtk9uoo9donj9epa597wizonn8kt6nhb""Computing work for subtype send, difficulty: fffffff800000000 (work being done locally: false)""Processing block with block:"
In the above screenshot, you can see that our third Nano Block has been processed for our Nano Account. And we also have a pending Nano Block! That’s because the source and destination of our send was the same! It is kind of like your left hand giving your right hand a dollar bill.
In this example I do take an input of Nano in its more user-friendly Nano (10³⁰) unit. I then lean on the nanocurrency-js package to convert from Nano to raw.
In a Nano Block of subtype
send we set the
link value to be the destination Nano Address. Under the hood in nanocurrency-js, the
link value is converted to the destination Nano Account’s Public Key and a field
link_as_account is added. The
link field is kind of the wildcard field when it comes to the various Nano Blocks:
- Subtype receive:
linkis the hash of the pending Nano Block
- Subtype change:
linkis set to all zeros
- Subtype send:
linkis the destination Nano Account’s Public Key
And that’s it! In this article we…
- Observed the Nano Network and listened for confirmed Nano Blocks
- Queried the Nano Network for information on specific Nano Accounts and Nano Blocks
- Interacted with the Nano Network and built our own Nano Blocks to receive, change representative, and send Nano
As a final capstone and comprehension test of what we’ve covered I’ll give you a challenge.
Write a script that will send Nano using one Public Nano Node and listen (via a WebSocket) for the confirmation of that Nano Block from a different Public Nano Node.