Solidity/Web3.js Не удается отправить значение бесплатному конструктору

У меня есть простой контракт, с которым я создал небольшое веб-приложение. Контракт заключается в следующем:

contract MyContract {
    address public creator;

    function MyContract() {
        creator = msg.sender;
    }

    function reject() {
        selfdestruct(creator);
    }

    function send(address target, uint256 amount) {
        if (!target.send(amount)) throw;
    }
       function destroy(address target) {

        selfdestruct(0x0000000000000000000000000000000000000000);
    }
}

Это всегда работало — я использую MetaMask для подписания платежей и заключения контрактов. Примерно через неделю я получаю сообщение об ошибке в своей консоли от Web3:Cannot send value to non-payable constructor

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

pragma solidity ^0.4.9;

contract Oursurance {
    address public creator;
    uint x;

    function() payable { x = 1; }

    function Oursurance() payable {
        creator = msg.sender;
    }

    function reject() payable {
        selfdestruct(creator);
    }

    function send(address target, uint256 amount) payable {
        if (!target.send(amount)) throw;
    }

    function destroy(address target) payable {
        selfdestruct(0x0000000000000000000000000000000000000000);
    }
}

Я знаю, что не каждая функция должна быть payable, но просто чтобы убедиться, что я добавил ее ко всему. Просто нужно, чтобы он снова работал.

Я все еще получаю эту ошибку с вышеуказанным (отредактированным) контрактом.

Ответы (1)

Небольшое объяснение. Я переименовал «отклонить» в «убить» и удалил подлежащие оплате функции, которые, по моему мнению, не должны его иметь.

Существует два способа внесения средств в контракт:

  1. При развертывании контракта добавляйте ценность. Вы можете сделать это через meta.mask при развертывании контракта.
  2. После его развертывания вы можете отправить ETH на адрес контракта так же, как вы отправляете ETH на другой кошелек. Функция с именем не требуется. Запустится безымянная (резервная) функция, которой является payable.

Вы также можете активировать откат из JavaScript web3.eth.sendTransaction({from: me, to: contract, value: amount})или другого контракта с contractAddress.send(amount). Контракт будет выполнять резервную функцию, когда функция не указана или указанная функция не существует.

Я добавил генератор событий в резервную функцию, чтобы показать, как вы можете использовать резервную копию для чего-то полезного. Для согласованности я также поместил его в конструктор и добавил аналогичное событие для send().

Можно с уверенностью сказать, что «необходимый учет» (в данном случае журналы) ведется для всех средств, которые приходят и уходят по этому контракту. Ничто не проникнет через такие функции send(), которые не предназначены для обработки квитанций.

pragma solidity ^0.4.9;
contract Oursurance {

  address public creator;

  event LogFundsReceived(address sender, uint amount);
  event LogFundsSent(address receiver, uint amount);

  function() payable {
    LogFundsReceived(msg.sender, msg.value);
  }

  function Oursurance() payable {
    creator = msg.sender;
    LogFundsReceived(msg.sender, msg.value);
  }

  function kill() {
    selfdestruct(creator);
  }

  function send(address target, uint256 amount) {
    if (!target.send(amount)) throw;
    LogFundsSent(target, amount);
  }

}

Надеюсь, это поможет.

Может ли контракт видеть внутри функции, сколько эфира он получил? Является ли msg.value эквивалентным этому? @Роб Хитченс
@Avatar Да, msg.value надежно предоставит вам значение, переданное в Wei. Это uint256.