Solidity/Web3.js No se puede enviar valor al constructor no pagable

Tengo un contrato simple con el que construí una pequeña aplicación web. El contrato es el siguiente:

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

Esto siempre funcionó: estoy usando MetaMask para firmar los pagos e iniciar los contratos. Desde hace una semana o algo así, recibo un error en mi consola de Web3:Cannot send value to non-payable constructor

Luego comencé a buscar en Google y descubrí payableque debía haber una función y que debería haber una función alternativa en mi contrato. Así que personalicé un poco mi contrato, esto es lo que tengo ahora:

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

Sé que no todas las funciones deberían ser payable, pero solo para estar seguro, las he agregado a todo. Solo necesito que vuelva a funcionar.

Sigo recibiendo este error con el contrato anterior (editado).

Respuestas (1)

Una pequeña explicación. Cambié el nombre de "rechazar" a "matar" y eliminé el pago de las funciones que no imagino que debería tener.

Hay dos formas de inyectar fondos en el contrato:

  1. Al implementar el contrato , agregue valor. Puede hacerlo a través de meta.mask mientras implementa el contrato.
  2. Una vez implementado , puede enviar Ether a la dirección del contrato de la misma manera que enviaría ETH a su otra billetera. No se necesita una función nombrada. Se ejecutará la función sin nombre (alternativa), que es payable.

También puede activar el respaldo desde JavaScript web3.eth.sendTransaction({from: me, to: contract, value: amount})o desde otro contrato con contractAddress.send(amount). El contrato va a ejecutar la función de reserva cuando no se especifica ninguna función o cuando la función especificada no existe.

Agregué un emisor de eventos a la función de respaldo para mostrar cómo puede usar el respaldo para algo útil. Para mantener la coherencia, también lo dejé caer en el constructor y agregué un evento similar para enviar().

Podemos decir con seguridad que la "contabilidad necesaria" (registros en este caso) se realiza para todos los fondos que llegan y salen de este contrato. Nada se colará a través de funciones como send()esas que no están diseñadas para procesar recibos.

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

}

Espero eso ayude.

Dentro de la función, ¿podría el contrato ver cuánto éter recibió? ¿Es msg.value equivalente a eso? @RobHitchens
@Avatar Sí, msg.value le dará de manera confiable el valor transferido en Wei. Es un uint256.