Skip to content

Latest commit

 

History

History
225 lines (144 loc) · 7.01 KB

File metadata and controls

225 lines (144 loc) · 7.01 KB

Chaincode

PREV: Deploy a Fabric Network <==> NEXT: Go Bananas


Using the traditional chaincode lifecycle, smart contract deployment requires a Fabric administrator to prepare and install a chaincode package declaring the contract source code, metadata, and target language/runtime. When the contract is committed to a channel, peers are responsible for compiling a custom chaincode binary and launching the contract as a child process. This workflow creates several issues for container-based runtimes, where the build phase is additionally responsible for compiling a Docker image, and the run phase is responsible for managing the lifecycle of a chaincode process in a container orchestrator.

In container based environments such as Kubernetes, the classical chaincode deployment was generally supported with a custom chaincode server / launcher.

With the introduction of Chaincode as a Service (>= 2.4.1), Fabric administrators were provided an alternative deployment option whereby an external chaincode builder could be configured as a "no-op builder". Using CCaaS, an administrator could prepare a custom chaincode container, upload the image to a container registry, launch the chaincode "as a service," and complete the peer lifecycle using traditional peer CLI commands.

While the CCaaS / no-op builder alleviated some mechanical issues and offered full customization of the chaincode lifecycle, it placed two new major responsibilities on the Fabric network administrator:

  • build : The admin must prepare a chaincode image and upload to a container registry.
  • run : The admin must prepare a Service, Deployment, and configure TLS for the chaincode endpoint.

"But - I just want to write some chaincode!"

In this exercise, we will see how the new Kubernetes Chaincode Builder enables an external container build pipeline and eliminates the administrative burdens associated with CCaaS.

Using the fabric-k8s-builder, you will deploy (and iterate) a smart contract definition by:

  1. Preparing a chaincode container image and uploading to a distribution registry.
  2. Preparing a type=k8s chaincode package specifying the unique and immutable container image digest.
  3. Using the peer CLI binaries to install and commit the smart contract to a channel.

Fabric k8s Builder

Ready?

just check-network

Set the peer client environment

export ORG1_PEER1_ADDRESS=${WORKSHOP_NAMESPACE}-org1-peer1-peer.${WORKSHOP_INGRESS_DOMAIN}:443
export ORG1_PEER2_ADDRESS=${WORKSHOP_NAMESPACE}-org1-peer2-peer.${WORKSHOP_INGRESS_DOMAIN}:443

# org1-peer1: 
export CORE_PEER_LOCALMSPID=Org1MSP
export CORE_PEER_ADDRESS=${ORG1_PEER1_ADDRESS}
export CORE_PEER_TLS_ENABLED=true
export CORE_PEER_MSPCONFIGPATH=${WORKSHOP_CRYPTO}/enrollments/org1/users/org1admin/msp
export CORE_PEER_TLS_ROOTCERT_FILE=${WORKSHOP_CRYPTO}/channel-msp/peerOrganizations/org1/msp/tlscacerts/tlsca-signcert.pem
export CORE_PEER_CLIENT_CONNTIMEOUT=15s
export CORE_PEER_DELIVERYCLIENT_CONNTIMEOUT=15s
export ORDERER_ENDPOINT=${WORKSHOP_NAMESPACE}-org0-orderersnode1-orderer.${WORKSHOP_INGRESS_DOMAIN}:443
export ORDERER_TLS_CERT=${WORKSHOP_CRYPTO}/channel-msp/ordererOrganizations/org0/orderers/org0-orderersnode1/tls/signcerts/tls-cert.pem

Docker Engine Configuration

NOTE: SKIP THIS STEP IF USING localho.st AS THE INGRESS DOMAIN

Configure the docker engine with the insecure container registry ${WORKSHOP_INGRESS_DOMAIN}:5000

For example: (Docker -> Preferences -> Docker Engine)

{
  "insecure-registries": [
    "192-168-205-6.nip.io:5000"
  ]
}
  • apply and restart

Chaincode Revision

CHANNEL_NAME=mychannel
VERSION=v0.0.1
SEQUENCE=1

Build the Chaincode Docker Image

CHAINCODE_NAME=asset-transfer
CHAINCODE_PACKAGE=${CHAINCODE_NAME}.tgz
CONTAINER_REGISTRY=$WORKSHOP_INGRESS_DOMAIN:5000
CHAINCODE_IMAGE=$CONTAINER_REGISTRY/$CHAINCODE_NAME

# Build the chaincode image
docker build -t $CHAINCODE_IMAGE contracts/$CHAINCODE_NAME-typescript

# Push the image to the insecure container registry
docker push $CHAINCODE_IMAGE

Prepare a k8s Chaincode Package

IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' $CHAINCODE_IMAGE | cut -d'@' -f2)

infrastructure/pkgcc.sh -l $CHAINCODE_NAME -n localhost:5000/$CHAINCODE_NAME -d $IMAGE_DIGEST

Install the Chaincode

# Install the chaincode package on both peers in the org 
CORE_PEER_ADDRESS=${ORG1_PEER1_ADDRESS} peer lifecycle chaincode install $CHAINCODE_PACKAGE
CORE_PEER_ADDRESS=${ORG1_PEER2_ADDRESS} peer lifecycle chaincode install $CHAINCODE_PACKAGE

export PACKAGE_ID=$(peer lifecycle chaincode calculatepackageid $CHAINCODE_PACKAGE) && echo $PACKAGE_ID

# Approve the contract for org1 
peer lifecycle \
	chaincode       approveformyorg \
	--channelID     ${CHANNEL_NAME} \
	--name          ${CHAINCODE_NAME} \
	--version       ${VERSION} \
	--package-id    ${PACKAGE_ID} \
	--sequence      ${SEQUENCE} \
	--orderer       ${ORDERER_ENDPOINT} \
	--tls --cafile  ${ORDERER_TLS_CERT} \
	--connTimeout   15s

# Commit the contract on the channel
peer lifecycle \
	chaincode       commit \
	--channelID     ${CHANNEL_NAME} \
	--name          ${CHAINCODE_NAME} \
	--version       ${VERSION} \
	--sequence      ${SEQUENCE} \
	--orderer       ${ORDERER_ENDPOINT} \
	--tls --cafile  ${ORDERER_TLS_CERT} \
	--connTimeout   15s
peer chaincode query -n $CHAINCODE_NAME -C mychannel -c '{"Args":["org.hyperledger.fabric:GetMetadata"]}' | jq

Take it Further

Edit, compile, upload, and re-install your chaincode:

SEQUENCE=$((SEQUENCE + 1))
VERSION=v0.0.$SEQUENCE
  • Make a change to the contracts/asset-transfer-typescript source code
  • build a new chaincode docker image and publish to the local container registry
  • prepare a new chaincode package as above.
  • install, approve, and commit as above.

Install chaincode from a CI Pipeline

SEQUENCE=$((SEQUENCE + 1))
VERSION=v0.1.3
CHAINCODE_PACKAGE=asset-transfer-typescript-${VERSION}.tgz
  • Download a chaincode release artifact from GitHub:
curl -LO https://github.com/hyperledgendary/full-stack-asset-transfer-guide/releases/download/${VERSION}/${CHAINCODE_PACKAGE}
  • install, approve, and commit as above.

Debug with Chaincode as a Service

  • prepare a chaincode package with connection.json -> HOST IP:9999 (todo: link to dig out)
  • compute CHAINCODE_ID=shasum CC package.tgz
  • docker run -e CHAINCODE_ID -e CHAINCODE_SERVER_ADDRESS ... $CHAINCODE_IMAGE in a different shell
  • install, approve, commit as above.

Deploy Chaincode With Ansible

  • cp tgz from github releases -> _cfg/
  • edit _cfg/cc yaml with package name
  • just ... chaincode

PREV: Deploy a Fabric Network <==> NEXT: Go Bananas