[Framework Tutorial 3] - Deploy asset ledger

[Framework Tutorial 3] - Deploy asset ledger

The goal of this tutorial series is to showcase how the 0xcert Framework can be used with the Ethereum blockchain for managing non-fungible tokens. This episode follows the previous tutorial and assumes you have Ethereum Ropsten node up and running.

In this tutorial series 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 it 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 which is done through a provider. Since we are using our own node, we will be connecting trough HttpProvider. We will 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: 'http://127.0.0.1:8545',
    accountId: '0x...',
    requiredConfirmations: 1
});

Here, we specified the url that points to our Ethereum node, accountId which represents our wallet that was generated in the previous tutorial, and we set the needed blockchain confirmations to 1 as a threshold for calling a mutation complete.

Now that we are connected to the Ethereum node, we can continue with deploying. 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 about all of 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
    });
    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 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 destory 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):

$.ajax({
     contentType: 'application/json'
});
$(function(){
    $('#deploy').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) {
                $('#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, read here, 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, but for this example, we will unlock the account for an unlimited period. We do this by typing the following into the Ethereum node console:

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

Replace the first parameter with the address generated in the previous tutorial 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 as long as the node is running or until we manually lock it.

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 blockchain.



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 to 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

Newsletter