node:assert:400 throw err; ^ AssertionError [ERR_ASSERTION]: Invalid callback object specified - node.js

I'm trying to run node compile.js but it's throwing me this error and idea what I am doing wrong:
node:assert:400 throw err; ^ AssertionError [ERR_ASSERTION]: Invalid callback object specified
my inbox.sol
pragma solidity ^0.8.9;
contract Inbox{
string public message;
function Inbox(string intialMessage) public {
message = intialMessage;
}
function setMessage(string newMessage) public {
message = newMessage;
}
}
my package.json
{
"dependencies": {
"ganache-cli": "^6.12.2",
"mocha": "^9.1.3",
"solc": "^0.8.9",
"web3": "^1.6.0"
}
}

Just rewrite your code like this in 'compile.js'.This work fine even in 0.8.0 version of solidity
const path = require('path');
const fs = require('fs');
const solc = require('solc');
const inboxpath = path.resolve(__dirname, 'Contracts', 'Inbox.sol');
const source = fs.readFileSync(inboxpath, 'UTF-8');
var input = {
language: 'Solidity',
sources: {
'Inbox.sol' : {
content: source
}
},
settings: {
outputSelection: {
'*': {
'*': [ '*' ]
}
}
}
};
var output = JSON.parse(solc.compile(JSON.stringify(input)));
// console.log(output.contracts['Inbox.sol']['Inbox']);
// exports.abi = output.contracts['Inbox.sol']['Inbox'].abi;
// exports.bytecode = output.contracts['Inbox.sol']['Inbox'].evm.bytecode.object;

That course is outdated, solidity version 0.6.6 is released and you better update your code to that version. if you are not a good programmer you better refund that course, cause you will encounter many problems later on, you will see some errors using meta mask and Web3. that course teachs you a lot, so i really recommend you to keep learning that course and update yourself throughout the course. this is the first problem and the solution to the updated version is this.
this will be your "inbox.sol" code:
pragma solidity ^0.6.6;
contract Inbox{
string public message;
constructor (string memory initialMessage) public{
message = initialMessage;
}
function setMessage(string memory newMessage) public{
message = newMessage;
}
}
and this will be your "compile.js" code:
const path = require('path');
const fs = require('fs');
const solc = require('solc');
const inboxpath = path.resolve(__dirname, 'Contracts', 'Inbox.sol');
const source = fs.readFileSync(inboxpath, 'UTF-8');
var input = {
language: 'Solidity',
sources: {
'Inbox.sol' : {
content: source
}
},
settings: {
outputSelection: {
'*': {
'*': [ '*' ]
}
}
}
};
var output = JSON.parse(solc.compile(JSON.stringify(input)));
exports.abi = output.contracts['Inbox.sol']['Inbox'].abi;
exports.bytecode = output.contracts['Inbox.sol'] ['Inbox'].evm.bytecode.object;
in the new solidity the compiler will give you another version of compiled code compared to old compiler, so you'll need to pass the json file to your compiler and in order to access to abi(interface) and bytecode you need to do like i did in here.

It will work with solc version 0.4.17.

Just add memory after both string which are present in function's parameters.
function Inbox(string memory initialMessage)...
AND
function setMessage(string memory newMessage)...

For the people who are here for the v0.4.17
Simply update your package.json file solc version to 0.4.17
var output = solc.compile(source,1);
console.log(output)
I guess all you have to do is rollback your complier version. You will get your output. That worked for me.

Related

Bundling node binaries with Parcel V2 (modern-syslog)

I need to add a node binary from modern-syslog package to the bundle (I need to bundle node modules into a single file). With Parcel V1 I used to do it with this code:
const { Asset } = require('parcel-bundler');
const path = require('path');
const URL = require('url');
class NodeAsset extends Asset {
load() {}
generate() {
const pathToAsset = this.urlJoin(
this.options.publicURL,
this.generateBundleName()
);
return [
{
type: 'js',
value: `module.exports=eval('require(${JSON.stringify(`.${pathToAsset}`)})');`
}
];
}
urlJoin(publicURL, assetPath) {
const url = URL.parse(publicURL, false, true);
const assetUrl = URL.parse(assetPath);
url.pathname = path.posix.join(url.pathname, assetUrl.pathname);
url.search = assetUrl.search;
url.hash = assetUrl.hash;
return URL.format(url);
}
}
module.exports = NodeAsset;
I tried to migrate this transformer to Parcel V2. I was able to add .node binary as an asset to the bundle with isIsolated option, but I wasn't able to do the eval('require trick to make it work. Do you have any ideas how to approach this problem?

Are Decorators allowed in NodeJS?

I'm trying to run the following code in NodeJS using terminal
function addStringToName(target, name, descriptor) {
const fn = descriptor.value;
descriptor.value = wrestler => {
fn.call(target, wrestler + ' is a wrestler');
};
}
class Wrestler {
#addStringToName
setName(name) {
this.name = name;
}
sayName() {
console.log(this.name);
}
}
const w = new Wrestler();
w.setName('Macho Man');
w.sayName();
Getting the following error
Can Decorators be used in NodeJS if yes what is wrong with the written code ?
Unfortunately, no. You have to use TypeScript in order to have decorators enabled. Moreover, even TypeScript doesn't support it natively. You will have to have target: "ES5" at least and "experimentalDecorators": true.
You can find more about decorators and TypeScript here: https://www.typescriptlang.org/docs/handbook/decorators.html

How to solve the error when deploying a smart contract in Ethereum?

When trying to compile the smart contract with solc-js I was getting the error
Krishna:Voting krishnakankipati$ node deploy.js
Compiling the contract
assert.js:350
throw err; ^
AssertionError [ERR_ASSERTION]: Invalid callback specified.
let compilerInput = {
'Voter': fs.readFileSync('Voter.sol', 'utf8')
};
console.log('Compiling the contract')
// Compile and optimize the contract
let compiledContract = solc.compile(compilerInput, 1);
// Get compiled contract
let contract = compiledContract.contracts['Voter:Voter'] // Voter contract from Voter file.
// Save contract's ABI
let abi = contract.interface;
fs.writeFileSync('abi.json', abi);
You aren't using solc-js correctly. You need to stringify the input, and you're passing a 1 instead of an import callback. Please read the docs before posting questions: https://github.com/ethereum/solc-js
Consider using etherjs, much better documentation and more robust than web3.
Please be sure to read the solc docs for solc v0.5.0+ to ensure you're adjusting for the changes to the Solidity compiler.
Something like this should be compatible with the latest version of solc:
// Note: You should be defining your contract sources as objects now.
// Note: You must also provide the compiler output selection as well.
const compilerInput = {
language: "Solidity",
sources: {
'Voter': { content: fs.readFileSync('Voter.sol', 'utf8') }
},
settings: {
outputSelection: {
"*": {
"*": [ "abi", "evm.bytecode" ]
}
}
}
};
console.log('Compiling the contract')
// Note: You have to pass the input in with JSON.stringify now.
const compiledContract = JSON.parse(solc.compile(JSON.stringify(compilerInput)));
if(compiledContract.errors) {
compiledContract.errors.forEach(err => console.log(err.formattedMessage));
}
// Note: This changed slightly since I'm using JSON.parse above.
const contract = compiledContract.contracts['Voter'].Voter; // Voter contract from Voter file.
// Note: This is now called 'abi' and not 'interface'
const abi = contract.abi;
fs.writeFileSync('abi.json', JSON.stringify(abi, null, 2));
You'll also need to update your deployContract function to be in sync with solc v0.5.0+
async function deployContract(web3, contract, sender) {
let Voter = new web3.eth.Contract(JSON.parse(JSON.stringify(abi)));
let bytecode = '0x' + contract.evm.bytecode.object;
let gasEstimate = await web3.eth.estimateGas({data: bytecode});
// The rest should work fine...
}

Solidity compiler - problem with HelloWorld smart contract

Im trying to run my first HelloWorld smart contract on the Enthereum network. This is my HelloWorld.sol contract.
pragma solidity ^0.5.0;
contract HelloWorld {
bytes32 message;
constructor (bytes32 myMessage) public {
message = myMessage;
}
function getMessage() public returns(bytes32) {
return message;
}
}
When I try to build this using solcjs HelloWorld.sol --bin, there is just one Warning and no errors. I have installed web3 and solc using npm. When I run this on a node
var solc = require('solc');
var x = fs.readFileSync('./HelloWorld.sol').toString();
var compiledContract = solc.compile(x);
the compiledContractcontains this:
'{"errors":[{"component":"general","formattedMessage":"* Line 1, Column 1\\n Syntax error: value, object or array expected.\\n* Line 1, Column 2\\n Extra non-whitespace after JSON value.\\n","message":"* Line 1, Column 1\\n Syntax error: value, object or array expected.\\n* Line 1, Column 2\\n Extra non-whitespace after JSON value.\\n","severity":"error","type":"JSONError"}]}'
Where is the problem?
The problem was, that you I can not put raw solidity smart contract into solc.compile() function. There must be Compiler Standard Input JSON. Based on my another thread I found this solution:
> var Web3 = require('web3');
> var solc = require('solc');
> var web3 = new Web3(new Web3.providers.HttpProvider('http://localhost:8545'));
> var CONTRACT_FILE = 'HelloWorld.sol'
> var content =fs.readFileSync(CONTRACT_FILE).toString()
> var input = {
language: 'Solidity',
sources: {
[CONTRACT_FILE]: {
content: content
}
},
settings: {
outputSelection: {
'*': {
'*': ['*']
}
}
}
}
> var compiled = solc.compile(JSON.stringify(input))
> var output = JSON.parse(compiled)
> var abi = output.contracts[CONTRACT_FILE]['HelloWorld'].abi
> var bytecode = output.contracts[CONTRACT_FILE]['HelloWorld'].evm.bytecode.object
> var HelloWorld = new web3.eth.Contract(abi);
> var HelloWorldTx = HelloWorld.deploy({data: bytecode, arguments: [web3.utils.asciiToHex('Hello')]});
> web3.eth.estimateGas(HelloWorldTx).then(console.log); //this does not work, because it can not connect to the localhost:8545. I don't know why.
> HelloWorldTx.send({from: '0x99d54a45f2cd3b9c6443d623003416aaf944338e', gas: 1000000}).then(console.log);

What version of Node does my library support?

I'm hoping for a library or a tool which will run through my code and tell me what version of Node is required in order to run it. Perhaps better would be it alerts me to areas of the code which could be changed to support older versions.
Is there anything like that in the wild?
I'm not sure if this exactly what you are looking for, but there is an existing package.json property called "engines" where package developers can specify what version(s) they require. Not too difficult to use glob and semver packages to look through all package.json files with an "engines" requirement and compile that into an object of:
{
[version1]: [{ packageName, currentlySupported }, { ... }],
[version2]: [...],
...
}
Here is a rudimentary example of a script which will create that object for you:
npm install glob semver
checkversions.js:
const glob = require('glob');
const path = require('path');
const semver = require('semver');
const currentVersion = process.version;
const versions = {};
glob('node_modules/*/package.json', (err, files) => {
files.forEach((file) => {
const pkg = require(path.resolve(__dirname, file));
// only check add package if it specifies "engines"
if (pkg.engines && pkg.engines.node) {
const reqdVersion = pkg.engines.node.replace(/\s+/g, '');
// assume you are using a supported version
let currentlySupported = true;
// check if current node version satisfies package requirements
if (!semver.satisfies(currentVersion, reqdVersion)) {
currentlySupported = false;
}
if (!Array.isArray(versions[reqdVersion])) {
versions[reqdVersion] = [];
}
versions[reqdVersion].push({
package: file.replace(/node_modules\/(.*)\/package.json/, '$1'),
currentlySupported,
});
}
});
console.log(versions);
});
Run it:
node checkversions.js

Resources