Here are the steps to run the basic_contract_rs using.

  • Rust Smart Contract hosted within a Wasm engine
  • Hyperledger Fabric v2

This guide will start up a 1 Organization, 1 Peer Fabric Network and start the contract. This is done using MicroFab - a single containerized fabric network that is perfect for fast prototyping and developement. It’s uses the Fabric binaries directly so it is really Fabric.

This is what we’re going to be starting up and running,

  • MicroFab will provide the Fabric v2 runtime, into which we are going to deploy a ‘proxy’ chaincode. We’ll use the ‘peer’ cli commands to do this.
  • This proxy chaincode contains the information (host/port etc) for the peer to locate the docker image that the chaincode is running in.
  • The chaincode here consists of a Wasm VM, into we’ll load a Wasm binary.
  • The Wasm binary will have been built from the Rust basic_contract_rs

Getting setup

  • Install the preqres for Rust and Wasm Development
    • Stable Rust is sufficient, nightly is not required. Instructions at the rust-lang.org
    • To build a Wasm binary you will need to have the wasm target. Note that wasm-pack is not required here as there is no JavaScript host.
      • rustup target add wasm32-unknown-unknown
  • VSCode is our preferred editor, with the Rust Extension and the Rust Analyser
  • Create a working directory to hold the github repos we’ll clone. (examples assume that this is ~/github.com).

Hyperledger Fabric Command Line Tools

We need Fabric Version 2 cli binaries, you may already have these so can skip this.

If not, to get the peer commands (rather than the docker images or samples directory).

curl -sSL https://raw.githubusercontent.com/hyperledger/fabric/master/scripts/bootstrap.sh | bash -s -- 2.2.0 1.4.4 0.4.18 -s -d

Ensure that the commands and configuration are setup correctly.

export PATH=$PATH:~/github.com/bin
export FABRIC_CFG_PATH=~/github.com/config

External builders

Fabric knows about the following languages implicitly. Java, Node, Go. However the peer is not really supposed to be the orchestrator of creating docker images. So this is where the external builder comes in. Microfab is already configured to handle these.

You still need to install a chaincode, but this is really configuration file that says where the actual chaincode is running. This is then added to a tgz archive file and installed as a regular chaincode.

This is a prebuilt copy of this available, but if later you want to do this yourself grab a copy of https://github.com/hyperledgendary/fabric-builders/blob/master/tools/pkgcc.sh which will do this for you.

curl -s https://raw.githubusercontent.com/hyperledgendary/fabric-builders/master/tools/pkgcc.sh > ./pkgcc.sh

Creation

Now we’re going to create the various assets etc that we need

Smart Contract

  • In your working directory, clone this repo
    • git clone https://github.com/hyperledgendary/fabric-contract-api-rust.git
  • Ensure it can be built correctly, cd into the fabric-contract-api-rust
    • Using make: make -f justfile wasm
    • Using just: just wasm
    • Using cargo: cargo build --target wasm32-unknown-unknown

This will have built a Wasm binary to fabric-contract-api-rust/target/wasm32-unknown-unknown/debug/basic_contract_rs.wasm

As we’ve cloned the whole repo, we’ve also got the Rust Contract crates source as well. Normally you would just add the dependencies from crates.io

External chaincode container

Finally we need to have the Docker image that will host the Wasm VM; there’s a prebuilt version of this on docker hub, but if you wish to build it yourself or to change from the default settings do the following.

Clone the fabric-chaincode-wasm reop

git clone git@github.com:hyperledgendary/fabric-chaincode-wasm.git
docker build -t hyperledgendary/fabric-chaincode-wasm .

Copy the chaincode.env.sample to chaincode.env. This will need to be editted shortly, so it’s good to keep a copy of the original

Start Microfab

First setup an environment variable:

export MICROFAB_CONFIG='{
    "endorsing_organizations":[
        {
            "name": "Ampretia"
        }
    ],
    "channels":[
        {
            "name": "minifignet",
            "endorsing_organizations":[
                "Ampretia"
            ]
        }
    ],
    "capability_level":"V2_0"
}'

Both Microfab and the Wasm chaincode will be run in separate docker containers. It’s easier therefore to create a docker network to link these two.

docker network create wasm_network

Then issue this docker command to run MicroFab

docker run --name microfab --rm -d -p 8080:8080 -e MICROFAB_CONFIG="${MICROFAB_CONFIG}"  --network=wasm_network sstone1/microfab

Get the MicroFab configuration

When applications (including the Peer commands ) run they need a local identity in a wallet and a gateway connection profile. In this case there’s a helpful script that can pull out all the information needed.

Run this in your working directory - some sub-directories will be created.

npm install -g @hyperledgendary/weftility
curl -s http://console.127-0-0-1.nip.io:8080/ak/api/v1/components | weft microfab -w ./_wallets -p ./_gateways -m ./_msp -f

Then setup some environment variables for the peer commands; these are

export CORE_PEER_LOCALMSPID=AmpretiaMSP                                       
export CORE_PEER_ADDRESS=ampretiapeer-api.127-0-0-1.nip.io:8080
export CORE_PEER_MSPCONFIGPATH="${WORKING_DIR}/_msp/Ampretia/ampretiaadmin/msp"

Contract Deploy

Tip: the wasmftw.tgz and chaincode.env files are in the fabric-contract-api-rust\tests\assets directory if you want to copy them directly.

Package Proxy Chaincode

If you want to build the wasmftw.tgz yourself then do this otherwise, skip to the next step.

Create a connection.json file with details of how Fabric will connect to the external service chaincode

{
  "address": "wasmcc.example.com:9999",
  "dial_timeout": "10s",
  "tls_required": false
}

Package the connection.json file using the pkgcc.sh script

Again if you have the same directory structure, this command

../pkgcc.sh -l wasmftw -t external connection.json

A wasmftw.tgz file will be created. This is the chaincode package that will be installed on the peer - as the proxy for the real chaincode. Feel free to unpack and investigate it’s contents. Note that this is the equiavlent of doing a peer lifecycle chaincode package

Install the Proxy Chaincode

Install this proxy chaincode package.

peer lifecycle chaincode install wasmftw.tgz

It’s important to keep the output from this command as it will be needed in the next step

Run Wasm chaincode

Create a chaincode.env file, making sure the CHAINCODE_ID matches the chaincode code package identifier from the install command. (the one in the tests/assets directory should be sufficient if you’ve also copied the wasmftw.tgz file. Just double check the package id matches)

CHAINCODE_SERVER_ADDRESS=wasmcc.example.com:9999
CHAINCODE_ID=wasmftw:eeae07c6e9455f329e28f9a0eed977ae3549be68e68247018f71dc5a5f511c0d
CHAINCODE_WASM_FILE=/local/basic_contract_rs.wasm

It’s also worth copying the wasm binary file created previously, for example if you’re following the same directory structure run this command from your working directory

mkdir -p contracts
cp ./fabric-contract-api-rust/target/wasm32-unknown-unknown/debug/basic_contract_rs.wasm ./contracts

Run the chaincode: note that this docker command runs it in foreground so you can watch what happens. Worth opening another terminal at this point to run this in docker command in.

If you’ve built you wown fabric-chaincode-wasm container adjust the image name.

docker run -it --rm -v ${PWD}/contracts:/local:ro --name wasmcc.example.com --hostname wasmcc.example.com --env-file chaincode.env --network=wasm_network hyperledgendary/fabric-chaincode-wasm

Approve and commit the Wasm chaincode

Approve the chaincode, making sure the package-id matches the chaincode code package identifier from the install command

peer lifecycle chaincode approveformyorg -o orderer-api.127-0-0-1.nip.io:8080 --channelID minifignet --name wasmftw --version 1 --sequence 1 --waitForEvent --package-id wasmftw:eeae07c6e9455f329e28f9a0eed977ae3549be68e68247018f71dc5a5f511c0d

Commit the chaincode

peer lifecycle chaincode commit -o orderer-api.127-0-0-1.nip.io:8080 --channelID minifignet --name wasmftw --version 1 --sequence 1

Run a transaction!

Create an asset….

peer chaincode invoke -o orderer-api.127-0-0-1.nip.io:8080 --channelID minifignet -n wasmftw -c '{"function":"AssetContract:create_asset","Args":["007","Bond"]}'

Get back the value

peer chaincode query  -o orderer-api.127-0-0-1.nip.io:8080 --channelID minifignet -n wasmftw -c '{"function":"AssetContract:read_asset_value","Args":["007"]}'

Using a node.js client application

Running the peer commands is ok, but really one of the SDKs will be used to run client applications.

As an example client application we can use runhfsc. This uses the latest Fabric Node SDKs, and runs in node 12.

npm install -g @hyperledgendary/runhfsc

From your working directory, run this command to point the application at the client wallets and connection profile

runhfsc --gateway ./_gateways/ampretiagateway.json --wallet ./_wallets/Ampretia --user ampretiaadmin --channel minifignet

This will connect and you can see the prompt with the id and channel, type in contract wasmftw

[default] ampretiaadmin@minifignet:<contractid> - $ contract wasmftw
Contract set to wasmftw
[default] ampretiaadmin@minifignet:wasmftw 

We can now repeat the final peer command but driving the Node.js SDK

evaluate 'AssetContract:read_asset_value' '["007"]'
Submitted AssetContract:read_asset_value  007
[ '007' ]
> 
Bond