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í payable
que 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).
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:
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.
alper
Rob Hitchens