我一直试图用ABAC调用我的链代码,并且无法以网络的注册用户身份调用链代码,但可以以管理员身份调用它。我需要作为用户调用以检查ABAC。
注册管理员:
const FabricClient = require('fabric-client');
const path = require('path');
var fabric_client = new FabricClient();
var Fabric_CA_Client = require('fabric-ca-client');
var user = null;
var admin = null;
module.exports.enrollAdmin = async function (orgName, mspID, caPort) {
try {
var store_path = path.join(__dirname, orgName + '-key-store');
var keyValueStore = await FabricClient.newDefaultKeyValueStore({ path: store_path });
console.log('Key store path detected');
console.log('Store -> ' + JSON.stringify(keyValueStore));
fabric_client.setStateStore(keyValueStore);
var crypto_suite = FabricClient.newCryptoSuite();
var cryptoKeyStore = FabricClient.newCryptoKeyStore({ path: store_path });
crypto_suite.setCryptoKeyStore(cryptoKeyStore);
fabric_client.setCryptoSuite(crypto_suite);
var tlsOptions = {
trustedRoots: [],
verify: false
};
fabric_CA_Client = new Fabric_CA_Client('http://localhost:' + caPort, tlsOptions, 'ca-' + orgName, crypto_suite);
var adminUser_from_store = await fabric_client.getUserContext('admin', true);
if (adminUser_from_store && adminUser_from_store.isEnrolled()) {
console.log('Admin user already exists.');
throw new Error('Admin already exists');
} else {
console.log('Enrolling admin.....');
var enrollmentSecret = await fabric_CA_Client.enroll({
enrollmentID: 'admin',
enrollmentSecret: 'adminpw',
attr_reqs: [
{ name: "firstName", optional: false },
{ name: "hf.Registrar.Attributes", optional: false }
]
});
}
console.log('enrollment success');
console.log('--------------------')
var enrolledUser = await fabric_client.createUser({
username: 'admin',
mspid: mspID,
cryptoContent: { privateKeyPEM: enrollmentSecret.key.toBytes(), signedCertPEM: enrollmentSecret.certificate }
});
console.log('Enrolled User -> ' + enrolledUser);
admin = enrolledUser;
// console.log(admin);
console.log('Admin successfully enrolled');
await fabric_client.setUserContext(admin);
return true;
} catch (err) {
console.log(err);
return false;
}
}
注册用户:
const FabricClient = require('fabric-client');
const path = require('path');
var fabClient = new FabricClient();
var Fabric_CA_Client = require('fabric-ca-client');
var user = null;
var admin = null;
var memberUser = null;
module.exports.registerNewUser = async function (orgName, mspID, caPort, username) {
try {
var store_path = path.join(__dirname, orgName + '-key-store');
var keyValueStore = await FabricClient.newDefaultKeyValueStore({ path: store_path });
console.log('Key store path detected');
console.log('Store -> ' + JSON.stringify(keyValueStore));
fabClient.setStateStore(keyValueStore);
var crypto_suite = FabricClient.newCryptoSuite();
var cryptoKeyStore = FabricClient.newCryptoKeyStore({ path: store_path });
crypto_suite.setCryptoKeyStore(cryptoKeyStore);
fabClient.setCryptoSuite(crypto_suite);
var tlsOptions = {
trustedRoots: [],
verify: false
};
fabric_CA_Client = new Fabric_CA_Client('http://localhost:' + caPort, tlsOptions, 'ca-' + orgName, crypto_suite);
var adminUser_from_store = await fabClient.getUserContext('admin', true);
if (!adminUser_from_store && !adminUser_from_store.isEnrolled()) {
throw new Error('Admin does not exist.');
}
console.log('Admin found');
admin = adminUser_from_store;
console.log('enrolled user -> ' + admin.getName());
user = {
enrollmentID: username,
affiliation: orgName + '.department1',
maxEnrollments: 5,
role: 'client',
attrs: [{ name: 'firstName', value: 'Lohith', ecert: true }]
}
var enrollmentSecret = await fabric_CA_Client.register(user, admin);
console.log('client registered');
console.log('Successfully registered user - secret:' + enrollmentSecret);
var enrollment = await fabric_CA_Client.enroll({
enrollmentID: username,
enrollmentSecret: enrollmentSecret,
attr_reqs: [
{ name: "firstName", optional: false }
]
});
console.log('enrollment certifiacte is ', enrollment.certificate)
var member = await fabClient.createUser({
username: username,
mspid: mspID,
cryptoContent: {
privateKeyPEM: enrollment.key.toBytes(),
signedCertPEM: enrollment.certificate
}
});
console.log('Member ->', member);
memberUser = member;
return await fabClient.setUserContext(member);
} catch (error) {
console.log(error);
return false;
}
}
调用链码:
module.exports.putData = async function (orgName, functionName, username, args) {
try {
const client = await getClient(orgName, username);
console.log('done with get client. client is ', client._userContext._identity._certificate);
const channel = await client.newChannel('mychannel');
let channelEventHub1 = channel.newChannelEventHub(peer1);
channelEventHub1.connect(true);
channel.addOrderer(order);
channel.addPeer(peer1);
channel.addPeer(peer2);
channel.addPeer(peer3);
channel.addPeer(peer4);
const peer = [peer1, peer2, peer3, peer4];
// var tx_id = new Transaction(client.getUserContext(username, true))
var tx_id = client.newTransactionID(false);
tx_id_string = tx_id.getTransactionID();
var request = {
targets: peer,
chaincodeId: 'hyperCC',
fcn: functionName,
args: args,
chainId: 'mychannel',
txId: tx_id
};
console.log('Sending proposal');
var results = await channel.sendTransactionProposal(request, 60000);
let isValid = channel.compareProposalResponseResults(results[0]);
if (isValid) {
console.log('Endorsement success')
var orderer_request = {
// txID: tx_id,
proposalResponses: results[0],
proposal: results[1]
};
console.log('proposal responses are ............');
const result = await channel.sendTransaction(orderer_request);
// console.log('done with everything', result);
return true;
} else {
return new Error('Endorsement failed.');
}
} catch (err) {
console.log(err);
return false;
}
}
测试链码:
package main
import (
// "bytes"
"encoding/json"
"fmt"
// "strconv"
"github.com/hyperledger/fabric/core/chaincode/lib/cid"
"github.com/hyperledger/fabric/core/chaincode/shim"
sc "github.com/hyperledger/fabric/protos/peer"
)
// Define the Smart Contract structure
type SmartContract struct {
}
type ShippingInstruction struct {
Shipper string `json:"shipper"`
Consignee string `json:"consignee"`
NotifyParty string `json:"notifyParty"`
SpecialInstructions string `json:"specialInstructions"`
}
func (s *SmartContract) Init(stub shim.ChaincodeStubInterface) sc.Response {
fmt.Println("inside the init function......")
return shim.Success(nil)
}
func (s *SmartContract) Invoke(stub shim.ChaincodeStubInterface) sc.Response {
function, args := stub.GetFunctionAndParameters()
fmt.Println()
if function == "generateShippingInstruction" {
return s.generateShippingInstruction(stub, args)
}
return shim.Error("Invalid chaincode function name...")
}
func (s *SmartContract) generateShippingInstruction(stub shim.ChaincodeStubInterface, args []string) sc.Response {
if len(args) != 5 {
return shim.Error("Invalid number of arguments. Expecting 5")
}
value, found, err := cid.GetAttributeValue(stub, "firstName")
if err != nil {
return shim.Error("could not do abac")
}
fmt.Println("value is ", value)
fmt.Println("found is ", found)
error := stub.SetEvent("test", []byte("hello"))
if error != nil {
return shim.Error("could not set the event")
}
var shippingInstruction = ShippingInstruction{Shipper: args[1], Consignee: args[2], NotifyParty: args[3], SpecialInstructions: args[4]}
shippingInstructionAsBytes, _ := json.Marshal(shippingInstruction)
stub.PutState(args[0], shippingInstructionAsBytes)
fmt.Println("the data has been successfully added to ledger...")
return shim.Success(nil)
}
// The main function is only relevant in unit test mode. Only included here for completeness.
func main() {
// Create a new Smart Contract
err := shim.Start(new(SmartContract))
if err != nil {
fmt.Printf("Error creating new Smart Contract: %s", err)
}
}
错误是
Error: No identity has been assigned to this client
at Client._getSigningIdentity (/home/lohith/Work/fabric-samples/HyperFabric_2/hyperFabric/node_modules/fabric-client/lib/Client.js:1213:11)
at Channel.sendTransaction (/home/lohith/Work/fabric-samples/HyperFabric_2/hyperFabric/node_modules/fabric-client/lib/Channel.js:2536:38)
at module.exports.putData (/home/lohith/Work/fabric-samples/HyperFabric_2/hyperFabric/app/app.invoke.js:172:42)
at <anonymous>
该错误发生在channel.sendTransaction()。链码在容器内成功执行,但返回时失败。