Skip to content

Creating a project

Now, let's create a project on this cloud. Although it can be done using tau-cli, which you might prefer if you're a terminal enthusiast like me, we're going to use the Web Console instead.

Open a new browser window or tab and navigate to

(1) Type your email, then (2) click on the network selection input, and finally (3) click on Dreamland/blackhole.

Next, click the Login with GitHub button.

You will be asked to grant the app GitHub access. This access is local to your browser and is used to create repositories related to your project, which will be cloned into a browser-based virtual file system.

The next screen will display "Your projects" and should show no projects. You'll want to click on Create project.

Enter a project name, a description, toggle private (unless you want the project repositories to be public), then click on Create Project.

The Web Console will create two repositories: one for configuration, containing mainly YAML files, and another for inline code, containing code in different languages to be compiled to WebAssembly. If everything goes well, you'll be directed to the dashboard.

Creating a Function

Taubyte-based Clouds support serverless functions. Let's create one!

Click on Functions in the side menu, then on the + button.

To expedite the process, we'll use a template. Skip filling any field for now and click on the Template Select button.

This action opens another modal at the top where you can select a template. Although you can choose Go, Rust, or AssemblyScript at the time of writing this article, we'll keep it simple and go for Go! (pun intended). So: (1) select Go, (2) select ping_pong, and finally (3) close the modal.

All fields have been automatically filled except for the domains. Proceed by (1) clicking on the list and (2) selecting GeneratedDomain. This action will create a domain resource for you.

It's worth noting that the Web Console clones your repositories in-browser, meaning there's always a code equivalent to everything you do. Let's review the YAML config by clicking on the Yaml tab.

You will see YAML code resembling the following:

id: ''
description: Returns pong to a ping over HTTP
tags: []
source: .
  type: https
  method: GET
    - /ping
  - GeneratedDomain
  timeout: 10s
  memory: 10MB
  call: ping

Most of this YAML should be self-explanatory, but let me clarify a few points: - source: can either be . for inline code or the name of a library (to be explored in other articles). - specifies the function to be executed and must be exported by the WebAssembly module.

Next, let's inspect the code. The Web Console features a modest code editor useful for quick inline code updates. Access it by clicking on the Code tab.

In the editor, you will observe (1) the usual Go files including go.mod, (2) the code for our handler function ping, and (3) a .taubyte folder defining how the function is built.

While understanding the entire code or mastering Go isn't necessary, I'll explain a few basic concepts that will map in a way or another to any serverless function in supported languages:

  • The package name can be anything except main. The building container, taubyte/go-wasi on Docker Hub, wraps your function in a special main function.
  • The package simplifies interactions with the Taubyte VM, making it straightforward to use VM primitives.
  • We use tinygo to compile Go into small, efficient WebAssembly modules. To export a function, annotate it with the //export comment.
  • Taubyte supports various trigger types, so handlers receive an event. We care about efficiency, so event.Event is really a wrapper of a uint32, minimizing unnecessary memory allocation and copying.

Click Done to proceed.

The function should now appear listed.

Everything done so far is confined to the virtual filesystem in your browser. To apply these changes, we need to push them. Find the green button at the bottom right of the screen and click on it.

A modal will guide you through the code changes, starting with configuration changes. Click on the domains folder, then open the GeneratedDomain.yaml file.

Copy the FQDN generated for you as we will need it later:

fqdn: gftxhd6h0.blackhole.localtau

Click on Next to review code changes.

One more click on Next takes you to the final step, where you'll (1) enter a commit message and (2) push the changes to GitHub.

In production, this push would trigger an event captured by patrick. However, because we're using dreamland and GitHub cannot reach your nodes directly, we run a fixture called push-all to emulate the git events. Switch back to your terminal and run:

dream inject push-all

Return to the Web Console and, on the side menu, click on Builds. You should see two CI/CD jobs, one for configuration and one for code.

After a few seconds, the build should complete. Click on Refresh if it seems delayed. Then, click on the stack icon to view the ping_pong function.

Executing the Function

Now that our function has been built and its configuration published on tns, we can execute it by hitting the endpoint. Since we're running a local cloud, we need to find out which port the substrate (or gateway, if you're using one) node uses to handle HTTP requests. To do this, run:

dream status substrate

In my case, the HTTP port is 14529.

│ substrate@blackhole │ copies │     1 │
│                     ├────────┼───────┤
│                     │ dns    │ 14304 │
│                     ├────────┼───────┤
│                     │ http   │ 14529 │
│                     ├────────┼───────┤
│                     │ p2p    │ 14282 │

You can test the function using curl as follows, making sure to replace gftxhd6h0.blackhole.localtau with your own generated domain:

curl -H "Host: gftxhd6h0.blackhole.localtau"



Alternatively, you can add the generated domain to your local hosts file (/etc/hosts in my case) as follows:

sudo vi /etc/hosts
Add: gftxhd6h0.blackhole.localtau
Save and exit, then run curl again but without the Host header:
curl http://gftxhd6h0.blackhole.localtau:14529/ping



If you've added the generated domain to your /etc/hosts, you can also use the Web Console to hit the function's endpoint: (1) In the sidebar, click on Functions, then (2) click on the thunder icon.

This action opens a new tab where you should see something like this:

Congratulations! You've successfully created a cloud and executed a serverless function on it!