hyperledger/fabric-sdk-py

Response of chaincode_invoke is empty

xunmeibuyue opened this issue · 2 comments

Hello, I'm trying to use fabric-sdk-py to operate Chaincodes on my Fabric Network, but when I invoke chaincode I get an empty response.

First, I build my Fabric Network simply based on first-network, only replace the domain name 'example.com' to 'srtp.com'. Then I follow the Tutorial.ipynb and Tutorial.md to get started.

Everything goes well until I invoke the chaincode, I got an empty response like this:

# Invoke a chaincode
args = ["set", "1", "2019/12/1", "619", "1", "32.14"]
# The response should be true if succeed
response = loop.run_until_complete(cli.chaincode_invoke(
               requestor=org1_admin,
               channel_name='mychannel',
               peers=['peer0.org1.srtp.com'],
               args=args,
               wait_for_event=True,
               cc_name='srtp'))
response

----------------------------------
''

Then I check the Fabric Network in cli bash, I find that the chaincode was installed. I try to invoke the chaincode by peer command(peer chaincode invoke.....), and it works, but I find if I use command peer chaincode query it returns error like this:

Error: endorsement failure during query. response: status:500 message:"\345\234\250get()\345\207\275\346\225\260\344\270\255\346\212\245\351\224\231: \346\240\271\346\215\256 1 \346\234\252\350\203\275\350\216\267\345\217\226\345\210\260\347\273\223\346\236\234"

It works well when I totally use command to operate the Fabric Network.

So I guess the problem occurred when I instantiate chaincode. This is the code and response:

from hfc.util.policies import s2d

# Instantiate Chaincode in Channel, the response should be true if succeed
args = ["1", "2019/12/1", "617", "1", "44.14"]

# This policy specifies the endorsement policy which is required while instantiating the chaincode
policy = s2d().parse("OR('Org1MSP.member', 'Org2MSP.member')")
# policy = s2d().parse("OR('Org1MSP.peer')")

response = loop.run_until_complete(cli.chaincode_instantiate(
               requestor=org1_admin,
               channel_name='mychannel',
               peers=['peer0.org1.srtp.com'],
               args=args,
               cc_name='srtp',
               cc_version='v1.0',
               cc_endorsement_policy=policy, # optional, but recommended
               collections_config=None, # optional, for private data policy
               transient_map=None, # optional, for private data
               wait_for_event=True # optional, for being sure chaincode is instantiated
               ))
response

--------------------------------------
context [TXContext:_tx_prop_req=<hfc.fabric.transaction.tx_proposal_request.TXProposalRequest object at 0x7f21ac017f28>,_user=[User:_name=Admin,_org=org1.srtp.com,_state_store=[FileKeyValueStore:path=/tmp/hfc-kvs],_state_store_key=user.Admin.org1.srtp.com,_roles=[],_account=None,_affiliation=None,_enrollment_secret=None,_enrollment=[Enrollment:_service=None,_private_key=<cryptography.hazmat.backends.openssl.ec._EllipticCurvePrivateKey object at 0x7f21ad4bf908>,_cert=b'-----BEGIN CERTIFICATE-----\nMIICIDCCAcegAwIBAgIQWIUquMZ0HbJJhXaDNZUKDTAKBggqhkjOPQQDAjBtMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEWMBQGA1UEChMNb3JnMS5zcnRwLmNvbTEZMBcGA1UEAxMQY2Eub3Jn\nMS5zcnRwLmNvbTAeFw0yMTA0MTAwMzM5MDBaFw0zMTA0MDgwMzM5MDBaMGkxCzAJ\nBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJh\nbmNpc2NvMQ8wDQYDVQQLEwZjbGllbnQxHDAaBgNVBAMME0FkbWluQG9yZzEuc3J0\ncC5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARojwa1Y1aVCnxPwuPuhE55\nQrhYkB/zazkeUn0CCOBMuPiARcgPjEJH0KHv/AV1UR+GKSmUqXk9SQXd5BK38aiL\no00wSzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADArBgNVHSMEJDAigCCQ\nvz92KKY7ng4LEVKIZFo6HWA3gqHC2XYoZhkN/ZSQMTAKBggqhkjOPQQDAgNHADBE\nAiA4mcRRAWi4m+MllHlbUEdZwYLgOqRG2zUBs56R6hnpWQIgPGInLcov/YO6Vnhw\nS4yPLPYvkKkdYtvokxGT4c/J0Ek=\n-----END CERTIFICATE-----\n',_caCert=None],_msp_id=Org1MSP,_cryptoSuite=<hfc.util.crypto.crypto.Ecies object at 0x7f21c4434358>],_crypto=<hfc.util.crypto.crypto.Ecies object at 0x7f21c4434358>,_identity=b'\n\x07Org1MSP\x12\x9e\x06-----BEGIN CERTIFICATE-----\nMIICIDCCAcegAwIBAgIQWIUquMZ0HbJJhXaDNZUKDTAKBggqhkjOPQQDAjBtMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEWMBQGA1UEChMNb3JnMS5zcnRwLmNvbTEZMBcGA1UEAxMQY2Eub3Jn\nMS5zcnRwLmNvbTAeFw0yMTA0MTAwMzM5MDBaFw0zMTA0MDgwMzM5MDBaMGkxCzAJ\nBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJh\nbmNpc2NvMQ8wDQYDVQQLEwZjbGllbnQxHDAaBgNVBAMME0FkbWluQG9yZzEuc3J0\ncC5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARojwa1Y1aVCnxPwuPuhE55\nQrhYkB/zazkeUn0CCOBMuPiARcgPjEJH0KHv/AV1UR+GKSmUqXk9SQXd5BK38aiL\no00wSzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADArBgNVHSMEJDAigCCQ\nvz92KKY7ng4LEVKIZFo6HWA3gqHC2XYoZhkN/ZSQMTAKBggqhkjOPQQDAgNHADBE\nAiA4mcRRAWi4m+MllHlbUEdZwYLgOqRG2zUBs56R6hnpWQIgPGInLcov/YO6Vnhw\nS4yPLPYvkKkdYtvokxGT4c/J0Ek=\n-----END CERTIFICATE-----\n',_nonce=b'\xd4\xc8\xb2\x06B\xe7\xfabS/\x91\xe36F\xc9\x8e#2ba\xaeQ\xef\x15',_tx_id=6fae5caaf2dd92db690386502dc4306483501f1cdf5082ce069da22f27202cc4,_prop_wait_time=-1]
{'name': 'srtp',
 'version': 'v1.0',
 'escc': 'escc',
 'vscc': 'vscc',
 'policy': {'version': 0,
  'rule': {'n_out_of': {'n': 1,
    'rules': [{'signed_by': 0}, {'signed_by': 1}]}},
  'identities': [{'principal_classification': 'ROLE',
    'principal': {'msp_identifier': 'Org1MSP', 'role': 'MEMBER'}},
   {'principal_classification': 'ROLE',
    'principal': {'msp_identifier': 'Org2MSP', 'role': 'MEMBER'}}]},
 'data': {'hash': b'\xb0\xd8L\xe7\xd7\x9d\xa4\xa0m\xe4\xc2j\xcd\x10m\xbcw\xe2\x9d\xfe+s\xa7e\xc5R\x98kS=\x0eF',
  'metadatahash': b'\x92\x97\x1c\xbfR\xadE\xd7%\xb5\x9c?+\xcaD\xaeq,\x05\xf8\xb0\xcb\xd6J\xc3\xfbo\xc7\x85\x86\xb6@'},
 'id': b'\xe2m\x07\xe06n]"\'o\r\xe1\xa0\x83\xb5&z\xf43\xe3P\xe5S\xff\xaa\xc9\x91$\xfep\\\x1b',
 'instantiation_policy': {'version': 0,
  'rule': {'n_out_of': {'n': 1,
    'rules': [{'signed_by': 0}, {'signed_by': 1}]}},
  'identities': [{'principal_classification': 'ROLE',
    'principal': {'msp_identifier': 'Org1MSP', 'role': 'ADMIN'}},
   {'principal_classification': 'ROLE',
    'principal': {'msp_identifier': 'Org2MSP', 'role': 'ADMIN'}}]}}

Could you tell me what's wrong with my code or my network? Thank you so much!

This is my code:

from hfc.fabric import Client
import json

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

with open('test/fixtures/network.json') as f:
    network_info = json.load(f)

org1_admin = cli.get_user(org_name='org1.srtp.com', name='Admin') # User instance with the Org1 admin's certs
org2_admin = cli.get_user(org_name='org2.srtp.com', name='Admin') # User instance with the Org2 admin's certs
orderer_admin = cli.get_user(org_name='orderer.srtp.com', name='Admin') # User instance with the orderer's certs

import asyncio
loop = asyncio.get_event_loop()
import nest_asyncio
nest_asyncio.apply()

cli.new_channel('mychannel')

# Install Example Chaincode to Peers
# GOPATH setting is only needed to use the example chaincode inside sdk
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)

responses = loop.run_until_complete(cli.chaincode_install(
               requestor=org1_admin,
               peers=['peer0.org1.srtp.com',
                      'peer1.org1.srtp.com'],
               cc_path='github.com/srtp',
               cc_name='srtp',
               cc_version='v1.0'
               ))

responses = loop.run_until_complete(cli.chaincode_install(
               requestor=org2_admin,
               peers=['peer0.org2.srtp.com',
                      'peer1.org2.srtp.com'],
               cc_path='github.com/srtp',
               cc_name='srtp',
               cc_version='v1.0'
               ))

node_info = network_info['peers']['peer0.org1.srtp.com']
set_tls = cli.set_tls_client_cert_and_key(
    node_info['clientKey']['path'],
    node_info['clientCert']['path']
)

from hfc.util.policies import s2d

# Instantiate Chaincode in Channel, the response should be true if succeed
args = ["1", "2019/12/1", "617", "1", "44.14"]

# This policy specifies the endorsement policy which is required while instantiating the chaincode
policy = s2d().parse("OR('Org1MSP.member','Org2MSP.member')")
# policy = s2d().parse("OR('Org1MSP.peer')")

response = loop.run_until_complete(cli.chaincode_instantiate(
               requestor=org1_admin,
               channel_name='mychannel',
               peers=['peer0.org1.srtp.com','peer1.org1.srtp.com'],
               args=["1", "2019/12/1", "617", "1", "44.14"],
               cc_name='srtp',
               cc_version='v1.0',
               cc_endorsement_policy=s2d().parse("OR('Org1MSP.member','Org2MSP.member')"), # optional, but recommended
               collections_config=None, # optional, for private data policy
               transient_map=None, # optional, for private data
               wait_for_event=True # optional, for being sure chaincode is instantiated
               ))

print(response)

# Invoke a chaincode
args = ["set", "1", "2019/12/1", "619", "1", "32.14"]
# The response should be true if succeed
response1 = loop.run_until_complete(cli.chaincode_invoke(
               requestor=org1_admin,
               channel_name='mychannel',
               peers=['peer0.org1.srtp.com'],
               args=["set", "1", "2019/12/1", "619", "1", "32.14"],
               wait_for_event=True,
               cc_name='srtp'))
print(response1)

# Invoke a chaincode
args = ["getHistory", "1"]
# The response should be true if succeed
response2 = loop.run_until_complete(cli.chaincode_invoke(
               requestor=org1_admin,
               channel_name='mychannel',
               peers=['peer0.org1.srtp.com'],
               args=["getHistory", "1"],
               cc_name='srtp',
               transient_map=None, # optional, for private data
               wait_for_event=True, # for being sure chaincode invocation has been commited in the ledger, default is on tx event
               #cc_pattern='^invoked*' # if you want to wait for chaincode event and you have a `stub.SetEvent("invoked", value)` in your chaincode
               ))
print(response2)

I know where the problem is.

There is a default param fnc in function chaincode_invoke and chaincode_query .

async def chaincode_invoke(self, requestor, channel_name, peers, args,
                               cc_name, cc_type=CC_TYPE_GOLANG,
                               fcn='invoke', cc_pattern=None,
                               transient_map=None,
                               wait_for_event=False,
                               wait_for_event_timeout=30,
                               grpc_broker_unavailable_retry=0,
                               grpc_broker_unavailable_retry_delay=3000,  # ms
                               raise_broker_unavailable=True)

async def chaincode_query(self, requestor, channel_name, peers, args,
                              cc_name, cc_type=CC_TYPE_GOLANG,
                              fcn='query', transient_map=None)

In Tutorial it does not set this param, and it was set to default value 'invoke' or 'query'.

So everytime my chaincode invoke or query, it gets the function name as 'invoke' or 'query', and does not find the function, so it return empty.

Actually I STRONGLY RECOMMAND you to update the Tutorial, as there is a bug in it, and fnc should be set in it to REMIND USERS.
Maybe next week I will make a pull request for it.