_addr.transfer(amount) 取決於消息中的值
我正在嘗試編寫一個簡單的智能合約,該合約接受少量固定的 eth 費用。我正在使用 _addr.transfer(fee) 函式,並且在施工時在契約中設置了“費用”。我發現,至少在測試套件中,如果 js 函式呼叫中沒有包含“值:somewei”,則傳輸失敗並出現恢復錯誤。如果我確實包含“value: somewei”,它會覆蓋傳遞給 transfer() 函式的“fee”參數。為什麼是這樣?
例如,合約設置如下:
... address payable public wallet; uint fee; ... function collectFee() public payable { wallet.transfer(fee); }
如果我從沒有如下值屬性的 js 測試案例中進行呼叫,則傳輸將失敗並出現一般還原原因:
let result = await myContract.collectFee( { from: fromAccount } );
如果我改為使用 value 屬性進行呼叫,則轉移成功,但會忽略契約中為“費用”設置的值:
let result = await myContract.collectFee( { from: fromAccount, value: web3.utils.toWei('10', 'ether') } );
因此,例如,如果我為“費用”實例化價值 1 乙太幣的合約,並從價值 10 乙太幣的 js 進行呼叫,則從呼叫者賬戶中扣除 10 乙太幣。
呼叫者發送的 10 個乙太幣儲存在合約本身中。
wallet
在您撥打轉接電話之前,它不會被發送到。這就是為什麼您看到從呼叫者那裡扣除了 10 個乙太幣的原因。因此,使用您的範例,呼叫者通過
collectFee
函式呼叫發送 10 個乙太幣。然後合約有 10 個乙太幣。transfer
然後呼叫該方法從合約向錢包發送 1 個乙太幣。現在合約有 9 個乙太幣,錢包有 1 個乙太幣。如果你想限制呼叫者只發送 1 個乙太幣,你需要添加一個 require 語句。
require(msg.value == 1 ether, "Value sent was greater than or less than one ether")
此外,您不應該使用轉移方法。相反,您應該使用
(bool success, ) = wallet.call{value: fee}("")
有關從合約中發送乙太幣的更多資訊,請點擊此處https://medium.com/coinmonks/solidity-transfer-vs-send-vs-call-function-64c92cfc878a