Solidity

msgSender() 這個程式碼在 OpenSea 儲存庫的範例 ERC721 中做了什麼?

  • March 6, 2022
abstract contract ContextMixin {
   function msgSender()
       internal
       view
       returns (address payable sender)
   {
       if (msg.sender == address(this)) {
           bytes memory array = msg.data;
           uint256 index = msg.data.length;
           assembly {
               // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
               sender := and(
                   mload(add(array, index)),
                   0xffffffffffffffffffffffffffffffffffffffff
               )
           }
       } else {
           sender = payable(msg.sender);
       }
       return sender;
   }
}

這是 OpenSea 特有的東西還是一般的東西?

我認為它應該用於元交易。您可以找到 OpenZeppelin 實現的類似範例,這些範例也旨在以這種方式使用。

為了支持原生元交易,OpenSea 繼承自NativeMetaTransaction執行另一個功能的合約(代錶帶有簽名的使用者),這將生成msg.sender自己的地址 ( address(this))。

(如果你不明白為什麼 msg.sender 可以是合約地址本身,請閱讀這篇文章:msg.sender == address(this) 怎麼可能?

在 OpenSea 的案例中,元事務由函式executeMetaTransactionhere執行,該函式將使用者地址作為第一個參數。所以這個_msgSender()函式基本上就是說,如果這是一個元交易,使用原始簽名者(使用者)的地址作為消息發送者,可以通過解析找到 msg.data

這就是他們如何支持一些無氣體交易的方式,您只需要簽署一個簽名,OpenSea 代理就會為您支付氣體,而契約將在您直接與其互動時工作,而無需在其中引入額外的角色契約。

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