Advertisement
Guest User

Untitled

a guest
Sep 13th, 2021
113
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.31 KB | None | 0 0
  1. // SPDX-License-Identifier: GPL-3.0
  2.  
  3. pragma solidity >=0.7.0 <0.9.0;
  4.  
  5. pragma solidity ^0.8.0;
  6.  
  7. /**
  8. * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
  9. *
  10. * These functions can be used to verify that a message was signed by the holder
  11. * of the private keys of a given address.
  12. */
  13.  
  14. enum RecoverError {
  15. NoError,
  16. InvalidSignature,
  17. InvalidSignatureLength,
  18. InvalidSignatureS,
  19. InvalidSignatureV
  20. }
  21.  
  22. function _throwError(RecoverError error) pure {
  23. if (error == RecoverError.NoError) {
  24. return; // no error: do nothing
  25. } else if (error == RecoverError.InvalidSignature) {
  26. revert("ECDSA: invalid signature");
  27. } else if (error == RecoverError.InvalidSignatureLength) {
  28. revert("ECDSA: invalid signature length");
  29. } else if (error == RecoverError.InvalidSignatureS) {
  30. revert("ECDSA: invalid signature 's' value");
  31. } else if (error == RecoverError.InvalidSignatureV) {
  32. revert("ECDSA: invalid signature 'v' value");
  33. }
  34. }
  35.  
  36. /**
  37. * @dev Returns the address that signed a hashed message (`hash`) with
  38. * `signature` or error string. This address can then be used for verification purposes.
  39. *
  40. * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
  41. * this function rejects them by requiring the `s` value to be in the lower
  42. * half order, and the `v` value to be either 27 or 28.
  43. *
  44. * IMPORTANT: `hash` _must_ be the result of a hash operation for the
  45. * verification to be secure: it is possible to craft signatures that
  46. * recover to arbitrary addresses for non-hashed data. A safe way to ensure
  47. * this is by receiving a hash of the original message (which may otherwise
  48. * be too long), and then calling {toEthSignedMessageHash} on it.
  49. *
  50. * Documentation for signature generation:
  51. * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
  52. * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
  53. *
  54. * _Available since v4.3._
  55. */
  56. function tryRecover(bytes32 hash, bytes memory signature) pure returns (address, RecoverError) {
  57. // Check the signature length
  58. // - case 65: r,s,v signature (standard)
  59. // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
  60. if (signature.length == 65) {
  61. bytes32 r;
  62. bytes32 s;
  63. uint8 v;
  64. // ecrecover takes the signature parameters, and the only way to get them
  65. // currently is to use assembly.
  66. assembly {
  67. r := mload(add(signature, 0x20))
  68. s := mload(add(signature, 0x40))
  69. v := byte(0, mload(add(signature, 0x60)))
  70. }
  71. return tryRecover(hash, v, r, s);
  72. } else if (signature.length == 64) {
  73. bytes32 r;
  74. bytes32 vs;
  75. // ecrecover takes the signature parameters, and the only way to get them
  76. // currently is to use assembly.
  77. assembly {
  78. r := mload(add(signature, 0x20))
  79. vs := mload(add(signature, 0x40))
  80. }
  81. return tryRecover(hash, r, vs);
  82. } else {
  83. return (address(0), RecoverError.InvalidSignatureLength);
  84. }
  85. }
  86.  
  87. /**
  88. * @dev Returns the address that signed a hashed message (`hash`) with
  89. * `signature`. This address can then be used for verification purposes.
  90. *
  91. * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
  92. * this function rejects them by requiring the `s` value to be in the lower
  93. * half order, and the `v` value to be either 27 or 28.
  94. *
  95. * IMPORTANT: `hash` _must_ be the result of a hash operation for the
  96. * verification to be secure: it is possible to craft signatures that
  97. * recover to arbitrary addresses for non-hashed data. A safe way to ensure
  98. * this is by receiving a hash of the original message (which may otherwise
  99. * be too long), and then calling {toEthSignedMessageHash} on it.
  100. */
  101. function recover(bytes32 hash, bytes memory signature) pure returns (address) {
  102. (address recovered, RecoverError error) = tryRecover(hash, signature);
  103. _throwError(error);
  104. return recovered;
  105. }
  106.  
  107. /**
  108. * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
  109. *
  110. * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
  111. *
  112. * _Available since v4.3._
  113. */
  114. function tryRecover(
  115. bytes32 hash,
  116. bytes32 r,
  117. bytes32 vs
  118. ) pure returns (address, RecoverError) {
  119. bytes32 s;
  120. uint8 v;
  121. assembly {
  122. s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
  123. v := add(shr(255, vs), 27)
  124. }
  125. return tryRecover(hash, v, r, s);
  126. }
  127.  
  128. /**
  129. * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
  130. *
  131. * _Available since v4.2._
  132. */
  133. function recover(
  134. bytes32 hash,
  135. bytes32 r,
  136. bytes32 vs
  137. ) pure returns (address) {
  138. (address recovered, RecoverError error) = tryRecover(hash, r, vs);
  139. _throwError(error);
  140. return recovered;
  141. }
  142.  
  143. /**
  144. * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
  145. * `r` and `s` signature fields separately.
  146. *
  147. * _Available since v4.3._
  148. */
  149. function tryRecover(
  150. bytes32 hash,
  151. uint8 v,
  152. bytes32 r,
  153. bytes32 s
  154. ) pure returns (address, RecoverError) {
  155. // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
  156. // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
  157. // the valid range for s in (301): 0 < s < secp256k1n รท 2 + 1, and for v in (302): v โˆˆ {27, 28}. Most
  158. // signatures from current libraries generate a unique signature with an s-value in the lower half order.
  159. //
  160. // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
  161. // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
  162. // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
  163. // these malleable signatures as well.
  164. if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
  165. return (address(0), RecoverError.InvalidSignatureS);
  166. }
  167. if (v != 27 && v != 28) {
  168. return (address(0), RecoverError.InvalidSignatureV);
  169. }
  170.  
  171. // If the signature is valid (and not malleable), return the signer address
  172. address signer = ecrecover(hash, v, r, s);
  173. if (signer == address(0)) {
  174. return (address(0), RecoverError.InvalidSignature);
  175. }
  176.  
  177. return (signer, RecoverError.NoError);
  178. }
  179.  
  180. /**
  181. * @dev Overload of {ECDSA-recover} that receives the `v`,
  182. * `r` and `s` signature fields separately.
  183. */
  184. function recover(
  185. bytes32 hash,
  186. uint8 v,
  187. bytes32 r,
  188. bytes32 s
  189. ) pure returns (address) {
  190. (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
  191. _throwError(error);
  192. return recovered;
  193. }
  194.  
  195. /**
  196. * @dev Returns an Ethereum Signed Message, created from a `hash`. This
  197. * produces hash corresponding to the one signed with the
  198. * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
  199. * JSON-RPC method as part of EIP-191.
  200. *
  201. * See {recover}.
  202. */
  203. function toEthSignedMessageHash(bytes32 hash) pure returns (bytes32) {
  204. // 32 is the length in bytes of hash,
  205. // enforced by the type signature above
  206. return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
  207. }
  208.  
  209. /**
  210. * @dev Returns an Ethereum Signed Typed Data, created from a
  211. * `domainSeparator` and a `structHash`. This produces hash corresponding
  212. * to the one signed with the
  213. * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
  214. * JSON-RPC method as part of EIP-712.
  215. *
  216. * See {recover}.
  217. */
  218. function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) pure returns (bytes32) {
  219. return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
  220. }
  221.  
  222.  
  223. /**
  224. * @title Storage
  225. * @dev Store & retrieve value in a variable
  226. */
  227. contract Storage {
  228.  
  229. uint256 number;
  230.  
  231. /**
  232. * @dev Store value in variable
  233. * @param num value to store
  234. */
  235. function store(uint256 num) public {
  236. number = num;
  237. }
  238.  
  239. /**
  240. * @dev Return value
  241. * @return value of 'number'
  242. */
  243. function retrieve(address _address, bytes calldata signature) public pure returns (address){
  244. return recover(
  245. toEthSignedMessageHash(
  246. keccak256(abi.encodePacked(false, _address))),
  247. signature);
  248. }
  249. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement