Как финансировать контракты Solidity с помощью эфира? Пример в часто задаваемых вопросах по Solidity, http://solidity.readthedocs.io/en/develop/frequently-asked-questions.html#store-ether-in-a-contract , финансирует контракт через конструктор контракта. Можно ли сделать то же самое вне конструктора?
Некоторый фон; Я хочу, чтобы контракт мог отправлять эфир на чей-то адрес через что-то вродеrecipient.send(169000000000000000000);
Во всяком случае, вот вывод из моей geth
консоли:
>eth.getBalance(eth.coinbase)
169531250000000000000
Итак, у меня есть ~169 Эфира для игры. Большой! Итак, я попробовал это:
contract A {
function fund() public {
Funded(msg.sender,msg.value);
}
}
Который я затем хотел профинансировать с помощью следующего вызова .js:
const exchangerContract = web3.eth.contract(exchangerAbi)
const contractAddress = '0x0d2bbe5af1fa1eaebc5ad6e27aa27a7328dc58bc'
const contract = exchangerContract.at(contractAddress)
contract.fund({from: web3.eth.accounts[0], value: web3.toWei(100,"ether")})
К сожалению, похоже, это не работает; При загрузке консоли получаю следующее:
>eth.getBalance('0x0d2bbe5af1fa1eaebc5ad6e27aa27a7328dc58bc')
0
Итак, задаваясь вопросом, был ли мой .js неисправен, я попробовал то же самое в консоли:
>eth.sendTransaction({from: eth.coinbase, to: '0x0d2bbe5af1fa1eaebc5ad6e27aa27a7328dc58bc', value: web3.toWei(100, "ether")})
"0x136ae6919bd2640425b03633b6709c3863d96600da6ca0c61956f694bbe62384"
>eth.getBalance('0x0d2bbe5af1fa1eaebc5ad6e27aa27a7328dc58bc')
0
Бу :( Вот тогда я и задумался, а можно ли вообще отправить Эфир! Но:
>personal.newAccount()
Passphrase:
Repeat passphrase:
"0x5e610b6696683e1c4173bd949279fd6127d8b808"
> eth.getBalance(eth.coinbase)
169531250000000000000
> eth.getBalance(eth.accounts[1])
0
> eth.sendTransaction({from: eth.coinbase, to: eth.accounts[1], value: web3.toWei(169, "ether")})
"0x136ae6919bd2640425b03633b6709c3863d96600da6ca0c61956f694bbe62384"
> eth.getBalance(eth.accounts[1])
169000000000000000000
Так что, похоже, я все-таки могу отправить эфир на неконтрактный адрес. Фу!
Как мне сделать то же самое с контрактными адресами?
Да , эфир можно отправить на контракт вне его конструктора.
Рекомендуемый способ — вызвать функцию в контракте (функция получения эфира / резервная функция) , и эта функция может делать больше, чем просто регистрировать событие .
Начиная с Solidity 0.4 , payable
модификатор должен быть прикреплен к функции или резервной функции.
Можно было бы сделать резервную функцию payable
, но это означает, что другие люди могут случайно отправить эфир на контракт. Этот вид устраняет преимущество payable
, которое Solidity добавила, чтобы контракты не должны были реализовывать свой собственный модификатор для отклонения эфира и присоединения его к большинству своих функций.
Функции, которые хотят получить эфир, должны указать новый модификатор payable (иначе они выбрасывают).
Контракты, которые хотят получить эфир с простой «отправкой», должны реализовать резервную функцию с модификатором payable. Контракты теперь выбрасываются, если не определена оплачиваемая резервная функция и ни одна функция не соответствует подписи.
светлячок
светлячок
onlyOwner
модификатор в резервную функцию (как описано здесь: solidity.readthedocs.io/en/develop/contracts.html )?эт
onlyOwner
может предотвратить отправку эфира с других адресов.