Smart contract deployment with node is not working - node.js

I have a problem like this. I am new to blockchain development and I have created a Smart contract using solidity. To compile it and to deploy it I have created a compile.js and deploy.js file.
This is my Solidity file.
pragma solidity 0.4.20;
contract Election {
// Model a Candidate
struct Candidate {
uint id;
string name;
uint voteCount;
}
// Store accounts that have voted
mapping(address => bool) public voters;
// Store Candidates
// Fetch Candidate
mapping(uint => Candidate) public candidates;
// Store Candidates Count
uint public candidatesCount;
// voted event
event votedEvent (
uint indexed _candidateId
);
function Election () public {
addCandidate("Candidate 1");
addCandidate("Candidate 2");
}
function addCandidate (string _name) private {
candidatesCount ++;
candidates[candidatesCount] = Candidate(candidatesCount, _name, 0);
}
function vote (uint _candidateId) public {
// require that they haven't voted before
require(!voters[msg.sender]);
// require a valid candidate
require(_candidateId > 0 && _candidateId <= candidatesCount);
// record that voter has voted
voters[msg.sender] = true;
// update candidate vote Count
candidates[_candidateId].voteCount ++;
// trigger voted event
votedEvent(_candidateId);
}
}
This is my compile.js file.
const path = require('path');
const fs =require('fs');
const solc = require('solc');
const electionPath= path.resolve(__dirname,'contracts','Election.sol');
const source = fs.readFileSync(electionPath,'utf8');
module.exports = solc.compile(source,1).contracts[':Election'];
This is my deploy.js file.
const HDWalletProvider = require('truffle-hdwallet-provider');
const Web3 = require('web3');
const { interface , bytecode } = require('./compile');
const provider = new HDWalletProvider(
'retire embark gravity flight also ceiling dinr wine example slender armor rate',
'https://rinkeby.infura.io/v3/mykey'
);
const web3 = new Web3(provider);
const deploy = async () => {
const accounts = await web3.eth.getAccounts();
console.log('Attempting to deploy from account',accounts[0]);
const result = await new web3.eth.Contract(JSON.parse(interface))
.deploy({data:bytecode})
.send({gas:'1000000',from :accounts[0]});
console.log( interface );
console.log( 'contract deploy to', result.options.address);
};
deploy();
When I hit node deploy.js in the command prompt it gives me an error like this.
TypeError: Cannot destructure property `interface` of 'undefined' or 'null'.
at Object.<anonymous> (C:\Users\tharindusa\Desktop\election\deploy.js:3:34)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
at Function.Module.runMain (module.js:693:10)
at startup (bootstrap_node.js:191:16)
at bootstrap_node.js:612:3
Can someone help me to solve this problem? I search a lot but I was unable to find a suitable solution for this. Thank you.

I got the same error. I used solc.compile(source, 1).errors as Adam suggested and found a typo in the contract. You should try that.

Related

Running smart contract using Ganache-Cli, Mocha, Web3, Solc 0.8.6 compiler

Following the udemy course for learning and understanding smart contracts, I decided to create a Lottery contract using the latest solc compiler 0.8.6 as the original course contract was made using solc compiler 0.4.17
Lottery.sol
// SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.6;
contract Lottery {
address public manager;
address[] public players;
constructor() {
manager=msg.sender;
}
function enter() public payable {
require(msg.value > .01 ether);
players.push(msg.sender);
}
function random() public view returns(uint) {
return uint(keccak256 (abi.encodePacked(block.difficulty, block.timestamp, players)));
}
function pickWinner() public restricted {
uint index = random () % players.length;
payable(players[index]).transfer(address(this).balance);
players = new address[](0);
}
modifier restricted() {
require(msg.sender == manager);
_;
}
function getPlayers() public view returns(address[] memory) {
return players;
}
}
Compile.js file
const path = require('path');
const fs = require('fs');
const solc = require('solc');
const lotteryPath = path.resolve(__dirname, 'contracts', 'lottery.sol');
const source = fs.readFileSync(lotteryPath, 'UTF-8');
var input = {
language: 'Solidity',
sources: {
'lottery.sol' : {
content: source
}
},
settings: {
outputSelection: {
'*': {
'*': [ '*' ]
}
}
}
};
var output = JSON.parse(solc.compile(JSON.stringify(input)));
exports.abi = output.contracts['lottery.sol']['Lottery'].abi;
exports.bytecode = output.contracts['lottery.sol']['Lottery'].evm.bytecode.object;
Lottery.test.js (Using Mocha, Ganache-Cli, web3)
I tried to run basic commands first so i could test it and then again test it with my test conditions.
const assert = require('assert');
const ganache = require('ganache-cli');
const Web3 = require('web3');
const web3 = new Web3(ganache.provider());
const {abi, bytecode} = require('./compile');
const deploy = async () => {
const accounts = await web3.eth.getAccounts();
console.log('Attempting to deploy from account',accounts[0]);
const result = await new web3.eth.Contract(abi)
.deploy({data: '0x' + bytecode})
.send({from: accounts[0]});
console.log('contract deployed to', result);
}
deploy();
When i run npm run test, it gives me this error.
$ npm run test
> lottery#1.0.0 test C:\cygwin64\home\KKL\lottery
> mocha
Error: Cannot find module './compile'
Require stack:
- C:\cygwin64\home\KKL\lottery\test\lottery.test.js
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15)
at Function.Module._load (internal/modules/cjs/loader.js:746:27)
at Module.require (internal/modules/cjs/loader.js:974:19)
at require (internal/modules/cjs/helpers.js:92:18)
at Object.<anonymous> (C:\cygwin64\home\KKL\lottery\test\lottery.test.js:5:25)
at Module._compile (internal/modules/cjs/loader.js:1085:14)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)
at Module.load (internal/modules/cjs/loader.js:950:32)
at Function.Module._load (internal/modules/cjs/loader.js:790:14)
at ModuleWrap.<anonymous> (internal/modules/esm/translators.js:199:29)
at ModuleJob.run (internal/modules/esm/module_job.js:169:25)
at Loader.import (internal/modules/esm/loader.js:177:24)
at formattedImport (C:\cygwin64\home\KKL\lottery\node_modules\mocha\lib\esm-utils.js:7:14)
at Object.exports.requireOrImport (C:\cygwin64\home\KKL\lottery\node_modules\mocha\lib\esm-utils.js:48:32)
at Object.exports.loadFilesAsync (C:\cygwin64\home\KKL\lottery\node_modules\mocha\lib\esm-utils.js:88:20)
at singleRun (C:\cygwin64\home\KKL\lottery\node_modules\mocha\lib\cli\run-helpers.js:125:3)
at Object.exports.handler (C:\cygwin64\home\KKL\lottery\node_modules\mocha\lib\cli\run.js:366:5)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! lottery#1.0.0 test: `mocha`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the lottery#1.0.0 test script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! C:\Users\KKL\AppData\Roaming\npm-cache\_logs\2021-08-06T09_39_41_164Z-debug.log
It is my first contract, I'd really appreciate if someone helps and explains me the problem. Thank you :)
You are importing compile.jsin this line const {abi, bytecode} = require('./compile');
Looks like you are not providing a correct path of compile.js. Check where your compile.js file is in your project directory. Get the correct path of the file and then paste it.
Based on this line of code in Compile.js :
const lotteryPath = path.resolve(__dirname, 'contracts', 'lottery.sol');
this is the file structure
rootDir/contracts/Lottery.sol
I think compile.js in root directory. "./compile.js" means it is in same directory as test file:
var { abi, evm } = require("../compile.js");

Nodejs doesnt recognize async function and reference

When i run my project in terminal like this
node index.js
I get a reference error: config not defined
/home/ether/Documents/nodesendeth/index.js:6
const {asset, base, spread, allocation} = config;
^
ReferenceError: config is not defined
at tick (/home/ether/Documents/nodesendeth/index.js:6:47)
at run (/home/ether/Documents/nodesendeth/index.js:49:3)
at Object.<anonymous> (/home/ether/Documents/nodesendeth/index.js:52:1)
at Module._compile (internal/modules/cjs/loader.js:1151:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1171:10)
at Module.load (internal/modules/cjs/loader.js:1000:32)
at Function.Module._load (internal/modules/cjs/loader.js:899:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47
in my code i have assigned the config constant like this:
require('dotenv').config;
const ccxt = require('ccxt');
const axios = require('axios');
const tick = async => {
const {asset, base, spread, allocation} = config;
const market = `${asset}/${base}`;
const orders = binanceClient.fetchOpenOrders(market);
orders.forEach(async order => {
await binanceClient.cancelOrder(order.id);
});
const results = Promise.all([
axios.get('https://api.coingecko.com/api/v3/simple/price?ids=bitcoin&vs_currencies=usd'),
axios.get('https://api.coingecko.com/api/v3/simple/price?ids=tether&vs_currencies=usd')
]);
const marketPrice = results[0].data.bitcoin.usd / results[1].data.tether.usd;
const sellPrice = marketPrice * (1 + spread);
const buyPrice = marketPrice * (1 - spread);
const balances = binanceClient.fetchBalance();
const assetBalance = balances.free[asset];
const baseBalance = balances.free[base];
const sellVolume = assetBalance * allocation;
const buyVolume = (baseBalance * allocation) / marketPrice;
binanceClient.createLimitSellOrder(market, sellVolume, sellPrice);
binanceClient.createLimitBuyOrder(market, sellVolume, buyPrice);
console.log(`
New tick for ${market}...
Created limit sell order for ${sellVolume}#${sellPrice}
Create limit buy order for ${buyVolume}#${buyPrice}`)
}
const run = () => {
const config = {
asset: 'BTC',
base: 'USDT',
allocation: 0.1,
spread: 0.2,
tickInterval: 2000
};
const binanceClient = new ccxt.binance({
apiKey: process.env.API_ENV,
secret: process.env.API_SECRET,
});
tick(config, binanceClient);
setInterval(tick, config.tickInterval, config, binanceClient);
}
run()
I also got await errors saying that i need to run them in an sync function which I do.
i have removed the await keyword now but the app should run with the await kewyword because those functions are async.
Why am i getting those errors when i have a config variable aswell as an async function?
I assume that something with my async function doesnt work because it neither recognises the config constant nor the async/await calls
config is undefined in your code.
You likely meant to declare it on this line, as follows:
const config = require('dotenv').config();
...but this is only half of your problem because, furthermore, the object returned by .config() puts all the variables in a parsed property.
So for example, if your .env looked like this:
apple=red
ball=blue
...and you just logged config, you'd see this:
{ parsed: { apple: 'red', ball: 'blue' } }
Then you could write:
const {apple, ball} = require('dotenv').config().parsed;
console.log(apple, ball);
And this would write:
red blue
In your specific case, if you are expecting asset, base, spread, and allocation to be environment variables in your .env file, then you could potentially change the line to say:
const {asset, base, spread, allocation} = config.parsed;

Error: Module did not self-register. (For onoff package require)

I am trying to require the package "onoff" in js file on one of he node js project. When i run a js file i get error as below
\node_modules\bindings\bindings.js:88
throw e
^
Error: Module did not self-register.
at Object.Module._extensions..node (module.js:670:18)
at Module.load (module.js:560:32)
at tryModuleLoad (module.js:503:12)
at Function.Module._load (module.js:495:3)
at Module.require (module.js:585:17)
at require (internal/module.js:11:18)
at bindings (\node_modules\bindings\bindings.js:81:44)
at Object.<anonymous> (\node_modules\epoll\epoll.js:1:99)
at Module._compile (module.js:641:30)
at Object.Module._extensions..js (module.js:652:10)
Please help through this.
Thanks in advance
Pallavi K
I've run into this issue as well and ended up mocking the library for local development. There has been a few issues created over the years, and it seems like the author either doesn't have OSX to test or he just isn't interested in supporting OSX in general.
Issues created related to this problem:
https://github.com/fivdi/epoll/issues/12
https://github.com/fivdi/onoff/issues/69
https://github.com/fivdi/onoff/issues/106
This is the work around I have:
// GpioFactory.js
class MockGPIO {
constructor(pin, direction) {
this._value = 0;
this._direction = direction;
}
readSync() { return this._value; }
read(cb) { cb(null, this._value) }
writeSync(value) { this._value = value }
write(value, cb) {
this._value = value;
cb(null, value);
}
watch(cb) {}
unwatch(cb) {}
unwatchAll() {}
direction() { return this._direction }
setDirection(direction) { this._direction = direction}
edge() { return 0; }
setEdge(edge) {}
activeLow() { return true; }
setActiveLow(invert) {}
unexport() {}
}
MockGPIO.accessible = false;
MockGPIO.HIGH = 1;
MockGPIO.LOW = 0;
module.exports = {
create: () => {
try {
return require('onoff').Gpio;
} catch (e) {
console.error('Using mock Gpio');
return MockGPIO;
}
}
};
The actual fix is the create() method that just returns the mock class. This allows my client code to use both the same way:
const GpioFactory = require('./GpioFactory');
const Gpio = GpioFactory.create();
const garageButton = new Gpio(4, 'out');
I don't use the full API of the library, so this example is likely missing some details.
Update: 12/15/2018
I submitted a PR to allow the accessible property to work on OSX as described in the docs. Hopefully it'll get merged.
PR: https://github.com/fivdi/onoff/pull/122

Creating a PEM file from javascript looks different from Java causing a failed signature verification

I'm trying to verify a SHA1 with RSA signature with its public key, I have written the java code below which works perfectly but but javascript cannot verify when it uses same modulus and exponent which is created by crypto or ursa. though If i use it against the pem file created by java it works.
any idea or suggestion of the best way of converting the java code to javascript?
JAVA:
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.Signature;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.RSAPublicKeySpec;
import java.util.Base64;
public class Verify {
static public Boolean verifySignature(String modulus, String exponent , String encodedMsg, String encodedSignature, String signatureAlgorithm)
throws Exception {
try {
RSAPublicKeySpec senderPublicKeySpec =
new RSAPublicKeySpec(
new BigInteger(modulus, 16),
new BigInteger(exponent, 16)
);
RSAPublicKey rsaPublicKey = (RSAPublicKey) KeyFactory.getInstance(Constants.RSA_KEY).generatePublic(senderPublicKeySpec);
System.out.println("------------ pem file ----------------");
System.out.println("format:" + rsaPublicKey.getFormat());//x.509
byte[] data = rsaPublicKey.getEncoded();
rsaPublicKey.getFormat();
String base64encoded = new String(Base64.getEncoder().encode(data));
System.out.println(base64encoded);
System.out.println("----------------------------");
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initVerify(rsaPublicKey);
signature.update(encodedMsg.getBytes());
//this returns true;
return signature.verify(Base64.getDecoder().decode(encodedSignature.getBytes()));
} catch (Exception invaKeySpeExp) {
throw new Exception(invaKeySpeExp.getMessage());
}
}
Javascript:
'use strict';
var ursa = require('ursa');
function verifySignature( modulus, exponent, encodedMsg) {
var pem = fs.readFileSync('./java.pem');
var publicKeyNode = ursa.createPublicKeyFromComponents(new Buffer(modulus,'binary'), new Buffer(exponent,'binary'));
var publicKeyJava = ursa.createPublicKey(pem);
var sig = ursa.createVerifier(signatureAlgorithm);
sig.update(encodedMsg);
var successJ = sig.verify(publicKeyJava , new Buffer(encodedSignature, 'base64'), 'base64');
console.log(successJ);
var successN = sig.verify(publicKeyNode , new Buffer(encodedSignature, 'base64'), 'base64');
console.log(successN);
}
OUTPUT:
true //from verifying against PEM file created by Java
crypto.js:126 //from Verifying against modulus and exponent
return this._handle.digest(outputEncoding);
^
Error: Not initialized
at Error (native)
at Hash.digest (crypto.js:126:23)
at Object.verify (/Users/aemami/WebstormProjects/temp/node_modules/ursa/lib/ursa.js:705:39)
at verifySignature (/Users/aemami/WebstormProjects/temp/index.js:28:22)
at Object.<anonymous> (/Users/aemami/WebstormProjects/temp/index.js:64:1)
at Module._compile (module.js:460:26)
at Object.Module._extensions..js (module.js:478:10)
at Module.load (module.js:355:32)
at Function.Module._load (module.js:310:12)
at Function.Module.runMain (module.js:501:10)

Exception when attempting to wrap Buffered-writer

Disclaimer: I'm fairly new to node (but not to JavaScript).
Im just trying to write a logger class, which holds a few lines at a time in memory, then flushes to disk when its buffer is reaching capacity
Problem
Calling my logger wrapper results in an exception in buffered writer
Im sure Ive misunderstood how require() works, and also various people advised me to create the object using new chatlogs.Chatlogger() but itI dont see many other node libs using this way of working
/www/im/node_modules/buffered-writer/lib/buffered-writer.js:125
cb ();
^
TypeError: undefined is not a function
at Writer.flush (/www/nodeim/node_modules/buffered-writer/lib/buffered-writer.js:125:3)
at Chatlogger.close (/www/nodeim/helpers/chatlogs.js:27:14)
at Object.<anonymous> (/www/nodeim/app.js:76:16)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)
at startup (node.js:119:16)
at node.js:901:3
calling code...
var chatlogs = require('./helpers/chatlogs.js');
var chatlogger_obj = new chatlogs.Chatlogger();
chatlogger_obj.open("logs/log.txt");
chatlogger_obj.log("TESTING");
chatlogger_obj.close();
process.exit(0);
Wrapper class
./helpers/chatlogs.js
exports.version = '0.0.1';
var
buffer = require('buffered-writer'),
fs = require('fs');
var Chatlogger = function() {
this.handle = null,
this.filename = "",
this.dirtyops = 0;
}
Chatlogger.prototype.open = function (filename) {
//fs.unlink(filename);
this.filename = filename;
this.handle = buffer.open(filename)
.on ("error", function (error) {
//this.handle = null;
console.log (error);
});
}
Chatlogger.prototype.close = function() {
console.log("CLOSING");
this.handle.flush();
this.handle.close();
this.handle = null;
}
Chatlogger.prototype.log = function (str) {
console.log(str);
this.handle.writeln(str);
if (this.dirtyops++ > 5)
{
console.log("FLUSHING");
this.handle.flush();
this.dirtyops = 0;
}
}
module.exports.Chatlogger = Chatlogger;
I'm the author of this module. You need to pass a callback to the flush function, but you don't need to call to flush. When the buffered-writer closes or you exceed the buffer size when writing, the data is automatically flushed to disk.
Writer#flush(callback)

Resources