【问题标题】:Solidity: ParserError: Expected pragma, import directive or contract /interface/library definitionSolidity:ParserError:预期的编译指示、导入指令或合同/接口/库定义
【发布时间】:2019-05-25 06:27:40
【问题描述】:

我在编写简单合同时,最新的 solc(0.5.2 版本)和 0.4.25 都出现错误

我尝试了以下步骤

  1. 已卸载 Solc:npm uninstall solc
  2. 安装的目标版本:npm install --save solc@0.4.25
  3. node compile.js(代码如下)

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

编译.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);

收件箱.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;
    }
}

代码在 Remix 上运行良好,对于 0.5.2 版,我添加了内存标签以使其在 Remix 上编译。

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

【问题讨论】:

    标签: node.js ethereum solidity


    【解决方案1】:

    solc

    您使用 Solidity/solc v0.4.25 的主要问题是您的构造函数定义。

    您当前的构造函数定义为:

    function Inbox(string passedName) public
    

    但是,在 Solidity 中已弃用定义与合约同名的构造函数。尝试使用 constructor 关键字来定义您的构造函数。

     constructor(string passedName) public
    

    如果您使用的是 solc v0.4.25,请参阅documentation 以了解如何正确地将输入传递给compile 函数。请参阅下面的参考资料:

    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

    如果您使用的是 Solidity/solc v0.5.2,您还需要修复您的 constructor 定义。此外,您需要将memory 关键字添加到每个返回或接受string 类型的function

    例如:

    function setMessage(string newMsg) public
    

    应该声明为:

    function setMessage(string memory newMsg) public
    

    此外,请参阅latest documentation 以了解最新的 Solidity 编译器与旧版本之间的差异。有关如何使用最新编译器定义 compile 函数的输入,请参阅下面的参考:

    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)}`);
    }
    

    【讨论】:

    • 感谢 Ben 抽出宝贵时间,正如我在评论中提到的,我也厌倦了 v 5。为简洁起见,我在上面添加了 v4 代码。我仍然遇到同样的错误。
    • @yogeshsharma,请查看我的更新答案。我已经包含了solc 的旧版本和最新版本的代码示例。
    • 感谢您的时间和帮助。我会试试这个,让你知道
    【解决方案2】:

    您似乎没有正确使用 solc-js。请参阅文档:https://github.com/ethereum/solc-js

    具体来说,您需要构造一个输入对象,然后将其字符串化并将其传递给solc.compile()

    【讨论】:

    • 感谢 DAnsermino 抽出宝贵时间。我试过使用 as const res = solc.compile(JSON.stringify(inPath), 1);但它仍然给我同样的错误
    • 不能只传入路径,需要构造一个导入对象。为什么包括1?如果您阅读文档,您会看到第二个参数是导入回调的可选参数。
    【解决方案3】:

    问题是您没有以 UTF-8 编码保存合同。 解决您可以在文本编辑器中打开合同文件并将其保存为 UTF8 的问题 (你可以在 VS 代码中轻松做到)

    【讨论】:

      【解决方案4】:

      这不是你的情况,但我将把这个解决方案留给可能需要它的人。当我忘记分号';'时出现此错误在第一行的末尾pragma solidity ^0.4.25;。所以一定要检查一下。

      【讨论】:

        【解决方案5】:

        检查您的 .sol 文件是否以没有 BOM 的 UTF-8 编码。

        否则,转换为 UTF-8。

        我使用 Notepad++ 来做到这一点。

        编码 > 转换为 UTF-8

        【讨论】:

          【解决方案6】:

          当您的程序语法出现错误时,就会发生解析错误。我得到了同样的错误,因为

          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 {
                 
              }
          }
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2019-11-06
            • 1970-01-01
            • 1970-01-01
            • 2014-09-05
            • 2020-05-22
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多