forked from SmartBFT-Go/fabric
-
Notifications
You must be signed in to change notification settings - Fork 0
/
chaincode.go
264 lines (235 loc) · 7.24 KB
/
chaincode.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
/*
Copyright IBM Corp. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package keylevelep
import (
"encoding/json"
"fmt"
"github.com/hyperledger/fabric/core/chaincode/shim"
"github.com/hyperledger/fabric/core/chaincode/shim/ext/statebased"
pb "github.com/hyperledger/fabric/protos/peer"
)
/*
EndorsementCC is an example chaincode that uses state-based endorsement.
In the init function, it creates two KVS states, one public, one private, that
can then be modified through chaincode functions that use the state-based
endorsement chaincode convenience layer. The following chaincode functions
are provided:
-) "addorgs": supply a list of MSP IDs that will be added to the
state's endorsement policy
-) "delorgs": supply a list of MSP IDs that will be removed from
the state's endorsement policy
-) "delep": delete the key-level endorsement policy for the state altogether
-) "listorgs": list the orgs included in the state's endorsement policy
*/
type EndorsementCC struct {
}
// Init callback
func (cc *EndorsementCC) Init(stub shim.ChaincodeStubInterface) pb.Response {
err := stub.PutState("pub", []byte("foo"))
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(nil)
}
// Invoke dispatcher
func (cc *EndorsementCC) Invoke(stub shim.ChaincodeStubInterface) pb.Response {
funcName, _ := stub.GetFunctionAndParameters()
if function, ok := functions[funcName]; ok {
return function(stub)
}
return shim.Error(fmt.Sprintf("Unknown function %s", funcName))
}
// function dispatch map used by Invoke()
var functions = map[string]func(stub shim.ChaincodeStubInterface) pb.Response{
"addorgs": addOrgs,
"delorgs": delOrgs,
"listorgs": listOrgs,
"delep": delEP,
"setval": setVal,
"getval": getVal,
"cc2cc": invokeCC,
}
// addOrgs adds the list of MSP IDs from the invocation parameters
// to the state's endorsement policy
func addOrgs(stub shim.ChaincodeStubInterface) pb.Response {
_, parameters := stub.GetFunctionAndParameters()
if len(parameters) < 2 {
return shim.Error("No orgs to add specified")
}
// get the endorsement policy for the key
var epBytes []byte
var err error
if parameters[0] == "pub" {
epBytes, err = stub.GetStateValidationParameter("pub")
} else if parameters[0] == "priv" {
epBytes, err = stub.GetPrivateDataValidationParameter("col", "priv")
} else {
return shim.Error("Unknown key specified")
}
if err != nil {
return shim.Error(err.Error())
}
ep, err := statebased.NewStateEP(epBytes)
if err != nil {
return shim.Error(err.Error())
}
// add organizations to endorsement policy
err = ep.AddOrgs(statebased.RoleTypePeer, parameters[1:]...)
if err != nil {
return shim.Error(err.Error())
}
epBytes, err = ep.Policy()
if err != nil {
return shim.Error(err.Error())
}
// set the modified endorsement policy for the key
if parameters[0] == "pub" {
err = stub.SetStateValidationParameter("pub", epBytes)
} else if parameters[0] == "priv" {
err = stub.SetPrivateDataValidationParameter("col", "priv", epBytes)
}
if err != nil {
return shim.Error(err.Error())
}
return shim.Success([]byte{})
}
// delOrgs removes the list of MSP IDs from the invocation parameters
// from the state's endorsement policy
func delOrgs(stub shim.ChaincodeStubInterface) pb.Response {
_, parameters := stub.GetFunctionAndParameters()
if len(parameters) < 2 {
return shim.Error("No orgs to delete specified")
}
// get the endorsement policy for the key
var epBytes []byte
var err error
if parameters[0] == "pub" {
epBytes, err = stub.GetStateValidationParameter("pub")
} else if parameters[0] == "priv" {
epBytes, err = stub.GetPrivateDataValidationParameter("col", "priv")
} else {
return shim.Error("Unknown key specified")
}
ep, err := statebased.NewStateEP(epBytes)
if err != nil {
return shim.Error(err.Error())
}
// delete organizations from the endorsement policy of that key
ep.DelOrgs(parameters...)
epBytes, err = ep.Policy()
if err != nil {
return shim.Error(err.Error())
}
// set the modified endorsement policy for the key
if parameters[0] == "pub" {
err = stub.SetStateValidationParameter("pub", epBytes)
} else if parameters[0] == "priv" {
err = stub.SetPrivateDataValidationParameter("col", "priv", epBytes)
}
if err != nil {
return shim.Error(err.Error())
}
return shim.Success([]byte{})
}
// listOrgs returns the list of organizations currently part of
// the state's endorsement policy
func listOrgs(stub shim.ChaincodeStubInterface) pb.Response {
_, parameters := stub.GetFunctionAndParameters()
if len(parameters) < 1 {
return shim.Error("No key specified")
}
// get the endorsement policy for the key
var epBytes []byte
var err error
if parameters[0] == "pub" {
epBytes, err = stub.GetStateValidationParameter("pub")
} else if parameters[0] == "priv" {
epBytes, err = stub.GetPrivateDataValidationParameter("col", "priv")
} else {
return shim.Error("Unknown key specified")
}
ep, err := statebased.NewStateEP(epBytes)
if err != nil {
return shim.Error(err.Error())
}
// get the list of organizations in the endorsement policy
orgs := ep.ListOrgs()
orgsList, err := json.Marshal(orgs)
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(orgsList)
}
// delEP deletes the state-based endorsement policy for the key altogether
func delEP(stub shim.ChaincodeStubInterface) pb.Response {
_, parameters := stub.GetFunctionAndParameters()
if len(parameters) < 1 {
return shim.Error("No key specified")
}
// set the modified endorsement policy for the key to nil
var err error
if parameters[0] == "pub" {
err = stub.SetStateValidationParameter("pub", nil)
} else if parameters[0] == "priv" {
err = stub.SetPrivateDataValidationParameter("col", "priv", nil)
} else {
return shim.Error("Unknown key specified")
}
if err != nil {
return shim.Error(err.Error())
}
return shim.Success([]byte{})
}
// setVal sets the value of the KVS key
func setVal(stub shim.ChaincodeStubInterface) pb.Response {
args := stub.GetArgs()
if len(args) != 3 {
return shim.Error("setval expects two arguments")
}
var err error
if string(args[1]) == "pub" {
err = stub.PutState("pub", args[2])
} else if string(args[1]) == "priv" {
err = stub.PutPrivateData("col", "priv", args[2])
} else {
return shim.Error("Unknown key specified")
}
if err != nil {
return shim.Error(err.Error())
}
return shim.Success([]byte{})
}
// getVal retrieves the value of the KVS key
func getVal(stub shim.ChaincodeStubInterface) pb.Response {
args := stub.GetArgs()
if len(args) != 2 {
return shim.Error("No key specified")
}
var err error
var val []byte
if string(args[1]) == "pub" {
val, err = stub.GetState("pub")
} else if string(args[1]) == "priv" {
val, err = stub.GetPrivateData("col", "priv")
} else {
return shim.Error("Unknown key specified")
}
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(val)
}
// invokeCC is used for chaincode to chaincode invocation of a given cc on another channel
func invokeCC(stub shim.ChaincodeStubInterface) pb.Response {
args := stub.GetArgs()
if len(args) < 3 {
return shim.Error("cc2cc expects at least two arguments (channel and chaincode)")
}
channel := string(args[1])
cc := string(args[2])
nargs := args[3:]
resp := stub.InvokeChaincode(cc, nargs, channel)
return resp
}