Solidity
將 msg.sender 轉換為“payable”的標準做法是什麼?
介紹
我正在製定一份賞金契約。這是回答賞金的人的功能。我試圖弄清楚什麼時候最好轉換為應付賬款,直覺上似乎總是保持地址類型預設並在轉移之前將其轉換會首先破壞具有類型的點。
程式碼
function answerBounty( uint _bountyId, string memory _answerId) public validateBountyArrayIndex(_bountyId) { bounties[_bountyId].hasBeenAnswered = true; bounties[_bountyId].fulfillments.push(Fulfillment(_answerId, msg.sender, block.timestamp)); uint answerIndex = bounties[_bountyId].fulfillments.length - 1; emit BountyFulfilled(_bountyId, msg.sender, _answerId, answerIndex); }
問題
我知道 msg.sender 預設類型是“地址”。如果選擇此答案,則儲存在該行契約中的 msg.sender :
bounties[_bountyId].fulfillments.push(Fulfillment(_answerId, msg.sender, block.timestamp));
將發送賞金的資金。僅從 Fulfillment 獲取地址並呼叫 .transfer() 會導致錯誤,因為 msg.sender 是類型“地址”。所以在呼叫 .transfer() 之前需要將其轉換為應付。
問題
如果我們知道它可能稍後會收到資金,最好盡快將地址轉換或聲明為應付賬款,還是在我們需要轉移資金並將其轉換為應付賬款之前等待更好?
.transfer
並且.send
已經被棄用了一段時間,由於它們的氣體有限,可能會引起頭痛。
.call
是目前推薦的方法,並且使用 .call,您不需要將地址轉換為應付例如
(bool success,) = msg.sender.call{value: _amount}("");
看媽媽;沒有鑄造!
強制轉換 msg.sender 不會更改全域變數。只有當您打算將payable(msg.sender) 的結果保存到另一個地址類型的變數中時,才會出現這個問題。在大多數情況下,這可能不值得額外的程式碼和氣體。只需在需要的時候(可能只有一次)施放它……但
.call
無論如何使用它都會成為一個有爭議的問題