Skip to content

Commit 87840b4

Browse files
authored
Merge pull request #30 from urgetolearn/main
made changes to local-network
2 parents cb8bee6 + ca705c2 commit 87840b4

File tree

5 files changed

+211
-22
lines changed

5 files changed

+211
-22
lines changed

extension.js

Lines changed: 176 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ const {
2222
const {
2323
BlockchainTreeDataProvider,
2424
} = require("./src/blockReader/blockchainExplorer.js");
25+
const { log } = require("console");
2526
let loadedConnectionProfile = null;
2627

2728
function activate(context) {
28-
const fabricDebuggerPath = "C:\\Users\\chinm\\fabric-debugger";
29+
const fabricDebuggerPath = context.extensionPath;
2930

3031
let greenButton = vscode.commands.registerCommand("myview.button1", () => {
3132
const platform = process.platform;
@@ -56,7 +57,6 @@ function activate(context) {
5657
command = `cd "${fabricDebuggerPath}" && bash local-networkdown.sh`;
5758
}
5859

59-
// Execute the command
6060
exec(command, (err, stdout, stderr) => {
6161
if (err) {
6262
vscode.window.showErrorMessage(`Error: ${stderr}`);
@@ -69,13 +69,124 @@ function activate(context) {
6969

7070
context.subscriptions.push(greenButton);
7171
context.subscriptions.push(redButton);
72+
const outputChannel = vscode.window.createOutputChannel("Chaincode Invocation");
73+
let disposableExtractFunctions = vscode.commands.registerCommand('extension.extractFunctions', function () {
74+
const editor = vscode.window.activeTextEditor;
75+
if (!editor) {
76+
vscode.window.showInformationMessage('No active editor. Open a chaincode file.');
77+
return;
78+
}
79+
const filePath = editor.document.fileName;
80+
const text = editor.document.getText();
81+
let functions = [];
82+
83+
if (isGoChaincodeFile(filePath)) {
84+
functions = extractGoFunctions(text);
85+
}
86+
87+
const filteredFunctions = filterIntAndStringFunctions(functions);
88+
const uniqueFunctions = [...new Set(filteredFunctions)];
89+
storeFunctions(uniqueFunctions, context);
90+
91+
vscode.window.showInformationMessage(`Extracted and stored ${uniqueFunctions.length} unique functions with int or string parameters.`);
92+
93+
showStoredFunctions(context, outputChannel);
94+
});
95+
96+
context.subscriptions.push(disposableExtractFunctions);
97+
function isGoChaincodeFile(filePath) {
98+
return filePath.toLowerCase().endsWith('.go');
99+
}
100+
101+
function extractGoFunctions(code) {
102+
const functionDetails = [];
103+
const regex = /func\s*\((\w+)\s+\*SmartContract\)\s*(\w+)\s*\((.*?)\)\s*(\w*)/g;
104+
let match;
105+
106+
while ((match = regex.exec(code)) !== null) {
107+
const functionName = match[2];
108+
const params = match[3];
109+
functionDetails.push({ name: functionName, params });
110+
}
111+
112+
return functionDetails;
113+
}
114+
115+
function filterIntAndStringFunctions(functions) {
116+
return functions.filter(func => /int|string/.test(func.params)).map(func => `${func.name}(${func.params})`);
117+
}
118+
119+
function storeFunctions(functions, context) {
120+
let storedFunctions = context.workspaceState.get('storedFunctions', []);
121+
storedFunctions = [...new Set([...storedFunctions, ...functions])];
122+
context.workspaceState.update('storedFunctions', storedFunctions);
123+
}
124+
125+
function showStoredFunctions(context, outputChannel) {
126+
const storedFunctions = context.workspaceState.get('storedFunctions', []);
127+
128+
vscode.window.showQuickPick(storedFunctions, {
129+
placeHolder: 'Select a function to invoke',
130+
canPickMany: false
131+
}).then(selectedFunction => {
132+
if (selectedFunction) {
133+
vscode.window.showInformationMessage(`Selected: ${selectedFunction}`);
134+
promptForArgumentsSequentially(selectedFunction, outputChannel);
135+
}
136+
});
137+
}
138+
139+
async function promptForArgumentsSequentially(selectedFunction, outputChannel) {
140+
const functionPattern = /(\w+)\((.*)\)/;
141+
const match = functionPattern.exec(selectedFunction);
142+
143+
if (!match) {
144+
vscode.window.showErrorMessage("Invalid function format.");
145+
return;
146+
}
147+
148+
const functionName = match[1];
149+
const paramList = match[2].split(',').map(param => param.trim());
150+
151+
let argumentValues = [];
152+
153+
for (let param of paramList) {
154+
if (/int/.test(param)) {
155+
const input = await vscode.window.showInputBox({ prompt: `Enter an integer value for ${param}` });
156+
const intValue = parseInt(input, 10);
157+
if (isNaN(intValue)) {
158+
vscode.window.showErrorMessage(`Invalid integer value for ${param}.`);
159+
return;
160+
}
161+
argumentValues.push(intValue);
162+
} else if (/string/.test(param)) {
163+
const input = await vscode.window.showInputBox({ prompt: `Enter a string value for ${param}` });
164+
if (!input) {
165+
vscode.window.showErrorMessage(`Invalid string value for ${param}.`);
166+
return;
167+
}
168+
argumentValues.push(`"${input}"`);
169+
}
170+
}
171+
172+
const finalArgs = argumentValues.join(', ');
173+
outputChannel.show();
174+
outputChannel.appendLine(`Function: ${functionName}`);
175+
outputChannel.appendLine(`Arguments: ${finalArgs}`);
176+
177+
vscode.window.showInformationMessage(`Arguments captured. Press "Invoke" to execute the command.`, "Invoke").then(selection => {
178+
if (selection === "Invoke") {
179+
invokeChaincode(functionName, argumentValues);
180+
}
181+
});
182+
}
72183

73184
factory = new DelveDebugAdapterDescriptorFactory();
74185
context.subscriptions.push(
75186
vscode.debug.registerDebugAdapterDescriptorFactory("delve", factory)
76187
);
77188
console.log("Delve Debug Adapter Registered");
78-
189+
79190
const hyperledgerProvider = new fabricsamples();
80191
const treeViewProviderFabric = new TreeViewProvider(
81192
"fabric-network",
@@ -1046,6 +1157,66 @@ function activate(context) {
10461157
}
10471158
}
10481159
}
1160+
async function invokeChaincode(functionName, args) {
1161+
try {
1162+
const walletPath = path.join(os.homedir(), "wallets");
1163+
const wallet = await Wallets.newFileSystemWallet(walletPath);
1164+
1165+
1166+
if (!loadedConnectionProfile) {
1167+
vscode.window.showErrorMessage("No connection profile loaded.");
1168+
return;
1169+
}
1170+
1171+
const identities = await wallet.list();
1172+
if (!identities.length) {
1173+
vscode.window.showErrorMessage("No identities found in the wallet.");
1174+
return;
1175+
}
1176+
1177+
const identityName = identities[0];
1178+
const gateway = new Gateway();
1179+
1180+
await gateway.connect(loadedConnectionProfile, {
1181+
wallet,
1182+
identity: identityName,
1183+
discovery: { enabled: true, asLocalhost: false },
1184+
});
1185+
1186+
1187+
const channelName = Object.keys(loadedConnectionProfile.channels || {})[0];
1188+
if (!channelName) {
1189+
vscode.window.showErrorMessage("No channel found in the connection profile.");
1190+
return;
1191+
}
1192+
1193+
const chaincodes =
1194+
loadedConnectionProfile.channels[channelName]?.chaincodes || [];
1195+
if (!chaincodes.length) {
1196+
vscode.window.showErrorMessage(
1197+
`No chaincodes found for channel "${channelName}".`
1198+
);
1199+
return;
1200+
}
1201+
1202+
const chaincodeName = chaincodes[0];
1203+
const network = await gateway.getNetwork(channelName);
1204+
const contract = network.getContract(chaincodeName);
1205+
1206+
1207+
const result = await contract.submitTransaction(functionName, ...args);
1208+
vscode.window.showInformationMessage(
1209+
`Transaction invoked successfully. Result: ${result.toString()}`
1210+
);
1211+
console.log("Transaction result:", result.toString());
1212+
1213+
1214+
await gateway.disconnect();
1215+
} catch (error) {
1216+
vscode.window.showErrorMessage(`Error invoking chaincode: ${error.message}`);
1217+
console.error("Error invoking chaincode:", error);
1218+
}
1219+
}
10491220
}
10501221

10511222
function extractNetworkDetails(profile) {
@@ -1152,23 +1323,13 @@ function extractWalletDetails(walletData) {
11521323
console.warn("Missing required wallet data fields:");
11531324
}
11541325
}
1155-
return null;
1156-
}
11571326

1158-
function packageChaincode(chaincodePath) {
1159-
class chaincodePackager extends BasePackager {
1160-
async package(directoryPath) {
1161-
const files = fs.readdirSync(directoryPath).map((file) => path.join(directoryPath, file));
1162-
return this.generateTarGz(files);
1163-
}
1164-
}
1165-
1166-
const packager = new chaincodePackager();
1167-
return await packager.package(chaincodePath);
1327+
return null;
11681328
}
11691329

11701330
function deactivate() {}
11711331

1332+
11721333
module.exports = {
11731334
activate,
11741335
deactivate,

local-networkdown.sh

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
#!/bin/bash
2-
cd $HOME/go/src/github.com/urgetolearn
3-
cd fabric-samples/test-network
4-
./network.sh down
2+
FABRIC_SAMPLES_PATH="${HOME}/go/src/github.com/urgetolearn/fabric-samples"
3+
if [ -n "$FABRIC_SAMPLES_CUSTOM_PATH" ]; then
4+
FABRIC_SAMPLES_PATH="$FABRIC_SAMPLES_CUSTOM_PATH"
5+
fi
6+
if [ ! -d "$FABRIC_SAMPLES_PATH" ]; then
7+
echo "Error: Fabric samples directory not found at $FABRIC_SAMPLES_PATH."
8+
echo "Please ensure the Fabric samples are cloned from https://github.com/hyperledger/fabric-samples"
9+
exit 1
10+
fi
11+
cd "$FABRIC_SAMPLES_PATH/test-network" || exit
12+
./network.sh down

local-networkup.sh

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
#!/bin/bash
2-
cd $HOME/go/src/github.com/urgetolearn
3-
cd fabric-samples/test-network
2+
FABRIC_SAMPLES_PATH="${HOME}/go/src/github.com/urgetolearn/fabric-samples"
3+
if [ -n "$FABRIC_SAMPLES_CUSTOM_PATH" ]; then
4+
FABRIC_SAMPLES_PATH="$FABRIC_SAMPLES_CUSTOM_PATH"
5+
fi
6+
if [ ! -d "$FABRIC_SAMPLES_PATH" ]; then
7+
echo "Error: Fabric samples directory not found at $FABRIC_SAMPLES_PATH."
8+
echo "Please ensure the Fabric samples are cloned from https://github.com/hyperledger/fabric-samples"
9+
exit 1
10+
fi
11+
cd "$FABRIC_SAMPLES_PATH/test-network" || exit
412
./network.sh up

package-lock.json

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,16 @@
165165
"command": "fabric-network.queryBlocks",
166166
"when": "view == blockchainExplorer",
167167
"group": "navigation"
168+
},
169+
{
170+
"command": "myview.button1",
171+
"when": "view == start-local-network",
172+
"group": "navigation"
173+
},
174+
{
175+
"command": "myview.button2",
176+
"when": "view == start-local-network",
177+
"group": "navigation"
168178
}
169179
],
170180
"view/item/context": [
@@ -195,7 +205,7 @@
195205
"commands": [
196206
{
197207
"command": "extension.extractFunctions",
198-
"title": "Debug-Chaincode ▶"
208+
"title": "Invoke-Chaincode ▶"
199209
},
200210
{
201211
"command": "myview.button1",
@@ -280,7 +290,6 @@
280290
"fabric-network": "^2.2.20",
281291
"fabric-protos": "^2.2.20",
282292
"js-yaml": "^4.1.0",
283-
"net": "^1.0.2",
284293
"protobufjs": "^7.4.0",
285294
"simple-git": "^3.27.0"
286295
},

0 commit comments

Comments
 (0)