github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/examples/chaincode/go/authorizable_counter/authorizable_counter.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "fmt" 21 "strconv" 22 23 "github.com/hyperledger/fabric/accesscontrol/impl" 24 "github.com/hyperledger/fabric/core/chaincode/shim" 25 pb "github.com/hyperledger/fabric/protos/peer" 26 ) 27 28 // AuthorizableCounterChaincode is an example that use Attribute Based Access Control to control the access to a counter by users with an specific role. 29 // In this case only users which TCerts contains the attribute position with the value "Software Engineer" will be able to increment the counter. 30 type AuthorizableCounterChaincode struct { 31 } 32 33 //Init the chaincode asigned the value "0" to the counter in the state. 34 func (t *AuthorizableCounterChaincode) Init(stub shim.ChaincodeStubInterface) pb.Response { 35 err := stub.PutState("counter", []byte("0")) 36 if err != nil { 37 return shim.Error(err.Error()) 38 } 39 40 return shim.Success(nil) 41 } 42 43 //Invoke makes increment counter 44 func (t *AuthorizableCounterChaincode) increment(stub shim.ChaincodeStubInterface, args []string) pb.Response { 45 val, err := impl.NewAccessControlShim(stub).ReadCertAttribute("position") 46 fmt.Printf("Position => %v error %v \n", string(val), err) 47 isOk, _ := impl.NewAccessControlShim(stub).VerifyAttribute("position", []byte("Software Engineer")) // Here the ABAC API is called to verify the attribute, just if the value is verified the counter will be incremented. 48 if isOk { 49 counter, err := stub.GetState("counter") 50 if err != nil { 51 return shim.Error(err.Error()) 52 } 53 var cInt int 54 cInt, err = strconv.Atoi(string(counter)) 55 if err != nil { 56 return shim.Error(err.Error()) 57 } 58 cInt = cInt + 1 59 counter = []byte(strconv.Itoa(cInt)) 60 stub.PutState("counter", counter) 61 } 62 return shim.Success(nil) 63 } 64 65 func (t *AuthorizableCounterChaincode) read(stub shim.ChaincodeStubInterface, args []string) pb.Response { 66 var err error 67 68 // Get the state from the ledger 69 Avalbytes, err := stub.GetState("counter") 70 if err != nil { 71 jsonResp := "{\"Error\":\"Failed to get state for counter\"}" 72 return shim.Error(jsonResp) 73 } 74 75 if Avalbytes == nil { 76 jsonResp := "{\"Error\":\"Nil amount for counter\"}" 77 return shim.Error(jsonResp) 78 } 79 80 jsonResp := "{\"Name\":\"counter\",\"Amount\":\"" + string(Avalbytes) + "\"}" 81 fmt.Printf("Query Response:%s\n", jsonResp) 82 return shim.Success(Avalbytes) 83 } 84 85 // Invoke method is the interceptor of all invocation transactions, its job is to direct 86 // invocation transactions to intended APIs 87 func (t *AuthorizableCounterChaincode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { 88 function, args := stub.GetFunctionAndParameters() 89 90 // Handle different functions 91 if function == "increment" { 92 return t.increment(stub, args) 93 } else if function == "read" { 94 return t.read(stub, args) 95 } 96 return shim.Error("Received unknown function invocation, Expecting \"increment\" \"read\"") 97 } 98 99 func main() { 100 err := shim.Start(new(AuthorizableCounterChaincode)) 101 if err != nil { 102 fmt.Printf("Error starting Simple chaincode: %s", err) 103 } 104 }