У меня есть простой контракт, с которым я создал небольшое веб-приложение. Контракт заключается в следующем:
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
, но просто чтобы убедиться, что я добавил ее ко всему. Просто нужно, чтобы он снова работал.
Я все еще получаю эту ошибку с вышеуказанным (отредактированным) контрактом.
Небольшое объяснение. Я переименовал «отклонить» в «убить» и удалил подлежащие оплате функции, которые, по моему мнению, не должны его иметь.
Существует два способа внесения средств в контракт:
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);
}
}
Надеюсь, это поможет.
альпер
Роб Хитченс