Skip to content

Instantly share code, notes, and snippets.

@dexhunter
Last active September 4, 2018 07:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dexhunter/30c01b98586846497371d4e7997e0e57 to your computer and use it in GitHub Desktop.
Save dexhunter/30c01b98586846497371d4e7997e0e57 to your computer and use it in GitHub Desktop.
fabric python sdk tutorial

Tutorial of using Fabric SDK

Notice: The tutorial is still in-progress, feel free to ask question in the rktchat channel. Code can be found at e2e_test.py.

Pre-requisites

Install Fabric SDK

$ git clone https://github.com/hyperledger/fabric-sdk-py.git
$ cd fabric-sdk-py
$ make install

After installation, you can optionally verify the installation.

$ python
>>> import hfc
>>> print(hfc.VERSION)
0.7.0

Start a Fabric Network

SDK needs a targeted fabric network to operate with, if there is not a running one, need to start a network manually.

To start a fabric network you can simple up the docker-compose-2orgs-4peers-tls under fixtures.

$ docker-compose -f test/fixtures/docker-compose-2orgs-4peers-tls.yaml up

Then you'll have 2 orgs (org1.example.com; org2.example.com) with 2 peers in each one and one orderer (orderer.example.com)

If you want to understand the fabric network and how to change the network configuration, feel free to follow the byfn tutorial, from crypto-generator section to start-the-network section. service on the yaml file either.

Create Connection Profile

A network connection profile will include all information that SDK requires to operate with a fabric network, including:

  • Service endpoints for peer, orderer, ca;
  • Credentials for identities that clients may act as;

e.g., network1.json.

Load Configurations

SDK can load all network information from the profile, and check the resources in the network.

# TODO: update code
from hfc.fabric import Client

cli = Client(net_profile="test/fixtures/network.json")

cli.organizations  # orgs in the network
cli.peers  # peers in the network
cli.orderers # orderers in the network
cli.CAs  # ca nodes in the network

Interaction with Fabric Network

After load the configuration, SDK can operate with the network.

Create a New Channel

from hfc.fabric import Client

cli = Client(net_profile="test/fixtures/network.json")
org1_admin = cli.get_user('org1.example.com', 'Admin')

# The response should be true if succeed
response = cli.channel_create(
		'orderer.example.com',
		'businesschannel',
		org1_admin,
		'test/fixtures/e2e_cli/channel-artifacts/channel.tx')

Join Peers into Channel

from hfc.fabric import Client

cli = Client(net_profile="test/fixtures/network.json")
org1_admin = cli.get_user('org1.example.com', 'Admin')

# The response should be true if succeed
response = cli.channel_join(
		org1_admin,
		'businesschannel',
		['peer0.org1.example.com', 'peer1.org1.example.com'],
		'orderer.example.com')

Install Chaincode to Peers

from hfc.fabric import Client

cli = Client(net_profile="test/fixtures/network.json")
org1_admin = cli.get_user('org1.example.com', 'Admin')

# The response should be true if succeed
response = cli.chaincode_install(
		requestor=org1_admin,
		peer_names=['peer0.org1.example.com'],
		cc_path='github.com/example_cc',
		cc_name='example_cc',
		cc_version='v1.0' )

Instantiate Chaincode in Channel

from hfc.fabric import Client

#TODO

Invoke a Chaincode

from hfc.fabric import Client

#TODO

License

Creative Commons License
This document is licensed under a Creative Commons Attribution 4.0 International License.

@dexhunter
Copy link
Author

dexhunter commented Jul 5, 2018

response = cli.channel_create('orderer.example.com', 'businesschannel', org1_admin, 'test/fixtures/e2e_cli/', 'TwoOrgsChannel')

# The response should be true if succeed
response = cli.channel_create(
		'orderer.example.com',
		'businesschannel',
		 org1_admin,
		'test/fixtures/e2e_cli/',
                'TwoOrgsChannel')

@dexhunter
Copy link
Author

response = cli.channel_join(org1_admin,'businesschannel',['peer0.org1.example.com', 'peer1.org1.example.com'],'orderer.example.com')

@dexhunter
Copy link
Author

dexhunter commented Jul 5, 2018

response = cli.chaincode_install(requestor=org1_admin,peer_names=['peer0.org1.example.com'],cc_path='github.com/example_cc',cc_name='example_cc',cc_version='v1.0' )

double check on whether the chaincode is installed

@dexhunter
Copy link
Author

dexhunter commented Jul 6, 2018

How to check the channel?

use cli._channels

@dexhunter
Copy link
Author

dexhunter commented Jul 7, 2018

response = cli.chaincode_instantiate(org1_admin, ['peer0.org1.example.com'], ['a', 100, 'b', 40], 'example_cc', 'v1.0')

@dexhunter
Copy link
Author

response = cli.chaincode_invoke(org1_admin, ['peer0.org1.example.com'], ['a', 'b', 200], 'example_cc', 'v1.0')

@dexhunter
Copy link
Author

Some notes on the query

after

response.subscribe(
on_next=lambda x: queue.put(x),
on_error=lambda x: queue.put(x)
)

res = queue.get(timeout=timeout)

we get res which is a tuple

it has three layers

res[0] is a list
res[1] is hfc.protos.peer.proposal_pb2.Proposal
res[2] is hfc.protos.common.common_pb2.Header

res[0][0] is tuple
res[0][0][0] is hfc.protos.peer.proposal_response_pb2.ProposalResponse

You can print the result as

         for i in range(len(res)):                                                                                                                                                                                 
             print('layer0 - {}'.format(i), type(res[i]))                                                                                                                                                          
             if isinstance(res[i], (tuple, list)):                                                                                                                                                                 
                 for k in range(len(res[i])):                                                                                                                                                                      
                     print('layer1 - {} {}'.format(i, k), type(res[i][k]))                                                                                                                                         
                     if isinstance(res[i][k], (tuple, list)):                                                                                                                                                      
                         for j in range(len(res[i][k])):                                                                                                                                                           
                             print('layer2 - {} {} {}'.format(i, k, j), type(res[i][k][j]))       

@dexhunter
Copy link
Author

@dexhunter
Copy link
Author

gopath = os.path.join(
                      os.path.dirname(os.path.realpath('__file__')),
                      'test/fixtures/chaincode'
                     )

@dexhunter
Copy link
Author

import os
gopath_bak = os.environ.get('GOPATH', '')
gopath = os.path.normpath(os.path.join(
                      os.path.dirname(os.path.realpath('__file__')),
                      'test/fixtures/chaincode'
                     ))
os.environ['GOPATH'] = os.path.abspath(gopath)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment