Learn the process of using IBM Blockchain Platform’s VSCode extension to streamline the process of developing, testing, and deploying a smart contract. Once you finish this tutorial, you will understand how to quickly develop, demo, and deploy your blockchain application on a local Hyperledger Fabric network using VSCode. This tutorial assumes some basic understanding of Hyperledger Fabric.

Watch the videos

Learning objectives

  • Install the IBM Blockchain Platform VSCode extension
  • Create a new JavaScript smart contract
  • Package a smart contract
  • Create, explore, and understand a Hyperledger Fabric network
  • Deploy the smart contract on a local Hyperledger Fabric instance
  • Use a Node.js SDK to interact with the deployed smart contract package

Prerequisites

You will need the following installed in order to use the extension:

If you are using Windows, you must also ensure the following:

  • Your version of Windows supports Hyper-V and Docker:
    • Windows 10 Enterprise, Pro, or Education with 1607 Anniversary Update or later
  • Docker for Windows is configured to use Linux containers (this is the default)
  • You have installed the C++ Build Tools for Windows from windows-build-tools
  • You have installed OpenSSL v1.0.2 from Win32 OpenSSL
    • Install the normal version, not the version marked as “light”
    • Install the Win32 version into C:\OpenSSL-Win32 on 32-bit systems
    • Install the Win64 version into C:\OpenSSL-Win64 on 64-bit systems

You can check your installed versions by running the following commands from a terminal:

  • node --version
  • npm --version
  • yo --version
  • docker --version
  • docker-compose --version

Estimated time

After the prerequisites are installed, this should take approximately 30-45 minutes to complete.

Steps

  1. Get started
  2. Create a new smart contract project
  3. Modify the smart contract
  4. Package the smart contract
  5. Install the smart contract
  6. Instantiate the smart contract
  7. Import the certificate and key
  8. Update the network ports
  9. Invoke the smart contract
  10. Update the smart contract
  11. Query the ledger
  12. Test the contract

Step 1. Get started

packageFile

The first thing you need to do is to install the IBM Blockchain Platform VSCode extension. To do this, you need to install the latest version of VSCode; to see if you have the latest VSCode extension, go to Code > Check for Updates. If VSCode crashes at this point (which it did for me), it likely means you don’t have the latest version. If your VSCode crashes, check the troubleshooting section below. Otherwise, update your VSCode, and once you’re done, click on extensions in the sidebar on the left side of your screen. At the top, search the extension marketplace for IBM Blockchain Platform. Click Install and then click reload. Now you should be all set to use the extension!

Step 2. Create a new smart contract project

packageFile

To create a smart contract project:

  1. Click on your newly downloaded IBM Blockchain Platform extension. It should be the extension all the way at the bottom of the left sidebar.
  2. Next, use the keyboard shortcut Shift + CMD + P to bring up the command pallete. Choose IBM Blockchain Platform: Create Smart Contract Project from the dropdown.
  3. Click JavaScript from the dropdown.
  4. Click New Folder, and name the project what you want. I named mine demoContract.
  5. Click Create and then Open your new folder which you just created. Next, from the dropdown, click Add to Workspace.
  6. Once the extension is done packaging your contract, you can open the lib/my-contract.js file to see your smart contract code scaffold. Nice job!

Step 3. Modify the smart contract

packageFile

Inside your lib/my-contract.js file, go ahead and copy and paste this code:

'use strict';

const { Contract } = require('fabric-contract-api');

class MyContract extends Contract {

  //update ledger with a greeting to show that the function was called
  async instantiate(ctx) {
    let greeting = { text: 'Instantiate was called!' };
    await ctx.stub.putState('GREETING', Buffer.from(JSON.stringify(greeting)));
  }

  //take argument and create a greeting object to be updated to the ledger
  async transaction1(ctx, arg1) {
    console.info('transaction1', arg1);
    let greeting = { text: arg1 };
    await ctx.stub.putState('GREETING', Buffer.from(JSON.stringify(greeting)));
    return JSON.stringify(greeting);
  }

}

module.exports = MyContract;

Note: The .gifs may not exactly match the above smart contract, but this is the one you should have in your lib/my-contract.js file now!

Let’s examine the functions you just defined. The instantiate function creates a greeting object and then stores that on the ledger with the key GREETING. The transaction1 function takes the Hyperledger Fabric context and one argument, arg1, which is used to store a greeting as defined by the user. The ctx.stub.putState method is used to record the greeting on the ledger and then you return that object back. Save the file and proceed!

Step 4. Package the smart contract

packageFile

Now that you have created your smart contract and understand which functions you’ve defined, it’s time to package it so you can install it on a peer.

  1. Open the command pallete with Shift + CMD + P and select package smart contract.
  2. In the left sidebar, click on the IBM Blockchain Platform icon (it looks like a square). In the top-left corner, you will see all of your smart contract packages. You should see demoContract@0.0.1 if everything went well.

Step 5. Install the smart contract

packageFile

Ok, you’re more than halfway there. Now for the fun part! Let’s install this contract on the peer! To do this, you must first connect to a Hyperledger Fabric network. The network that comes with the VSCode extension is perfect for development — it offers the minimal resources to develop and test your contract.

The following Docker containers are started on your local machine, each with a different role in the network: Orderer, Certificate Authority, CouchDB, and Peer.

To start your network, look at your IBM Blockchain Platform extension, at the bottom-right corner where it says Blockchain Connections.

  1. You should see local_fabric. Go ahead and click that. It should automatically run a script and you should see the following output:

    Starting fabricvscodelocalfabric_orderer.example.com_1 ... done
    Starting fabricvscodelocalfabric_ca.example.com_1      ... done
    Starting fabricvscodelocalfabric_couchdb_1             ... done
    Starting fabricvscodelocalfabric_peer0.org1.example.com_1 ... done
    
  2. Click the local_fabric connection again. Now that it’s up and running, it should take you to your channel view, which should show one channel, named mychannel. Click on that.
  3. This will expand your channel and show the peers and smart contracts. Click on peers and you should see peer0.org1.example.com. Right-click on that peer, and click on Install Smart Contract.
  4. The extension will ask you which package to install: Choose demoContract@0.0.1. That’s it! Nice job!

Step 6. Instantiate the smart contract

packageFile

This is the real test — will your smart contract instantiate properly? Let’s find out…

  1. From the IBM Blockchain extension, in the bottom-left corner, under Blockchain Connections, right-click on mychannel and then on `Instantiate / Upgrade Smart Contract OR use the keyboard shortcut Shift + CMD + P to bring up the command pallete. Choose IBM Blockchain Platform: Instantiate Smart Contract from the dropdown.
  2. The extension will then ask you which contract and version to instantiate — choose demoContract@0.0.1.
  3. The extension will then ask you which function to call — type in instantiate.
  4. Next, it will ask you for the arguments. There are none, so just hit enter.

The extension will do some work, and then in the bottom-right corner you should see that the contract was successfully instantiated. Hooray!!

Step 7. Import the certificate and key

packageFile

At this point, you need to start interacting a bit more closely with your Fabric instance. You’ll need to prove to the certificate authority that you are allowed to create a digital identity on the network. This is done by showing the certificate authority your certificate and private key.

  1. You now need a script to connect to the network. Clone this Github Repo outside of your smart contract directory.

    $ git clone https://github.com/horeaporutiu/VSCodeTutorialBlockchain.git
    
  2. Import this folder into your VSCode workspace by right-clicking an empty space under your smart contract directory in VSCode and selecting Add folder to workspace. Find the recently cloned folder VSCodeTutorialBlockchain and double-click it.

  3. In VSCode, click on the IBM Blockchain Platform extension in the left sidebar.

  4. If you are connected to the local_fabric, click on the left arrow symbol to go back to your blockchain connections.

  5. Under Blockchain Connections in the bottom-left corner, right-click on the local_fabric connection and select Export Connection Details. Then choose to export the details in the VSCodeTutorialBlockchain directory.

  6. You should see something like:

    Successfully exported connection details to 
    /Users/Horea.Porutiu@ibm.com/Workdir/VSCodeTutorialBlockchain/local_fabric
    

Step 8. Update the network ports

packageFile

First, run npm install in the VSCodeTutorialBlockchain folder.

  1. Next, open the network.yaml in the VSCodeTutorialBlockchain folder. You will use this file to connect to your Docker containers running locally.

  2. To see your Docker containers running locally, open the demoContract/local_fabric/connection.json file.

    packageFile

    Important Note: Your ports will differ from those shown.

  3. Next, look for the URLs to connect to your peer, orderer, and certificate authority in the demoContract/local_fabric/connection.json file. Copy the corresponding url field from orderer.example.com, peer0.org1.example.com, and ca.org1.example.com.

    In the picture above, the ports in network.yaml would be set as follows:

    First, the orderer:

    orderers:
     orderer.example.com:
       url: grpc://localhost:17050
    

    Then the peer:

    peers:
     peer0.org1.example.com:
       # this URL is used to send endorsement and query requests
       url: grpc://localhost:17051
    

    Then the CA:

    certificateAuthorities:
     ca-org1:
       url: http://localhost:17054
    
  4. Great job. Save the file.

Step 9. Invoke the smart contract

packageFile

Ok, so you’ve instantiated your contract and created your identity — so now what? Well, now it’s time to actually invoke the functions in your contract! To do this, you can use the VSCode extension.

  1. From VSCode, click on the IBM Blockchain Platform Icon (The square) on the left-hand side of VSCode.

  2. Click on local_fabric.

  3. Expand mychannel, and then expand demoContract@0.0.1. You should see two functions, instantiate and transaction1.

  4. Right click on transaction1 and then select submit transaction. For the arguments, enter in ‘hello’.

Nice job! You’ve just invoked your smart contract through VSCode!

Step 10. Update the smart contract

packageFile In the previous step, you updated the ledger by using the putState API, passing in a key and a value. The key happened to be “GREETING” and the value happened to be the object.

{
  text: 'hello'
}

The last thing you should learn is how to query — how to retrieve data from the ledger. You will do this by using the getState API, which takes in a key and returns the value associated with that key, if it finds it.

Let’s add a query function to our demoContract.

  1. Copy and paste the following code into your lib/my-contract.js file:

    'use strict';
    
    const { Contract } = require('fabric-contract-api');
    
    class MyContract extends Contract {
    
     //update ledger with a greeting 
     async instantiate(ctx) {
       let greeting = { text: 'Instantiate was called!' };
       await ctx.stub.putState('GREETING', Buffer.from(JSON.stringify(greeting)));
     }
    
     //add a member along with their email, name, address, and number
     async addMember(ctx, email, name, address, phoneNumber) {
       let member = {
         name: name,
         address: address,
         number: phoneNumber,
         email: email
       };
       await ctx.stub.putState(email, Buffer.from(JSON.stringify(member)));
       return JSON.stringify(member);
     }
    
     // look up data by key
     async query(ctx, key) {
       console.info('querying for key: ' + key  );
       let returnAsBytes = await ctx.stub.getState(key);
       let result = JSON.parse(returnAsBytes);
       return JSON.stringify(result);
     }
    
    }
    
    module.exports = MyContract;
    

    The code adds an addMember function which takes in arguments from the user such as email, name, address, and phone number, and saves that data on the ledger as a key-value pair.

    This code also adds a query function; this function takes in one argument, which is the key to look up. The function returns the value associated with a given key, if there is any.

  2. Update the package.json file such that line 3, which contains the version number, now reads:

     "version": "0.0.2",
    

    Save the file.

  3. After you have updated your package.json, go back and follow steps 3 and 4 to package and install the new smart contract.

  4. To upgrade your existing smart contract to the new version, in the bottom left corner of the IBM Blockchain extension, expand the Instantiated Smart Contract link, and then right-click on demoContract and choose Upgrade Smart Contract. If all goes well, you should get a notification in the bottom-right corner saying Successfully upgraded smart contract.

    packageFile

  5. Now, you can invoke your transactions from the VSCode extension. Under Blockchain Connections from the bottom-left corner of the IBM Blockchain Extension, under mychannel, expand peer0.org1.example.com and then expand the demoContract to view the functions you have defined in my-contract.js, namely instantiate, addMember, and query.

  6. Right-click on addMember and click Submit Transaction. For the arguments, copy and paste the following:

    ginny@ibm.com, Ginny Rometty, Wall Street NY, 1234567890
    

    In the output, you should see the following:

    Submitting transaction addMember with args Ginny Rometty, Wall Street NY, 1234567890, ginny@ibm.com
    

    Let’s add one more member, so repeat this step, but for the arguments copy and paste the following:

    arvind@ibm.com, Arvind Krishna, Broadway Street NY, 1231231111
    

    Nice job. Now on to the last step!

Step 11. Query the ledger

packageFile

After you have added some objects on the ledger, it’s time to query the ledger to see if your data is properly stored on the CouchDB instance of your local fabric network.

  1. Take a look at the query.js file from the VSCodeTutorialBlockchain directory. It’s very similar to the invoke.js file, except it has a few key differences:

     const channel = network.getChannel();
    
     //set up our request - specify which chaincode, which function, and which arguments
     let request = { chaincodeId: 'demoContract', fcn: 'query', args: ['GREETING'] };
    
     //query the ledger by the key in the args above
     let resultBuffer = await channel.queryByChaincode(request);
    

    The main difference is that in this file, you will use the queryByChaincode API, which does not send the transactions to the ordering service — hence, it will not update the ledger. This is very important. In the invoke.js file, you submit transactions to the ordering service, which will all get written to the ledger, but here in the query.js file, you will not update the ledger.

  2. Run the script, to find the value stored in the GREETING variable:

    $ node query.js
    

    You should get the following output:

    Connected to Fabric gateway.
    { text: 'Instantiate was called!' }
    Disconnect from Fabric gateway.
    done
    
  3. Next, query for Ginny Rometty. Change the following line:

     let request = { chaincodeId: 'demoContract', fcn: 'query', args: ['GREETING'] };
    

    to this:

    let request = { chaincodeId: 'demoContract', fcn: 'query', args: ['ginny@ibm.com'] };
    

    Your output should be as follows:

    VSCodeTutorialBlockchain$ node query.js
    Connected to Fabric gateway.
    {"address":" Wall Street NY","email":"ginny@ibm.com","name":" Ginny Rometty","number":" 1234567890"}
    Disconnect from Fabric gateway.
    done
    
  4. Lastly, query for Arvind. Modify the request to be as follows:

    let request = { chaincodeId: 'demoContract', fcn: 'query', args: ['arvind@ibm.com'] };
    

    The output should be similar to the one above, except with Arvind’s data.

Step 12. Test the contract

packageFile

Testing functionality is a feature of the IBM Blockchain extension, and can be done through the UI.

  1. Under Blockchain Connections from the bottom-left corner of the IBM Blockchain Extension, under mychannel right-click on your latest smart contract demoContract@0.0.2 and then select Generate Smart Contract Tests.

  2. Once the extension is done generating the tests, you can run npm test from the demoContract directory, or you can click on the run test button from the VSCode UI from the demoContract@0.0.2.test.js file, as shown in the gif.

Summary

Nice work! You learned how to create, package, install, instantiate, and invoke a smart contract using Hyperledger’s newest APIs. At this point, you can focus on developing your smart contract and updating your my-contract.js file knowing that you have taken care of the networking aspects of blockchain. You can also successfully invoke and update your ledger using just VSCode, Node.js, and Docker. Please, please, please reach out to me if there are bugs — comment on this post and I will fix them. Thanks so much for reading this tutorial. I hope you enjoyed it! Horea Blockchain out!