Skip to content

Commit ecf8edb

Browse files
committed
updated invoke chaincode function
Signed-off-by: urgetolearn <[email protected]>
1 parent f5d96b5 commit ecf8edb

File tree

2 files changed

+175
-3
lines changed

2 files changed

+175
-3
lines changed

extension.js

+174-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const { log } = require("console");
2626
let loadedConnectionProfile = null;
2727

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

3131
let greenButton = vscode.commands.registerCommand("myview.button1", () => {
3232
const platform = process.platform;
@@ -69,6 +69,118 @@ 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+
}
183+
72184
const hyperledgerProvider = new fabricsamples();
73185
const treeViewProviderFabric = new TreeViewProvider(
74186
"fabric-network",
@@ -702,7 +814,6 @@ function activate(context) {
702814
})
703815
);
704816

705-
706817
context.subscriptions.push(
707818
vscode.debug.registerDebugAdapterDescriptorFactory(
708819
"delve",
@@ -862,6 +973,66 @@ function activate(context) {
862973
}
863974
}
864975
}
976+
async function invokeChaincode(functionName, args) {
977+
try {
978+
const walletPath = path.join(os.homedir(), "wallets");
979+
const wallet = await Wallets.newFileSystemWallet(walletPath);
980+
981+
982+
if (!loadedConnectionProfile) {
983+
vscode.window.showErrorMessage("No connection profile loaded.");
984+
return;
985+
}
986+
987+
const identities = await wallet.list();
988+
if (!identities.length) {
989+
vscode.window.showErrorMessage("No identities found in the wallet.");
990+
return;
991+
}
992+
993+
const identityName = identities[0];
994+
const gateway = new Gateway();
995+
996+
await gateway.connect(loadedConnectionProfile, {
997+
wallet,
998+
identity: identityName,
999+
discovery: { enabled: true, asLocalhost: false },
1000+
});
1001+
1002+
1003+
const channelName = Object.keys(loadedConnectionProfile.channels || {})[0];
1004+
if (!channelName) {
1005+
vscode.window.showErrorMessage("No channel found in the connection profile.");
1006+
return;
1007+
}
1008+
1009+
const chaincodes =
1010+
loadedConnectionProfile.channels[channelName]?.chaincodes || [];
1011+
if (!chaincodes.length) {
1012+
vscode.window.showErrorMessage(
1013+
`No chaincodes found for channel "${channelName}".`
1014+
);
1015+
return;
1016+
}
1017+
1018+
const chaincodeName = chaincodes[0];
1019+
const network = await gateway.getNetwork(channelName);
1020+
const contract = network.getContract(chaincodeName);
1021+
1022+
1023+
const result = await contract.submitTransaction(functionName, ...args);
1024+
vscode.window.showInformationMessage(
1025+
`Transaction invoked successfully. Result: ${result.toString()}`
1026+
);
1027+
console.log("Transaction result:", result.toString());
1028+
1029+
1030+
await gateway.disconnect();
1031+
} catch (error) {
1032+
vscode.window.showErrorMessage(`Error invoking chaincode: ${error.message}`);
1033+
console.error("Error invoking chaincode:", error);
1034+
}
1035+
}
8651036
}
8661037

8671038
function extractNetworkDetails(profile) {
@@ -968,6 +1139,7 @@ function extractWalletDetails(walletData) {
9681139
console.warn("Missing required wallet data fields:");
9691140
}
9701141
}
1142+
9711143
return null;
9721144
}
9731145

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@
197197
"commands": [
198198
{
199199
"command": "extension.extractFunctions",
200-
"title": "Debug-Chaincode ▶"
200+
"title": "Invoke-Chaincode ▶"
201201
},
202202
{
203203
"command": "myview.button1",

0 commit comments

Comments
 (0)