Как устранить эту ошибку в надежности "Конструктор должен быть платным, если вы отправляете значение."? - PullRequest
1 голос
/ 22 января 2020

В этом коде солидности finalizeRequest() дает ошибку во время выполнения. Вот ошибка:

Campaign.finalizeRequest(uint256) 0x692...77b3a

transact to Campaign.finalizeRequest errored: VM error: revert.
revert  The transaction has been reverted to the initial state.
Note: The constructor should be payable if you send value.  Debug the transaction to get more information.

Вот код:

pragma solidity ^0.4.17;

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

    address public manager;
    uint public minimumContribution;
    // address[] public approvers;
    mapping (address => bool) public approvers;
    Request[] public requests;
    uint public approversCount;


    function Campaign(uint minimum) public {
        manager=msg.sender;
        minimumContribution=minimum;
    }

    function contribute() public payable {
        require(msg.value>minimumContribution);
        // approvers.push(msg.sender);
        approvers[msg.sender]=true;
        approversCount++;
    }

    function createRequest(string description,uint value,address  recipient) public restricted {
        // require (approvers[msg.sender]);    
        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.approvalCount>=(approversCount/2));
        require(!request.complete);
        request.recipient.transfer(request.value);
        request.complete=true;

    } 

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

Насколько я мог отладить, когда я комментирую request.recipient.transfer(request.value); в функции finalizeRequest() нет времени выполнения ошибка брошена. Так что, похоже, ошибка в этой строке кода.

1 Ответ

1 голос
/ 22 января 2020

Насколько я вижу, ваша finalizeRequest() функция состоит из передачи эфира, как определено request.recipient.transfer(request.value);, поэтому вам нужно сделать finalizeRequest() как payable.

заменить finalizeRequest() на:

function finalizeRequest(uint index) public restricted payable {
    Request storage request = requests[index];
    require(request.approvalCount>=(approversCount/2));
    require(!request.complete);
    request.recipient.transfer(request.value);
    request.complete=true;
} 

Правило большого пальца: Всякий раз, когда вы отправляете или получаете эфир в любой функции, пометьте его как payable.

Причина, по которой вам нужно ключевое слово payable, хорошо объяснена здесь .

...