diff --git a/.gitignore b/.gitignore index a0565f0..c4f967f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,10 @@ node_modules out .eslintcache .idea -resources/persistence/ +/resources/persistence/: +/resources/key/users: +/resources/key/tx: +!.gitkeep # fabric network fabric/fabcar/hfc-key-store diff --git a/resources/key/tls/orderers/ca.crt b/resources/key/tls/orderers/ca.crt deleted file mode 100644 index 94f1df5..0000000 --- a/resources/key/tls/orderers/ca.crt +++ /dev/null @@ -1,14 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICNjCCAdygAwIBAgIRAK2WsXvR4OVWDh0AZPoUV2wwCgYIKoZIzj0EAwIwbDEL -MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG -cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRowGAYDVQQDExF0bHNjYS5l -eGFtcGxlLmNvbTAeFw0xODExMTYwMjQ2NDlaFw0yODExMTMwMjQ2NDlaMGwxCzAJ -BgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJh -bmNpc2NvMRQwEgYDVQQKEwtleGFtcGxlLmNvbTEaMBgGA1UEAxMRdGxzY2EuZXhh -bXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAR/C34xCWg/DLNUyt86 -DRbyVjy1DutKvkdad8zToq/2h/NTdicIBLJY8taueC+1xCWSRVEJFeSE56d+s46r -z0kGo18wXTAOBgNVHQ8BAf8EBAMCAaYwDwYDVR0lBAgwBgYEVR0lADAPBgNVHRMB -Af8EBTADAQH/MCkGA1UdDgQiBCBQX3abwtV5QAe6l9Uv6iwKFCvn8PYb5h2d86P4 -SV+XwDAKBggqhkjOPQQDAgNIADBFAiEA1eeBhrv/F5sIXGaJTTQXj7ZRtuYrppQk -TB9vL4MGcwYCIENadcZf7HMmBv1F96F7K3pu/02Bvikjm8hLcgzvwyy/ ------END CERTIFICATE----- diff --git a/resources/key/tls/peer/ca.crt b/resources/key/tls/peer/ca.crt deleted file mode 100644 index 15d7e01..0000000 --- a/resources/key/tls/peer/ca.crt +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN CERTIFICATE----- -MIICSTCCAe+gAwIBAgIQYz3pvu91K40ecI6p7G6xlTAKBggqhkjOPQQDAjB2MQsw -CQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy -YW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEfMB0GA1UEAxMWdGxz -Y2Eub3JnMS5leGFtcGxlLmNvbTAeFw0xODExMTYwMjQ2NDlaFw0yODExMTMwMjQ2 -NDlaMHYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQH -Ew1TYW4gRnJhbmNpc2NvMRkwFwYDVQQKExBvcmcxLmV4YW1wbGUuY29tMR8wHQYD -VQQDExZ0bHNjYS5vcmcxLmV4YW1wbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0D -AQcDQgAE6aBKDdHl7nreV/2fDTGesS/JBSztE3P9qUfcWw0ooo664BAVz1vWHTsL -YFo6ccGdVbEGF81L9/hevINoJUnL96NfMF0wDgYDVR0PAQH/BAQDAgGmMA8GA1Ud -JQQIMAYGBFUdJQAwDwYDVR0TAQH/BAUwAwEB/zApBgNVHQ4EIgQgkUb8kwjsoH6s -ZGatOHRJ2c9W39XpZCPtpACrNe1gDpEwCgYIKoZIzj0EAwIDSAAwRQIhAMY2b94f -QrBXJba+J85wmblPIMxUMYXTkgYQ4qfWaMHZAiA975uL86onAD749GPEH3p+8VXj -kw4xH7m/9ER+t4UAFg== ------END CERTIFICATE----- diff --git a/resources/key/tx/.gitkeep b/resources/key/tx/.gitkeep new file mode 100644 index 0000000..a10d4fe --- /dev/null +++ b/resources/key/tx/.gitkeep @@ -0,0 +1,3 @@ +# Ignore everything in this directory +* +# Except this file !.gitkeep \ No newline at end of file diff --git a/resources/key/tx/configtx.yaml b/resources/key/tx/configtx.yaml deleted file mode 100644 index 3d61347..0000000 --- a/resources/key/tx/configtx.yaml +++ /dev/null @@ -1,130 +0,0 @@ -# Copyright IBM Corp. All Rights Reserved. -# -# SPDX-License-Identifier: Apache-2.0 -# - ---- -################################################################################ -# -# Profile -# -# - Different configuration profiles may be encoded here to be specified -# as parameters to the configtxgen tool -# -################################################################################ -Profiles: - - OneOrgOrdererGenesis: - Orderer: - <<: *OrdererDefaults - Organizations: - - *OrdererOrg - Consortiums: - SampleConsortium: - Organizations: - - *Org1 - OneOrgChannel: - Consortium: SampleConsortium - Application: - <<: *ApplicationDefaults - Organizations: - - *Org1 - -################################################################################ -# -# Section: Organizations -# -# - This section defines the different organizational identities which will -# be referenced later in the configuration. -# -################################################################################ -Organizations: - - # SampleOrg defines an MSP using the sampleconfig. It should never be used - # in production but may be used as a template for other definitions - - &OrdererOrg - # DefaultOrg defines the organization which is used in the sampleconfig - # of the fabric.git development environment - Name: OrdererOrg - - # ID to load the MSP definition as - ID: OrdererMSP - - # MSPDir is the filesystem path which contains the MSP configuration - MSPDir: crypto-config/ordererOrganizations/example.com/msp - - - &Org1 - # DefaultOrg defines the organization which is used in the sampleconfig - # of the fabric.git development environment - Name: Org1MSP - - # ID to load the MSP definition as - ID: Org1MSP - - MSPDir: org1.example.com/msp - - AnchorPeers: - # AnchorPeers defines the location of peers which can be used - # for cross org gossip communication. Note, this value is only - # encoded in the genesis block in the Application section context - - Host: peer0.org1.example.com - Port: 7051 - -################################################################################ -# -# SECTION: Orderer -# -# - This section defines the values to encode into a config transaction or -# genesis block for orderer related parameters -# -################################################################################ -Orderer: &OrdererDefaults - - # Orderer Type: The orderer implementation to start - # Available types are "solo" and "kafka" - OrdererType: solo - - Addresses: - - orderer.example.com:7050 - - # Batch Timeout: The amount of time to wait before creating a batch - BatchTimeout: 2s - - # Batch Size: Controls the number of messages batched into a block - BatchSize: - - # Max Message Count: The maximum number of messages to permit in a batch - MaxMessageCount: 10 - - # Absolute Max Bytes: The absolute maximum number of bytes allowed for - # the serialized messages in a batch. - AbsoluteMaxBytes: 99 MB - - # Preferred Max Bytes: The preferred maximum number of bytes allowed for - # the serialized messages in a batch. A message larger than the preferred - # max bytes will result in a batch larger than preferred max bytes. - PreferredMaxBytes: 512 KB - - Kafka: - # Brokers: A list of Kafka brokers to which the orderer connects - # NOTE: Use IP:port notation - Brokers: - - 127.0.0.1:9092 - - # Organizations is the list of orgs which are defined as participants on - # the orderer side of the network - Organizations: - -################################################################################ -# -# SECTION: Application -# -# - This section defines the values to encode into a config transaction or -# genesis block for application related parameters -# -################################################################################ -Application: &ApplicationDefaults - - # Organizations is the list of orgs which are defined as participants on - # the application side of the network - Organizations: diff --git a/resources/key/tx/configtxgen b/resources/key/tx/configtxgen deleted file mode 100755 index 473045d..0000000 Binary files a/resources/key/tx/configtxgen and /dev/null differ diff --git a/resources/key/users/.gitkeep b/resources/key/users/.gitkeep new file mode 100644 index 0000000..a10d4fe --- /dev/null +++ b/resources/key/users/.gitkeep @@ -0,0 +1,3 @@ +# Ignore everything in this directory +* +# Except this file !.gitkeep \ No newline at end of file diff --git a/resources/persistence/.gitkeep b/resources/persistence/.gitkeep new file mode 100644 index 0000000..a10d4fe --- /dev/null +++ b/resources/persistence/.gitkeep @@ -0,0 +1,3 @@ +# Ignore everything in this directory +* +# Except this file !.gitkeep \ No newline at end of file diff --git a/resources/persistence/config.db b/resources/persistence/config.db deleted file mode 100644 index 792e368..0000000 --- a/resources/persistence/config.db +++ /dev/null @@ -1 +0,0 @@ -{"id":0,"isSign":2,"_id":"kmd4rIC0jZLRORL9","peerGrpcUrl":"grpc://localhost:7051","peerEventUrl":"grpc://localhost:7053","ordererUrl":"grpc://localhost:7050","username":"Org1Admin","path":"resources/key/","tlsPeerPath":"","tlsOrdererPath":""} diff --git a/src/components/UserLayout.jsx b/src/components/UserLayout.jsx index 863ae6f..10bfb0c 100644 --- a/src/components/UserLayout.jsx +++ b/src/components/UserLayout.jsx @@ -25,10 +25,10 @@ export default class UserLayout extends React.Component { super(props); this.state = { - peerGrpcUrl: 'grpc://localhost:7051', - peerEventUrl: 'grpc://localhost:7053', - ordererUrl: 'grpc://localhost:7050', - username: 'Org1Admin', + peerGrpcUrl: 'grpcs://139.198.122.54:7051', + peerEventUrl: 'grpcs://139.198.122.54:7053', + ordererUrl: 'grpcs://139.198.122.54:7050', + username: 'Org1', certPath: '', keyPath: '', tlsPeerPath: '', diff --git a/src/components/content/ChannelManangeContent.jsx b/src/components/content/ChannelManangeContent.jsx index aa831c9..d2cbd45 100644 --- a/src/components/content/ChannelManangeContent.jsx +++ b/src/components/content/ChannelManangeContent.jsx @@ -160,3 +160,11 @@ export default class ChannelManangeContent extends React.Component { ); } } +/* +* 1.显示通道,包含通道成员等信息(可简化,目前暂未在SDK找到查找通道成员的方法) +* 2.创建通道,用户可以通过客户端来制定哪些组织可加入通道, 即可通过客户端生成用户自定义的yaml文件 +* (1)前端,用户添加组织,包括组织名称,MSPID, MSPDir,AnchorPeers,MSPDir即msp证书的目录 +* (2)后台,通过用户所输入的,生成yaml文件,并配置好证书,后面创建通道跟现有操作保持一致 +* 3.更新通道,用户可以通过更新通道来新增成员,该成员在创建通道时未定义在yaml文件内 +* +* */ diff --git a/src/components/content/DataContent.jsx b/src/components/content/DataContent.jsx index a9b6106..9136e26 100644 --- a/src/components/content/DataContent.jsx +++ b/src/components/content/DataContent.jsx @@ -400,7 +400,7 @@ export default class DataContent extends React.Component { width="640px" centered > - Tx:{this.state.block[this.state.currentBlock] ? this.state.block[this.state.currentBlock][this.state.currentTransaction].tx : '1'}
+ Tx:{this.state.block[this.state.currentBlock] ? this.state.block[this.state.currentBlock][this.state.currentTransaction].tx : ''}
Creator MSP:{this.state.block[this.state.currentBlock] ? this.state.block[this.state.currentBlock][this.state.currentTransaction].creatorMSP : ''}
Endorser:{this.state.block[this.state.currentBlock] ? this.state.block[this.state.currentBlock][this.state.currentTransaction].endorser : ''}
Chaincode Name:{this.state.block[this.state.currentBlock] ? this.state.block[this.state.currentBlock][this.state.currentTransaction].chaincodeName : ''}
diff --git a/src/util/fabric.js b/src/util/fabric.js index 5cb68a5..ea7f169 100644 --- a/src/util/fabric.js +++ b/src/util/fabric.js @@ -60,31 +60,31 @@ class FabricClient { obj.store_path = storePath; obj.channels = {}; - resolve('success'); + resolve(obj); }); } /** * * @returns {Promise} - * @private + * */ - _enrollUser() { - const usrName = this.config.username; + _enrollUser(self) { + const usrName = self.config.username; // logger.info('start to load member user.'); - return FabricClientSDK.newDefaultKeyValueStore({ path: this.store_path, + return FabricClientSDK.newDefaultKeyValueStore({ path: self.store_path, }).then((stateStore) => { // assign the store to the fabric client - this.fabric_client.setStateStore(stateStore); + self.fabric_client.setStateStore(stateStore); const cryptoSuite = FabricClientSDK.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) - const cryptoStore = FabricClientSDK.newCryptoKeyStore({ path: this.store_path }); + const cryptoStore = FabricClientSDK.newCryptoKeyStore({ path: self.store_path }); cryptoSuite.setCryptoKeyStore(cryptoStore); - this.fabric_client.setCryptoSuite(cryptoSuite); + self.fabric_client.setCryptoSuite(cryptoSuite); - return this.fabric_client.getUserContext(usrName, true); + return self.fabric_client.getUserContext(usrName, true); }); } @@ -97,13 +97,13 @@ class FabricClient { // setup each channel once let channel = this.channels[channelName]; if (!channel) { - logger.info('******************'); + logger.info('start create channel'); channel = this.fabric_client.newChannel(channelName); if (this.flag) { logger.info('-----------'); this.peer = this.fabric_client.newPeer(this.config.peerGrpcUrl, - { pem: Buffer.from(this.peerCert).toString(), 'ssl-target-name-override': 'peer0.org1.example.com' }); + { pem: Buffer.from(this.peerCert).toString(), 'ssl-target-name-override': 'peer0.' + this.config.username.toLocaleLowerCase() + '.example.com' }); channel.addPeer(this.peer); this.order = this.fabric_client.newOrderer(this.config.ordererUrl, { pem: Buffer.from(this.orderersCert).toString(), 'ssl-target-name-override': 'orderer.example.com' }); @@ -145,42 +145,33 @@ class FabricClient { return Promise.reject(err); } - return this._enrollUser().then((user) => { - if (user && user.isEnrolled()) { - logger.info('Successfully loaded user1 from persistence, user:', user.toString()); - } else { - logger.error('Failed to get user1.... run registerUser.js'); - return Promise.reject(new Error('Failed to get user1.... run registerUser.js')); - } - - const request = { - chaincodeId, - fcn, - args: FabricClient._argsNullHelper(args), - }; + const request = { + chaincodeId, + fcn, + args: FabricClient._argsNullHelper(args), + }; // send the query proposal to the peer - - return channel.queryByChaincode(request); - }).then((queryResponses) => { - logger.info('Query has completed, checking results'); - // queryResponses could have more than one results if there were multiple peers targets - if (queryResponses && queryResponses.length === 1) { - if (queryResponses[0] instanceof Error) { - logger.error('error from query = ', queryResponses[0]); - return Promise.reject(new Error(queryResponses[0])); + return channel.queryByChaincode(request) + .then((queryResponses) => { + logger.info('Query has completed, checking results'); + // queryResponses could have more than one results if there were multiple peers targets + if (queryResponses && queryResponses.length === 1) { + if (queryResponses[0] instanceof Error) { + logger.error('error from query = ', queryResponses[0]); + return Promise.reject(new Error(queryResponses[0])); + } + const result = queryResponses[0].toString(); + logger.info('Success, response is ', result); + + return Promise.resolve(result); } - const result = queryResponses[0].toString(); - logger.info('Success, response is ', result); - - return Promise.resolve(result); - } - logger.info('No payloads were returned from query'); - return Promise.reject(new Error('No payloads were returned from query')); - }).catch((err) => { - logger.error(`Failed to query successfully :: ${err}`); - return Promise.reject(new Error(`Failed to query successfully :: ${err}`)); - }); + logger.info('No payloads were returned from query'); + return Promise.reject(new Error('No payloads were returned from query')); + }).catch((err) => { + logger.error(`Failed to query successfully :: ${err}`); + return Promise.reject(new Error(`Failed to query successfully :: ${err}`)); + }); } /** @@ -200,128 +191,112 @@ class FabricClient { logger.error(err); return Promise.reject(err); } - let txID; const fabricClient = this.fabric_client; - return this._enrollUser().then((user) => { - if (user && user.isEnrolled()) { - logger.info('Successfully loaded user1 from persistence'); - } else { - logger.error('Failed to get user1.... run registerUser.js'); - return Promise.reject(new Error('Failed to get user1.... run registerUser.js')); - } + // get a transaction id object based on the current user assigned to fabric client + const txID = fabricClient.newTransactionID(); + logger.info('Assigning transaction_id: ', txID._transaction_id); - // get a transaction id object based on the current user assigned to fabric client - txID = fabricClient.newTransactionID(); - logger.info('Assigning transaction_id: ', txID._transaction_id); - - // must send the proposal to endorsing peers - const request = { - // targets: let default to the peer assigned to the client - chaincodeId, - fcn, - args: FabricClient._argsNullHelper(args), - chainId: channelName, - txId: txID, - }; + // must send the proposal to endorsing peers + const request = { + // targets: let default to the peer assigned to the client + chaincodeId, + fcn, + args: FabricClient._argsNullHelper(args), + chainId: channelName, + txId: txID, + }; // send the transaction proposal to the peers - return channel.sendTransactionProposal(request); - }).then((results) => { - const proposalResponses = results[0]; - const proposal = results[1]; - let isProposalGood = false; - if (proposalResponses && proposalResponses[0].response && - proposalResponses[0].response.status === 200) { - isProposalGood = true; - logger.info('Transaction proposal was good:'); - } else { - logger.error('Transaction proposal was bad'); - return Promise.reject(new Error('Transaction proposal was bad')); - } - if (isProposalGood) { - logger.info(util.format( - 'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s"', - proposalResponses[0].response.status, proposalResponses[0].response.message)); - - // build up the request for the orderer to have the transaction committed - const request = { - proposalResponses, - proposal, - }; - - // set the transaction listener and set a timeout of 30 sec - // if the transaction did not get committed within the timeout period, - // report a TIMEOUT status - const transactionIDString = txID.getTransactionID(); - const promises = []; - - // send transaction first, so that we know where to check status - const sendPromise = channel.sendTransaction(request); - promises.push(sendPromise); - - // get an eventhub once the fabric client has a user assigned. The user - // is required bacause the event registration must be signed - const eventHub = fabricClient.newEventHub(); - eventHub.setPeerAddr(this.config.peerEventUrl); - - // using resolve the promise so that result status may be processed - // under the then clause rather than having the catch clause process - // the status - const txPromise = new Promise((resolve, reject) => { - const handle = setTimeout(() => { - eventHub.disconnect(); - resolve({ event_status: 'TIMEOUT' }); - // could use reject(new Error('Trnasaction did not complete within 30 seconds')); - }, 3000); - eventHub.connect(); - eventHub.registerTxEvent(transactionIDString, (tx, code) => { - // this is the callback for transaction event status - // first some clean up of event listener - clearTimeout(handle); - eventHub.unregisterTxEvent(transactionIDString); - eventHub.disconnect(); - - // now let the application know what happened - const returnStatus = { event_status: code, tx_id: transactionIDString }; - if (code !== 'VALID') { - logger.error(`The transaction was invalid, code = ${code}`); - resolve(returnStatus); - // could use reject(new Error('Problem with the tranaction, event status ::'+code)); - } else { - logger.info(`The transaction has been committed on peer ${eventHub._ep._endpoint.addr}`); - resolve(returnStatus); - } - }, (err) => { - // this is the callback if something goes wrong - // with the event registration or processing - reject(new Error(`There was a problem with the eventhub ::${err}`)); + return channel.sendTransactionProposal(request) + .then((results) => { + const proposalResponses = results[0]; + const proposal = results[1]; + let isProposalGood = false; + if (proposalResponses && proposalResponses[0].response && + proposalResponses[0].response.status === 200) { + isProposalGood = true; + logger.info('Transaction proposal was good:'); + } else { + logger.error('Transaction proposal was bad'); + return Promise.reject(new Error('Transaction proposal was bad')); + } + if (isProposalGood) { + logger.info(util.format( + 'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s"', + proposalResponses[0].response.status, proposalResponses[0].response.message)); + // set the transaction listener and set a timeout of 30 sec + // if the transaction did not get committed within the timeout period, + // report a TIMEOUT status + const transactionIDString = txID.getTransactionID(); + const promises = []; + + // send transaction first, so that we know where to check status + const sendPromise = channel.sendTransaction({ proposalResponses, proposal }); + promises.push(sendPromise); + + // get an eventhub once the fabric client has a user assigned. The user + // is required bacause the event registration must be signed + const eventHub = fabricClient.newEventHub(); + eventHub.setPeerAddr(this.config.peerEventUrl); + + // using resolve the promise so that result status may be processed + // under the then clause rather than having the catch clause process + // the status + const txPromise = new Promise((resolve, reject) => { + const handle = setTimeout(() => { + eventHub.disconnect(); + resolve({ event_status: 'TIMEOUT' }); + // could use reject(new Error('Trnasaction did not complete within 30 seconds')); + }, 3000); + eventHub.connect(); + eventHub.registerTxEvent(transactionIDString, (tx, code) => { + // this is the callback for transaction event status + // first some clean up of event listener + clearTimeout(handle); + eventHub.unregisterTxEvent(transactionIDString); + eventHub.disconnect(); + + // now let the application know what happened + const returnStatus = { event_status: code, tx_id: transactionIDString }; + if (code !== 'VALID') { + logger.error(`The transaction was invalid, code = ${code}`); + resolve(returnStatus); + // could use reject(new Error('Problem with the tranaction, event status ::'+code)); + } else { + logger.info(`The transaction has been committed on peer ${eventHub._ep._endpoint.addr}`); + resolve(returnStatus); + } + }, (err) => { + // this is the callback if something goes wrong + // with the event registration or processing + reject(new Error(`There was a problem with the eventhub ::${err}`)); + }); }); - }); - promises.push(txPromise); + promises.push(txPromise); - return Promise.all(promises); - } - logger.error('Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...'); - return Promise.reject(new Error('Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...')); - }).then((results) => { - logger.info('Send transaction promise and event listener promise have completed'); - // check the results in the order the promises were added to the promise all list - if (results && results[0] && results[0].status === 'SUCCESS') { - logger.info('Successfully sent transaction to the orderer.'); - } else { - logger.error(`Failed to order the transaction. Error code: ${results[0].status}`); - } + return Promise.all(promises); + } + logger.error('Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...'); + return Promise.reject(new Error('Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...')); + }).then((results) => { + logger.info('Send transaction promise and event listener promise have completed'); + // check the results in the order the promises were added to the promise all list + if (results && results[0] && results[0].status === 'SUCCESS') { + logger.info('Successfully sent transaction to the orderer.'); + } else { + logger.error(`Failed to order the transaction. Error code: ${results[0].status}`); + } - if (results && results[1] && results[1].event_status === 'VALID') { - logger.info('Successfully committed the change to the ledger by the peer'); - } else { - logger.info(`Transaction failed to be committed to the ledger due to ::${results[1].event_status}`); - } - logger.info('Invoke result:', results); + if (results && results[1] && results[1].event_status === 'VALID') { + logger.info('Successfully committed the change to the ledger by the peer'); + } else { + logger.info(`Transaction failed to be committed to the ledger due to ::${results[1].event_status}`); + } + logger.info('Invoke result:', results); - return Promise.resolve('调用成功'); - }) + return Promise.resolve('调用成功'); + }) .catch((err) => { logger.error(`Failed to invoke successfully :: ${err}`); return Promise.reject(new Error(`Failed to invoke successfully :: ${err}`)); @@ -339,35 +314,32 @@ class FabricClient { */ installCc(chaincodePath, chaincodeName, chaincodeVersion) { logger.info(`${chaincodePath}, ${chaincodeName}, ${chaincodeVersion}`); - const self = this; - return this._enrollUser().then((user) => { - logger.info('Successfully loaded user from persistence, user:', user.toString()); - - const request = { - targets: [self.peer], // peerAddress - chaincodePath, - chaincodeId: chaincodeName, - chaincodeVersion, - }; - return self.fabric_client.installChaincode(request); - }).then((results) => { - const proposalResponses = results[0]; - if (proposalResponses && proposalResponses[0].response && - proposalResponses[0].response.status === 200) { - logger.info('Transaction proposal was good:'); - return Promise.resolve('success'); - } - logger.error('Transaction proposal was bad'); - return Promise.reject('fail'); - }, (err) => { - logger.error(`Failed to send install proposal due to error: ${err.stack}` ? err.stack : err); - // throw new Error(`Failed to send install proposal due to error: ${err.stack}` - // ? err.stack : err); - return Promise.reject('fail'); - }).catch((err) => { - logger.error(`Failed to install :: ${err}`); - return Promise.reject('fail'); - }); + + const request = { + targets: [this.peer], // peerAddress + chaincodePath, + chaincodeId: chaincodeName, + chaincodeVersion, + }; + return this.fabric_client.installChaincode(request) + .then((results) => { + const proposalResponses = results[0]; + if (proposalResponses && proposalResponses[0].response && + proposalResponses[0].response.status === 200) { + logger.info('Transaction proposal was good:'); + return Promise.resolve('success'); + } + logger.error('Transaction proposal was bad'); + return Promise.reject('fail'); + }, (err) => { + logger.error(`Failed to send install proposal due to error: ${err.stack}` ? err.stack : err); + // throw new Error(`Failed to send install proposal due to error: ${err.stack}` + // ? err.stack : err); + return Promise.reject('fail'); + }).catch((err) => { + logger.error(`Failed to install :: ${err}`); + return Promise.reject('fail'); + }); } @@ -387,44 +359,35 @@ class FabricClient { logger.error(err); return Promise.reject('fail'); } - let txID; const self = this; - return this._enrollUser().then((user) => { - logger.info('Successfully loaded user from persistence, user:', user.toString()); - - txID = self.fabric_client.newTransactionID(); - const request = { - targets: [self.peer], // peerAddress - chaincodeId: chaincodeName, - chaincodeVersion, - args, - txId: txID, - }; - - // 提案 - return channel.sendInstantiateProposal(request); - }).then((results) => { - const proposalResponses = results[0]; - const proposal = results[1]; - const isGood = proposalResponses && proposalResponses[0].response - && proposalResponses[0].response.status === 200; - - if (!isGood) { - return Promise.reject('fail'); - } - logger.info('Transaction proposal was good:'); - // 提案成功后,提交 - const request = { - proposalResponses, - proposal, - }; - return channel.sendTransaction(request); - }).then((results) => { - logger.info('Complete instantiating chaincode.', results); - return Promise.resolve('success'); - }) + const txID = self.fabric_client.newTransactionID(); + const request = { + targets: [self.peer], // peerAddress + chaincodeId: chaincodeName, + chaincodeVersion, + args, + txId: txID, + }; + + // 提案 + return channel.sendInstantiateProposal(request) + .then((results) => { + const proposalResponses = results[0]; + const proposal = results[1]; + const isGood = proposalResponses && proposalResponses[0].response + && proposalResponses[0].response.status === 200; + if (!isGood) { + return Promise.reject('fail'); + } + logger.info('Transaction proposal was good:'); + // 提案成功后,提交 + return channel.sendTransaction({ proposalResponses, proposal }); + }).then((results) => { + logger.info('Complete instantiating chaincode.', results); + return Promise.resolve('success'); + }) .catch((err) => { logger.error(`Fail to instantiate chaincode. Error message: ${err.stack}` ? err.stack : err); return Promise.reject('fail'); @@ -446,8 +409,7 @@ class FabricClient { return Promise.reject('fail'); } - return this._enrollUser() - .then(() => channel.queryBlock(blockNumber)) + return channel.queryBlock(blockNumber) .then(block => Promise.resolve(block)); } @@ -465,8 +427,7 @@ class FabricClient { return Promise.reject('fail'); } - return this._enrollUser() - .then(() => channel.queryInfo()) + return channel.queryInfo() .then(blockInfo => Promise.resolve(blockInfo)); } @@ -477,18 +438,16 @@ class FabricClient { importCer(keyPath, certPath) { // -------------------- admin start --------- this._setupChannelOnce('mychannel'); - const self = this; logger.info('start to create admin user.'); - return this._enrollUser() - .then(() => self.fabric_client.createUser({ - username: self.config.username, - mspid: 'Org1MSP', - cryptoContent: { - privateKey: keyPath, - signedCert: certPath, - }, - }), - ).then(() => Promise.resolve('success')); + return this.fabric_client.createUser({ + username: this.config.username, + mspid: this.config.username + 'MSP', + cryptoContent: { + privateKey: keyPath, + signedCert: certPath, + }, + }) + .then(() => Promise.resolve('success')); // ---------------admin finish --------------- } @@ -498,22 +457,12 @@ class FabricClient { */ queryInstalledChaincodes() { try { - this._setupChannelOnce('mychannel'); + this._setupChannelOnce('mychannel200'); } catch (err) { logger.error(err); return Promise.reject('fail'); } - const self = this; - return this._enrollUser() - .then((user) => { - if (user && user.isEnrolled()) { - logger.info('Successfully loaded user1 from persistence'); - } else { - logger.error('Failed to get user1.... run registerUser.js'); - return Promise.reject(new Error('Failed to get user1.... run registerUser.js')); - } - return self.fabric_client.queryInstalledChaincodes(self.peer); - }) + return this.fabric_client.queryInstalledChaincodes(this.peer) .then((response) => { if (response) { logger.info('Successfully get response from fabric client'); @@ -545,16 +494,7 @@ class FabricClient { return Promise.reject('fail'); } - return this._enrollUser() - .then((user) => { - if (user && user.isEnrolled()) { - logger.info('Successfully loaded user1 from persistence'); - } else { - logger.error('Failed to get user1.... run registerUser.js'); - return Promise.reject(new Error('Failed to get user1.... run registerUser.js')); - } - return channel.queryInstantiatedChaincodes(); - }) + return channel.queryInstantiatedChaincodes() .then((response) => { if (response) { logger.info('Successfully get response from channel'); @@ -586,16 +526,7 @@ class FabricClient { return Promise.reject('fail'); } const self = this; - return this._enrollUser() - .then((user) => { - if (user && user.isEnrolled()) { - logger.info('Successfully loaded user1 from persistence'); - } else { - logger.error('Failed to get user1.... run registerUser.js'); - return Promise.reject(new Error('Failed to get user1.... run registerUser.js')); - } - return self.fabric_client.queryChannels(self.peer); - }) + return self.fabric_client.queryChannels(self.peer) .then((response) => { if (response) { logger.info('Successfully get response from fabric client'); @@ -622,7 +553,7 @@ class FabricClient { createChannelTX(channelName) { return new Promise((resolve, reject) => { const txPath = path.join(__dirname, '../../resources/key/tx'); - const cmd = 'cd ' + txPath + ' && ./configtxgen -profile OneOrgChannel -outputCreateChannelTx ' + channelName + '.tx -channelID ' + channelName; exec(cmd, (err, stdout, stderr) => { + const cmd = 'cd ' + txPath + ' && ./configtxgen -profile TwoOrgsChannel -outputCreateChannelTx ' + channelName + '.tx -channelID ' + channelName; exec(cmd, (err, stdout, stderr) => { if (err) { console.log(err); reject('fail'); @@ -650,15 +581,7 @@ class FabricClient { logger.error(err); return Promise.reject('fail'); } - return this._enrollUser(); - }) - .then((user) => { - if (user && user.isEnrolled()) { - logger.info('Successfully loaded user1 from persistence'); - } else { - logger.error('Failed to get user1.... run registerUser.js'); - return Promise.reject(new Error('Failed to get user1.... run registerUser.js')); - } + const tempTxId = self.fabric_client.newTransactionID(); const envelopeBytes = fs.readFileSync(path.join(__dirname, '../../resources/key/tx/' + channelName + '.tx')); const tempConfig = self.fabric_client.extractChannelConfig(envelopeBytes); @@ -691,7 +614,7 @@ class FabricClient { } /** - * 创建通道 + * 加入通道 * @returns {Promise} * @param channelName 通道名字 */ @@ -704,35 +627,27 @@ class FabricClient { return Promise.reject('fail'); } const self = this; - return this._enrollUser() - .then((user) => { - if (user && user.isEnrolled()) { - logger.info('Successfully loaded user1 from persistence'); - } else { - logger.error('Failed to get user1.... run registerUser.js'); - return Promise.reject('fail'); - } - const tempTxId = self.fabric_client.newTransactionID(); - const request = { - txId: tempTxId, - }; - return channel.getGenesisBlock(request); - }) + const tempTxId = self.fabric_client.newTransactionID(); // 根据用户的证书构建新的事务ID,并自动生成nonce值。 + const request = { + txId: tempTxId, + }; + return channel.getGenesisBlock(request) + // }) .then((block) => { - logger.info(' block ::%j', block); + console.warn(' block ::%j', block); const tempTargets = []; tempTargets.push(self.peer); const genesisBlock = block; - const tempTxId = self.fabric_client.newTransactionID(); - const request = { + const _tempTxId = self.fabric_client.newTransactionID(); + const _request = { targets: tempTargets, block: genesisBlock, - txId: tempTxId, + txId: _tempTxId, }; // send genesis block to the peer - return channel.joinChannel(request); + return channel.joinChannel(_request); }) .then((results) => { logger.info(' results ::%j', results); @@ -747,6 +662,34 @@ class FabricClient { return Promise.reject('fail'); }); } + + + /** + * 获得peer + * @returns {Promise} + * @param channelName 通道名字 + */ + getPeers(channelName) { + let channel; + try { + channel = this._setupChannelOnce(channelName); + } catch (err) { + logger.error(err); + return Promise.reject('fail'); + } + return Promise.resolve(channel.getPeers()); + } + + + /** + * 获得peer + * @returns {Promise} + * @param url peer节点地址 + * @param opts 对象 + */ + newPeer(url, opts) { + return this.fabric_client.newPeer(url, opts); + } } @@ -759,8 +702,15 @@ export default function getFabricClientSingleton() { __fabricClient = new FabricClient(); return __fabricClient._gitConfig() .then(__fabricClient._config) - .then((result) => { - logger.info('create fabric client', result); + .then(__fabricClient._enrollUser) + .then((user) => { + if (user && user.isEnrolled()) { + logger.info('Successfully loaded user1 from persistence, user:', user.toString()); + } else { + logger.error('Failed to get user1.... run registerUser.js'); + return Promise.reject(new Error('Failed to get user1.... run registerUser.js')); + } + logger.info('create fabric client success'); return Promise.resolve(__fabricClient); }); }