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 #2 and assumes you have set up Express server.

In this tutorial series, you will learn:

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

At the end of this tutorial, you will have a connection between the 0xcert Framework and Wanchain established and asset ledger deployed.

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

Deploy an asset ledger

The first thing we want to write is a way to deploy an asset ledger (ERC-721 smart contract). We create a POST HTTP request and call deploy:

app.post( '/deploy' , async (req, res) => { res.send( 'deploying' ); });

Now let's see how deploying with the 0xcert Framework works. If we follow the specification, we first need to connect to the blockchain through a provider. Since we are using our own node, we will be connecting through HttpProvider. We do this by adding the following lines before our API call definitions so that we can use it in every call:

const provider = new HttpProvider({ url: 'http://127.0.0.1:8545' , accountId: '0x...' , requiredConfirmations: 1 });

Here we specified the url that points to our Wanchain node, the accountId that represents our Wanchain wallet and was generated in Tutorial #1, and we require at least one (1) confirmation before calling a mutation complete.

Now that we are connected to the Wanchain node, we can continue with deployment. For that, we need to set up an actual asset ledger, its name, symbol, and capabilities. To learn all about these parameters, check the official documentation. For the API, we will just set all of these as POST parameters.

app.post( '/deploy' , async (req, res) => { const mutation = await AssetLedger.deploy(provider, { name: req.body.name, symbol: req.body.symbol, uriBase: req.body.uriBase, schemaId: req.body.schemaId, capabilities: req.body.capabilities }); res.send(mutation.id); });

This code will now deploy a new asset ledger with specified parameters and then return the transaction hash which we can check on the Wanchain block explorer. This function will return the transaction hash as soon as it is known, but it will not wait for the transaction to be accepted onto the blockchain. For that, we would need to wait until completion with: await mutation.complete().

To test this function, we can now write a super simple front-end. Let's use jQuery for simplicity.

The HTML part is as follows (if you are not familiar with HTML, check the final product on GitHub.)

< input id = "name" type = "text" placeholder = "Name" /> < br /> < input id = "symbol" type = "text" placeholder = "Symbol" /> < br /> < input id = "baseUri" type = "text" placeholder = "Base uri (http://example.com/)" /> < br /> < input id = "schemaId" type = "text" placeholder = "Schema Id" /> < br /> < br /> < input type = "checkbox" value = "1" /> Asset owner can destroy the asset < br /> < input type = "checkbox" value = "2" /> Asset ledger owner can update assets < br /> < input type = "checkbox" value = "3" /> Asset ledger owner can stop/start all asset transfers < br /> < input type = "checkbox" value = "4" /> Asset ledger owner can revoke (destroy) any asset < br /> < br /> < button id = "submit" > Deploy </ button > < p id = "console" > </ p >

The bottom line on the screen below appears after you click the Deploy button.

JavaScript function API call (inside tags):

$.ajax({ contentType : 'application/json' }); $( function ( ) { $( '#submit' ).click( function ( ) { const capabilities = []; $( "input:checkbox:checked" ).each( function ( ) { capabilities.push($( this ).val()); }); $.post( "http://localhost:3000/deploy" , { name : $( '#name' ).val(), symbol : $( '#symbol' ).val(), uriBase : $( '#baseUri' ).val(), schemaId : $( '#schemaId' ).val(), capabilities : capabilities }, function ( response ) { $( '#console' ).html( '<a href="http://testnet.wanscan.org/tx/ + response + ' "target=_blank" > Check transaction on block explorer< /a>.'); } ); }); });

Now it's time to try it out. First, we start Express with npm run start. Then, we open our webpage and insert all the data. You can use the example data below. If you are unfamiliar with schemaId, please check this introduction.

Name: Test

Symbol: TST

Base URI: http://test.com/

Schema ID: 0x0000000000000000000000000000000000000000000000000000000000000000

Next, we check a few capabilities. If we did everything right, we see that nothing happens when we press Deploy (if you get a CORS error in the browser console, scroll to the bottom of this section). But if we look at the Wanchain node, you will see an error saying "Account is not unlocked". This is because the account we are using is locked and we cannot perform any mutation with it unless we unlock it. ⚠️ Please note that unlocking the account is dangerous, and before doing it in production, you should read all about Account management and security. For our example, however, we will unlock the account for an unlimited period of time. We do this by typing the following lines into the Wanchain node console:

personal.unlockAccount( "0x...." , "password" , 0 )

Replace the first parameter with the address generated in the Tutorial #1 and replace the second parameter with your account's password. The final parameter is time indicating how long the account should remain unlocked. Since we input "0", the account will be unlocked for as long as the node is running or until we manually lock it back.

Now that we unlocked the account let's try the Deploy function again. A link to the transaction should appear, and we should be able to open the Wanchain block explorer to see whether and when it was accepted onto the Wanchain network.

The block explorer will show that a new contract was created. Let's copy the contract address as shown above, so that we can use it in the following steps when issuing new assets for this asset ledger. Note that it can take some time before the transaction is shown on the block explorer.

If the local set-up impedes the call to your API because of cross-origin error, you can add the following lines to the API functions and bypass it:

res.header( "Access-Control-Allow-Origin" , "*" ); res.header( "Access-Control-Allow-Headers" , "Origin, X-Requested-With, Content-Type, Accept" );

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?

Now that we have deployed an asset ledger for our dapp on Wanchain, we can start creating (issuing) our assets.

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 #4: Create new assets

Framework tutorial for Wanchain #5: Transfer assets

Framework tutorial for Wanchain #6: Atomic operations in asset exchange on Wanchain