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.