Solidity
使用 web3 簽名,使用 Solidity 驗證
這幾天我一直在嘗試、調試和哭泣。我一生都無法弄清楚如何在 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!"); }
正如一開始提到的,我知道我只是在這裡遺漏了一些非常基本的東西,但還是想分享我嘗試過的東西。我希望有人能指出我正確的方向!
問題是您將簽名作為字元串傳遞,並且需要將其作為字節數組傳遞
function checkIt () public { bytes memory signature = hex"564f8b7ca4a729a34aedf3b065e20b5eaa129fd663243697025a428f27db086e6a7d6dc429c95a44143117a9ea02cd452bce4242b1adb2742b02a4a44e6d389b1c"; require(signature.length == 65, "invalid signature length");
該
require
聲明是為了驗證簽名具有適當的長度。