[Framework Tutorial for Wanchain #6] - Atomic operations in asset exchange

[Framework Tutorial for Wanchain #6] - Atomic operations in asset exchange

The goal of this Wanchain tutorial series is to show how the 0xcert Framework can be used with the Wanchain blockchain for building a dapp, as well as creating and managing non-fungible tokens.

⚠️Prefer building on Ethereum? This tutorial should help.


Before we begin

This episode follows the Tutorial #5 and assumes you have completed the step of transferring assets.

In this tutorial series, you will learn:

  1. How to set up a Wanchain test node (gwan)
  2. How to create a Wanchain wallet and obtain test WAN tokens
  3. How to set up Express server with TypeScript
  4. How to connect Wanchain with the 0xcert Framework
  5. How to use the 0xcert Framework for back-end
  6. How to set up a simple front-end for testing

At the end of the tutorial, you will be able to deploy, create, transfer, and query for information about non-fungible tokens on the Wanchain network.

To achieve this, we are using the following technologies:

  • Wanchain testnet
  • TypeScript
  • Node.js
  • Express.js
  • 0xcert Framework
  • jQuery

It is assumed that you know and understand the basics of JavaScript, Node.js, jQuery, HTML, and usage of the terminal.

All the code used for examples can be found on GitHub with additional functions and explanations.

Build your dapp on Wanchain


1. Atomic order

In this section, we will perform two atomic operations. We assume you know the basic principles of atomic operations within the 0xcert Framework, so if you're unfamiliar with it, we suggest you read this article.

1.1 Before we begin

Atomic operations are performed via the Order Gateway structure which is deployed permanently on the platform and available to the public. The cryptographic mechanisms embedded in the Order Gateway structure guarantee protection for a fixed sequence of required steps and conditions.

1.2 Installation

First, we need to install the Order Gateway package:

$ npm i --save @0xcert/wanchain-order-gateway

2. Usage overview

For this tutorial, we will transfer an existent asset but also create a new asset and transfer it to our main digital wallet - all in a single atomic operation.

We should already have a deployed asset ledger from the previous steps, and now we can create another asset and send it to ourselves with ID 100. We will be using that asset ledger and the newly created asset with ID 100 in our atomic operation.

We will also need to set up another wallet and unlock it to represent the Taker - check the Step 2 in the tutorial.

Now, we import a module into the application. In our case, we import the OrderGateway class that represents a wrapper around a specific pre-deployed structure on the Wanchain network.

import { OrderGateway, Order, OrderActionKind } from '@0xcert/wanchain-order-gateway';

Next, we add a new API endpoint called atomic-order.

app.post('/atomic-order', async (req, res) => {
});

In all the previous sections, we have created a front-end that required you to specify all the input parameters. But since atomic orders are a bit more complex and dynamic, we will hard code all the parameters and press a button on the front-end. In a real-world dapp, you would either handle this on the front-end, similarly to SwapMarket or generate an atomic order on the back-end yourself, depending on what you want to use it for. In this example, we only want to show how it works, so a primitive set-up like this is sufficient.

Next, we create a new instance of the OrderGateway class of an ID that points to a pre-deployed order gateway smart contract on the Wanchain testnet.

You can find the orderGatewayId for your preferred network here. Since this tutorial is made for building on the Wanchain testnet, we will copy OrderGateway address from the Wanchain section.

const orderGatewayId = '0x90A8D7e2138ABB28393906Ae162238B5A18fE846';
const orderGateway = OrderGateway.getInstance(provider, orderGatewayId);

Now, we can define an operation with two actions:

  1. The first action will transfer an asset of ID 1 to our second wallet.
  2. The second action will create (mint) a new asset of ID 2 and add it to our wallet.

Every atomic operation has a Maker and a Taker. In this tutorial, we will act as both the Maker and the Taker of the order. For the makerId, we will use the gwan account we created at the begging of this tutorial, and for the takerId, we will use the one we created a few steps before.

This is how our order will look like:

const account1 = '0x...'; // 0x... - Account we used at the begging of the tutorial.
const account2 = '0x...'; // 0x... - Account we just created.
const assetLedgerId = '0x...'; // Your already deployed asset ledger.
const order = {
    makerId: account1,
    takerId: account2,
    actions: [
        {
            kind: OrderActionKind.TRANSFER_ASSET,
            ledgerId: assetLedgerId,
            senderId: account1,
            receiverId: account2,
            assetId: '1',
        },
        {
            kind: OrderActionKind.CREATE_ASSET,
            ledgerId: assetLedgerId,
            receiverId: account1,
            assetId: '2',
            assetImprint: '0000000000000000000000000000000000000000000000000000000000000000', // check certification section in documentation on how to create a valid imprint
        },
    ],
    seed: Date.now(), // unique order identification
    expiration: Date.now() + 60 * 60 * 24, // 1 day
} as Order;

3. Atomic order in action

Atomic operations work in multiple steps and with multiple parties, as follows:

1. Maker signs an atomic order.
2. Maker approves their operations.
3. Maker sends an order with a signature to the Taker.
4. Taker approves their operations.
5. Taker performs the atomic order.

For this example, we will do all of the above in one API call and therefore act as both the Maker and the Taker, and we will do all the operations in a single go. So there is no need for Step 3, since we already have all the needed information.

Let's begin with Step 1.

const signedClaim = await orderGateway.claim(order);

By calling the claim function, we sign the order. Next, we need to send this signature to the Taker, together with the order object via an agreed communication channel.

Steps 2 and 4 are described below (each party should do this on their side):

For our example, we don't have any actions that need approval from the Taker, so we only do the Maker's part.

All parties participating in the operation must unlock the assets to be transferred and allow the OrderGateway to manage them. This step should be done by every person that participates in a transfer within order operations. In the example below, we authorize the OrderGateway to transfer the asset of ID 100 to another wallet address and grant it the ability to create (mint) assets.

The API section of the 0xcert Framework Documentation provides instructions on how to authorize the Order Gateway for all the assets simultaneously, to avoid authorizing only one asset at a time.

Order Gateway is comprised of multiple smart contracts. To save you the hassle of having to know their exact addresses, we handle all of this under one roof. However, the instance of OrderGateway is needed so that we know how to manage it. You may also decide to do this manually by finding the exact proxy contracts for the Order Gateway, but we recommend using Order Gateway Instance and let the 0xcert Framework handle that for you.

// approve account for transfering asset
await assetLedger.approveAccount('1', orderGateway).then((mutation) => {
    return mutation.complete();
});
// assign ability to mint
await assetLedger.grantAbilities(orderGateway, [GeneralAssetLedgerAbility.CREATE_ASSET]).then((mutation) => {
    return mutation.complete();
});

Make sure you create an instance of assetLedger and import GeneralAssetLedgerAbility.

For Step 5, we perform the order as a Taker (who will pay the network fee).

To specify that we perform this as a Taker, we will need to create a new instance of Provider and a new instance of OrderGateway with that provider, like this:

const providerTaker = new HttpProvider({
    url: 'http://127.0.0.1:8545',
    accountId: account2,
    requiredConfirmations: 1
  });
const orderGatewayTaker = OrderGateway.getInstance(providerTaker, orderGatewayId);

Now, we can execute the order and return the result:

const mutation = await orderGatewayTaker.perform(order, signedClaim);
res.send(mutation.id);

To trigger the API, let's add a button to our webpage,...

<h1>Atomic order</h1>
<button id="atomicOrder">Perform atomic order</button>
<p id="console"></p>

..., add JavaScript code for the API call:

$.ajax({
  contentType: 'application/json'
});
$(function(){
  $('#atomicOrder').click(function(){
    $.post(
      "http://localhost:3000/atomic-order",
      { },
      function (response) {
        $('#console').html('<a href="http://testnet.wanscan.org/tx/ + response + '" target="_blank">Check transaction on block explorer</a>.');
      }
    );
  });
});

Now we can trigger and check whether the atomic operations work as intended.

This is just a simple introduction to atomic operations. You can specify multiple actions and as such transfer multiple assets, create multiple new assets, update asset imprint and transfer value.

4. Conclusion

If you followed the tutorial, you hopefully learned something new about the Wanchain network and how to run their node, how to set up the Express server with TypeScript, and how to manage assets with the 0xcert Framework. To keep the tutorial readable, we only grazed all the functionalities that the 0xcert Framework provides. To learn more, you can check our GitHub and Documentation. The whole tutorial is also available on GitHub here.


If you have questions about the code or you experience trouble developing your dapp, you can ask our developers for help in our Gitter channel.

What comes next?

Congrats, you've made it to the end of our tutorial series for building dapps on the Wanchain network with the 0xcert Framework!

All that you have to do now is put the theory into practice, and create an awesome new dapp.

Start building

⬇️Check other tutorial episodes, too⬇️

Framework tutorial for Wanchain #1: Run and prepare Wanchain test node for back-end integration
Framework tutorial for Wanchain #2: Set up Express server with TypeScript for dapp back-end
Framework tutorial for Wanchain #3: Deploy asset ledger
Framework tutorial for Wanchain #4: Create new assets
Framework tutorial for Wanchain #5: Transfer assets

Newsletter