Dapp-Development
Solidity:從簽名消息中提取數據?
為了降低使用者的 gas 成本,我正在尋找一種將某些交易委託給合約所有者的方法,以便所有者進行原本由使用者發送的交易。因此,使用者可以在 MetaMask 中籤署消息並將消息作為授權發送到伺服器,而不是直接向區塊鏈發送交易,假設滿足其他條件,伺服器隨後會將交易發送到區塊鏈。
但是,為了向使用者提供最大程度的保證,即只有授權交易由契約所有者處理/發送,我希望能夠在契約中解壓縮已簽名的消息,以便驗證以下內容:
使用者地址
交易數據
在高層次上,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/