运行 Solidity 合约导致“ENOENT:没有这样的文件或目录”错误

Posted

技术标签:

【中文标题】运行 Solidity 合约导致“ENOENT:没有这样的文件或目录”错误【英文标题】:Running Solidity contract results in "ENOENT: no such file or directory" error 【发布时间】:2019-03-06 01:51:10 【问题描述】:

我正在练习在 Solidity 中编写智能合约并运行下面的代码导致 没有这样的文件或目录错误。

错误:ENOENT:没有这样的文件或目录,打开 'C:\kickstart\ethereum\build:Campaign.json'

这是一个 Kickstarter 类型的合同,有多个参与者和一个经理(合同的所有者)。用户可以捐款。经理是唯一可以提款的人,但该类型的操作需要其他用户的许可。

 **Campaign.sol**
    pragma solidity ^0.4.20;

contract CampaignFactory 
    address[] public deployedCampaigns;


    function createCampaign(uint minimum) public 
     address newCampaign = new Campaign(minimum, msg.sender);
     deployedCampaigns.push(newCampaign);
    

    function getDeployedCampaigns() public view returns(address []) 
        return deployedCampaigns;
    


contract Campaign 
    struct Request 
        string description;
        uint value;
        address recipient;
        bool complete;
        uint approvalCount;
        mapping(address => bool) approvals;
            

Request[] public requests;
address public manager;

uint public minimumContribution;
//address[] public approvers; mapping has a constant time lookup
mapping(address => bool) public approvers;
uint public approversCount;

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


constructor (uint minimum, address creator) public 
    manager = creator;
    minimumContribution = minimum;


function contribute() public payable 
    require(msg.value > minimumContribution);

  approvers[msg.sender] = true;  
  approversCount++;



function createRequest(string description, uint value, address recipient) public restricted 
    Request memory newRequest = Request(
        description: description,
        value:value,
        recipient: recipient,
        complete: false,
        approvalCount:0
    );

    requests.push(newRequest);
     

     function approveRequest(uint index) public 
         Request storage request = requests[index];

         require (approvers [msg.sender]);
         require(!request.approvals[msg.sender]);

         request.approvals[msg.sender] = true;
         request.approvalCount++;



     

     function finalizeRequest(uint index) public restricted 
     Request storage request = requests[index];

     require(!request.complete);
     request.complete = true;

     
 

**compile.js**
const path = require("path");
const solc = require("solc");
//file system on local compuiter
const fs = require("fs-extra");

const buildPath = path.resolve(__dirname, "build");
// file removal in fs-extra version
fs.removeSync(buildPath);
//path to the file
const campaignPath = path.resolve(__dirname, "contracts", "Campaign.sol");
//get a content of file
const source = fs.readFileSync(campaignPath, "utf8");
// output from the compiler
const output = solc.compile(source, 1).contracts;

for (let contract in output) 
  fs.outputJsonSync(
    path.resolve(buildPath, contract + ".json"),
    output[contract]
  );

【问题讨论】:

你在用什么运行它?混音,松露,你自己的编译器?!文件 Campaign.json 怎么样,它存在吗?您是否不小心告诉编译器编译 Campaign.json 而不是 Campaign.sol?如果没有所有信息,我们将无法有效地帮助您。 我首先在 Remix 中运行它,然后在 Atom 中运行。为了更好地可视化:我的 kickstart 项目包含 ethereum 和 node_modules 文件夹。以太坊相应地持有构建和合同。我在项目的构建文件夹中有 Campaign.json。 (C:\kickstart\ethereum\build\Campaign.json)。我在合同文件夹中也有一个 Campaign.sol (C:\kickstart\ethereum\contracts\Campaign.sol)。运行 node compile.js 时出现此错误 好的,我们越来越接近能够回答这个问题了。只是为了将来帮助你,你没有回答我最重要的问题。你在用什么运行它?说你在 Remix 中运行它是一个很好的答案。但是你说你在 Atom 中运行它,但 Atom 是一个编辑器而不是一个可靠的编译器。如果我不得不从您对node compile.js 的描述中猜测,您似乎正在遵循此处描述的过程:medium.com/coinmonks/… 如果您遵循不同的说明,我需要知道。 抱歉编译器不清楚。我正在关注以太坊和 Solidty:Stephen Grider 的完整开发人员指南。 udemy.com/ethereum-and-solidity-the-complete-developers-guide 无需道歉,我很高兴我们离答案越来越近了。不幸的是,我从未使用过 Udemy,也无法访问课程资料。是否有某种类型的老师可以联系到课程以提出这个问题?如果不是,我的下一个问题是 Campain.json 的目的是什么?就我个人而言,我只使用 Remix 来满足我的 Solidity 编译需求,并且只使用 .sol 文件,没有使用 .json。 JSON 文件是否定义了依赖关系或其他内容? 【参考方案1】:

如果您更改了文件名,则需要迁移它。

npx truffle migrate --reset --compile-all

我遇到了同样的问题,这对我有用。

【讨论】:

【参考方案2】:

我遇到了同样的问题。问题是 Windows 不喜欢在文件名中包含特殊字符,在这种情况下是冒号“:”字符。

因此在输出结果时删除冒号,如下所示:

for (let contract in output) 
  fs.outputJSONSync(
    path.resolve(buildPath, contract.replace(':', '') + ".json"),
    output[contract]
  );

【讨论】:

【参考方案3】:

如果您想确保您的 compile.js 文件配置正确,请在 for 循环之前添加“console.log(solc.compile(source, 1));”并检查输出.

关于这个问题,你可以替换: path.resolve(buildPath, contract + '.json'), 和 path.resolve(buildPath, contract.replace(':', '') + '.json'),

希望这会有所帮助!

【讨论】:

【参考方案4】:

回答您的问题:Campain.json 位于构建文件夹中,包含所有 Campaign 合同实例的输出。

我能够通过执行以下步骤来修复错误:

彻底删除项目中的node_modules文件夹 运行 npm cache clean --force 命令 运行 npm install

请在下面找到该项目的链接: https://github.com/StephenGrider/EthereumCasts

【讨论】:

很高兴看到问题已解决。如果您不介意,我看到您获得了 -1 票(我提高了以抵消它;))这很可能是由于您的答案缺乏细节。如果您可以正确格式化您的数字(编辑器中应该有一个按钮),并添加您可以提供的任何信息(想想我提出的问题),那就太棒了。 请记住,您的问题及其答案不仅适用于您,也适用于未来遇到同样问题的人。当您提出或回答问题(尤其是自我回答)时,请务必牢记未来的开发者。

以上是关于运行 Solidity 合约导致“ENOENT:没有这样的文件或目录”错误的主要内容,如果未能解决你的问题,请参考以下文章

solidity 智能合约(3):使用truffle编译部署及测试合约

Solidity实现简单的智能合约

Solidity 合约不起作用

solidity合约详解

区块链开发之Solidity智能合约开发

区块链实战如何创建一个带参数的智能合约