Ether

_addr.transfer(amount) 取決於消息中的值

  • February 28, 2022

我正在嘗試編寫一個簡單的智能合約,該合約接受少量固定的 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

引用自:https://ethereum.stackexchange.com/questions/122808