payable 修飾符
payable 方法是讓 Solidity 和以太坊變得如此酷的一部分 —— 它們是一種可以接收以太的特殊函數(shù)。
在以太坊中, 因為錢 (以太), 數(shù)據(jù) (事務(wù)負(fù)載), 以及合約代碼本身都存在于以太坊。你可以在同時調(diào)用函數(shù) 并付錢給另外一個合約。
contract OnlineStore {
function buySomething() external payable {
// 檢查以確定0.001以太發(fā)送出去來運行函數(shù):
require(msg.value == 0.001 ether);
// 如果為真,一些用來向函數(shù)調(diào)用者發(fā)送數(shù)字內(nèi)容的邏輯
transferThing(msg.sender);
}
}
在這里,msg.value 是一種可以查看向合約發(fā)送了多少以太的方法,另外 ether 是一個內(nèi)建單元。
這里發(fā)生的事是,一些人會從 web3.js 調(diào)用這個函數(shù) (從DApp的前端), 像這樣 :
// 假設(shè) `OnlineStore` 在以太坊上指向你的合約:
OnlineStore.buySomething().send(from: web3.eth.defaultAccount, value: web3.utils.toWei(0.001))
注意這個 value 字段, JavaScript 調(diào)用來指定發(fā)送多少(0.001)以太。如果把事務(wù)想象成一個信封,你發(fā)送到函數(shù)的參數(shù)就是信的內(nèi)容。 添加一個 value 很像在信封里面放錢 —— 信件內(nèi)容和錢同時發(fā)送給了接收者。
提現(xiàn)
在你發(fā)送以太之后,它將被存儲進(jìn)以合約的以太坊賬戶中, 并凍結(jié)在哪里 —— 除非你添加一個函數(shù)來從合約中把以太提現(xiàn)。
你可以寫一個函數(shù)來從合約中提現(xiàn)以太,類似這樣:
contract GetPaid is Ownable {
function withdraw() external onlyOwner {
owner.transfer(this.balance);
}
}
你可以通過 transfer 函數(shù)向一個地址發(fā)送以太, 然后 this.balance 將返回當(dāng)前合約存儲了多少以太。 所以如果100個用戶每人向我們支付1以太, this.balance 將是100以太。
你可以通過 transfer 向任何以太坊地址付錢。 比如,你可以有一個函數(shù)在 msg.sender 超額付款的時候給他們退錢:
uint itemFee = 0.001 ether;
msg.sender.transfer(msg.value - itemFee);