Skip to content

made changes to local-network #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 176 additions & 15 deletions extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@ const {
const {
BlockchainTreeDataProvider,
} = require("./src/blockReader/blockchainExplorer.js");
const { log } = require("console");
let loadedConnectionProfile = null;

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

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

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

context.subscriptions.push(greenButton);
context.subscriptions.push(redButton);
const outputChannel = vscode.window.createOutputChannel("Chaincode Invocation");
let disposableExtractFunctions = 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;
const text = editor.document.getText();
let functions = [];

if (isGoChaincodeFile(filePath)) {
functions = extractGoFunctions(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(disposableExtractFunctions);
function isGoChaincodeFile(filePath) {
return filePath.toLowerCase().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") {
invokeChaincode(functionName, argumentValues);
}
});
}

factory = new DelveDebugAdapterDescriptorFactory();
context.subscriptions.push(
vscode.debug.registerDebugAdapterDescriptorFactory("delve", factory)
);
console.log("Delve Debug Adapter Registered");

const hyperledgerProvider = new fabricsamples();
const treeViewProviderFabric = new TreeViewProvider(
"fabric-network",
Expand Down Expand Up @@ -1046,6 +1157,66 @@ function activate(context) {
}
}
}
async function invokeChaincode(functionName, args) {
try {
const walletPath = path.join(os.homedir(), "wallets");
const wallet = await Wallets.newFileSystemWallet(walletPath);


if (!loadedConnectionProfile) {
vscode.window.showErrorMessage("No connection profile loaded.");
return;
}

const identities = await wallet.list();
if (!identities.length) {
vscode.window.showErrorMessage("No identities found in the wallet.");
return;
}

const identityName = identities[0];
const gateway = new Gateway();

await gateway.connect(loadedConnectionProfile, {
wallet,
identity: identityName,
discovery: { enabled: true, asLocalhost: false },
});


const channelName = Object.keys(loadedConnectionProfile.channels || {})[0];
if (!channelName) {
vscode.window.showErrorMessage("No channel found in the connection profile.");
return;
}

const chaincodes =
loadedConnectionProfile.channels[channelName]?.chaincodes || [];
if (!chaincodes.length) {
vscode.window.showErrorMessage(
`No chaincodes found for channel "${channelName}".`
);
return;
}

const chaincodeName = chaincodes[0];
const network = await gateway.getNetwork(channelName);
const contract = network.getContract(chaincodeName);


const result = await contract.submitTransaction(functionName, ...args);
vscode.window.showInformationMessage(
`Transaction invoked successfully. Result: ${result.toString()}`
);
console.log("Transaction result:", result.toString());


await gateway.disconnect();
} catch (error) {
vscode.window.showErrorMessage(`Error invoking chaincode: ${error.message}`);
console.error("Error invoking chaincode:", error);
}
}
}

function extractNetworkDetails(profile) {
Expand Down Expand Up @@ -1152,23 +1323,13 @@ function extractWalletDetails(walletData) {
console.warn("Missing required wallet data fields:");
}
}
return null;
}

function packageChaincode(chaincodePath) {
class chaincodePackager extends BasePackager {
async package(directoryPath) {
const files = fs.readdirSync(directoryPath).map((file) => path.join(directoryPath, file));
return this.generateTarGz(files);
}
}

const packager = new chaincodePackager();
return await packager.package(chaincodePath);
return null;
}

function deactivate() {}


module.exports = {
activate,
deactivate,
Expand Down
14 changes: 11 additions & 3 deletions local-networkdown.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
#!/bin/bash
cd $HOME/go/src/github.com/urgetolearn
cd fabric-samples/test-network
./network.sh down
FABRIC_SAMPLES_PATH="${HOME}/go/src/github.com/urgetolearn/fabric-samples"
if [ -n "$FABRIC_SAMPLES_CUSTOM_PATH" ]; then
FABRIC_SAMPLES_PATH="$FABRIC_SAMPLES_CUSTOM_PATH"
fi
if [ ! -d "$FABRIC_SAMPLES_PATH" ]; then
echo "Error: Fabric samples directory not found at $FABRIC_SAMPLES_PATH."
echo "Please ensure the Fabric samples are cloned from https://github.com/hyperledger/fabric-samples"
exit 1
fi
cd "$FABRIC_SAMPLES_PATH/test-network" || exit
./network.sh down
12 changes: 10 additions & 2 deletions local-networkup.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
#!/bin/bash
cd $HOME/go/src/github.com/urgetolearn
cd fabric-samples/test-network
FABRIC_SAMPLES_PATH="${HOME}/go/src/github.com/urgetolearn/fabric-samples"
if [ -n "$FABRIC_SAMPLES_CUSTOM_PATH" ]; then
FABRIC_SAMPLES_PATH="$FABRIC_SAMPLES_CUSTOM_PATH"
fi
if [ ! -d "$FABRIC_SAMPLES_PATH" ]; then
echo "Error: Fabric samples directory not found at $FABRIC_SAMPLES_PATH."
echo "Please ensure the Fabric samples are cloned from https://github.com/hyperledger/fabric-samples"
exit 1
fi
cd "$FABRIC_SAMPLES_PATH/test-network" || exit
./network.sh up
3 changes: 3 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 11 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,16 @@
"command": "fabric-network.queryBlocks",
"when": "view == blockchainExplorer",
"group": "navigation"
},
{
"command": "myview.button1",
"when": "view == start-local-network",
"group": "navigation"
},
{
"command": "myview.button2",
"when": "view == start-local-network",
"group": "navigation"
}
],
"view/item/context": [
Expand Down Expand Up @@ -195,7 +205,7 @@
"commands": [
{
"command": "extension.extractFunctions",
"title": "Debug-Chaincode ▶"
"title": "Invoke-Chaincode ▶"
},
{
"command": "myview.button1",
Expand Down Expand Up @@ -280,7 +290,6 @@
"fabric-network": "^2.2.20",
"fabric-protos": "^2.2.20",
"js-yaml": "^4.1.0",
"net": "^1.0.2",
"protobufjs": "^7.4.0",
"simple-git": "^3.27.0"
},
Expand Down
Loading