Atra released new features this week including the ability to build relational data tables on Ethereum. Walk through the short tutorial below to learn how you can create relational data on the blockchain.

Hannah Duckworth
Jul 20 · 7 min read

Hey, it’s Hannah from Atra Blockchain Services. I’m going to give you a quick overview of one of our newer features, relational data tables. With our service, dTables, you can now quickly create relational data tables to power your decentralized application. For this tutorial, we are going to create a simple dApp that houses Members of an organization and allows them to post a message to the group.

Let’s get started!

You will find direct instructions in bold.
Metamask with test Ether is required to insert data at the end but not to build.

Start on your management console.
If you do not have an account, create one at — it will take less than a minute!

Part 1: Laying the Foundational Data Tables

Atra Console Homepage

If you are not familiar with dTables, it is a service that allows you to create decentralized data tables with our point and click interface, and deploy them to the public Ethereum network.

We are going to build a simple application to showcase how to setup relational tables.

Head to dTables service dashboard

Here we are on the dTables dashboard home page.
Click Create Table

In this simple scenario, we are going to show you how to use relational data by connecting users for a Decentralized Organization dApp with their own messages from a feed, in sort of a ‘profile’ way.

For my first dTable, we’re going to create the members table.

Name your table OrgMembers, add description ‘a database of all org members’.

I’m going to store our member’s Name, UserName, Date Joined and WalletAddress.

Enter the following column names and type:
[Text] Name, [Text] UserName, [Date] DateJoined, [Address] WalletAddress.

This is what you should have at this step

Hit Create Table. This table isn’t using the new Pointer feature yet, but serves at the base for our application to be pointed to. You’ll see in the next step.

Back on the dTables dash, make sure your table deploys and is live (indicated by green lightning bolt).

Now that our users table is live, let’s create the next one that we will relate to it.

Click Create dTable.

Now we are going to create our message feed.
Type MessageFeed in the Name.
For our columns, we are going to store the Post and the PostDate. Now we will want to display the user who posted this. That’s where the pointer comes in — adding a pointer column to a dTable will allow you to pull a record from one table to another, thus creating relational data.

Let’s name our table and add the necessary columns.

Add columns [Text] Post and [Date] PostDate.
Add a pointer column to OrgMembers

Notice the Pointer Column is utilized in this step

Click Create dTable

Part 2: Creating API Endpoints to Facilitate Business Logic

Once live, let’s make Triggers to be able to insert posts our feed. Once we create the Triggers, we will wrap this up into a LiteUI and be done!

Head to your Triggers Dashboard and hit Create Trigger.

We are going to select Insert Record, as we are looking to insert posts into the feed.

Select MessageFeed as the dTable you want to modify.

For Post Text we will choose User Input.

For Post Date we will choose CurrentDateTime.

For the Pointer, we will choose OrgMembers and set the configuration to Automap User’s Address, WalletAddress.

Notice we Automap the Pointer using the Member’s Wallet Address stored in the table

This tells the dTables to pull in the user info by taking the user’s address and matching it to a record in the Members dTable.


Add conditions to the Trigger by clicking on New Condition. Maybe you want to make sure the post is not blank. Type “make sure post is not blank” in the description box. For our configuration we want to display Post / Not Equal To / Text, and leave the form blank, hence not allowing a user to post a blank message.

Add New Condition so that we can then make sure the user is in our Members table to begin with. We want our configuration to display User’s Address / Is In / dTable / OrgMembers / WalletAddress. This will enforce that the poster is a registered user.

Set conditions for your application to enforce business logic


You can add payments to your trigger. In this case, if you wanted to charge the user to post a message, you would select Yes, and choose either a static price or a range you are willing to accept to post. Set your price, and then autofill your address into the receiving wallet so that you receive all of the funds.

Name your trigger ‘InsertPost’ and set the description to ‘allow member to insert post’.

Review the summary and if everything is correct, click Deploy.

Now we need another simple trigger to make sure we can allow members to sign up. Stay within the Triggers service, and on your dashboard click Create Trigger.

We are going to select Insert Record, as we are looking to insert users into the member table.

Select OrgMembers as the dTable you want to modify.

For Name we will choose User Input.

For UserName we will choose User Input.

For DateJoined we will choose Current DateTime.

For WalletAddress, we will choose User’s Address.

Create a Trigger to allow users to join your dApp as a member

Set a New Condition so that the username does not already exist in the table. The configuration should display UserName / Is Not In / dtable / OrgMembers / UserName. Add another condition making sure the user’s wallet address does not already exist in the table. The configuration should display User’s Address / Is Not In / dtable / OrgMembers / WalletAddress.

Set up authentication easily using Triggers

Hit Next.

We will not be adding a payment to complete the action, but you can if you see fit.

Hit Next again.

Name the Trigger ‘InsertMember’ and set a description.

Review the summary.

Click Deploy.

Important! Click in to each Trigger you just created, and click ‘Grant Permission’.

Part 3: Create a User Interface

Now let’s build a LiteUI to test this out, put in some fake data, and see relational tables at work.

Head to your LiteUI dashboard.

Click the create button to the top right.

Name your site My dOrg. Insert an image and tagline if you’d like.

Add a Page, name it Feed.

Click Add Element. Choose List, and select MessageFeed from the dropdown, click Add.

You will see your message feed appear on the screen, and you will see columns that are pulled from the users table. We will configure this in a few, and make it look much better.

Click Add Element, choose Form and select InsertPost from the dropdown.

Click on the header of the InsertPost element and drag it above the MessageFeed.

Before configuring, this is what your page should look like at this step

Add a Page, name it Members.

Add UI Element, Form, InsertMember.

Add UI Element, List, OrgMembers.

Let’s add some dummy data.

Insert your first user:

Name: Rob Lowe

UserName: dAppDude

Confirm the transaction via MetaMask.

Try to insert a second user:

Name: Rashida Jones

UserName: Ann123

Notice you get an error, because metamask is pulling your address which is already used for Robe Lowe. Remember that condition we set earlier? It works.

Go to your Feed page. Insert a message: Hello Friends

Let’s configure our elements to make this dApp look a little better.

Go to your Members page, Click the 3 dots in the upper right hand corner of OrgMembers and hit configure.

Change the name to dOrg Members.

Change ‘Details’ to ‘Profile’.

Below in the Render As columns, we want to remove WalletAddress from the table. Leave Name and UserName as text, Render WalletAddress as None.

Click Save.

Configure your InsertUser form to be named ‘Sign Up’.

Go back to the feed page.

Configure the InsertPost form to be named ‘Post a Message’.

Now configure the Message Feed.

Change the Name to Feed. Render every column as text, except OrgMembers_Pointer, Name and WalletAddress to None.

Click Save.

Configured Message Feed

Looks great, right?

Now, back on our Members page, click ‘Profile’ for a member.

Here you will see all the details of that member’s record in the table. We want this to act more as a profile where other users can see all the posts from a user.

Add UI Element, List, Message Feed.

Configure the new Message feed inside the Profile.

Change name to Member Messages.

Check the checkbox that says ‘filter by record ID’.

Render the Pointer and the WalletAddress as None.

Relational Data at work!

Now you will see how relational data can start to shape functioning dApps. Now any other user profile you click on will filter to that member’s post.

Important: Save your LiteUI.

Now open and share in the public URL and play around!

Questions? Email me at

Atra Blockchain Services

A cloud platform of web services that helps you build, deploy and maintain decentralized applications without the headache of building and maintaining the infrastructure.

Hannah Duckworth

Written by

cofounder @ atra blockchain services

Atra Blockchain Services

A cloud platform of web services that helps you build, deploy and maintain decentralized applications without the headache of building and maintaining the infrastructure.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade