[Framework Tutorial for Ethereum #3] - Deploy asset ledger

[Framework Tutorial for Ethereum #3] - Deploy asset ledger

The goal of this Ethereum tutorial series is to show you how to use the 0xcert Framework for building a dapp on the Ethereum blockchain plus creating and managing non-fungible tokens.

(Prefer building on Wanchain? This tutorial should help.)

This tutorial episode follows the previous tutorial and assumes you have Ethereum Ropsten node up and running.

In this tutorial, we will:

  • Connect Ethereum with the 0xcert Framework
  • Use the 0xcert Framework for back-end development
  • Build a simple front-end to test the API

At the end of the tutorial series, you will be able to deploy, create, transfer assets on the Ethereum network.

To achieve this, we will use the following technologies:

  • Ethereum Ropsten testnet
  • TypeScript
  • Node.js
  • Express
  • 0xcert Framework
  • jQuery

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

All the code used for the examples can be found on GitHub.

Build your own dapp

Deploy an asset ledger

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

app.post('/deploy', async (req, res) => {

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

const provider = new HttpProvider({
    url: '',
    accountId: '0x...',
    requiredConfirmations: 1

Here, we specified the url that points to our Ethereum node, accountId that represents our 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 Ethereum node, we can continue with deployment. The next step is setting up the actual asset ledger. How will we name it? What symbol will it use? What capabilities will it have? To learn all about these parameters, check the official documentation. For the API, we will just say that all of these are 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

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

To test the API call, we can now write a super simple front-end, we will be using jQuery. We shall create a basic HTML file and insert the code below. If you are not familiar with HTML, check the final product on GitHub.

HTML part:

<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="deploy">Deploy</button>
<p id="deployConsole"></p>

JavaScript function API call (inside tags):

     contentType: 'application/json'
        const capabilities = [];
                name: $('#name').val(),
                symbol: $('#symbol').val(),
                uriBase: $('#baseUri').val(),
                schemaId: $('#schemaId').val(),
                capabilities: capabilities
            function (response) {
                $('#deployConsole').html('<a href="http://ropsten.etherscan.io/tx/' + response + '" target="_blank">Check transaction on Etherscan</a>.');

Now, let's try it out. First, we start Express with npm run start command. Then, we open our webpage (we are not hosting the webpage anywhere but just locally opening it) and insert all the data. You can use the example data below. To learn more about schemaId, please check this introduction, and about other parameters here.

Name: Test
Symbol: TST
Base URI: http://test.com/metadata/
Schema ID: 0x0000000000000000000000000000000000000000000000000000000000000000

Here, we tick off a few capabilities. If we did everything right by pressing Deploy, we should see that nothing happens (if you get a CORS error in browser console, scroll to the bottom of this section). But if we look at the Express console, you will see an error saying "Generic provider error", and if you .catch((e) => console.log(e)) the error, you will see the error details: authentication needed: password or unlock. This is because the account we are using is locked and we cannot do any mutation with it unless we unlock it. Before doing this in production, you should read all about Account management and security - for this example, however, we will unlock the account for an unlimited period of time. We do this by typing the following lines into the Ethereum node console:

web3.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. We chose to input "0", which means 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 again. We should see the link to the transaction, and we should be able to open Etherscan to see whether and when it was accepted onto the Ethereum blockchain.

Note that if you are unable to unlock the account you may need to run the GETH node with additional flag: --allow-insecure-unlock.

Etherscan will show a new contract was created. Let's copy the contract address so that we can use it in the following steps when we issue new assets for this asset ledger. Note that it can take some time before the transaction is shown in Etherscan.

If the local setup impedes the call to your API because of cross-origin error (check your console), you can add this 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, we can start creating (issuing) our assets.

Start building

Framework tutorial #1: Run and prepare Geth node for back-end integration
Framework tutorial #2: Set up Express server with Typescript for dapp backend
Framework tutorial #4: Create new assets
Framework tutorial #5: Transfer assets