2

I'm trying to compile my contract but get this error:

AssertionError [ERR_ASSERTION]: Invalid callback specified.

One answer was to change the version of the compiler but my version is up to date (0.5.0). I'm actually trying to take an old code (0.4.17) and upgrade it. Tried for 2 days and just kept failing.

Here is my contract:

pragma solidity ^0.5.0;

contract Lottery{
 address public manager;
 address payable [] public players;

 modifier restricted {
     require(msg.sender == manager);
     _;
 }

 constructor() public {
     manager = msg.sender;
 }

 function participate() public payable {
     require(msg.value > .01 ether);
     players.push(msg.sender);
 }

 function pseudoRandom() private view returns(uint){
     return uint(keccak256(abi.encodePacked(block.difficulty, now, players)));
 }

 function pickWinner() public restricted {
     require(msg.sender == manager);
     uint index = pseudoRandom() % players.length;
     address(players[index]).transfer(address(this).balance);
     (players) = new address payable[](0);
 }

 function getPlayers() public view returns(address payable[] memory){
     return players;
 }  
}

here is my package.json:

{
 "name": "lottery",
 "version": "1.0.0",
 "description": "lottery contract with Solidity",
 "main": "compile.js",
 "directories": {
   "test": "test"
 },
 "scripts": {
   "test": "mocha"
 },
 "author": "Torof",
 "license": "ISC",
 "dependencies": {
   "ganache-cli": "^6.2.1",
  "mocha": "^5.2.0",
  "save": "^2.3.2",
  "solc": "^0.5.0",
  "tar": "^4.4.8",
  "truffle": "^4.1.14",
  "truffle-hdwallet-provider": "0.0.6",
  "web3": "^1.0.0-beta.36"
}
}

and here is the compiler:

const path = require('path');
const fs = require('fs');
const solc = require('solc');            //Could the error be here ?

const lotteryPath = path.resolve(__dirname, 'contracts', 'Lottery.sol');
const source = fs.readFileSync( lotteryPath, 'utf8');

module.exports = solc.compile(source, 1).contracts[':Lottery'];


console.log(solc.compile(source, 1));

And lastly I found this err message but don't get it:

[ts]
Could not find a declaration file for module 'solc'. 
'/home/torof/desk/coding/Udemy/ETH-stephenGrider/lottery/node_modules/solc/index.js'  
implicitly has an 'any' type.
Try `npm install @types/solc` if it exists or add a new declaration (.d.ts) file containing `declare module 'solc';`
Torof
  • 227
  • 3
  • 13

3 Answers3

6

Previous versions of solc supported the style of compilation you're using, but it looks like the new versions only support standard JSON in and out. You probably want something like this:

console.log(JSON.parse(solc.compile(JSON.stringify({
  language: 'Solidity',
  sources: {
    'lottery.sol': {
      content: source,
    },
  },
  settings: {
    outputSelection: {
      '*': {
        '*': ['evm', 'bytecode'],
      },
    },
  },
}))).contracts['lottery.sol'].Lottery);
user94559
  • 59,196
  • 6
  • 103
  • 103
  • Wow thanks, finally a useful tip. But where d'you find that ? I haven't been able to find anything about how to compile in 0.5.0 – Torof Dec 05 '18 at 01:51
  • I tried the code myself, saw that the error came from the call to `solc.compile`, and then read the README and saw that syntax isn't there anymore: https://github.com/ethereum/solc-js#readme. – user94559 Dec 05 '18 at 02:09
3

Here is one way implementation for 0.5.X, together with the deploy code: This is how I compile, there is deep nesting destruction to fetch the bytecode.

const path = require('path');
const fs = require('fs');
const solc = require('solc');

const templatePath = path.resolve(__dirname, 'contracts', 'templatename.sol');
const source = fs.readFileSync(templatePath, 'utf8');

const input = {
    language: 'Solidity',
    sources: {
        'yourtemplate.sol': {
            content: source
        }
    },
    settings: {
        outputSelection: {
            '*': {
                '*': ['*']
            }
        }
    }
}

const { abi: interface, evm: { bytecode: { object } } } = JSON.parse(solc.compile(JSON.stringify(input))).contracts['yourtemplate.sol'].Templatename; // 

module.exports = { interface, object }; // object is the actual name of the bytecode

And the code for deploy:

const ganache = require('ganache-cli');
const Web3 = require('web3');
const web3 = new Web3(ganache.provider());
const { interface, object: bytecode } = require('../compile'); 
// i've renamed object with bytecode 

const accounts = await web3.eth.getAccounts();
  templatename = await new web3.eth.Contract(interface)
    .deploy({ data: bytecode, arguments: [INPUT_PARAMETER_GOES_HERE] })
    .send({ from: accounts[0], gas: '1000000' });
0

Did you try installing this package:

npm install @types/solc
itsHarshad
  • 1,519
  • 14
  • 16
  • `npm ERR! code E404 npm ERR! 404 Not Found: @types/solc@latest npm ERR! A complete log of this run can be found in: npm ERR! /home/torof/.npm/_logs/2018-12-04T05_40_55_564Z-debug.log` – Torof Dec 04 '18 at 05:43
  • Maybe try the answers here : [https://stackoverflow.com/questions/41292559/could-not-find-a-declaration-file-for-module-module-name-path-to-module-nam] – itsHarshad Dec 04 '18 at 07:09