Skip to content

maheshwarishikha/securitization_blockchain

 
 

Repository files navigation

Implement Asset Securitization on a Blockchain Ledger

In this Code Pattern, we'll demonstrate how to simulate a securitization process using React.js, Hyperledger Fabric Node SDK, and an IBM Blockchain service instance.

Securitization is a financial process that can be used to consolidate a set of illiquid assets into a set of tradable securities. A common example of an illiquid asset would be a home mortgage, as they cannot be readily bought and sold. An example of a tradable asset can be a stock or bond. This process can be useful for financial institutions that are looking to increase the liquidity of their assets and free up capital. This application provides a dashboard that will allow users to create and view the relationship between Assets, Pools, Investors, and Securities.

When the reader has completed this Code Pattern, they will understand how to:

  • Deploy a Hyperledger Blockchain network on IBM Cloud
  • Create and enroll a administrative client using the Hyperledger Node SDK
  • Deploy and Instantiate a set of smart contracts to handle transactions and pool assets

Flow

  1. A homebuyer leverages the services of a Loan Originator to secure financing for a home mortgage

  2. The Loan Originator loads the application, and submits requests to update the Blockchain ledger state with a new Asset

This request is handled by the node.js Express backend formats CRUD request into a jsonrpc object like below, and submits it to a Hyperledger peer as a transaction proposal. The request below would register a mortgage with a value of $540000, an interest rate of 3.3%, and a credit score of 720. The credit score is used to calculate risk for potential investors.

{
    "jsonrpc": "2.0",
    "method": "invoke",
    "params": {
        "type": "1",
        "chaincodeID": {
            "name": "securitization_contracts"
        },
        "ctorMsg": {
            "function": 'init_asset',
            "args": '["asset1" , "540000", "0.033", "720"]'
        },
        "secureContext": "[email protected]"
    },
    "id": "5"
}
  1. Peer uses an "endorsement" service to simulate the proposed transaction against the relevant smart contracts. This endorsement service is used to confirm that the transaction is possible given the current state of the ledger. Examples of invalid proposals might be creating an asset that already exists, querying the state of an asset that does not exist, etc.

  2. If the simulation is successful, the proposal is then "signed" by the peer's endorser.

  3. The signed transaction is forwarded to an ordering service, which executes the transaction. In this case, the newly created "Asset" would be placed in an "Asset Pool"

  4. The updated state is committed to the blockchain ledger

  5. The Securitization UI queries the updated ledger state and renders tables with the updated information

  6. If the Asset Pool has been split up into "Securities", an investor has the ability to buy and sell them. The security price should be updated every time there is a change to the ledger state

  7. A creditor checks the ledger state to determine the risk of losses by late payments or mortgages going into default. If a significant change is found, the security credit rating will be recalculated by the creditor and updated in the ledger.

Install Prerequisites:

IBM Cloud CLI

To interact with the hosted offerings, the IBM Cloud CLI will need to be installed beforehand. The latest CLI releases can be found at the link here. An install script is maintained at the mentioned link, which can be executed with one of the following commands

# Mac OSX
curl -fsSL https://clis.ng.bluemix.net/install/osx | sh

# Linux
curl -fsSL https://clis.ng.bluemix.net/install/linux | sh

# Powershell
iex(New-Object Net.WebClient).DownloadString('https://clis.ng.bluemix.net/install/powershell')

After installation is complete, confirm the CLI is working by printing the version like so

ibmcloud -v
# Log in
ibmcloud login

Finally, install the container service plugin, which is required to interact with IBM Kubernetes deployments

ibmcloud plugin install container-service -r Bluemix

Kubernetes CLI

# OS X
curl https://storage.googleapis.com/kubernetes-release/release/v1.11.7/bin/darwin/amd64/kubectl -P /usr/local/bin/
# Linux
curl https://storage.googleapis.com/kubernetes-release/release/v1.11.7/bin/linux/amd64/kubectl -P /usr/local/bin/

chmod +x /usr/local/bin/kubectl
kubectl -v

Node.js packages

If expecting to run this application locally, please install Node.js and NPM. Currently the Hyperledger Fabric SDK only appears to work with node v8.9.0+, but is not yet supported on node v9.0+. If your system requires newer versions of node for other projects, we'd suggest using nvm to easily switch between node versions. We did so with the following commands

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash
# Place next three lines in ~/.bash_profile
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completion
nvm install v8.9.0
nvm use 8.9.0

To run the Securitization UI locally, we'll need to install a few node libraries which are listed in our package.json file.

  • React.js: Used to simplify the generation of front-end components
  • MQTT: Client package to subscribe to Watson IoT Platform and handle incoming messages
  • Hyperledger Fabric SDK: Enables backend to connect to IBM Blockchain service

Included components

Featured technologies

Steps

There are two methods we can use to deploy the application, either run everything locally on your development machine, OR initialize a hosted blockchain service and run in IBM Cloud. These separate steps are labeled as local or hosted, respectively

  1. Provision Blockchain+Kubernetes services in IBM Cloud Platform
  2. Configure IBM Cloud Services
  3. Clone repository
  1. Configure and Deploy application locally OR On IBM Cloud
  2. Import Service Credentials
  3. Configure Application

1. Provision Cloud Services (hosted)

Next, we'll need to deploy our service instances using the IBM Cloud dashboard. This step is only required if you're not deploying the application locally. If you will be running the app and blockchain cluster locally, please skip ahead to the "Clone Repository" section

Blockchain

The IBM Blockchain service can be found by logging in to the IBM Cloud dashboard, selecting the Catalog button, searching for Blockchain, and clicking on the resulting icon. Or click this link.

After selecting the blockchain icon, a form will be presented for configuring the service name, region, and pricing plan. The default values for these fields can be left as is. Also, be sure that the free pricing tier is selected, which is titled Starter Membership Plan. If you are using an IBM Cloud Lite account, this plan can be used for free for up to 30 days. After validating that the information in the form is correct, scroll down and click the Create button in the lower right corner

Kubernetes

Create a Kubernetes cluster here. The free offering will suffice for this demo app. Kubernetes will be used to host a container running the express and react applications

Run the following command to download the configuration file for your cluster. The "mycluster" parameter is the default cluster name (as seen in above screenshot). Be sure to change this parameter if you entered a custom cluster name.

ibmcloud cs cluster-config mycluster

The result of the previous command will download a configuration file which will be used to connect to the Container service. The output will contain an export command like so

export KUBECONFIG=/Users/$USER/.bluemix/plugins/container-service/clusters/mycluster/kube-config-hou02-mycluster.yml

After running the command above, confirm that the kubernetes cli can communicate with the container service by running the following

kubectl get nodes

2. Configure IBM Cloud Services

In this section, we'll be uploading our securitization logic to the Blockchain service.

"Smart contracts", commonly referred to as "Chaincode", can be used to execute business logic and validate incoming requests. In this context, the contracts are used to initialize all participants of the securitization process, define their relationships, and verify transactions. These contracts can be hosted either on IBM Cloud or on a local Hyperledger network managed by Docker.

IBM Cloud Hosted Hyperledger (hosted)

To begin the process of uploading the smart contracts to the hosted blockchain service, we can start by opening the IBM Cloud dashboard, selecting your provisioned Blockchain service, and accessing the blockchain network monitor by clicking Enter Monitor

Next, click the Install code option on the left hand menu, and then the Install Chaincode button on the right of the page

Enter an id and a version (here we'll use "sec" and "v1"). Then, select the Choose Files button to upload the smart contracts, which are titled lib.go, read_ledger.go, write_ledger.go, and securitization.go. These files are located in the chaincode/src directory of this project

Finally, we'll need to Instantiate the chaincode. This can be done by opening the chaincode Actions menu and selecting Instantiate. This will present a form where arguments can be provided to the chaincode init function. In this case, we'll just need to provide an integer (we used "101") to the Arguments section, then click Next and then Submit

Hyperledger Network Setup (local)

As an alternative to the hosted IBM Blockchain service, we can deploy a local Hyperledger network using docker-compose like so

git clone https://github.com/hyperledger/fabric-samples.git
cd fabric-samples/chaincode-docker-devmode

# clear your previous network if it exists
docker-compose -f docker-compose-simple.yaml down

# start up a new local hyperledger network
docker-compose -f docker-compose-simple.yaml up

By default, this will stay open and aggregate the logs from the container. If you'd prefer it to run in headless mode, please add the -d flag to the command

In a separate tab, run the following commands from the root directory of this project to copy the chaincode files into the "chaincode" container, build the binary, and start the chaincode service. The last command will run as a daemon, and will not exit

docker exec -it chaincode mkdir -p securitization
docker cp ./chaincode/src/. chaincode:/opt/gopath/src/chaincode/securitization/
docker exec -it chaincode bash -c 'cd securitization && go build'
docker exec -it chaincode bash -c 'CORE_PEER_ADDRESS=peer:7052 CORE_CHAINCODE_ID_NAME=sec:0 ./securitization/securitization'

In a third tab, run the following commands to install and instantiate the chaincode

docker exec cli peer chaincode install -p chaincodedev/chaincode/securitization -n sec -v 0
docker exec cli peer chaincode instantiate -n sec  -v 0 -c '{"Args":["101"]}' -C myc

Finally, run an invoke command to ensure the chaincode was installed successfully

docker exec cli peer chaincode invoke -n sec -c '{"Args":["read_everything"]}' -C myc

3. Clone the repository

Clone the securitization_blockchain project locally. In a terminal, run:

git clone https://github.com/IBM/securitization_blockchain.git

4. Deploy Application on IBM Cloud (hosted)

Deploy the kubernetes application with the following command

kubectl apply -f kubernetes/kube-config.yml

If successful, you should get the following output

Kalonjis-MacBook-Pro:securitization_blockchain [email protected]$ kubectl apply -f kubernetes/kube-config.yml
service/api-service created
pod/securitization-pod created

This may take a few minutes. In a different tab, following along by running the logs command like so.

kubectl logs -f securitization-pod

We should get output saying the backend and react servers have started. Continue on to access the application

Find the public ip address of the Kubernetes cluster

# Get id of cluster (if it's not the default "mycluster")
ibmcloud ks clusters

# Print workers associated with cluster, take note of public ip
ibmcloud ks workers mycluster

Confirm that the Node.js application is up and running by opening the following

<worker_public_ip>:30000

4. Deploy Application Locally (local)

Install the Securitization UI node packages by running npm install in the project root directory and in the react-backend directory. Both python and build-essential are required for these dependencies to install properly:

# install react dependencies
cd sc-ui
npm install
npm run build

# install express/hyperledger dependencies
cd react-backend
npm install

# return to the root project directory
cd ../../

As an alternative to installing these additional dependencies on your system, you can build the application and dependencies in a docker container like so

docker build -t securitization_blockchain .

NOTE: These steps are only needed when running locally instead of using the Deploy to IBM Cloud button.

Make sure the correct version of node is equipped

nvm use 8.9.0

Start the app locally

cd sc-ui
npm start | PORT=3001 node react-backend/bin/www

If you built the application using docker, then simply run

docker run -it -p 30000:30000 -p 30001:30001 -v /var/run/docker.sock:/var/run/docker.sock -v /usr/local/bin/docker:/usr/local/bin/docker securitization_blockchain bash -c 'cd /root/securitization_blockchain/sc-ui ; npm start | PORT=30001 node react-backend/bin/www'

To access the local Securitization application, open the following URL in a browser: http://localhost:30000/

5. Import Service Credentials (hosted)

This section is only necessary for working on the hosted IBM Cloud blockchain offering. If deploying locally, you can skip to step #7. The credentials for IBM Cloud Blockchain service can be found in the Services menu in IBM Cloud by selecting the Service Credentials option for each service. If using the local network,

The Blockchain credentials consist of the key, secret, and network_id parameters.

We'll also need to provide the Chaincode Id and Version, which is "sec" and "v1" in this example

The credentials will need to be entered in the configuration form, which can be opened by clicking the button in the upper right of the UI

After submitting this form, the UI will fetch a "connection profile" json file, which contains all information needed by our hyperledger client to connect to the blockchain ledger.

Once the connection profile has been retrieved, a certificate will be generated to allow the application to make administrative requests. These elevated privileges are required to make calls to the chaincode service. This PEM encoded certificate will be output in the terminal logs like so. If deploying on IBM Cloud, this certificate can be found parsing the logs using kubectl logs -f securitization-pod, or by opening the developer console in your browser

Once the PEM certificate is generated, it can be copied and uploaded by visiting the printed url, or by revisiting the Blockchain Monitor, navigating to Members on the left hand menu, and then clicking "Certificates" and "Add Certificate"

6. Configure Application

The securitization flow generally occurs in the following format

  1. A homebuyer will apply for financing of an asset via a loan "originator". The loan will have a balance, interest rate, monthly payment, and expected time period for payback (many mortgages are roughly 30 years). A total expected payoff amount will be generated based off this information as well.

  2. Once the loan has been approved and processed, the loan originator then finances the asset, and transfers the debt to a "Special Purpose Vehicle", which is a entity that protects the assets even if the originator goes bankrupt.

  3. The Asset is then placed into a "Pool" along with other assets. Once Assets have been placed into a pool, a set of "securities" can be generated to allow the pool to become tradable. Each Security can be bought and sold by investors, and has a "Yield" which determines the return each security holder will receive on their investment.

  4. The Homebuyer submits payments towards their mortgage.

  5. Each payment is split up and distributed amongst investors who own "securities" associated with the pool. When all mortgages in the pool are paid off, each investor should have received their original investment back plus the agreed "Yield" amount. Each payment will also have a processing fee which will be dispersed to the originator

This securitization process can be replicated with this application by visiting the dashboard and creating Originators, Assets, Pools, Securities, and Investors using the provided forms. Each form requests an unique id format with the name of the object type followed by an integer asset1, pool123, security15

First, we'll need to create a loan "Originator", which will require an ID, Processing Fee (percentage), and (optional) Company Name. This form can be loaded by selecting the Create Originator button. (Note: There is a known intermittent issue with this Originator creation process, so the initial submission may fail. If this occurs, please try submitting again)

Note that the Balance and Assets fields in the table are initially blank, but will be filled in as we associate assets with the originator. And as the originator receives processing fees and security sale proceeds, their Balance will increase as well

Next, we'll create an Asset, which will require an outstanding balance, interest rate, and a payment period, which defines how many monthly payments they'll need to pay off their entire balance. This can be done by scrolling directly down to the Assets Table, clicking the Create New Asset button.

Once the Asset has been created, we can also link it to an originator using the Transfer Asset button

The resulting table should then reflect the following

Create an Asset Pool via the Create Pool form by providing an ID. We can also transfer our asset(s) to the pool using the Transfer Asset button in the Assets table

Create one or more "Securities". The create security form will require a ID, associated Asset Pool, and "Coupon Rate". The Coupon Rate defines the return on investment.

Finally, we can create our Investors, which have the ability to buy and sell securities. This can be done by clicking the Create Investor button and providing a unique id. Once the investor is created, we can then buy and sell securities using the respective buttons. So in this example, we'll do so by clicking the Buy Security button and providing the Security and Investor Id.

Now we can simulate a mortgage payment and view the corresponding payment distributions. We can do so by scrolling back up to the Assets table selecting the "Process Payment" view, and entering an Asset Id and Payment Amount.

Submitting the payment will then:

  • Calculate the payment amount allocated to interest and principal
  • Adjust the remaining balance
  • Calculate and disperse payment amount owed to security holders and originator

Once these calculations are complete, the dashboard tables will then be updated with the latest ledger state

Troubleshooting

  • sendPeersProposal - Promise is rejected: Error: 2 UNKNOWN: chaincode error (status: 500, message: Authorization for GETINSTALLEDCHAINCODES on channel getinstalledchaincodes has been denied with error Failed verifying that proposal's creator satisfies local MSP principal during channelless check policy with policy [Admins]: [This identity is not an admin]

This error occurs if the certificate generated by the SDK user has not been uploaded to the peer

  • Error: The gRPC binary module was not installed. This may be fixed by running "npm rebuild"

grpc is a requirement for the fabric-client SDK. Confirm that it has been installed in the react_backend directory with npm install [email protected]

  • error: [client-utils.js]: sendPeersProposal - Promise is rejected: Error: 2 UNKNOWN: chaincode error (status: 500, message: Authorization for GETINSTALLEDCHAINCODES on channel getinstalledchaincodes has been denied with error Failed verifying that proposal's creator satisfies local MSP principal during channelless check policy with policy [Admins]: [This identity is not an admin])

This error occurs if the admin certificate for the hosted IBM Blockchain service has not been uploaded.

  • Objects are not valid as a React child

This error occurs if one of the Golang structs defined in the chaincode are invalid. These may not have nested objects. To fix this, clear cookies or open a different browser

Links

Learn more

License

This code pattern is licensed under the Apache Software License, Version 2. Separate third party code objects invoked within this code pattern are licensed by their respective providers pursuant to their own separate licenses. Contributions are subject to the Developer Certificate of Origin, Version 1.1 (DCO) and the Apache Software License, Version 2.

Apache Software License (ASL) FAQ

About

Use Hyperledger Fabric to consolidate a set of illiquid assets into a set of tradable securities

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 68.5%
  • Go 28.9%
  • Shell 1.3%
  • Other 1.3%