对Solidity不熟悉 – 需要帮助解决编译智能合约时的ParserError。

huangapple go评论53阅读模式
英文:

New to Solidity - Need Help Troubleshooting ParserError When Compiling Smart Contract

问题

I tried compile my contract for about 2 days now. I keep getting the error: ParserError: Expected pragma, import directive or contract/interface/library/struct/enum/constant/function/error definition.--> project:/contracts/Donation.sol:57:5:|57 | }| ^but i can't figure out what is wrong with my code. Anyone to assist me.

我的代码:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract DonationContract {
    struct Donation {
        string pickupAddress;
        string pickupDate;
        string pickupTime;
        string availabilityDate;
        string pickupHours;
        string itemType;
        string otherItem;
        string itemDescription;
        uint quantity;
        string requiresRefrigeration;
        string bestConsumedDate;
        string partialDonation;
    }

    Donation[] public donations;

    function createDonation(
        string memory _pickupAddress,
        string memory _pickupDate,
        string memory _pickupTime,
        string memory _availabilityDate,
        string memory _pickupHours,
        string memory _itemType,
        string memory _otherItem,
        string memory _itemDescription,
        uint _quantity,
        string memory _requiresRefrigeration,
        string memory _bestConsumedDate,
        string memory _partialDonation 
    )

    public {
        Donation memory newDonation = Donation(
            _pickupAddress,
            _pickupDate,
            _pickupTime,
            _availabilityDate,
            _pickupHours,
            _itemType,
            _otherItem,
            _itemDescription,
            _quantity,
            _requiresRefrigeration,
            _bestConsumedDate,
            _partialDonation
        );
        donations.push(newDonation);
    }
    function getDonationCount() public view returns (uint){
        return donations.length;
    }
}

trying to save the content of a form to blockchain after a user fill it. i am new solidity

英文:

I tried compile my contract for about 2 days now. I keep getting the error: ParserError: Expected pragma, import directive or contract/interface/library/struct/enum/constant/function/error definition.--> project:/contracts/Donation.sol:57:5:|57 | }| ^but i can't figure out what is wrong with my code. Anyone to assist me.

my code:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

contract DonationContract {
    struct Donation {
        string pickupAddress;
        string pickupDate;
        string pickupTime;
        string availabilityDate;
        string pickupHours;
        string itemType;
        string otherItem;
        string itemDescription;
        uint quantity;
        string requiresRefrigeration;
        string bestConsumedDate;
        string partialDonation;
    }

    Donation[] public donations;

    function createDonation(
        string memory _pickupAddress,
        string memory _pickupDate,
        string memory _pickupTime,
        string memory _availabilityDate,
        string memory _pickupHours,
        string memory _itemType,
        string memory _otherItem,
        string memory _itemDescription,
        uint _quantity,
        string memory _requiresRefrigeration,
        string memory _bestConsumedDate,
        string memory _partialDonation 
    )

    public {
        Donation memory newDonation = Donation(
            _pickupAddress,
            _pickupDate,
            _pickupTime,
            _availabilityDate,
            _pickupHours,
            _itemType,
            _otherItem,
            _itemDescription,
            _quantity,
            _requiresRefrigeration,
            _bestConsumedDate,
            _partialDonation
        );
        donations.push(newDonation);
    }
    function getDonationCount() public view returns (uint){
        return donations.length;
    }
}          
            
            
            
           
           
       

trying to save the content of a form to blockchain after a user fill it. i am new solidity

答案1

得分: 1

(1) 切换到 solc 版本 0.8.20 - 目前的最新版本。

(2) 如果您编译,您将获得不同的编译器错误:"Stack too deep."

CompilerError: Stack too deep. Try compiling with `--via-ir` (cli) or the equivalent `viaIR: true` (standard JSON) while enabling the optimizer. Otherwise, try removing local variables. When compiling inline assembly: Variable headStart is 1 slot(s) too deep inside the stack. Stack too deep. Try compiling with `--via-ir` (cli) or the equivalent `viaIR: true` (standard JSON) while enabling the optimizer. Otherwise, try removing local variables.

(3) 减小您的 createDonation 函数参数的大小以修复上述问题。存在最大可能大小,您已经超过了它。

仅注释掉其中一个似乎足以修复您的合同:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

contract DonationContract {
    struct Donation {
        // string pickupAddress;
        string pickupDate;
        string pickupTime;
        string availabilityDate;
        string pickupHours;
        string itemType;
        string otherItem;
        string itemDescription;
        uint quantity;
        string requiresRefrigeration;
        string bestConsumedDate;
        string partialDonation;
    }

    Donation[] public donations;

    function createDonation(
        // string memory _pickupAddress,
        string memory _pickupDate,
        string memory _pickupTime,
        string memory _availabilityDate,
        string memory _pickupHours,
        string memory _itemType,
        string memory _otherItem,
        string memory _itemDescription,
        uint _quantity,
        string memory _requiresRefrigeration,
        string memory _bestConsumedDate,
        string memory _partialDonation
    )

    public {
        Donation memory newDonation = Donation(
            // _pickupAddress,
            _pickupDate,
            _pickupTime,
            _availabilityDate,
            _pickupHours,
            _itemType,
            _otherItem,
            _itemDescription,
            _quantity,
            _requiresRefrigeration,
            _bestConsumedDate,
            _partialDonation
        );
        donations.push(newDonation);
    }
    function getDonationCount() public view returns (uint){
        return donations.length;
    }
}

这可以成功编译。

进一步细节

(1) 请注意,切换到 solc 的最新版本并不是绝对必要的。只是如果您要开始一个新项目的建议。

(2) 之所以有最大大小限制,是因为 EVM 堆栈只有 16 个插槽,有时不足以容纳所有变量/参数/返回值。拥有太多参数通常不被认为是良好的 Solidity 编程风格,因此应通过重构来避免。

(3) 那么在这种情况下,如何重构您的代码呢?
我建议您考虑将 string 替换为用于表示您的结构中使用的信息类型的其他数据类型。
更紧凑,更适用于您要表示的信息类型的数据类型。
例如,您可以:

  • _pickupDate_pickupTime 合并为一个 uint256,通过存储自纪元以来的秒数来实现。参见 Unix 时间
  • 对其他日期也执行相同的操作。
  • 如果 _requiresRefrigeration_partialDonation 仅为 true 或 false,则将其切换为 bool
英文:

(1) Switch to solc version 0.8.20 - the current latest.

(2) If you compile, you will get a different compiler error: "Stack too deep."

CompilerError: Stack too deep. Try compiling with `--via-ir` (cli) or the equivalent `viaIR: true` (standard JSON) while enabling the optimizer. Otherwise, try removing local variables. When compiling inline assembly: Variable headStart is 1 slot(s) too deep inside the stack. Stack too deep. Try compiling with `--via-ir` (cli) or the equivalent `viaIR: true` (standard JSON) while enabling the optimizer. Otherwise, try removing local variables.

(3) Reduce the size of your createDonation function parameters to fix the above. There is a maximum possible size, and you have exceeded it.

Commenting out just one appears to be sufficient in your contract:

// SPDX-License-Identifier: MIT
pragma solidity 0.8.20;

contract DonationContract {
    struct Donation {
        // string pickupAddress;
        string pickupDate;
        string pickupTime;
        string availabilityDate;
        string pickupHours;
        string itemType;
        string otherItem;
        string itemDescription;
        uint quantity;
        string requiresRefrigeration;
        string bestConsumedDate;
        string partialDonation;
    }

    Donation[] public donations;

    function createDonation(
        // string memory _pickupAddress,
        string memory _pickupDate,
        string memory _pickupTime,
        string memory _availabilityDate,
        string memory _pickupHours,
        string memory _itemType,
        string memory _otherItem,
        string memory _itemDescription,
        uint _quantity,
        string memory _requiresRefrigeration,
        string memory _bestConsumedDate,
        string memory _partialDonation
    )

    public {
        Donation memory newDonation = Donation(
            // _pickupAddress,
            _pickupDate,
            _pickupTime,
            _availabilityDate,
            _pickupHours,
            _itemType,
            _otherItem,
            _itemDescription,
            _quantity,
            _requiresRefrigeration,
            _bestConsumedDate,
            _partialDonation
        );
        donations.push(newDonation);
    }
    function getDonationCount() public view returns (uint){
        return donations.length;
    }
}

This does compile successfully.


Further details

(1) Note that switching to the latest version of solc isn't strictly necessary. Just a recommendation if you're starting a new project.

(2) The reason that there is a max size is that the EVM stack only has 16 slots, and that is (sometimes) insufficient to fit all the variables/ parameters/ return values. Having too many parameters is generally not considered to be good Solidity programming style, and therefore to be avoided through refactoring.

(3) So in this case, how would to refactor your code?
I would recommend instead of strings you may want to consider other
data types for the values used in your struct.
Ones that are more compact, and more specific to the types of information you are trying to represent.
For example you could:

  • Combine _pickupDate and _pickupTime into a single uint256 by using that to store the number of seconds since epoch. See Unix time.
  • Do the same for the other dates.
  • Switch _requiresRefrigeration and _partialDonation to bool if these are only true or false.

huangapple
  • 本文由 发表于 2023年5月25日 06:18:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/76327744.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定