Solidity

使用 web3 簽名,使用 Solidity 驗證

  • November 23, 2021

這幾天我一直在嘗試、調試和哭泣。我一生都無法弄清楚如何在 Solidity 中驗證我使用 web3 創建的簽名。我確定我只是在這裡遺漏了一些非常基本的東西,但我無法弄清楚它是什麼。

我正在努力解決一些不同的問題。所有顯示如何在 Solidity 中驗證的指南都有一個檢查,例如:require(sig.length == 65),但是我從 web3 獲得的簽名是 132 個字元長,所以它已經失敗了。

我生成簽名的 JS 程式碼:

var hash = "0x" + ethereumjs.soliditySHA3(
   ["uint256"],
   [1000000]
).toString("hex");

this.web3.eth.personal.sign(hash, "0x8809465617E09405a1af06C2d93C2bcE0Ce5Ac80").then(console.log);

>>0x564f8b7ca4a729a34aedf3b065e20b5eaa129fd663243697025a428f27db086e6a7d6dc429c95a44143117a9ea02cd452bce4242b1adb2742b02a4a44e6d389b1c

我用來驗證的 Solidity 程式碼:

function prefixed(bytes32 hash) internal pure returns (bytes32) {
   return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}

function checkIt () public {
   bytes memory signature = "0x564f8b7ca4a729a34aedf3b065e20b5eaa129fd663243697025a428f27db086e6a7d6dc429c95a44143117a9ea02cd452bce4242b1adb2742b02a4a44e6d389b1c";
   
   //require(signature.length == 65, "invalid signature length");
   
   bytes32 r;
   bytes32 s;
   uint8 v;
   
   assembly {
       r := mload(add(signature, 32))
       s := mload(add(signature, 64))
       v := byte(0, mload(add(signature, 96)))
   }
   
   uint256 message = 1000000;
   address signerAddress = 0x8809465617E09405a1af06C2d93C2bcE0Ce5Ac80;
   
   Assert.equal(ecrecover(prefixed(keccak256(abi.encodePacked(message))), v, r, s), signerAddress, "Not equal!");
}

測試結果: https://imgur.com/a/qpO6Yaq

正如一開始提到的,我知道我只是在這裡遺漏了一些非常基本的東西,但還是想分享我嘗試過的東西。我希望有人能指出我正確的方向!

問題是您將簽名作為字元串傳遞,並且需要將其作為字節數組傳遞

function checkIt () public {

   bytes memory signature = hex"564f8b7ca4a729a34aedf3b065e20b5eaa129fd663243697025a428f27db086e6a7d6dc429c95a44143117a9ea02cd452bce4242b1adb2742b02a4a44e6d389b1c";

   require(signature.length == 65, "invalid signature length");

require聲明是為了驗證簽名具有適當的長度。

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