Solidity

如果 toSignString 僅包含數字,則 ecrecover 返回錯誤的地址

  • May 8, 2022
//web3 code
     let hash = web3.utils.soliditySha3("String"); //if replace "String" with "0" "123" etc , ecrecover returns wrong address
     console.log("hash", web3.utils.soliditySha3("\x19Ethereum Signed Message:\n32", hash))
     let signature = await web3.eth.personal.sign(hash, currentAccount);
     console.log("signature", signature);
     let r = signature.slice(0, 66);
     let s = "0x" + signature.slice(66, 130);
     let v = web3.utils.hexToNumberString("0x" + signature.slice(130, 132));
     console.log("r", r);
     console.log("s", s);
     console.log("v", v);
//solidity code
function extractSigner(
       uint8 v,
       bytes32 r,
       bytes32 s
   ) internal view returns (address) {
       string memory n = toString(nonce); //nonce corresponding to "String" in web3 code above
       bytes32 hash = keccak256(
           abi.encodePacked(
               "\x19Ethereum Signed Message:\n32",
               keccak256(bytes(n))
           )
       );
       return ecrecover(hash, v, r, s);
   }

整個過程是,使用web3js對字元串進行簽名,並在solidity中輸入v,r,s。如果 toSignString 包含任何字母,solidity 會返回正確的地址。但是如果 toSignString 只包含數字,solidity 返回一個錯誤的地址,為什麼?

你的問題在這裡:

let hash = web3.utils.soliditySha3("String");

根據文件,非數字字元串將被解釋為,string而數字字元串輸入將被解釋為,uint256但在可靠性方面,您將字節解釋為string輸入。abi 編碼不同,您沒有驗證已簽名的相同數據。

如果您想確保在簽名者方面進行字元串解釋,則可以快速解決:

let hash = web3.utils.soliditySha3({ type: "string", value: "YOUR-STRING-DATA" });

這樣,傳遞的任何數據都soliditiSha3將被解釋為字元串,匹配驗證者的邏輯並允許您恢復正確的地址。

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