yogesh sharma
yogesh sharma

Reputation: 81

Solidity: ParserError: Expected pragma, import directive or contract /interface/library definition

I am getting error with both latest solc (0.5.2 version) and 0.4.25 too while I am writing Simple contract

I have tried following steps

  1. uninstalled Solc: npm uninstall solc
  2. Installed targeted version: npm install --save [email protected]
  3. node compile.js (code given below)

      { contracts: {},
      errors:
       [ ':1:1: ParserError: Expected pragma, import directive or contract
     /interface/library definition.\nD:\\RND\\BlockChain\\contracts\\Inbox.sol\n^\n' ],sourceList: [ '' ],sources: {} }
    

Compile.js

const path  = require('path');
const fs = require('fs');
const solc = require('solc');
const inPath = path.resolve(__dirname,'contracts','Inbox.sol');
const src =  fs.readFileSync(inPath,'UTF-8');
const res = solc.compile(inPath, 1);

console.log(res);

Inbox.sol

pragma solidity ^0.4.25;

contract Inbox {
    string  message;


    function Inbox(string passedName) public {
        message = passedName;
    } 

    function setMessage(string newMsg) public {
        message = newMsg;
    }

    function getMessage() public view returns(string){
        return message;
    }
}

Code worked well on Remix, for version 0.5.2 I have added memory tag to make it compile on Remix.

ex:   function setMessage(string **memory** newMsg) 

Upvotes: 5

Views: 24685

Answers (7)

Priyanka Reddy
Priyanka Reddy

Reputation: 1

This may or may not apply to you, but in my case, I got this error when there was an extra single curly bracket in my code. I just aligned all my curly brackets, removed the extra one and Voila! problem solved.

Upvotes: 0

Yilmaz
Yilmaz

Reputation: 49361

Parse errors happen when you make an error in the syntax of your program. I got the same error because

contract ERC721Enumerable is ERC721{

    function totalSupply() public view returns (uint256){
        return _allTokens.length;
    }
// THIS WAS THE REASON
// this was closing contract and then outside of the contract i had function
}

    function _mint(address to, uint256 tokenId) internal override {
       
    }
}

Upvotes: 1

Moises Marques
Moises Marques

Reputation: 167

Check if your .sol file is encoded in UTF-8 without BOM.

Otherwise, convert to UTF-8.

I used Notepad++ to do that.

Encoding > Convert to UTF-8

Upvotes: 0

user0221441
user0221441

Reputation: 346

This is not the case for you, but I'm going to leave this solution here for someone who may need this. I got this error when I forgot the semicolon ';' at the end of the first line pragma solidity ^0.4.25;. So be sure to check that.

Upvotes: 9

Keyvan Gordnian
Keyvan Gordnian

Reputation: 31

The problem is that you've not save your contract in UTF-8 encoding. to solve that you can open your contract file in a text editor and just save it as UTF8 (you can easily do it in VS code)

Upvotes: 2

Ben
Ben

Reputation: 2706

solc <= v0.4.25

Your primary issue using Solidity/solc v0.4.25 is your constructor definition.

You currently have your constructor defined as:

function Inbox(string passedName) public

However, defining constructors with the same name as the contract has been deprecated in Solidity. Try defining your constructor using the constructor keyword instead.

 constructor(string passedName) public

If you are using solc v0.4.25, please refer to the documentation in order to understand how to properly pass input to the compile function. See my reference below:

const input = { 
    'Inbox.sol': fs.readFileSync(path.resolve(__dirname, 'contracts', 'Inbox.sol'), 'utf8') 
}
const output= solc.compile({sources: input}, 1);

if(output.errors) {
    output.errors.forEach(err => {
        console.log(err);
    });
} else {
    const bytecode = output.contracts['Inbox.sol:Inbox'].bytecode;
    const abi = output.contracts['Inbox.sol:Inbox'].interface;
    console.log(`bytecode: ${bytecode}`);
    console.log(`abi: ${JSON.stringify(JSON.parse(abi), null, 2)}`);
}

solc >= v0.5.0

If you are using Solidity/solc v0.5.2, you will also need to fix your constructor definition. Furthermore, you will need to add the memory keyword to each function that returns or accepts the string type.

For example:

function setMessage(string newMsg) public

should be declared as:

function setMessage(string memory newMsg) public

Futhermore, please see the latest documentation in order to understand the differences between the latest Solidity compiler and the older version. See my reference below for how to define the input for the compile function utilizing the latest compiler:

const input = { 
    language: "Solidity",
    sources: {
        "Inbox.sol": {
            content: fs.readFileSync(path.resolve(__dirname, "contracts", "Inbox.sol"), "utf8") 
        }
    },
    settings: {
        outputSelection: {
            "*": {
                "*": [ "abi", "evm.bytecode" ]
            }
        }
    }
}
const output = JSON.parse(solc.compile(JSON.stringify(input)));

if(output.errors) {
    output.errors.forEach(err => {
        console.log(err.formattedMessage);
    });
} else {
    const bytecode = output.contracts['Inbox.sol'].Inbox.evm.bytecode.object;
    const abi = output.contracts['Inbox.sol'].Inbox.abi;
    console.log(`bytecode: ${bytecode}`);
    console.log(`abi: ${JSON.stringify(abi, null, 2)}`);
}

Upvotes: 3

DAnsermino
DAnsermino

Reputation: 383

You don't seem to be using solc-js correctly. Please see the documentation: https://github.com/ethereum/solc-js

Specifically, you need to construct an input object and then stringify it and pass that to solc.compile().

Upvotes: 0

Related Questions