From a4c7b3b5fcd95ba753327606fe96c8c8cdbd497f Mon Sep 17 00:00:00 2001 From: urgetolearn Date: Sat, 28 Sep 2024 23:41:32 +0530 Subject: [PATCH 1/4] extracting methods from chaincode file Signed-off-by: urgetolearn --- extension.js | 235 +++++++++++++++++++++++++++++++++++++++++++--- package-lock.json | 54 ++++++++++- package.json | 21 ++++- 3 files changed, 295 insertions(+), 15 deletions(-) diff --git a/extension.js b/extension.js index 735f818..12ae122 100644 --- a/extension.js +++ b/extension.js @@ -6,10 +6,51 @@ const vscode = require("vscode"); const fs = require("fs"); const { TreeViewProvider } = require("./src/treeview"); const { createConnectionProfileWebview } = require("./src/webview"); - +const simpleGit = require('simple-git'); +const { exec } = require('child_process'); +const path = require('path'); +const os = require('os'); const fabricsamples = require('./src/fabricsamples'); +const outputChannel = vscode.window.createOutputChannel("Function Arguments Logger"); function activate(context) { + let disposable5 = vscode.commands.registerCommand('extension.extractFunctions', function () { + const editor = vscode.window.activeTextEditor; + if (!editor) { + vscode.window.showInformationMessage('No active editor. Open a chaincode file.'); + return; + } + + const filePath = editor.document.fileName; + + + if (!isChaincodeFile(filePath)) { + vscode.window.showInformationMessage('This is not a recognized Go or Java chaincode file.'); + return; + } + + + const text = editor.document.getText(); + let functions = []; + + if (isGoChaincodeFile(filePath)) { + functions = extractGoFunctions(text); + } else if (isJavaChaincodeFile(filePath)) { + functions = extractJavaFunctions(text); + } + + const filteredFunctions = filterIntAndStringFunctions(functions); + const uniqueFunctions = [...new Set(filteredFunctions)]; + storeFunctions(uniqueFunctions, context); + + vscode.window.showInformationMessage(`Extracted and stored ${uniqueFunctions.length} unique functions with int or string parameters.`); + + + showStoredFunctions(context, outputChannel); + }); + + context.subscriptions.push(disposable5); + const hyperledgerProvider = new fabricsamples(); vscode.window.registerTreeDataProvider('start-local-network', hyperledgerProvider); const treeViewProviderFabric = new TreeViewProvider( @@ -18,20 +59,57 @@ function activate(context) { ); const treeViewProviderDesc = new TreeViewProvider("network-desc", context); const treeViewProviderWallet = new TreeViewProvider("wallets", context); - const disposable1 = vscode.commands.registerCommand( - "myview.button1", - function () { - vscode.window.showInformationMessage("Stop Network!"); - console.log("Button1"); + function runCommand(command, callback) { + const platform = os.platform(); // Detect the OS platform + + if (platform === 'win32') { + command = `bash -c "${command}"`; + } else if (platform === 'darwin' || platform === 'linux') { + // For macOS no need to modify the command } - ); - const disposable2 = vscode.commands.registerCommand( - "myview.button2", - function () { - vscode.window.showInformationMessage("Start Network!"); - console.log("Button2"); + + exec(command, (err, stdout, stderr) => { + if (err) { + console.error(`Error: ${err.message}`); + return; + } + console.log(stdout); + if (stderr) { + console.error(`Stderr: ${stderr}`); + } + if (callback) callback(); + }); + } + + function ensureRepoCloned(commandToRun) { + if (!fs.existsSync('fabric-samples')) { + console.log('Cloning the repository...'); + runCommand('git clone https://github.com/urgetolearn/fabric-samples.git', () => { + console.log('Repository cloned. Executing the next command...'); + runCommand(commandToRun); + }); + } else { + console.log('Repository already cloned. Executing the command...'); + runCommand(commandToRun); } - ); + } + + const setupNetwork = () => { + const command = 'cd fabric-samples/test-network && ./network.sh up'; + ensureRepoCloned(command); + }; + + const shutDownNetwork = () => { + const command = 'cd fabric-samples/test-network && ./network.sh down'; + ensureRepoCloned(command); + }; + + const disposableUp = vscode.commands.registerCommand('myview.button1', setupNetwork); + const disposableDown = vscode.commands.registerCommand('myview.button2', shutDownNetwork); + + context.subscriptions.push(disposableUp); + context.subscriptions.push(disposableDown); + vscode.window.createTreeView("fabric-network", { treeDataProvider: treeViewProviderFabric, }); @@ -346,7 +424,138 @@ function extractWalletsFromProfile(profile) { } return wallets; } +function isChaincodeFile(filePath) { + return isGoChaincodeFile(filePath) || isJavaChaincodeFile(filePath); +} + +function isGoChaincodeFile(filePath) { + const fileName = filePath.toLowerCase(); + return fileName.endsWith('.go'); +} + +function isJavaChaincodeFile(filePath) { + const fileName = filePath.toLowerCase(); + return fileName.endsWith('.java'); +} + +function extractGoFunctions(code) { + const functionDetails = []; + + + const regex = /func\s*\((\w+)\s+\*SmartContract\)\s*(\w+)\s*\((.*?)\)\s*(\w*)/g; + let match; + + while ((match = regex.exec(code)) !== null) { + const functionName = match[2]; + const params = match[3]; + functionDetails.push({ name: functionName, params }); + } + + return functionDetails; +} + +function extractJavaFunctions(code) { + const functionDetails = []; + + + const regex = /public\s+(\w+)\s+(\w+)\s*\((.*?)\)/g; + let match; + + while ((match = regex.exec(code)) !== null) { + const returnType = match[1]; + const functionName = match[2]; + const params = match[3]; + functionDetails.push({ name: functionName, params }); + } + + return functionDetails; +} + +function filterIntAndStringFunctions(functions) { + return functions.filter(func => /int|string/.test(func.params)).map(func => `${func.name}(${func.params})`); +} + +function storeFunctions(functions, context) { + let storedFunctions = context.workspaceState.get('storedFunctions', []); + storedFunctions = [...new Set([...storedFunctions, ...functions])]; + context.workspaceState.update('storedFunctions', storedFunctions); +} + +function showStoredFunctions(context, outputChannel) { + const storedFunctions = context.workspaceState.get('storedFunctions', []); + + vscode.window.showQuickPick(storedFunctions, { + placeHolder: 'Select a function to invoke', + canPickMany: false + }).then(selectedFunction => { + if (selectedFunction) { + vscode.window.showInformationMessage(`Selected: ${selectedFunction}`); + promptForArgumentsSequentially(selectedFunction, outputChannel); + } + }); +} + +async function promptForArgumentsSequentially(selectedFunction, outputChannel) { + const functionPattern = /(\w+)\((.*)\)/; + const match = functionPattern.exec(selectedFunction); + if (!match) { + vscode.window.showErrorMessage("Invalid function format."); + return; + } + + const functionName = match[1]; + const paramList = match[2].split(',').map(param => param.trim()); + + let argumentValues = []; + + + for (let param of paramList) { + if (/int/.test(param)) { + const input = await vscode.window.showInputBox({ prompt: `Enter an integer value for ${param}` }); + const intValue = parseInt(input, 10); + if (isNaN(intValue)) { + vscode.window.showErrorMessage(`Invalid integer value for ${param}.`); + return; + } + argumentValues.push(intValue); + } else if (/string/.test(param)) { + const input = await vscode.window.showInputBox({ prompt: `Enter a string value for ${param}` }); + if (!input) { + vscode.window.showErrorMessage(`Invalid string value for ${param}.`); + return; + } + argumentValues.push(`"${input}"`); + } + } + + + const finalArgs = argumentValues.join(', '); + outputChannel.show(); + outputChannel.appendLine(`Function: ${functionName}`); + outputChannel.appendLine(`Arguments: ${finalArgs}`); + + showInvokeCommand(functionName, argumentValues); +} + +function showInvokeCommand(functionName, argumentValues) { + const invokeCommand = `peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"${functionName}","Args":[${argumentValues.join(', ')}]}'`; + + vscode.window.showInformationMessage(`Invoke Command:\n${invokeCommand}`, 'Copy Command', 'Run Command').then(selection => { + if (selection === 'Copy Command') { + vscode.env.clipboard.writeText(invokeCommand); + vscode.window.showInformationMessage('Command copied to clipboard.'); + } else if (selection === 'Run Command') { + runInvokeCommand(invokeCommand); + } + }); +} + +function runInvokeCommand(command) { + const terminal = vscode.window.createTerminal('Chaincode Invoke'); + terminal.show(); + terminal.sendText(command); +} function extractWalletDetails(walletData) { if (walletData && walletData.name && walletData.mspId && walletData.type) { return { diff --git a/package-lock.json b/package-lock.json index 1953808..36947c5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,11 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "fabric-network": "^2.2.20" + "fabric-network": "^2.2.20", + "simple-git": "^3.26.0" + }, + "engines": { + "vscode": "^1.91.0" } }, "node_modules/@grpc/grpc-js": { @@ -41,6 +45,19 @@ "node": ">=6" } }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dependencies": { + "debug": "^4.1.1" + } + }, + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" + }, "node_modules/@protobufjs/aspromise": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", @@ -237,6 +254,22 @@ "node": ">=0.4.0" } }, + "node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, "node_modules/define-data-property": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", @@ -590,6 +623,11 @@ "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==" }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "node_modules/nan": { "version": "2.20.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", @@ -784,6 +822,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/simple-git": { + "version": "3.26.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.26.0.tgz", + "integrity": "sha512-5tbkCSzuskR6uA7uA23yjasmA0RzugVo8QM2bpsnxkrgP13eisFT7TMS4a+xKEJvbmr4qf+l0WT3eKa9IxxUyw==", + "dependencies": { + "@kwsites/file-exists": "^1.1.1", + "@kwsites/promise-deferred": "^1.1.1", + "debug": "^4.3.5" + }, + "funding": { + "type": "github", + "url": "https://github.com/steveukx/git-js?sponsor=1" + } + }, "node_modules/sjcl": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.8.tgz", diff --git a/package.json b/package.json index 70eca93..ed783a8 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,20 @@ ] }, "menus": { + "commandPalette": [ + { + "command": "extension.extractFunctions", + "when": "editorTextFocus", + "group": "navigation" + } + ], + "editor/title": [ + { + "command": "extension.extractFunctions", + "when": "resourceLangId == go", + "group": "navigation" + } + ], "view/title": [ { "command": "fabricDebugger.openFilePicker", @@ -127,6 +141,10 @@ ] }, "commands": [ + { + "command": "extension.extractFunctions", + "title": "Debug-Chaincode ▶" + }, { "command": "connectionProfile.start", "title": "Connection profile form", @@ -196,6 +214,7 @@ ] }, "dependencies": { - "fabric-network": "^2.2.20" + "fabric-network": "^2.2.20", + "simple-git": "^3.26.0" } } From 90dbef3e9ca6e897453d55fb9a583dfe67cd4592 Mon Sep 17 00:00:00 2001 From: urgetolearn Date: Sat, 5 Oct 2024 18:41:34 +0530 Subject: [PATCH 2/4] start a local-network Signed-off-by: urgetolearn --- .gitignore | 1 + extension.js | 101 ++++++++++++++++++++++--------------------- local-networkdown.sh | 11 +++++ local-networkup.sh | 12 +++++ package.json | 4 +- 5 files changed, 77 insertions(+), 52 deletions(-) create mode 100644 local-networkdown.sh create mode 100644 local-networkup.sh diff --git a/.gitignore b/.gitignore index 6289b62..458b7b6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules *.vsix .DS_Store +.hidden/ \ No newline at end of file diff --git a/extension.js b/extension.js index 12ae122..84f073a 100644 --- a/extension.js +++ b/extension.js @@ -11,9 +11,58 @@ const { exec } = require('child_process'); const path = require('path'); const os = require('os'); const fabricsamples = require('./src/fabricsamples'); +const { Console } = require("console"); const outputChannel = vscode.window.createOutputChannel("Function Arguments Logger"); function activate(context) { + const fabricDebuggerPath = 'C:\\Users\\Public\\fabric-debugger'; + + let greenButton = vscode.commands.registerCommand('myview.button1', () => { + const platform = process.platform; + const scriptUpPath = path.join(fabricDebuggerPath, 'local-networkup.sh'); + // Command to execute based on the platform + let command; + if (platform === 'win32') { + command = `wsl bash "${scriptUpPath}"`; + } else { + command = `bash "${scriptUpPath}"`; + } + + exec(command, (err, stdout, stderr) => { + if (err) { + vscode.window.showErrorMessage(`Error: ${stderr}`); + return; + } + vscode.window.showInformationMessage(`Output: ${stdout}`); + console.log("network is up and running"); + }); + }); + + // Command for the red button + let redButton = vscode.commands.registerCommand('myview.button2', () => { + const platform = process.platform; + + const scriptDownPath = path.join(fabricDebuggerPath, 'local-networkdown.sh'); + let command; + if (platform === 'win32') { + command = `wsl bash "${scriptDownPath}"`; + } else { + command = `bash "${scriptDownPath}"`; + } + + // Execute the command + exec(command, (err, stdout, stderr) => { + if (err) { + vscode.window.showErrorMessage(`Error: ${stderr}`); + return; + } + vscode.window.showInformationMessage(`Output: ${stdout}`); + console.log("network is down"); + }); + }); + + context.subscriptions.push(greenButton); + context.subscriptions.push(redButton); let disposable5 = vscode.commands.registerCommand('extension.extractFunctions', function () { const editor = vscode.window.activeTextEditor; if (!editor) { @@ -57,58 +106,10 @@ function activate(context) { "fabric-network", context ); + const treeViewProviderDesc = new TreeViewProvider("network-desc", context); const treeViewProviderWallet = new TreeViewProvider("wallets", context); - function runCommand(command, callback) { - const platform = os.platform(); // Detect the OS platform - - if (platform === 'win32') { - command = `bash -c "${command}"`; - } else if (platform === 'darwin' || platform === 'linux') { - // For macOS no need to modify the command - } - - exec(command, (err, stdout, stderr) => { - if (err) { - console.error(`Error: ${err.message}`); - return; - } - console.log(stdout); - if (stderr) { - console.error(`Stderr: ${stderr}`); - } - if (callback) callback(); - }); - } - - function ensureRepoCloned(commandToRun) { - if (!fs.existsSync('fabric-samples')) { - console.log('Cloning the repository...'); - runCommand('git clone https://github.com/urgetolearn/fabric-samples.git', () => { - console.log('Repository cloned. Executing the next command...'); - runCommand(commandToRun); - }); - } else { - console.log('Repository already cloned. Executing the command...'); - runCommand(commandToRun); - } - } - - const setupNetwork = () => { - const command = 'cd fabric-samples/test-network && ./network.sh up'; - ensureRepoCloned(command); - }; - - const shutDownNetwork = () => { - const command = 'cd fabric-samples/test-network && ./network.sh down'; - ensureRepoCloned(command); - }; - - const disposableUp = vscode.commands.registerCommand('myview.button1', setupNetwork); - const disposableDown = vscode.commands.registerCommand('myview.button2', shutDownNetwork); - - context.subscriptions.push(disposableUp); - context.subscriptions.push(disposableDown); + vscode.window.createTreeView("fabric-network", { treeDataProvider: treeViewProviderFabric, diff --git a/local-networkdown.sh b/local-networkdown.sh new file mode 100644 index 0000000..4484287 --- /dev/null +++ b/local-networkdown.sh @@ -0,0 +1,11 @@ +#!/bin/bash +if [ ! -d ".hidden/fabric-samples" ]; then + curl -sSLO https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh -o .hidden/install-fabric.sh && chmod +x .hidden/install-fabric.sh + # Clone into the hidden directory + git clone https://github.com/hyperledger/fabric-samples.git ".hidden/fabric-samples" + + # Run the install script + .hidden/install-fabric.sh docker samples binary +fi +cd .hidden/fabric-samples/test-network +./network.sh down diff --git a/local-networkup.sh b/local-networkup.sh new file mode 100644 index 0000000..d55a470 --- /dev/null +++ b/local-networkup.sh @@ -0,0 +1,12 @@ +#!/bin/bash +if [ ! -d ".hidden/fabric-samples" ]; then + curl -sSLO https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh -o .hidden/install-fabric.sh && chmod +x .hidden/install-fabric.sh + # Clone into the hidden directory + git clone https://github.com/hyperledger/fabric-samples.git ".hidden/fabric-samples" + + # Run the install script + .hidden/install-fabric.sh docker samples binary +fi +cd .hidden/fabric-samples/test-network +./network.sh up + diff --git a/package.json b/package.json index d1350ca..aa9c74f 100644 --- a/package.json +++ b/package.json @@ -205,11 +205,11 @@ }, { "command": "myview.button1", - "title": "🔴" + "title": "🟢" }, { "command": "myview.button2", - "title": "🟢" + "title": "🔴" } ] }, From 0bf9672929c7a7a212a3339e3d23e1f991206d42 Mon Sep 17 00:00:00 2001 From: urgetolearn Date: Tue, 15 Oct 2024 20:38:17 +0530 Subject: [PATCH 3/4] start a local-network Signed-off-by: urgetolearn --- extension.js | 208 ++++++++++++++++++++++++++++++++++--------- local-networkdown.sh | 11 +-- local-networkup.sh | 14 +-- package-lock.json | 8 +- package.json | 5 +- 5 files changed, 176 insertions(+), 70 deletions(-) diff --git a/extension.js b/extension.js index 84f073a..6fabdc8 100644 --- a/extension.js +++ b/extension.js @@ -11,81 +11,72 @@ const { exec } = require('child_process'); const path = require('path'); const os = require('os'); const fabricsamples = require('./src/fabricsamples'); -const { Console } = require("console"); +const { Console, log } = require("console"); const outputChannel = vscode.window.createOutputChannel("Function Arguments Logger"); +const { Gateway, Wallets } = require('fabric-network'); function activate(context) { - const fabricDebuggerPath = 'C:\\Users\\Public\\fabric-debugger'; - - let greenButton = vscode.commands.registerCommand('myview.button1', () => { + const fabricDebuggerPath = 'C:\\Users\\Public\\fabric-debugger'; + function runupBashScript() { const platform = process.platform; - const scriptUpPath = path.join(fabricDebuggerPath, 'local-networkup.sh'); - // Command to execute based on the platform - let command; + const changeDirCommand = `cd "${fabricDebuggerPath}"`; + let runScriptCommand; if (platform === 'win32') { - command = `wsl bash "${scriptUpPath}"`; + runScriptCommand = `wsl bash local-networkup.sh`; } else { - command = `bash "${scriptUpPath}"`; + runScriptCommand = `bash local-networkup.sh`; } - - exec(command, (err, stdout, stderr) => { + const fullCommand = `${changeDirCommand} && ${runScriptCommand}`; + exec(fullCommand, (err, stdout, stderr) => { if (err) { vscode.window.showErrorMessage(`Error: ${stderr}`); + console.error(`Error: ${stderr}`); return; } vscode.window.showInformationMessage(`Output: ${stdout}`); - console.log("network is up and running"); + console.log(`Output: ${stdout}`); }); + } + let greenButton = vscode.commands.registerCommand('myview.button1', () => { + runupBashScript(); }); - - // Command for the red button - let redButton = vscode.commands.registerCommand('myview.button2', () => { + context.subscriptions.push(greenButton); + function rundownBashScript() { const platform = process.platform; - - const scriptDownPath = path.join(fabricDebuggerPath, 'local-networkdown.sh'); - let command; + const changeDirCommand = `cd "${fabricDebuggerPath}"`; + let runScriptCommand; if (platform === 'win32') { - command = `wsl bash "${scriptDownPath}"`; + runScriptCommand = `wsl bash local-networkdown.sh`; } else { - command = `bash "${scriptDownPath}"`; + runScriptCommand = `bash local-networkdown.sh`; } - - // Execute the command - exec(command, (err, stdout, stderr) => { + const fullCommand = `${changeDirCommand} && ${runScriptCommand}`; + exec(fullCommand, (err, stdout, stderr) => { if (err) { vscode.window.showErrorMessage(`Error: ${stderr}`); + console.error(`Error: ${stderr}`); return; } vscode.window.showInformationMessage(`Output: ${stdout}`); - console.log("network is down"); + console.log(`Output: ${stdout}`); }); + } + let redButton = vscode.commands.registerCommand('myview.button2', () => { + rundownBashScript(); }); - - context.subscriptions.push(greenButton); context.subscriptions.push(redButton); - let disposable5 = vscode.commands.registerCommand('extension.extractFunctions', function () { + let disposable = vscode.commands.registerCommand('extension.extractFunctions', function () { const editor = vscode.window.activeTextEditor; if (!editor) { vscode.window.showInformationMessage('No active editor. Open a chaincode file.'); return; } - const filePath = editor.document.fileName; - - - if (!isChaincodeFile(filePath)) { - vscode.window.showInformationMessage('This is not a recognized Go or Java chaincode file.'); - return; - } - - const text = editor.document.getText(); let functions = []; if (isGoChaincodeFile(filePath)) { functions = extractGoFunctions(text); - } else if (isJavaChaincodeFile(filePath)) { - functions = extractJavaFunctions(text); } const filteredFunctions = filterIntAndStringFunctions(functions); @@ -94,11 +85,10 @@ function activate(context) { vscode.window.showInformationMessage(`Extracted and stored ${uniqueFunctions.length} unique functions with int or string parameters.`); - showStoredFunctions(context, outputChannel); }); - context.subscriptions.push(disposable5); + context.subscriptions.push(disposable); const hyperledgerProvider = new fabricsamples(); vscode.window.registerTreeDataProvider('start-local-network', hyperledgerProvider); @@ -109,7 +99,7 @@ function activate(context) { const treeViewProviderDesc = new TreeViewProvider("network-desc", context); const treeViewProviderWallet = new TreeViewProvider("wallets", context); - + vscode.window.createTreeView("fabric-network", { treeDataProvider: treeViewProviderFabric, @@ -391,7 +381,140 @@ function activate(context) { } ) ); + function isGoChaincodeFile(filePath) { + const fileName = filePath.toLowerCase(); + return fileName.endsWith('.go'); + } + + function extractGoFunctions(code) { + const functionDetails = []; + const regex = /func\s*\((\w+)\s+\*SmartContract\)\s*(\w+)\s*\((.*?)\)\s*(\w*)/g; + let match; + + while ((match = regex.exec(code)) !== null) { + const functionName = match[2]; + const params = match[3]; + functionDetails.push({ name: functionName, params }); + } + + return functionDetails; + } + + function filterIntAndStringFunctions(functions) { + return functions.filter(func => /int|string/.test(func.params)).map(func => `${func.name}(${func.params})`); + } + + function storeFunctions(functions, context) { + let storedFunctions = context.workspaceState.get('storedFunctions', []); + storedFunctions = [...new Set([...storedFunctions, ...functions])]; + context.workspaceState.update('storedFunctions', storedFunctions); + } + + function showStoredFunctions(context, outputChannel) { + const storedFunctions = context.workspaceState.get('storedFunctions', []); + + vscode.window.showQuickPick(storedFunctions, { + placeHolder: 'Select a function to invoke', + canPickMany: false + }).then(selectedFunction => { + if (selectedFunction) { + vscode.window.showInformationMessage(`Selected: ${selectedFunction}`); + promptForArgumentsSequentially(selectedFunction, outputChannel); + } + }); + } + + async function promptForArgumentsSequentially(selectedFunction, outputChannel) { + const functionPattern = /(\w+)\((.*)\)/; + const match = functionPattern.exec(selectedFunction); + + if (!match) { + vscode.window.showErrorMessage("Invalid function format."); + return; + } + + const functionName = match[1]; + const paramList = match[2].split(',').map(param => param.trim()); + + let argumentValues = []; + + for (let param of paramList) { + if (/int/.test(param)) { + const input = await vscode.window.showInputBox({ prompt: `Enter an integer value for ${param}` }); + const intValue = parseInt(input, 10); + if (isNaN(intValue)) { + vscode.window.showErrorMessage(`Invalid integer value for ${param}.`); + return; + } + argumentValues.push(intValue); + } else if (/string/.test(param)) { + const input = await vscode.window.showInputBox({ prompt: `Enter a string value for ${param}` }); + if (!input) { + vscode.window.showErrorMessage(`Invalid string value for ${param}.`); + return; + } + argumentValues.push(`"${input}"`); + } + } + const finalArgs = argumentValues.join(', '); + outputChannel.show(); + outputChannel.appendLine(`Function: ${functionName}`); + outputChannel.appendLine(`Arguments: ${finalArgs}`); + + + vscode.window.showInformationMessage(`Arguments captured. Press "Invoke" to execute the command.`, "Invoke").then(selection => { + if (selection === "Invoke") { + invokeCommand(functionName, argumentValues); + } + }); + } + + async function invokeCommand(functionName, argumentValues) { + try { + const { Gateway, Wallets } = require('fabric-network'); + const path = require('path'); + const fs = require('fs'); + + + const ccpPath = path.resolve(__dirname, '..', 'organizations', 'peerOrganizations', 'org1.example.com', 'connection-org1.json'); + const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8')); + + + const walletPath = path.join(process.cwd(), 'wallet'); + const wallet = await Wallets.newFileSystemWallet(walletPath); + console.log(`Wallet path: ${walletPath}`); + + + const identity = await wallet.get('appUser'); + if (!identity) { + vscode.window.showErrorMessage('An identity for the user "appUser" does not exist in the wallet. Run the registerUser.js application before retrying.'); + return; + } + + + const gateway = new Gateway(); + await gateway.connect(ccp, { wallet, identity: 'appUser', discovery: { enabled: true, asLocalhost: true } }); + + + const network = await gateway.getNetwork('mychannel'); + + + const contract = network.getContract('basic'); + + + await contract.submitTransaction(functionName, ...argumentValues); + vscode.window.showInformationMessage(`Chaincode invoke successful: ${functionName}`); + outputChannel.appendLine(`Chaincode invoke successful: ${functionName}`); + + + await gateway.disconnect(); + + } catch (error) { + vscode.window.showErrorMessage(`Failed to submit transaction: ${error}`); + console.error(`Failed to submit transaction: ${error}`); + } + } function extractNetworkDetails(profile) { const organizations = Object.keys(profile.organizations || {}); const peers = Object.values(profile.peers || {}).map((peer) => peer.url); @@ -540,7 +663,7 @@ async function promptForArgumentsSequentially(selectedFunction, outputChannel) { } function showInvokeCommand(functionName, argumentValues) { - const invokeCommand = `peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "${PWD}/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "${PWD}/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"${functionName}","Args":[${argumentValues.join(', ')}]}'`; + const invokeCommand = `peer chaincode invoke -o localhost:7050 --ordererTLSHostnameOverride orderer.example.com --tls --cafile "%CD%/organizations/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem" -C mychannel -n basic --peerAddresses localhost:7051 --tlsRootCertFiles "%CD%/organizations/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt" --peerAddresses localhost:9051 --tlsRootCertFiles "%CD%/organizations/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt" -c '{"function":"${functionName}","Args":[${argumentValues.join(', ')}]}'`; vscode.window.showInformationMessage(`Invoke Command:\n${invokeCommand}`, 'Copy Command', 'Run Command').then(selection => { if (selection === 'Copy Command') { @@ -573,4 +696,5 @@ function deactivate() { } module.exports = { activate, deactivate, + }; diff --git a/local-networkdown.sh b/local-networkdown.sh index 4484287..9c46207 100644 --- a/local-networkdown.sh +++ b/local-networkdown.sh @@ -1,11 +1,4 @@ #!/bin/bash -if [ ! -d ".hidden/fabric-samples" ]; then - curl -sSLO https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh -o .hidden/install-fabric.sh && chmod +x .hidden/install-fabric.sh - # Clone into the hidden directory - git clone https://github.com/hyperledger/fabric-samples.git ".hidden/fabric-samples" - - # Run the install script - .hidden/install-fabric.sh docker samples binary -fi -cd .hidden/fabric-samples/test-network +cd $HOME/go/src/github.com/urgetolearn +cd fabric-samples/test-network ./network.sh down diff --git a/local-networkup.sh b/local-networkup.sh index d55a470..79db847 100644 --- a/local-networkup.sh +++ b/local-networkup.sh @@ -1,12 +1,4 @@ #!/bin/bash -if [ ! -d ".hidden/fabric-samples" ]; then - curl -sSLO https://raw.githubusercontent.com/hyperledger/fabric/main/scripts/install-fabric.sh -o .hidden/install-fabric.sh && chmod +x .hidden/install-fabric.sh - # Clone into the hidden directory - git clone https://github.com/hyperledger/fabric-samples.git ".hidden/fabric-samples" - - # Run the install script - .hidden/install-fabric.sh docker samples binary -fi -cd .hidden/fabric-samples/test-network -./network.sh up - +cd $HOME/go/src/github.com/urgetolearn +cd fabric-samples/test-network +./network.sh up \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 36947c5..b30d2c2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "ISC", "dependencies": { "fabric-network": "^2.2.20", - "simple-git": "^3.26.0" + "simple-git": "^3.27.0" }, "engines": { "vscode": "^1.91.0" @@ -823,9 +823,9 @@ } }, "node_modules/simple-git": { - "version": "3.26.0", - "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.26.0.tgz", - "integrity": "sha512-5tbkCSzuskR6uA7uA23yjasmA0RzugVo8QM2bpsnxkrgP13eisFT7TMS4a+xKEJvbmr4qf+l0WT3eKa9IxxUyw==", + "version": "3.27.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.27.0.tgz", + "integrity": "sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==", "dependencies": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", diff --git a/package.json b/package.json index aa9c74f..0a1f5a1 100644 --- a/package.json +++ b/package.json @@ -214,13 +214,10 @@ ] }, "dependencies": { - "fabric-network": "^2.2.20", - "simple-git": "^3.26.0" - + "simple-git": "^3.27.0" }, "publish": { "registry": "https://npm.pkg.github.com" - } } From 2f43fe268fbc92f4a165c12f7303fffc466dae48 Mon Sep 17 00:00:00 2001 From: urgetolearn Date: Tue, 15 Oct 2024 20:56:14 +0530 Subject: [PATCH 4/4] start a local-network Signed-off-by: urgetolearn --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 458b7b6..6289b62 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ node_modules *.vsix .DS_Store -.hidden/ \ No newline at end of file