From 1287605225bebe0e398a44d5bf9dfa475fdac7a4 Mon Sep 17 00:00:00 2001 From: cheethas Date: Thu, 25 Aug 2022 19:14:47 +0100 Subject: [PATCH 1/2] fix: Enable non mounted wsl configurations --- package-lock.json | 4 +- package.json | 2 +- src/features/debugger/debuggerUtils.js | 125 ++++++++------- src/features/debugger/function/debugger.js | 86 +++++----- src/features/debugger/macro/macroDebugger.js | 156 +++++++++---------- 5 files changed, 186 insertions(+), 187 deletions(-) diff --git a/package-lock.json b/package-lock.json index aa090d4..0acd892 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "huff-language", - "version": "0.0.22", + "version": "0.0.28", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "huff-language", - "version": "0.0.22", + "version": "0.0.28", "dependencies": { "@ethersproject/abi": "^5.6.4", "@vscode/webview-ui-toolkit": "^1.0.0", diff --git a/package.json b/package.json index c717dc6..85dd511 100644 --- a/package.json +++ b/package.json @@ -129,4 +129,4 @@ "command-exists": "^1.2.9", "keccak": "^3.0.2" } -} +} \ No newline at end of file diff --git a/src/features/debugger/debuggerUtils.js b/src/features/debugger/debuggerUtils.js index 455ff2d..2599500 100644 --- a/src/features/debugger/debuggerUtils.js +++ b/src/features/debugger/debuggerUtils.js @@ -1,8 +1,7 @@ const vscode = require("vscode"); const commandExists = require("command-exists"); const fs = require("fs"); -const {execSync, spawnSync} = require("child_process"); -const { isWsl } = require("../../settings"); +const { execSync, spawnSync } = require("child_process"); /**Deploy Contract @@ -16,30 +15,30 @@ const { isWsl } = require("../../settings"); * @returns */ function deployContract( - bytecode, - config, + bytecode, + config, cwd - ) { - if (config.stateChecked || config.storageChecked){ +) { + if (config.stateChecked || config.storageChecked) { console.log("resetting state") checkStateRepoExistence(config.statePath, cwd) } - - const statePath = `${(isWsl) ? ("/mnt/" + config.mountedDrive) : ""}${cwd}/${config.statePath}` - const command = `hevm exec --code ${bytecode} --address ${config.hevmContractAddress} --create --caller ${config.hevmCaller} --gas 0xffffffff ${(config.stateChecked || config.storageChecked) ? "--state " + statePath : ""}` + + const statePath = `${(config.mountedDrive) ? ("/mnt/" + config.mountedDrive) : ""}${cwd}/${config.statePath}` + const command = `hevm exec --code ${bytecode} --address ${config.hevmContractAddress} --create --caller ${config.hevmCaller} --gas 0xffffffff ${(config.stateChecked || config.storageChecked) ? "--state " + statePath : ""}` console.log(command) // cache command writeHevmCommand(command, config.tempHevmCommandFilename, cwd); - + // execute command // const result = execSync("`cat " + cwd + "/" + config.tempHevmCommandFilename + "`", {cwd: cwd}); const hevmCommand = craftTerminalCommand(cwd, config); - try{ + try { const result = executeCommand(cwd, command) console.log(result) return result - }catch (e) { + } catch (e) { console.log("deployment failure") console.log(e.message) console.log("e.stdout", e.stdout.toString()); @@ -57,24 +56,24 @@ function deployContract( * * @param {String} command */ -function runInUserTerminal(command){ - const terminal = vscode.window.createTerminal({name: "Huff debug"}); +function runInUserTerminal(command) { + const terminal = vscode.window.createTerminal({ name: "Huff debug" }); terminal.sendText(command); terminal.show(); - } +} -function writeHevmCommand(command, file, cwd){ - +function writeHevmCommand(command, file, cwd) { + try { !fs.accessSync(`${cwd}/cache`) } - catch (e) {fs.mkdirSync(`${cwd}/cache`) } + catch (e) { fs.mkdirSync(`${cwd}/cache`) } fs.writeFileSync(`${cwd}/${file}`, command); } -function purgeCache(cwd){ - try { fs.rmSync(`${cwd}/cache`, {recursive:true}) } - catch (e){console.log("Cache didn't exist")}; +function purgeCache(cwd) { + try { fs.rmSync(`${cwd}/cache`, { recursive: true }) } + catch (e) { console.log("Cache didn't exist") }; } function checkStateRepoExistence(statePath, cwd) { @@ -89,42 +88,42 @@ function checkStateRepoExistence(statePath, cwd) { * TODO: Windows compatibility * @param statePath */ - function resetStateRepo(statePath, cwd) { +function resetStateRepo(statePath, cwd) { console.log("Creating state repository...") const fullPath = cwd + "/" + statePath; - + // delete old state - try{ fs.rmSync(fullPath, {recursive:true}) } - catch (e){console.log("Cache didn't exist")}; + try { fs.rmSync(fullPath, { recursive: true }) } + catch (e) { console.log("Cache didn't exist") }; // check if a cache folder exists try { !fs.accessSync(`${cwd}/cache`) } - catch (e) {fs.mkdirSync(`${cwd}/cache`) } + catch (e) { fs.mkdirSync(`${cwd}/cache`) } fs.mkdirSync(fullPath); - + const initStateRepositoryCommand = `git init`; const setHuffAsCommitter = `git config user.name "huff" && git config user.email "huff"`; const initCommit = `git commit --allow-empty -m "init"`; - execSync(initStateRepositoryCommand, {cwd: fullPath}) - execSync(setHuffAsCommitter, {cwd: fullPath}) - execSync(initCommit, {cwd: fullPath}) + execSync(initStateRepositoryCommand, { cwd: fullPath }) + execSync(setHuffAsCommitter, { cwd: fullPath }) + execSync(initCommit, { cwd: fullPath }) console.log("Created state repository...") - } - +} - /**Compile - * - * @param {String} sourceDirectory The location in which the users workspace is - where the child processes should be executed - * @param {String} fileName - * @returns - */ + +/**Compile +* +* @param {String} sourceDirectory The location in which the users workspace is - where the child processes should be executed +* @param {String} fileName +* @returns +*/ function compile(sourceDirectory, fileName) { console.log("Compiling contract...") // having issues with the function level debugger const command = `huffc ${fileName} --bytecode` - const bytecode = execSync(command, {cwd: sourceDirectory}); + const bytecode = execSync(command, { cwd: sourceDirectory }); return `0x${bytecode.toString()}`; } @@ -141,13 +140,13 @@ function compile(sourceDirectory, fileName) { */ function compileFromFile(source, filename, cwd) { writeHevmCommand(source, filename, cwd); - + const command = `huffc ${filename} --bytecode` let bytecode; // if huffc is not found, then try add huffup to path try { - bytecode = execSync(command, {cwd: cwd }); + bytecode = execSync(command, { cwd: cwd }); } catch (e) { try { bytecode = executeCommand(cwd, command); @@ -156,13 +155,13 @@ function compileFromFile(source, filename, cwd) { registerError( e, "Huffc was not found in the system path, add it to $PATH or install here: https://github.com/huff-language/huff-rs" - ) + ) return false; } } // remove temp file - fs.rmSync(`${cwd}/${filename}`); + fs.rmSync(`${cwd}/${filename}`); return `0x${bytecode.toString()}`; } @@ -172,7 +171,7 @@ function compileFromFile(source, filename, cwd) { * @param {String} filename * @param {String} cwd */ -function createTempFile(source, filename, cwd){ +function createTempFile(source, filename, cwd) { fs.writeFileSync(`${cwd}/${filename}`, source); } @@ -185,11 +184,11 @@ function createTempFile(source, filename, cwd){ * @param {String} cwd * @param {String} tempMacroFilename * @param {String} macro - */ + */ function writeMacro(cwd, tempMacroFilename, macro) { fs.writeFileSync(`${cwd}/${tempMacroFilename}.huff`, macro); } - + /**Check Hevm Installation * @@ -217,7 +216,7 @@ async function checkHuffcInstallation() { * @param {*} command * @returns */ -async function checkInstallation(command){ +async function checkInstallation(command) { try { // Depending on what enviornment the code is running in, check if a command is installed if (vscode.env.remoteName === "wsl") { @@ -232,17 +231,17 @@ async function checkInstallation(command){ // Fallback to use the commandExists package await commandExists(command); return true; - } catch (e){ + } catch (e) { registerError( e, `${command} installation required - install here: ${getInstallationLink(command)}` - ) + ) return false; } } -function craftTerminalCommand(cwd, config){ - return "`cat " + ((isWsl) ? ("/mnt/" + config.mountedDrive) : "") + cwd + "/" + config.tempHevmCommandFilename + "`"; +function craftTerminalCommand(cwd, config) { + return "`cat " + ((config.mountedDrive) ? ("/mnt/" + config.mountedDrive) : "") + cwd + "/" + config.tempHevmCommandFilename + "`"; } /**Execute Command @@ -253,12 +252,12 @@ function craftTerminalCommand(cwd, config){ * @param {String} command * @returns */ -function executeCommand(cwd, command){ +function executeCommand(cwd, command) { // Depending on what enviornment the code is running in, check if a command is installed if (vscode.env.remoteName === "wsl") { // check installation using unix command executed in wsl console.log(`wsl bash -l -c "${command}"`) - + const output = spawnSync('wsl bash -l -c "' + command + '"', { shell: true, cwd @@ -270,8 +269,8 @@ function executeCommand(cwd, command){ } } const output = execSync(command, { - cwd: cwd, - env: {...process.env, PATH: `${process.env.PATH}:${process.env.HOME}/.huff/bin`} + cwd: cwd, + env: { ...process.env, PATH: `${process.env.PATH}:${process.env.HOME}/.huff/bin` } }); return output.toString(); } @@ -282,9 +281,9 @@ function executeCommand(cwd, command){ * @param {String} command * @returns {String} link */ -function getInstallationLink(command){ - switch (command){ - case ("huffc") : { +function getInstallationLink(command) { + switch (command) { + case ("huffc"): { return "https://github.com/huff-language/huff-rs"; } case ("hevm"): { @@ -301,7 +300,7 @@ function getInstallationLink(command){ * Check for both hevm and huffc installations * @returns {Promise} */ -async function checkInstallations(){ +async function checkInstallations() { const results = await Promise.all([ checkHevmInstallation(), checkHuffcInstallation @@ -326,10 +325,10 @@ async function registerError(e, message) { * @param {String} bytes */ const formatEvenBytes = (bytes) => { - if (bytes.length % 2) { - return bytes.replace("0x", "0x0"); - } - return bytes; + if (bytes.length % 2) { + return bytes.replace("0x", "0x0"); + } + return bytes; }; diff --git a/src/features/debugger/function/debugger.js b/src/features/debugger/function/debugger.js index 65a28e1..0f6ec8e 100644 --- a/src/features/debugger/function/debugger.js +++ b/src/features/debugger/function/debugger.js @@ -18,7 +18,7 @@ const { isWsl, wslMountedDriveRegex } = require("../../../settings"); * @param {Array>} argsArray Each arg is provided in the format [type, value] so that they can easily be parsed with abi encoder * @param {Object} options Options - not explicitly defined */ -async function startDebugger(sourceDirectory, currentFile, imports, functionSelector, argsArray, options={state:true}){ +async function startDebugger(sourceDirectory, currentFile, imports, functionSelector, argsArray, options = { state: true }) { try { if (!(await checkInstallations())) return; @@ -28,23 +28,23 @@ async function startDebugger(sourceDirectory, currentFile, imports, functionSele mountedDrive = wslMountedDriveRegex.exec(sourceDirectory)?.groups?.drive; sourceDirectory = sourceDirectory.replace(`/mnt/${mountedDrive}`, ""); } - const cwd = sourceDirectory.replace("/c:",""); - + const cwd = sourceDirectory.replace("/c:", ""); + // Create deterministic deployment address for each contract for the deployed contract const config = { - ...hevmConfig, + ...hevmConfig, hevmContractAddress: createKeccakHash("keccak256") .update(Buffer.from(currentFile)) .digest("hex") .toString("hex") - .slice(0,42), + .slice(0, 42), stateChecked: true, - mountedDrive + mountedDrive, } - + // Get calldata const calldata = await encodeCalldata(functionSelector, argsArray); - + // Flatten file to prevent the need to file linking -> this will be required for a wasm implementation const compilableFile = flattenFile(cwd, currentFile, imports); @@ -53,8 +53,8 @@ async function startDebugger(sourceDirectory, currentFile, imports, functionSele // Get runtime bytecode and run constructor logic const runtimeBytecode = deployContract(bytecode, config, cwd); - - runDebugger(runtimeBytecode, calldata, options, config, cwd) + + runDebugger(runtimeBytecode, calldata, options, config, cwd) } catch (e) { registerError(e, "Compilation failed, please contact the team in the huff discord"); @@ -69,19 +69,19 @@ async function startDebugger(sourceDirectory, currentFile, imports, functionSele * @param {Array} imports declared file imports at the top of the current file * @returns */ -function flattenFile(cwd, currentFile, imports){ +function flattenFile(cwd, currentFile, imports) { // Get relative path of files - const dirPath = currentFile.split("/").slice(0,-1).join("/") - + const dirPath = currentFile.split("/").slice(0, -1).join("/") + // Get absolute paths - const paths = imports.map(importPath => path.join(`${cwd}/${dirPath}`,importPath.replace(/#include\s?"/, "").replace('"', ""))); + const paths = imports.map(importPath => path.join(`${cwd}/${dirPath}`, importPath.replace(/#include\s?"/, "").replace('"', ""))); // Read file contents and remove other instances of main // main regex const mainRegex = /#define\s+macro\s+MAIN\s?\((?[^\)]*)\)\s?=\s?takes\s?\((?[\d])\)\s?returns\s?\((?[\d])\)\s?{(?[\s\S]*?(?=}))}/gsm const files = [ - fs.readFileSync(cwd+ "/" + currentFile).toString(), - ...paths.map(path => { + fs.readFileSync(cwd + "/" + currentFile).toString(), + ...paths.map(path => { return fs.readFileSync(path) .toString().replace(mainRegex, "") }) @@ -111,13 +111,13 @@ function runDebugger(bytecode, calldata, flags, config, cwd) { --address ${config.hevmContractAddress} \ --caller ${config.hevmCaller} \ --gas 0xffffffff \ - --state ${((isWsl) ? ("/mnt/" + config.mountedDrive) : "") + cwd + "/" + config.statePath} \ + --state ${((config.mountedDrive) ? ("/mnt/" + config.mountedDrive) : "") + cwd + "/" + config.statePath} \ --debug \ ${calldata ? "--calldata " + calldata : ""}` - + // command is cached into a file as execSync has a limit on the command size that it can execute - writeHevmCommand(hevmCommand, config.tempHevmCommandFilename, cwd); - const terminalCommand = craftTerminalCommand(cwd, config) + writeHevmCommand(hevmCommand, config.tempHevmCommandFilename, cwd); + const terminalCommand = craftTerminalCommand(cwd, config) runInUserTerminal(terminalCommand); } @@ -130,29 +130,29 @@ function runDebugger(bytecode, calldata, flags, config, cwd) { * @param {Array} argsObject * @returns */ -async function encodeCalldata(functionSelector, argsObject){ - console.log("Preparing debugger calldata...") - try { - if (argsObject.length == 0) return `0x${functionSelector[0]}`; - - // TODO: error handle with user prompts - const abiEncoder = new AbiCoder() - - // create interface readable by the abi encoder - let type = []; - let value = []; - argsObject.forEach(arg => { - type.push(arg[0]); - value.push(arg[1]); - }); - - const encoded = abiEncoder.encode(type,value); - - return `0x${functionSelector[0]}${encoded.slice(2, encoded.length)}` - - } catch (e){ - registerError(e, `Compilation failed\nSee\n${e}`); - } +async function encodeCalldata(functionSelector, argsObject) { + console.log("Preparing debugger calldata...") + try { + if (argsObject.length == 0) return `0x${functionSelector[0]}`; + + // TODO: error handle with user prompts + const abiEncoder = new AbiCoder() + + // create interface readable by the abi encoder + let type = []; + let value = []; + argsObject.forEach(arg => { + type.push(arg[0]); + value.push(arg[1]); + }); + + const encoded = abiEncoder.encode(type, value); + + return `0x${functionSelector[0]}${encoded.slice(2, encoded.length)}` + + } catch (e) { + registerError(e, `Compilation failed\nSee\n${e}`); + } } module.exports = { diff --git a/src/features/debugger/macro/macroDebugger.js b/src/features/debugger/macro/macroDebugger.js index 86e5fbd..b75dbf8 100644 --- a/src/features/debugger/macro/macroDebugger.js +++ b/src/features/debugger/macro/macroDebugger.js @@ -2,15 +2,15 @@ const createKeccakHash = require('keccak'); const fs = require("fs"); const { hevmConfig } = require("../../../options"); const path = require("path"); -const { - deployContract, - runInUserTerminal, - writeHevmCommand, - registerError, - compileFromFile, - checkInstallations, +const { + deployContract, + runInUserTerminal, + writeHevmCommand, + registerError, + compileFromFile, + checkInstallations, formatEvenBytes, - craftTerminalCommand, + craftTerminalCommand, } = require("../debuggerUtils"); const vscode = require("vscode"); @@ -31,28 +31,28 @@ const { isWsl, wslMountedDriveRegex } = require('../../../settings'); * @param {Object} macro Macro object - contains takes, returns and the macro body text * @param {*} argsObject The stack args provided by the user */ -async function startMacroDebugger(sourceDirectory, currentFile, imports, macro, argsObject, options){ - if (!(await checkInstallations())) return; - - // Remove /c: appended to source directory on windows systems - nodes file system apis absolutely hate it - let mountedDrive = null; - if (isWsl) { - mountedDrive = wslMountedDriveRegex.exec(sourceDirectory)?.groups?.drive; - sourceDirectory = sourceDirectory.replace(`/mnt/${mountedDrive}`, ""); - } - const cwd = sourceDirectory.replace("/c:","") - - try { - // Create deterministic deployment address for each contract - const config = { - ...hevmConfig, - ...options, - mountedDrive, - hevmContractAddress: createKeccakHash("keccak256") - .update(Buffer.from(macro.toString())) - .digest("hex") - .toString("hex") - .slice(0,42), +async function startMacroDebugger(sourceDirectory, currentFile, imports, macro, argsObject, options) { + if (!(await checkInstallations())) return; + + // Remove /c: appended to source directory on windows systems - nodes file system apis absolutely hate it + let mountedDrive = null; + if (isWsl) { + mountedDrive = wslMountedDriveRegex.exec(sourceDirectory)?.groups?.drive; + sourceDirectory = sourceDirectory.replace(`/mnt/${mountedDrive}`, ""); + } + const cwd = sourceDirectory.replace("/c:", "") + + try { + // Create deterministic deployment address for each contract + const config = { + ...hevmConfig, + ...options, + mountedDrive, + hevmContractAddress: createKeccakHash("keccak256") + .update(Buffer.from(macro.toString())) + .digest("hex") + .toString("hex") + .slice(0, 42), } // Compilable macro is the huff source code for our new macro object @@ -66,13 +66,13 @@ async function startMacroDebugger(sourceDirectory, currentFile, imports, macro, // deploy the contract to get the runtime code runMacroDebugger(bytecode, runtimeBytecode, config, cwd); - } catch (e) { - registerError(e, "Macro Compilation Error, this is pre-release software, please report this issue to the huff team in the discord"); - return null; - } - + } catch (e) { + registerError(e, "Macro Compilation Error, this is pre-release software, please report this issue to the huff team in the discord"); + return null; } +} + /**Create compiled macro * * Creates a huff file that imports all required macros and builds ONLY @@ -86,68 +86,68 @@ async function startMacroDebugger(sourceDirectory, currentFile, imports, macro, * @returns */ function createCompiledMacro(cwd, macro, argsObject, currentFile, imports) { - // get relative path, remove "/:c" appended on windows routes - const dirPath = currentFile.split("/").slice(0,-1).join("/"); - - // flatten imports - const paths = imports.map(importPath => path.join(`${cwd}/${dirPath}`,importPath.replace(/#include\s?"/, "").replace('"', ""))); - paths.push(cwd+ "/" + currentFile); - const files = paths.map(path => fs.readFileSync(path) - .toString() - .replace(/#define\s?macro\s?MAIN[\s\S]*?{[\s\S]*?}/gsm, "") // remove main - .replace(/#include\s".*"/gm, "") // remove include - ); - - // replace jump labels - let macroBody = macro.body; - const jumpLabelRegex = /<.*>/gm; - if (jumpLabelRegex.test(macroBody)) { - console.log("jump label found in macro") - macroBody = macroBody.replace(jumpLabelRegex, "error"); - macroBody += "error:\n\t0x0 dup1 stop"; - } + // get relative path, remove "/:c" appended on windows routes + const dirPath = currentFile.split("/").slice(0, -1).join("/"); + + // flatten imports + const paths = imports.map(importPath => path.join(`${cwd}/${dirPath}`, importPath.replace(/#include\s?"/, "").replace('"', ""))); + paths.push(cwd + "/" + currentFile); + const files = paths.map(path => fs.readFileSync(path) + .toString() + .replace(/#define\s?macro\s?MAIN[\s\S]*?{[\s\S]*?}/gsm, "") // remove main + .replace(/#include\s".*"/gm, "") // remove include + ); + + // replace jump labels + let macroBody = macro.body; + const jumpLabelRegex = /<.*>/gm; + if (jumpLabelRegex.test(macroBody)) { + console.log("jump label found in macro") + macroBody = macroBody.replace(jumpLabelRegex, "error"); + macroBody += "error:\n\t0x0 dup1 stop"; + } - // Main contains the debugable macro - const compilableMacro = ` + // Main contains the debugable macro + const compilableMacro = ` ${files.join("\n")} #define macro MAIN() = takes(0) returns (0) { ${argsObject.reverse().join(" ")} ${macroBody} }`; - return compilableMacro + return compilableMacro } function runMacroDebugger(bytecode, runtimeBytecode, config, cwd) { // extract state - const { - stateChecked, - hevmContractAddress, - hevmCaller, - statePath, + const { + stateChecked, + hevmContractAddress, + hevmCaller, + statePath, calldataChecked, calldataValue, storageChecked, mountedDrive - } = config; - + } = config; + const hevmCommand = `hevm exec \ --code ${runtimeBytecode.toString()} \ --address ${hevmContractAddress} \ --caller ${hevmCaller} \ --gas 0xffffffff \ - ${stateChecked || storageChecked ? "--state " + ((isWsl) ? ("/mnt/" + mountedDrive) : "") + cwd + "/" + statePath : ""} \ + ${stateChecked || storageChecked ? "--state " + ((mountedDrive) ? ("/mnt/" + mountedDrive) : "") + cwd + "/" + statePath : ""} \ ${calldataChecked ? "--calldata " + formatEvenBytes(calldataValue) : ""} \ --debug` - // command is cached into a file as execSync has a limit on the command size that it can execute - writeHevmCommand(hevmCommand, config.tempHevmCommandFilename, cwd) + // command is cached into a file as execSync has a limit on the command size that it can execute + writeHevmCommand(hevmCommand, config.tempHevmCommandFilename, cwd) - // TODO: run the debugger - attach this to a running terminal - const terminalCommand = craftTerminalCommand(cwd, config) - // "`cat " + cwd + "/" + config.tempHevmCommandFilename + "`"; - runInUserTerminal(terminalCommand); + // TODO: run the debugger - attach this to a running terminal + const terminalCommand = craftTerminalCommand(cwd, config) + // "`cat " + cwd + "/" + config.tempHevmCommandFilename + "`"; + runInUserTerminal(terminalCommand); } /**Override storage @@ -161,23 +161,23 @@ function runMacroDebugger(bytecode, runtimeBytecode, config, cwd) { */ function overrideStorage(macro, config) { // write a temp file that will set storage slots - const {stateValues} = config; + const { stateValues } = config; const constructorRegex = /#define\s+macro\s+CONSTRUCTOR\s?\((?[^\)]*)\)\s?=\s?takes\s?\((?[\d])\)\s?returns\s?\((?[\d])\)\s?{(?[\s\S]*?(?=}))/gsm const constructorMatch = constructorRegex.exec(macro); // get string of sstore overrides let overrides = ""; - for (const state of stateValues){ + for (const state of stateValues) { overrides += `${state.value} ${state.key} sstore\n` } - + // if there is a constructor if (constructorMatch) { // append overrides to the end of the constructor macro - return macro.replace(constructorRegex, constructorMatch[0] + "\n\t" + overrides); + return macro.replace(constructorRegex, constructorMatch[0] + "\n\t" + overrides); } - + // otherwise create a constructor at the end let content = ""; content = "\n#define macro CONSTRUCTOR() = takes(0) returns(0) {\n\t"; @@ -189,5 +189,5 @@ function overrideStorage(macro, config) { module.exports = { - startMacroDebugger + startMacroDebugger } \ No newline at end of file From 419a621b748250378a1d2b907917291852ed5e9f Mon Sep 17 00:00:00 2001 From: Cheethas <47148561+cheethas@users.noreply.github.com> Date: Thu, 25 Aug 2022 19:21:39 +0100 Subject: [PATCH 2/2] bump: version --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 85dd511..3ec7e55 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "huff-language", - "version": "0.0.28", + "version": "0.0.30", "displayName": "Huff", "preview": true, "icon": "resources/huff.png", @@ -129,4 +129,4 @@ "command-exists": "^1.2.9", "keccak": "^3.0.2" } -} \ No newline at end of file +}