HoloWorld Tutorial: Writing Functions

Make sure that you’ve completed the last HoloWorld tutorial step of writing the application DNA.

Recall that while writing the application DNA, in dna.json, we declared two functions called holoTextWrite and holoTextRead and an entry type called holoText.  In this tutorial, we will implement those functions, and any others needed in order to make our app function.

With a text editor, open up the dna/readerWriter/readerWriter.js file. To maximize learning, let’s start by removing all the code from the file. Delete it all, don’t worry.

The code we will write in this file is responsible for multiple things: 

  • Defining a small number of functions required by Holochain to function (the "required callbacks")
  • Defining any validation rules of the application
  • Defining any custom functions implemented by an application

When writing code, we have access to the entire suite of "native functions" that Holochain provides. We use some of these functions to read and write data. 

Sidenotes: 

  • Holochain currently only supports ES5 JavaScript syntax, if you want to use the latest syntax, use a transpiler
  • Each time it calls a function in this file, Holochain runs the code in a sandboxed way in a virtual machine, so nothing can be held in memory

 

Genesis

The first step to take in our code file is to implement the critical genesis function. This is the one function which Holochain requires you to implement for each Zome. It is a function which is called the first time any individual attempts to run a Holochain application, and it provides an opportunity for any setup to occur, and any validation rules to execute to check whether the user is able to join the app. It must return true or false. For HoloWorld, we have nothing special to define here, but we must add it regardless, and return true. 

Add the following at the very top of the file

function genesis() {
  return true
}

 

holoTextWrite

Next we will implement our first custom function, holoTextWrite, which will take a string of text as an input, and write it to our local source chain. 

Below the genesis function we defined, add a new function by adding the code below:

function holoTextWrite() {}

Provide an input for the function by adding it between the parentheses, so the code looks like this:

function holoTextWrite(text) {}

Now some background. When an entry gets written to the source chain, it gets assigned a "hash". The hash is generated by using a hashing algorithm (whichever one is specified in the dna file under DHTConfig.HashType, such as sha2-256) on the combination of two things: the entry type, and the entry contents. The data is also signed using the private key of the current user/agent. When attempting to write something to the chain, we call the native function  commit.

We can simply call the native functions from anywhere in our code, without doing anything fancy like "importing" it. Make your function look like this:

function holoTextWrite(text) {
  var hash = commit('holoText', text)
}

We declare a variable, hash, to store the result of calling  commit. The first parameter we pass  commit is the entry type we are adding, as declared in our DNA file, holoText. The second parameter we pass to  commit is the variable text, which was passed as the input to the function. 

!!The following is very important!!

A very important aspect of Holochain, as a platform for P2P applications to be built with, is the concept of data validation. Validation occurs at many points, but it all begins with  commit, since  commit is where data is originally authored to a chain. Every time that your application triggers a call to  commit, Holochain will also perform a built in call to another function which you must implement, called  validateCommit. You only need to define  validateCommit if you utilize  commit. Let’s finish authoring holoTextWrite, and then define  validateCommit.

If  commit succeeds, it will return a hash. In turn, we should make our function use this hash as the value that it returns, so that the caller has the value with which it can be retrieved again, similar (but different!) to its ID in a standard database. 

Modify your function so it looks like this:

function holoTextWrite(text) {
  var hash = commit('holoText', text)
  return hash
}

The function is complete, except we need to perform the required validation that was mentioned before it will work!

Because at this point in time, we have no special validation rules, implementing  validateCommit is very simple. We just need it to return true. Add the following function definition in between the genesis and holoTextWrite functions:

function validateCommit() {
  return true
}

With that, we’ve successfully implemented holoTextWrite!

 

holoTextRead

Fortunately, reading data is actually much simpler than writing it! To retrieve data from the source chain, we must have the hash for the contents we want to retrieve. This is the same as the hash that was returned by holoTextWrite. For holoTextRead, a hash will be our input, and a holoText entry will be our return value, if one is found with the hash.

So add your function definition below holoTextWrite, so that it looks like this: 

function holoTextRead(hash) {}

To retrieve contents from our local source chain, we use the native function  get get takes a hash and an optional config object, and returns an entry, or a HC.HashNotFound message.

Recall that in dna.json, we declared the "Sharing" property for holoText to be "private". This means that entries were only written to local source chains and not the DHT. In order for  get to work properly, we need to mention this by passing a Local: true option into it. 

Make your holoTextRead function look like this: 

function holoTextRead(hash) {
  var holoText = get(hash, { Local: true })
  return holoText
}

 

That’s it! We’ve implemented functions which write data to a local source chain, and read it back. With this, we could technically write "Hello World" into our chain and read it back, but there are other things to learn before we get to see it in action. The following HoloWorld Tutorial articles will cover how to test your application, how to do more complex validation of entries, and how to connect a user interface.

Return to the API documentation page, or continue with the tutorial.