Dapp-Development

Solidity:從簽名消息中提取數據?

  • August 18, 2019

為了降低使用者的 gas 成本,我正在尋找一種將某些交易委託給合約所有者的方法,以便所有者進行原本由使用者發送的交易。因此,使用者可以在 MetaMask 中籤署消息並將消息作為授權發送到伺服器,而不是直接向區塊鏈發送交易,假設滿足其他條件,伺服器隨後會將交易發送到區塊鏈。

但是,為了向使用者提供最大程度的保證,即只有授權交易由契約所有者處理/發送,我希望能夠在契約中解壓縮已簽名的消息,以便驗證以下內容:

  1. 使用者地址

  2. 交易數據

在高層次上,solidity 函式看起來像這樣。

function processDelegatedTransaction(
   address userAddress,
   bytes32 msgHash,
   uint8 v,
   bytes32 r,
   bytes32 s,
   uint16 param1,
   uint16 param2
) public requireOwner {

   require(userAddress == ecrecover(msgHash, v, r, s));

   // Do something else to verify that param1 and param2 are packed in msgHash
}

require語句應該處理上面的#1,但#2是問題所在。

消息簽名過程可以將多個參數編碼為單個uint,該參數將包含在散列中,然後,如果我能夠解壓縮散列,則類似於此處描述的方法對它們進行解碼:

https://medium.com/@novablitz/storing-structs-is-costing-you-gas-774da988895e

所以唯一的癥結是能夠從散列中提取參數或從參數中重新創建散列。這可能嗎?

這裡的典型解決方案是根本不接受雜湊,而只是重新創建它。像這樣的東西:

function processDelegatedTransaction(
   address userAddress,
   uint8 v,
   bytes32 r,
   bytes32 s,
   uint16 param1,
   uint16 param2
) public requireOwner {
   bytes32 msgHash = keccak256(abi.encodePacked(param1, param2));
   require(userAddress == ecrecover(msgHash, v, r, s));
}

根據您首先生成簽名的方式,您可能需要執行 EIP712 或前綴(geth/Parity 樣式)消息。對於後者,請參見此範例:

https://programtheblockchain.com/posts/2018/02/17/signing-and-verifying-messages-in-ethereum/

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