-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
queryByChaincode が offlineでも使えるか調べる #12
Comments
https://github.com/loucho/hyperledger-fabric/blob/master/fabcar/javascript-low-level/query.js#L23-L28 以下で実現できてるっぽい var firstnetwork_path = path.resolve('..', '..', 'first-network');
var org1tlscacert_path = path.resolve(firstnetwork_path, 'crypto-config', 'peerOrganizations', 'org1.example.com', 'tlsca', 'tlsca.org1.example.com-cert.pem');
var org1tlscacert = fs.readFileSync(org1tlscacert_path, 'utf8');
:
// setup the fabric network
var channel = fabric_client.newChannel('mychannel');
var peer = fabric_client.newPeer('grpcs://localhost:7051', {
'ssl-target-name-override': 'peer0.org1.example.com',
pem: org1tlscacert
});
channel.addPeer(peer);
// queryCar chaincode function - requires 1 argument, ex: args: ['CAR4'],
// queryAllCars chaincode function - requires no arguments , ex: args: [''],
const request = {
//targets : --- letting this default to the peers assigned to the channel
chaincodeId: 'fabcar',
fcn: 'queryAllCars',
args: ['']
};
// send the query proposal to the peer
return channel.queryByChaincode(request); ただ、以下のように実装しても var request = {
fcn: 'find',
args: [
'apart',
'000001',
],
chaincodeId: 'estate'
};
let response_payloads = await channel.queryByChaincode(request); 以下エラー
|
以下部分で "No identity has been assigned to this client" を出している。 _getSigningIdentity(admin) {
logger.debug('_getSigningIdentity - admin parameter is %s :%s', (typeof admin), admin);
if (admin && this._adminSigningIdentity) {
return this._adminSigningIdentity;
} else {
if (this._userContext) {
return this._userContext.getSigningIdentity();
} else {
throw new Error('No identity has been assigned to this client');
}
}
} user.js
queryByChaincode /**
* Sends a proposal to one or more endorsing peers that will be handled by the chaincode.
* There is no difference in how the endorsing peers process a request
* to invoke a chaincode for transaction vs. to invoke a chaincode for query. All requests
* will be presented to the target chaincode's 'Invoke' method which must be implemented to
* understand from the arguments that this is a query request. The chaincode must also return
* results in the byte array format and the caller will have to be able to decode
* these results.
*
* If the request contains a <code>txId</code> property, that transaction ID will be used, and its administrative
* privileges will apply. In this case the <code>useAdmin</code> parameter to this function will be ignored.
*
* @param {ChaincodeQueryRequest} request
* @param {boolean} useAdmin - Optional. Indicates that the admin credentials should be used in making
* this call. Ignored if the <code>request</code> contains a <code>txId</code> property.
* @returns {Promise} A Promise for an array of byte array results returned from the chaincode
* on all Endorsing Peers
* @example
* <caption>Get the list of query results returned by the chaincode</caption>
* const responsePayloads = await channel.queryByChaincode(request);
* for (let i = 0; i < responsePayloads.length; i++) {
* console.log(util.format('Query result from peer [%s]: %s', i, responsePayloads[i].toString('utf8')));
* }
*/
async queryByChaincode(request, useAdmin) {
logger.debug('queryByChaincode - start');
if (!request) {
throw new Error('Missing request object for this queryByChaincode call.');
}
if (request.txId) {
useAdmin = request.txId.isAdmin();
}
const targets = this._getTargets(request.targets, Constants.NetworkConfig.CHAINCODE_QUERY_ROLE);
const signer = this._clientContext._getSigningIdentity(useAdmin);
const txId = request.txId || new TransactionID(signer, useAdmin);
const proposalResults = await Channel.sendTransactionProposal(query_request, this._name, this._clientContext, request.request_timeout);
const responses = proposalResults[0];
logger.debug('queryByChaincode - results received');
if (!responses || !Array.isArray(responses)) {
throw new Error('Payload results are missing from the chaincode query');
}
const results = [];
responses.forEach((response) => {
if (response instanceof Error) {
results.push(response);
} else if (response.response && response.response.payload) {
if (response.response.status === 200) {
results.push(response.response.payload);
} else {
if (response.response.message) {
results.push(new Error(response.response.message));
} else {
results.push(new Error(response));
}
}
} else {
logger.error('queryByChaincode - unknown or missing results in query ::' + results);
results.push(new Error(response));
}
});
return results; /*
* Internal static method to allow transaction proposals to be called without
* creating a new channel
*/
static async sendTransactionProposal(request, channelId, client_context, timeout) {
const method = 'sendTransactionProposal(static)';
logger.debug('%s - start', method);
let errorMsg = client_utils.checkProposalRequest(request, true);
if (errorMsg) {
// do nothing so we skip the rest of the checks
} else if (!request.args) {
// args is not optional because we need for transaction to execute
errorMsg = 'Missing "args" in Transaction proposal request';
} else if (!request.targets || request.targets.length < 1) {
errorMsg = 'Missing peer objects in Transaction proposal';
}
if (errorMsg) {
logger.error('%s error %s', method, errorMsg);
throw new Error(errorMsg);
}
const proposal = Channel._buildSignedProposal(request, channelId, client_context);
const responses = await client_utils.sendPeersProposal(request.targets, proposal.signed, timeout);
return [responses, proposal.source];
} adminで実行してしまうとまずいので、_userContext があればいいと。 /**
* Sets an instance of the {@link User} class as the security context of this client instance. This user’s
* signing identity (the private key and its corresponding certificate), will be used to sign all requests
* with the fabric backend.
* <br><br>
* Upon setting the user context, the SDK saves the object in a persistence cache if the “state store”
* has been set on the Client instance. If no state store has been set, this cache will not be established
* and the application is responsible for setting the user context again if the application crashes and is recovered.
*
* @param {User | UserNamePasswordObject} user - An instance of the User class encapsulating the authenticated
* user’s signing materials (private key and enrollment certificate).
* The parameter may also be a {@link UserNamePasswordObject} that contains the username
* and optionally the password and caName. A common connection profile must has been loaded to use the
* {@link UserNamePasswordObject} which will also create the user context and set it on
* this client instance. The created user context will be based on the current network
* configuration( i.e. the current organization's CA, current persistence stores).
* @param {boolean} skipPersistence - Whether to skip saving the user object into persistence. Default is false and the
* method will attempt to save the user object to the state store. When using a
* common connection profile and {@link UserNamePasswordObject}, the user object will
* always be stored to the persistence store.
* @returns {Promise} Promise of the 'user' object upon successful persistence of the user to the state store
*/
async setUserContext(user, skipPersistence) {
logger.debug(`setUserContext - user: ${user}, skipPersistence: ${skipPersistence}`);
if (!user) {
logger.debug('setUserContext, Cannot save null userContext.');
throw new Error('Cannot save null userContext.');
}
if (user && user.constructor && user.constructor.name === 'User') {
this._userContext = user;
if (!skipPersistence) {
logger.debug('setUserContext - begin promise to saveUserToStateStore');
return this.saveUserToStateStore();
}
logger.debug('setUserContext - resolved user');
return user;
}
// must be they have passed in an object
logger.debug('setUserContext - will try to use common connection profile to set the user');
return this._setUserFromConfig(user);
} |
以下作ってみたが相変わらず "Error: No identity has been assigned to this client" const testclient = new Client();
var testchannel = testclient.newChannel('mychannel');
const peerTLSCertPath = path.resolve(
__dirname,
'../../first-network/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/msp/tlscacerts/tlsca.org1.example.com-cert.pem'
)
const peerPEMCert = fs.readFileSync(peerTLSCertPath, 'utf8')
const peer = testclient.newPeer('grpcs://localhost:7051', {
pem: peerPEMCert,
'ssl-target-name-override': 'peer0.org1.example.com'
})
testchannel.addPeer(peer);
const request = {
fcn: 'find',
args: [
'apart',
'000001',
],
chaincodeId: 'estate'
};
let response = await testchannel.queryByChaincode(request);
console.log('evaluteTest ====== ', response); やはり、setUserContext を作る必要がある。
|
fabcarでqueryByChaincodeを試してみる動かす
同じ書き方で、以下のようにデータ取得できるんだよな、、、なぞ
わかったnewDefaultKeyValueStoreとかで前処理やってるのか。これだ。 // create the key value store as defined in the fabric-client/config/default.json 'key-value-store' setting
Fabric_Client.newDefaultKeyValueStore({ path: store_path
}).then((state_store) => {
// assign the store to the fabric client
fabric_client.setStateStore(state_store);
var crypto_suite = Fabric_Client.newCryptoSuite();
// use the same location for the state store (where the users' certificate are kept)
// and the crypto store (where the users' keys are kept)
var crypto_store = Fabric_Client.newCryptoKeyStore({path: store_path});
crypto_suite.setCryptoKeyStore(crypto_store);
fabric_client.setCryptoSuite(crypto_suite);
// get the enrolled user from persistence, this user will sign all requests
return fabric_client.getUserContext('user1', true);
}).then((user_from_store) => {
if (user_from_store && user_from_store.isEnrolled()) {
console.log('Successfully loaded user1 from persistence');
} else {
throw new Error('Failed to get user1.... run registerUser.js');
}
// queryCar chaincode function - requires 1 argument, ex: args: ['CAR4'],
// queryAllCars chaincode function - requires no arguments , ex: args: [''],
const request = {
//targets : --- letting this default to the peers assigned to the channel
chaincodeId: 'fabcar',
fcn: 'queryAllCars',
args: ['']
};
// send the query proposal to the peer
return channel.queryByChaincode(request); |
queryByChaincode は client. setUserContext つかわなければ access できなさそうで、これは secret をサーバーに通信しなければいけなさそうだから、offlineじゃないっぽい? |
#13 で解決 |
#11 (comment)
でも書いたが、ledgerからデータだけ取得したい場合のofflineの方法がわからない。
を使った際のresponseが
とだけで、データが取得できない。
queryByChaincode は channelからtransaction発行するわけではなさそうなので、こちらを調べてみる
The text was updated successfully, but these errors were encountered: