Skip to content

Commit 803da71

Browse files
committed
[FAB-4430] - WYFA scripts and node code
Hard code rc1 tag to docker-compose Change-Id: I72c04a8c03df6179f69197a87f27c18a668b186d Signed-off-by: Nick Gaski <ngaski@us.ibm.com>
1 parent fbc120f commit 803da71

File tree

65 files changed

+1227
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1227
-0
lines changed

fabcar/chaincode/fabcar.go

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
/*
21+
* The sample smart contract for documentation topic:
22+
* Writing Your First Blockchain Application
23+
*/
24+
25+
package main
26+
27+
/* Imports
28+
* 4 utility libraries for formatting, handling bytes, reading and writing JSON, and string manipulation
29+
* 2 specific Hyperledger Fabric specific libraries for Smart Contracts
30+
*/
31+
import (
32+
"bytes"
33+
"encoding/json"
34+
"fmt"
35+
"strconv"
36+
37+
"github.com/hyperledger/fabric/core/chaincode/shim"
38+
sc "github.com/hyperledger/fabric/protos/peer"
39+
)
40+
41+
// Define the Smart Contract structure
42+
type SmartContract struct {
43+
}
44+
45+
// Define the car structure, with 4 properties. Structure tags are used by encoding/json library
46+
type Car struct {
47+
Make string `json:"make"`
48+
Model string `json:"model"`
49+
Colour string `json:"colour"`
50+
Owner string `json:"owner"`
51+
}
52+
53+
/*
54+
* The Init method is called when the Smart Contract "fabcar" is instantiated by the blockchain network
55+
* Best practice is to have any Ledger initialization in separate function -- see initLedger()
56+
*/
57+
func (s *SmartContract) Init(APIstub shim.ChaincodeStubInterface) sc.Response {
58+
return shim.Success(nil)
59+
}
60+
61+
/*
62+
* The Invoke method is called as a result of an application request to run the Smart Contract "fabcar"
63+
* The calling application program has also specified the particular smart contract function to be called, with arguments
64+
*/
65+
func (s *SmartContract) Invoke(APIstub shim.ChaincodeStubInterface) sc.Response {
66+
67+
// Retrieve the requested Smart Contract function and arguments
68+
function, args := APIstub.GetFunctionAndParameters()
69+
// Route to the appropriate handler function to interact with the ledger appropriately
70+
if function == "queryCar" {
71+
return s.queryCar(APIstub, args)
72+
} else if function == "initLedger" {
73+
return s.initLedger(APIstub)
74+
} else if function == "createCar" {
75+
return s.createCar(APIstub, args)
76+
} else if function == "queryAllCars" {
77+
return s.queryAllCars(APIstub)
78+
} else if function == "changeCarOwner" {
79+
return s.changeCarOwner(APIstub, args)
80+
}
81+
82+
return shim.Error("Invalid Smart Contract function name.")
83+
}
84+
85+
func (s *SmartContract) queryCar(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
86+
87+
if len(args) != 1 {
88+
return shim.Error("Incorrect number of arguments. Expecting 1")
89+
}
90+
91+
carAsBytes, _ := APIstub.GetState(args[0])
92+
return shim.Success(carAsBytes)
93+
}
94+
95+
func (s *SmartContract) initLedger(APIstub shim.ChaincodeStubInterface) sc.Response {
96+
cars := []Car{
97+
Car{Make: "Toyota", Model: "Prius", Colour: "blue", Owner: "Tomoko"},
98+
Car{Make: "Ford", Model: "Mustang", Colour: "red", Owner: "Brad"},
99+
Car{Make: "Hyundai", Model: "Tucson", Colour: "green", Owner: "Jin Soo"},
100+
Car{Make: "Volkswagen", Model: "Passat", Colour: "yellow", Owner: "Max"},
101+
Car{Make: "Tesla", Model: "S", Colour: "black", Owner: "Adriana"},
102+
Car{Make: "Peugeot", Model: "205", Colour: "purple", Owner: "Michel"},
103+
Car{Make: "Chery", Model: "S22L", Colour: "white", Owner: "Aarav"},
104+
Car{Make: "Fiat", Model: "Punto", Colour: "violet", Owner: "Pari"},
105+
Car{Make: "Tata", Model: "Nano", Colour: "indigo", Owner: "Valeria"},
106+
Car{Make: "Holden", Model: "Barina", Colour: "brown", Owner: "Shotaro"},
107+
}
108+
109+
i := 0
110+
for i < len(cars) {
111+
fmt.Println("i is ", i)
112+
carAsBytes, _ := json.Marshal(cars[i])
113+
APIstub.PutState("CAR"+strconv.Itoa(i), carAsBytes)
114+
fmt.Println("Added", cars[i])
115+
i = i + 1
116+
}
117+
118+
return shim.Success(nil)
119+
}
120+
121+
func (s *SmartContract) createCar(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
122+
123+
if len(args) != 5 {
124+
return shim.Error("Incorrect number of arguments. Expecting 5")
125+
}
126+
127+
var car = Car{Make: args[1], Model: args[2], Colour: args[3], Owner: args[4]}
128+
129+
carAsBytes, _ := json.Marshal(car)
130+
APIstub.PutState(args[0], carAsBytes)
131+
132+
return shim.Success(nil)
133+
}
134+
135+
func (s *SmartContract) queryAllCars(APIstub shim.ChaincodeStubInterface) sc.Response {
136+
137+
startKey := "CAR0"
138+
endKey := "CAR999"
139+
140+
resultsIterator, err := APIstub.GetStateByRange(startKey, endKey)
141+
if err != nil {
142+
return shim.Error(err.Error())
143+
}
144+
defer resultsIterator.Close()
145+
146+
// buffer is a JSON array containing QueryResults
147+
var buffer bytes.Buffer
148+
buffer.WriteString("[")
149+
150+
bArrayMemberAlreadyWritten := false
151+
for resultsIterator.HasNext() {
152+
queryResponse, err := resultsIterator.Next()
153+
if err != nil {
154+
return shim.Error(err.Error())
155+
}
156+
// Add a comma before array members, suppress it for the first array member
157+
if bArrayMemberAlreadyWritten == true {
158+
buffer.WriteString(",")
159+
}
160+
buffer.WriteString("{\"Key\":")
161+
buffer.WriteString("\"")
162+
buffer.WriteString(queryResponse.Key)
163+
buffer.WriteString("\"")
164+
165+
buffer.WriteString(", \"Record\":")
166+
// Record is a JSON object, so we write as-is
167+
buffer.WriteString(string(queryResponse.Value))
168+
buffer.WriteString("}")
169+
bArrayMemberAlreadyWritten = true
170+
}
171+
buffer.WriteString("]")
172+
173+
fmt.Printf("- queryAllCars:\n%s\n", buffer.String())
174+
175+
return shim.Success(buffer.Bytes())
176+
}
177+
178+
func (s *SmartContract) changeCarOwner(APIstub shim.ChaincodeStubInterface, args []string) sc.Response {
179+
180+
if len(args) != 2 {
181+
return shim.Error("Incorrect number of arguments. Expecting 2")
182+
}
183+
184+
carAsBytes, _ := APIstub.GetState(args[0])
185+
car := Car{}
186+
187+
json.Unmarshal(carAsBytes, &car)
188+
car.Owner = args[1]
189+
190+
carAsBytes, _ = json.Marshal(car)
191+
APIstub.PutState(args[0], carAsBytes)
192+
193+
return shim.Success(nil)
194+
}
195+
196+
// The main function is only relevant in unit test mode. Only included here for completeness.
197+
func main() {
198+
199+
// Create a new Smart Contract
200+
err := shim.Start(new(SmartContract))
201+
if err != nil {
202+
fmt.Printf("Error creating new Smart Contract: %s", err)
203+
}
204+
}

fabcar/invoke.js

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
'use strict';
2+
3+
/*
4+
* Chaincode Invoke
5+
*/
6+
7+
var hfc = require('fabric-client');
8+
var path = require('path');
9+
var util = require('util');
10+
11+
var options = {
12+
wallet_path: path.join(__dirname, './network/creds'),
13+
user_id: 'PeerAdmin',
14+
channel_id: 'mychannel',
15+
chaincode_id: 'fabcar',
16+
peer_url: 'grpc://localhost:7051',
17+
event_url: 'grpc://localhost:7053',
18+
orderer_url: 'grpc://localhost:7050'
19+
};
20+
21+
var channel = {};
22+
var client = null;
23+
var targets = [];
24+
var tx_id = null;
25+
Promise.resolve().then(() => {
26+
console.log("Create a client and set the wallet location");
27+
client = new hfc();
28+
return hfc.newDefaultKeyValueStore({ path: options.wallet_path });
29+
}).then((wallet) => {
30+
console.log("Set wallet path, and associate user ", options.user_id, " with application");
31+
client.setStateStore(wallet);
32+
return client.getUserContext(options.user_id, true);
33+
}).then((user) => {
34+
console.log("Check user is enrolled, and set a query URL in the network");
35+
if (user === undefined || user.isEnrolled() === false) {
36+
console.error("User not defined, or not enrolled - error");
37+
}
38+
channel = client.newChannel(options.channel_id);
39+
var peerObj = client.newPeer(options.peer_url);
40+
channel.addPeer(peerObj);
41+
channel.addOrderer(client.newOrderer(options.orderer_url));
42+
targets.push(peerObj);
43+
return;
44+
}).then(() => {
45+
//console.log("send Invoke with function name :"+fcn);
46+
tx_id = client.newTransactionID();
47+
console.log("Assigning transaction_id: ", tx_id._transaction_id);
48+
// createCar - requires 5 args, ex: args: ['CAR11', 'Honda', 'Accord', 'Black', 'Tom'],
49+
// changeCarOwner - requires 2 args , ex: args: ['CAR10', 'Barry'],
50+
// send proposal to endorser
51+
var request = {
52+
targets: targets,
53+
chaincodeId: options.chaincode_id,
54+
fcn: '',
55+
args: [''],
56+
chainId: options.channel_id,
57+
txId: tx_id
58+
};
59+
return channel.sendTransactionProposal(request);
60+
}).then((results) => {
61+
var proposalResponses = results[0];
62+
var proposal = results[1];
63+
var header = results[2];
64+
let isProposalGood = false;
65+
if (proposalResponses && proposalResponses[0].response &&
66+
proposalResponses[0].response.status === 200) {
67+
isProposalGood = true;
68+
console.log('transaction proposal was good');
69+
} else {
70+
console.error('transaction proposal was bad');
71+
}
72+
if (isProposalGood) {
73+
console.log(util.format(
74+
'Successfully sent Proposal and received ProposalResponse: Status - %s, message - "%s", metadata - "%s", endorsement signature: %s',
75+
proposalResponses[0].response.status, proposalResponses[0].response.message,
76+
proposalResponses[0].response.payload, proposalResponses[0].endorsement
77+
.signature));
78+
var request = {
79+
proposalResponses: proposalResponses,
80+
proposal: proposal,
81+
header: header
82+
};
83+
// set the transaction listener and set a timeout of 30sec
84+
// if the transaction did not get committed within the timeout period,
85+
// fail the test
86+
var transactionID = tx_id.getTransactionID();
87+
var eventPromises = [];
88+
let eh = client.newEventHub();
89+
eh.setPeerAddr(options.event_url);
90+
eh.connect();
91+
92+
let txPromise = new Promise((resolve, reject) => {
93+
let handle = setTimeout(() => {
94+
eh.disconnect();
95+
reject();
96+
}, 30000);
97+
98+
eh.registerTxEvent(transactionID, (tx, code) => {
99+
clearTimeout(handle);
100+
eh.unregisterTxEvent(transactionID);
101+
eh.disconnect();
102+
103+
if (code !== 'VALID') {
104+
console.error(
105+
'The transaction was invalid, code = ' + code);
106+
reject();
107+
} else {
108+
console.log(
109+
'The transaction has been committed on peer ' +
110+
eh._ep._endpoint.addr);
111+
resolve();
112+
}
113+
});
114+
});
115+
eventPromises.push(txPromise);
116+
var sendPromise = channel.sendTransaction(request);
117+
return Promise.all([sendPromise].concat(eventPromises)).then((results) => {
118+
console.log(' event promise all complete and testing complete');
119+
return results[0]; // the first returned value is from the 'sendPromise' which is from the 'sendTransaction()' call
120+
}).catch((err) => {
121+
console.error(
122+
'Failed to send transaction and get notifications within the timeout period.'
123+
);
124+
return 'Failed to send transaction and get notifications within the timeout period.';
125+
});
126+
} else {
127+
console.error(
128+
'Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...'
129+
);
130+
return 'Failed to send Proposal or receive valid response. Response null or status is not 200. exiting...';
131+
}
132+
}, (err) => {
133+
console.error('Failed to send proposal due to error: ' + err.stack ? err.stack :
134+
err);
135+
return 'Failed to send proposal due to error: ' + err.stack ? err.stack :
136+
err;
137+
}).then((response) => {
138+
if (response.status === 'SUCCESS') {
139+
console.log('Successfully sent transaction to the orderer.');
140+
return tx_id.getTransactionID();
141+
} else {
142+
console.error('Failed to order the transaction. Error code: ' + response.status);
143+
return 'Failed to order the transaction. Error code: ' + response.status;
144+
}
145+
}, (err) => {
146+
console.error('Failed to send transaction due to error: ' + err.stack ? err
147+
.stack : err);
148+
return 'Failed to send transaction due to error: ' + err.stack ? err.stack :
149+
err;
150+
});
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgS0L+WeTBa4vdUW4j
3+
rogLu8JmLSjda0YcA2TWOfaR+8yhRANCAAQO41JsWQE2pt2UZ/DBdIcpa/inDZ4U
4+
54P5VcIdXgISsEqdRcGLBz+cvvrpTNedaeyNRSndk5LMIJ/npw2Qua/p
5+
-----END PRIVATE KEY-----
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEDuNSbFkBNqbdlGfwwXSHKWv4pw2e
3+
FOeD+VXCHV4CErBKnUXBiwc/nL766UzXnWnsjUUp3ZOSzCCf56cNkLmv6Q==
4+
-----END PUBLIC KEY-----

fabcar/network/creds/PeerAdmin

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"name":"PeerAdmin","mspid":"Org1MSP","roles":null,"affiliation":"","enrollmentSecret":"","enrollment":{"signingIdentity":"9022d671ceedbb24af3ea69b5a8136cc64203df6b9920e26f48123fcfcb1d2e9","identity":{"certificate":"-----BEGIN CERTIFICATE-----\nMIICKjCCAdGgAwIBAgIQIVQ6HvVnJP1qZ5YKfh50hzAKBggqhkjOPQQDAjBwMQsw\nCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZy\nYW5jaXNjbzEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEZMBcGA1UEAxMQb3Jn\nMS5leGFtcGxlLmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMFsx\nCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g\nRnJhbmNpc2NvMR8wHQYDVQQDDBZBZG1pbkBvcmcxLmV4YW1wbGUuY29tMFkwEwYH\nKoZIzj0CAQYIKoZIzj0DAQcDQgAEDuNSbFkBNqbdlGfwwXSHKWv4pw2eFOeD+VXC\nHV4CErBKnUXBiwc/nL766UzXnWnsjUUp3ZOSzCCf56cNkLmv6aNiMGAwDgYDVR0P\nAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAwGA1UdEwEB/wQCMAAwKwYD\nVR0jBCQwIoAgoi2vNWsqq1eS6lPjX2b8zvHX8aorOiuS2/v5akSOomowCgYIKoZI\nzj0EAwIDRwAwRAIgbEqKoKrFuYQG0ndiX7dT7GKGlF17Skf8DYil9cqbp00CID5T\nURQPp0/vJ3tldK0z9xjFvsSecj8aqnDvZvGz07/v\n-----END CERTIFICATE-----\n"}}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIGHAgEBMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgMOKUs/EytOuKG/kW
3+
qZ8OHBb1aJ4zodJVqYWwcpH5FluhRANCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCU
4+
PEe1Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQ
5+
-----END PRIVATE KEY-----
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIICNDCCAdqgAwIBAgIRAIBOtq8vZiC0+uLSi2MIS4swCgYIKoZIzj0EAwIwZjEL
3+
MAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBG
4+
cmFuY2lzY28xFDASBgNVBAoTC2V4YW1wbGUuY29tMRQwEgYDVQQDEwtleGFtcGxl
5+
LmNvbTAeFw0xNzA0MjIxMjAyNTZaFw0yNzA0MjAxMjAyNTZaMGYxCzAJBgNVBAYT
6+
AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2Nv
7+
MRQwEgYDVQQKEwtleGFtcGxlLmNvbTEUMBIGA1UEAxMLZXhhbXBsZS5jb20wWTAT
8+
BgcqhkjOPQIBBggqhkjOPQMBBwNCAARD2rvgyAmhn8hpu82kAjX3QUg2iqCUPEe1
9+
Q5CzD5MVv/dK5wrRgkcoMhJLe4HPxYbjV3rodm5Pwi5m3zMGkqNQo2kwZzAOBgNV
10+
HQ8BAf8EBAMCAaYwGQYDVR0lBBIwEAYEVR0lAAYIKwYBBQUHAwEwDwYDVR0TAQH/
11+
BAUwAwEB/zApBgNVHQ4EIgQg6q3lkIfG2X/PNQ6U83rZ8saSu2bxghSM5YlA3nCt
12+
6c4wCgYIKoZIzj0EAwIDSAAwRQIhAL5Lgy7jZ2W74L6i0B23a3JD0W8TSYlTcqXb
13+
RMSXlLIoAiB2glBl0wM/ITn5+tnHOnq2wrIGuYIiNbLK5oq2zf+gtA==
14+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)