Solidity
無法使用 ecrecover 驗證 Ledger 在 Solidity 中生成的簽名
我使用智能合約來驗證簽名:
function verify(string memory _msg, bytes memory _sig) public pure returns (address) { bytes memory _msgHex = bytes(_msg); bytes32 prefixedHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", uint2str(_msgHex.length), _msgHex)); (bytes32 _r, bytes32 _s, uint8 _v) = splitSignature(_sig); address signer = ecrecover(prefixedHash, _v, _r, _s); return signer; } function splitSignature(bytes memory sig) internal pure returns (bytes32 r, bytes32 s, uint8 v) { require(sig.length == 65, "invalid signature length"); assembly { r := mload(add(sig, 32)) s := mload(add(sig, 64)) v := byte(0, mload(add(sig, 96))) } }
函式
uint2str
體並不重要。例如,它轉換438
為"438"
.主函式
verify
根據消息和簽名值返回簽名者地址。這適用於所有簽名,但對於特定簽名,它會返回
0x0000000000000000000000000000000000000000
給它的任何消息。這個特殊的簽名是:
0x8ecd9d9f1ece5bd0ea1638d9a05bc194bb7536aed42fd6a09fbeb1a9479c316760ce3ff2dfbf73ad7a488e6d46988a443430a13153b26b99a83d1101d00e36bb00
但是 MEW 驗證這個簽名沒有任何問題。
任何人都可以建議一種驗證此簽名的方法嗎?
PS:此簽名由 Ledger 錢包製作。
問題是 ECRecover 期望 v 參數為 27 或 28,而在簽名中它為 0。
- r:8ecd9d9f1ece5bd0ea1638d9a05bc194bb7536aed42fd6a09fbeb1a9479c3167
- s : 60ce3ff2dfbf73ad7a488e6d46988a443430a13153b26b99a83d1101d00e36bb
- 在: 00
來自乙太坊的黃皮書附錄 F -簽名交易。v 的可接受值為 27 或 28。
一種解決方案是替換簽名末尾的字節:替換為
00
(1B
27) 或01
替換為1C
(28)。