-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
213 lines (173 loc) · 5.67 KB
/
main.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
package main
import (
"encoding/json"
"fmt"
uuid "github.com/satori/go.uuid"
"github.com/hyperledger/fabric-chaincode-go/shim"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/rs/zerolog/log"
)
// ObjectType defines single type od data stored in the ledger
const ObjectType = "DATA"
// ExampleCC implements a simple chaincode to share channel config updates
type ExampleCC struct {
}
// Init is called during chaincode instantiation to initialize any
// data. Note that chaincode upgrade also calls this function to reset
// or to migrate data.
func (t *ExampleCC) Init(stub shim.ChaincodeStubInterface) peer.Response {
return shim.Success(nil)
}
// Invoke is called per transaction on the chaincode. Each transaction is
// one of the: 'put', 'update', 'list', 'read' methods
// defined by the function name passed to Invoke
func (t *ExampleCC) Invoke(stub shim.ChaincodeStubInterface) peer.Response {
fn, args := stub.GetFunctionAndParameters()
var result []byte
var err error
switch fn {
case "put":
result, err = put(stub, args)
case "update":
result, err = update(stub, args)
case "list":
result, err = list(stub, args)
case "delete":
result, err = del(stub, args)
default:
result, err = read(stub, args)
}
if err != nil {
return shim.Error(err.Error())
}
return shim.Success(result)
}
// put creates entry in the ledger
func put(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
var err error
var id, key string
ret := make(map[string]interface{})
if len(args) <= 1 && len(args) >= 2 {
log.Error().Msg(fmt.Sprintf("FNPUT: Incorrect number of arguments %v", len(args)))
return nil, fmt.Errorf("Incorrect number of arguments %v", len(args))
}
if len(args) == 2 {
id = args[1]
} else {
id = uuid.NewV4().String()
}
key, err = stub.CreateCompositeKey(ObjectType, []string{id})
if err != nil {
log.Error().Stack().Err(err)
return nil, fmt.Errorf("Failed to create composite key, err: %v", err.Error())
}
if err = stub.PutState(key, []byte(args[0])); err != nil {
log.Error().Stack().Err(err)
return nil, fmt.Errorf("Failed to put data: %v, err: %v", args[0], err.Error())
}
ret["put"] = id
return json.Marshal(ret)
}
// update updates entry in the ledger
func update(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
var err error
ret := make(map[string]interface{})
if len(args) != 2 {
log.Error().Msg("FNUPDATE: Incorrect arguments. Expecting key and data")
return nil, fmt.Errorf("Incorrect arguments. Expecting key and data")
}
key, err := stub.CreateCompositeKey(ObjectType, []string{args[0]})
if err != nil {
log.Error().Stack().Err(err)
return nil, fmt.Errorf("Failed to create composite key, err: %v", err.Error())
}
err = stub.PutState(key, []byte(args[1]))
if err != nil {
log.Error().Stack().Err(err)
return nil, fmt.Errorf("Failed to update data: %v, err: %v", args[1], err.Error())
}
ret["update"] = args[0]
return json.Marshal(ret)
}
// del deletes entry in the ledger
func del(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
var err error
ret := make(map[string]interface{})
if len(args) != 1 {
log.Error().Msg("FNUPDATE: Incorrect arguments. Expecting a key")
return nil, fmt.Errorf("Incorrect arguments. Expecting a key")
}
key, err := stub.CreateCompositeKey(ObjectType, []string{args[0]})
if err != nil {
log.Error().Stack().Err(err)
return nil, fmt.Errorf("Failed to create composite key, err: %v", err.Error())
}
err = stub.DelState(key)
if err != nil {
log.Error().Stack().Err(err)
return nil, fmt.Errorf("Failed to delete data: %v, err: %v", args[1], err.Error())
}
ret["delete"] = args[0]
return json.Marshal(ret)
}
// read reads entry from the ledger
func read(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
ret := make(map[string]interface{})
if len(args) != 1 {
log.Error().Msg("FNREAD: Incorrect arguments. Expecting a key")
return nil, fmt.Errorf("Incorrect arguments. Expecting a key")
}
key, err := stub.CreateCompositeKey(ObjectType, []string{args[0]})
if err != nil {
log.Error().Stack().Err(err)
return nil, fmt.Errorf("Failed to create composite key, err: %v", err.Error())
}
data, err := stub.GetState(key)
if err != nil {
log.Error().Stack().Err(err)
return nil, fmt.Errorf("Failed to get data: %v, err: %v", args[0], err.Error())
}
if data == nil {
log.Error().Msg("FNREAD: Data not found")
return nil, fmt.Errorf("Data not found: %v", args[0])
}
ret[args[0]] = string(data)
return json.Marshal(ret)
}
// list returns collection of entries from the ledger
func list(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
ret := make(map[string]interface{})
value, err := stub.GetStateByPartialCompositeKey(ObjectType, []string{})
if err != nil {
log.Error().Stack().Err(err)
return nil, fmt.Errorf("Failed to list data, err: %v", err)
}
if value == nil {
log.Error().Stack().Err(err)
return nil, fmt.Errorf("No data found")
}
for value.HasNext() {
kv, err := value.Next()
if err != nil {
log.Error().Stack().Err(err)
return nil, fmt.Errorf("Failed to parse data, err: %v", err)
}
_, ids, err := stub.SplitCompositeKey(kv.GetKey())
if err != nil {
log.Error().Stack().Err(err)
return nil, fmt.Errorf("Failed to parse key, err: %v", err)
}
if len(ids) == 0 {
log.Error().Msg("FNLIST: Failed to get ID: " + ids[1])
return nil, fmt.Errorf("Failed to get ID: " + ids[1])
}
ret[ids[0]] = string(kv.GetValue())
}
return json.Marshal(ret)
}
// main function starts up the chaincode in the container during instantiate
func main() {
if err := shim.Start(new(ExampleCC)); err != nil {
fmt.Printf("Error starting ExampleCC chaincode: %v", err)
}
}