-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathsetup.go
211 lines (185 loc) · 6.64 KB
/
setup.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
package blockchain
import (
"fmt"
"os"
api "github.com/hyperledger/fabric-sdk-go/api"
fsgConfig "github.com/hyperledger/fabric-sdk-go/pkg/config"
"github.com/hyperledger/fabric-sdk-go/pkg/fabric-client/events"
fcutil "github.com/hyperledger/fabric-sdk-go/pkg/util"
bccspFactory "github.com/hyperledger/fabric/bccsp/factory" //Blockchain Cryptographic Service Provider
)
// FabricSetup implementation
type FabricSetup struct {
Client api.FabricClient
Channel api.Channel
EventHub api.EventHub
Initialized bool
ChannelId string
ChannelConfig string
ChaincodeId string
ChaincodeVersion string
ChaincodeGoPath string
ChaincodePath string
}
// Initialize reads the configuration file and sets up the client, chain and event hub
func Initialize() (*FabricSetup, error) {
// Add parameters for the initialization
setup := FabricSetup{
// Channel parameters
ChannelId: "mychannel",
ChannelConfig: "fixtures/channel/mychannel.tx",
// Chaincode parameters
ChaincodeId: "servntire-demo-service",
ChaincodeVersion: "v1.0.11",
ChaincodeGoPath: os.Getenv("GOPATH"),
ChaincodePath: "github.com/servntire/servntire-demo/chaincode",
}
// Initialize the configuration
// This will read the config.yaml, in order to tell to
// the SDK all options and how contact a peer
configImpl, err := fsgConfig.InitConfig("config.yaml")
if err != nil {
return nil, fmt.Errorf("Initialize the config failed: %v", err)
}
// Initialize blockchain cryptographic service provider (BCCSP)
// This tool manages certificates and keys
err = bccspFactory.InitFactories(configImpl.GetCSPConfig())
if err != nil {
return nil, fmt.Errorf("Failed getting ephemeral software-based BCCSP [%s]", err)
}
// This will make a user access (here the admin) to interact with the network
// To do so, it will contact the Fabric CA to check if the user has access
// and give it to him (enrollment)
client, err := fcutil.GetClient("admin", "adminpw", "/tmp/enroll_user", configImpl)
if err != nil {
return nil, fmt.Errorf("Create client failed: %v", err)
}
setup.Client = client
// Make a new instance of channel pre-configured with the info we have provided,
// but for now we can't use this channel because we need to create and
// make some peer join it
channel, err := fcutil.GetChannel(setup.Client, setup.ChannelId)
if err != nil {
return nil, fmt.Errorf("Create channel (%s) failed: %v", setup.ChannelId, err)
}
setup.Channel = channel
// Get an orderer user that will validate a proposed order
// The authentication will be made with local certificates
ordererUser, err := fcutil.GetPreEnrolledUser(
client,
"ordererOrganizations/example.com/users/[email protected]/keystore",
"ordererOrganizations/example.com/users/[email protected]/signcerts",
"ordererAdmin",
)
if err != nil {
return nil, fmt.Errorf("Unable to get the orderer user failed: %v", err)
}
// Get an organisation user (admin) that will be used to sign the proposal
// The authentication will be made with local certificates
orgUser, err := fcutil.GetPreEnrolledUser(
client,
"peerOrganizations/org1.example.com/users/[email protected]/keystore",
"peerOrganizations/org1.example.com/users/[email protected]/signcerts",
"peerorg1Admin",
)
if err != nil {
return nil, fmt.Errorf("Unable to get the organisation user failed: %v", err)
}
// Initialize the channel "mychannel" based on the genesis block by
// 1. locating in fixtures/channel/mychannel.tx and
// 2. joining the peer given in the configuration file to this channel
if err := fcutil.CreateAndJoinChannel(client, ordererUser, orgUser, channel, setup.ChannelConfig); err != nil {
return nil, fmt.Errorf("CreateAndJoinChannel return error: %v", err)
}
// Give the organisation user to the client for next proposal
client.SetUserContext(orgUser)
// Setup Event Hub
// This will allow us to listen for some event from the chaincode
// and act on it. We won't use it for now.
eventHub, err := getEventHub(client)
if err != nil {
return nil, err
}
if err := eventHub.Connect(); err != nil {
return nil, fmt.Errorf("Failed eventHub.Connect() [%s]", err)
}
setup.EventHub = eventHub
// Tell that the initialization is done
setup.Initialized = true
return &setup, nil
}
// getEventHub initialize the event hub
func getEventHub(client api.FabricClient) (api.EventHub, error) {
eventHub, err := events.NewEventHub(client)
if err != nil {
return nil, fmt.Errorf("Error creating new event hub: %v", err)
}
foundEventHub := false
peerConfig, err := client.GetConfig().GetPeersConfig()
if err != nil {
return nil, fmt.Errorf("Error reading peer config: %v", err)
}
for _, p := range peerConfig {
if p.EventHost != "" && p.EventPort != 0 {
fmt.Printf("EventHub connect to peer (%s:%d)\n", p.EventHost, p.EventPort)
eventHub.SetPeerAddr(fmt.Sprintf("%s:%d", p.EventHost, p.EventPort),
p.TLS.Certificate, p.TLS.ServerHostOverride)
foundEventHub = true
break
}
}
if !foundEventHub {
return nil, fmt.Errorf("No EventHub configuration found")
}
return eventHub, nil
}
// Install and instantiate the chaincode
func (setup *FabricSetup) InstallAndInstantiateCC() error {
// Check if chaincode ID is provided
// otherwise, generate a random one
if setup.ChaincodeId == "" {
setup.ChaincodeId = fcutil.GenerateRandomID()
}
fmt.Printf(
"Chaincode %s (version %s) will be installed (Go Path: %s / Chaincode Path: %s)\n",
setup.ChaincodeId,
setup.ChaincodeVersion,
setup.ChaincodeGoPath,
setup.ChaincodePath,
)
// Install ChainCode
// Package the go code and make a proposal to the network with this new chaincode
err := fcutil.SendInstallCC(
setup.Client, // The SDK client
setup.Channel, // The channel concerned
setup.ChaincodeId,
setup.ChaincodePath,
setup.ChaincodeVersion,
nil,
setup.Channel.GetPeers(), // Peers concerned by this change in the channel
setup.ChaincodeGoPath,
)
if err != nil {
return fmt.Errorf("Send install proposal return error: %v", err)
} else {
fmt.Printf("Chaincode %s installed (version %s)\n", setup.ChaincodeId, setup.ChaincodeVersion)
}
// Instantiate ChainCode
// Call the Init function of the chaincode in order to initialize in every peer the new chaincode
err = fcutil.SendInstantiateCC(
setup.Channel,
setup.ChaincodeId,
setup.ChannelId,
[]string{"init"}, // Arguments for the invoke request
setup.ChaincodePath,
setup.ChaincodeVersion,
[]api.Peer{setup.Channel.GetPrimaryPeer()}, // Which peer to contact
setup.EventHub,
)
if err != nil {
return err
} else {
fmt.Printf("Chaincode %s instantiated (version %s)\n", setup.ChaincodeId, setup.ChaincodeVersion)
}
return nil
}