Skip to content

Commit 5b21cad

Browse files
authored
Merge branch 'main' into main
Signed-off-by: Claudia <153988396+technomad01@users.noreply.github.com>
2 parents 8fe3de4 + 87840b4 commit 5b21cad

File tree

5 files changed

+212
-11
lines changed

5 files changed

+212
-11
lines changed

extension.js

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

@@ -36,7 +37,10 @@ function activate(context) {
3637
console.log("Fabric Debugger extension Registered");
3738

3839

39-
const fabricDebuggerPath = "C:\\Users\\chinm\\fabric-debugger";
40+
const fabricDebuggerPathNew = "C:\\Users\\chinm\\fabric-debugger";
41+
=======
42+
const fabricDebuggerPath = context.extensionPath;
43+
4044

4145
let greenButton = vscode.commands.registerCommand("myview.button1", () => {
4246
const platform = process.platform;
@@ -67,7 +71,6 @@ function activate(context) {
6771
command = `cd "${fabricDebuggerPath}" && bash local-networkdown.sh`;
6872
}
6973

70-
// Execute the command
7174
exec(command, (err, stdout, stderr) => {
7275
if (err) {
7376
vscode.window.showErrorMessage(`Error: ${stderr}`);
@@ -80,6 +83,118 @@ function activate(context) {
8083

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

84199
const hyperledgerProvider = new fabricsamples();
85200
const treeViewProviderFabric = new TreeViewProvider(
@@ -1051,6 +1166,66 @@ function activate(context) {
10511166
}
10521167
}
10531168
}
1169+
async function invokeChaincode(functionName, args) {
1170+
try {
1171+
const walletPath = path.join(os.homedir(), "wallets");
1172+
const wallet = await Wallets.newFileSystemWallet(walletPath);
1173+
1174+
1175+
if (!loadedConnectionProfile) {
1176+
vscode.window.showErrorMessage("No connection profile loaded.");
1177+
return;
1178+
}
1179+
1180+
const identities = await wallet.list();
1181+
if (!identities.length) {
1182+
vscode.window.showErrorMessage("No identities found in the wallet.");
1183+
return;
1184+
}
1185+
1186+
const identityName = identities[0];
1187+
const gateway = new Gateway();
1188+
1189+
await gateway.connect(loadedConnectionProfile, {
1190+
wallet,
1191+
identity: identityName,
1192+
discovery: { enabled: true, asLocalhost: false },
1193+
});
1194+
1195+
1196+
const channelName = Object.keys(loadedConnectionProfile.channels || {})[0];
1197+
if (!channelName) {
1198+
vscode.window.showErrorMessage("No channel found in the connection profile.");
1199+
return;
1200+
}
1201+
1202+
const chaincodes =
1203+
loadedConnectionProfile.channels[channelName]?.chaincodes || [];
1204+
if (!chaincodes.length) {
1205+
vscode.window.showErrorMessage(
1206+
`No chaincodes found for channel "${channelName}".`
1207+
);
1208+
return;
1209+
}
1210+
1211+
const chaincodeName = chaincodes[0];
1212+
const network = await gateway.getNetwork(channelName);
1213+
const contract = network.getContract(chaincodeName);
1214+
1215+
1216+
const result = await contract.submitTransaction(functionName, ...args);
1217+
vscode.window.showInformationMessage(
1218+
`Transaction invoked successfully. Result: ${result.toString()}`
1219+
);
1220+
console.log("Transaction result:", result.toString());
1221+
1222+
1223+
await gateway.disconnect();
1224+
} catch (error) {
1225+
vscode.window.showErrorMessage(`Error invoking chaincode: ${error.message}`);
1226+
console.error("Error invoking chaincode:", error);
1227+
}
1228+
}
10541229
}
10551230

10561231
function extractNetworkDetails(profile) {
@@ -1157,8 +1332,6 @@ function extractWalletDetails(walletData) {
11571332
console.warn("Missing required wallet data fields:");
11581333
}
11591334
}
1160-
return null;
1161-
}
11621335

11631336
function deactivate() {
11641337
console.log("Deactivating Fabric Debugger extension...");

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
@@ -166,6 +166,16 @@
166166
"command": "fabric-network.queryBlocks",
167167
"when": "view == blockchainExplorer",
168168
"group": "navigation"
169+
},
170+
{
171+
"command": "myview.button1",
172+
"when": "view == start-local-network",
173+
"group": "navigation"
174+
},
175+
{
176+
"command": "myview.button2",
177+
"when": "view == start-local-network",
178+
"group": "navigation"
169179
}
170180
],
171181
"view/item/context": [
@@ -196,7 +206,7 @@
196206
"commands": [
197207
{
198208
"command": "extension.extractFunctions",
199-
"title": "Debug-Chaincode ▶"
209+
"title": "Invoke-Chaincode ▶"
200210
},
201211
{
202212
"command": "myview.button1",
@@ -281,7 +291,6 @@
281291
"fabric-network": "^2.2.20",
282292
"fabric-protos": "^2.2.20",
283293
"js-yaml": "^4.1.0",
284-
"net": "^1.0.2",
285294
"protobufjs": "^7.4.0",
286295
"simple-git": "^3.27.0"
287296
},

0 commit comments

Comments
 (0)