// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; struct Signature { uint8 v; bytes32 r; bytes32 s; } /// @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`. /// @notice Make sure to peform a bounds check for @param pos, to avoid out of bounds access on @param signatures /// @param pos which signature to read. A prior bounds check of this parameter should be performed, to avoid out of bounds access /// @param signatures concatenated rsv signatures function signatureSplit(bytes memory signatures, uint256 pos) pure returns (Signature memory sign) { uint8 v; bytes32 r; bytes32 s; // The signature format is a compact form of: // {bytes32 r}{bytes32 s}{uint8 v} // Compact means, uint8 is not padded to 32 bytes. // solhint-disable-next-line no-inline-assembly assembly { let signaturePos := mul(0x41, pos) r := mload(add(signatures, add(signaturePos, 0x20))) s := mload(add(signatures, add(signaturePos, 0x40))) // Here we are loading the last 32 bytes, including 31 bytes // of 's'. There is no 'mload8' to do this. // // 'byte' is not working due to the Solidity parser, so lets // use the second best option, 'and' v := and(mload(add(signatures, add(signaturePos, 0x41))), 0xff) } sign = Signature( { v:v, r:r, s:s } ); } contract Ecrecover { function ssig ( bytes32 txHash,//keccak256 hash bytes memory signaturePacked,//ECDSA签名 bytes memory ERC1271_signatureDataPacked //如果是合约签名(v==0)输入合约签名数据,否则输入0x ) external pure returns(bytes memory signaturesSorted,address[] memory signers) { uint256 num = signaturePacked.length/65; bytes memory ERC1271_SignatureDataPacked; address signer; Signature memory sign; bytes[] memory signatures = new bytes[](num); signers = new address[](num); for (uint256 i = 0; i < num;) { sign = signatureSplit(signaturePacked, i); if (sign.v == 0 || sign.v == 1) { signer = address(uint160(uint256(sign.r))); } else if (sign.v > 30) { signer = ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", txHash)), sign.v - 4, sign.r, sign.s); } else { signer = ecrecover(txHash, sign.v, sign.r, sign.s); } signatures[i] = abi.encodePacked(sign.r,sign.s,sign.v); signers[i] = signer; unchecked { ++i; } } for (uint i = 1;i < signers.length;){ address temp = signers[i]; bytes memory _temp = signatures[i]; uint j=i; while( (j >= 1) && (temp < signers[j-1])){ signatures[j] = signatures[j-1]; signers[j] =signers[j-1]; j--; } signatures[j] = _temp; signers[j] =temp; unchecked { ++i; } } for(uint i = 0;i