index.js 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. "use strict";
  2. import { BigNumber } from "@ethersproject/bignumber";
  3. import { arrayify, concat, hexlify, zeroPad } from "@ethersproject/bytes";
  4. import { keccak256 as hashKeccak256 } from "@ethersproject/keccak256";
  5. import { sha256 as hashSha256 } from "@ethersproject/sha2";
  6. import { toUtf8Bytes } from "@ethersproject/strings";
  7. const regexBytes = new RegExp("^bytes([0-9]+)$");
  8. const regexNumber = new RegExp("^(u?int)([0-9]*)$");
  9. const regexArray = new RegExp("^(.*)\\[([0-9]*)\\]$");
  10. const Zeros = "0000000000000000000000000000000000000000000000000000000000000000";
  11. import { Logger } from "@ethersproject/logger";
  12. import { version } from "./_version";
  13. const logger = new Logger(version);
  14. function _pack(type, value, isArray) {
  15. switch (type) {
  16. case "address":
  17. if (isArray) {
  18. return zeroPad(value, 32);
  19. }
  20. return arrayify(value);
  21. case "string":
  22. return toUtf8Bytes(value);
  23. case "bytes":
  24. return arrayify(value);
  25. case "bool":
  26. value = (value ? "0x01" : "0x00");
  27. if (isArray) {
  28. return zeroPad(value, 32);
  29. }
  30. return arrayify(value);
  31. }
  32. let match = type.match(regexNumber);
  33. if (match) {
  34. //let signed = (match[1] === "int")
  35. let size = parseInt(match[2] || "256");
  36. if ((match[2] && String(size) !== match[2]) || (size % 8 !== 0) || size === 0 || size > 256) {
  37. logger.throwArgumentError("invalid number type", "type", type);
  38. }
  39. if (isArray) {
  40. size = 256;
  41. }
  42. value = BigNumber.from(value).toTwos(size);
  43. return zeroPad(value, size / 8);
  44. }
  45. match = type.match(regexBytes);
  46. if (match) {
  47. const size = parseInt(match[1]);
  48. if (String(size) !== match[1] || size === 0 || size > 32) {
  49. logger.throwArgumentError("invalid bytes type", "type", type);
  50. }
  51. if (arrayify(value).byteLength !== size) {
  52. logger.throwArgumentError(`invalid value for ${type}`, "value", value);
  53. }
  54. if (isArray) {
  55. return arrayify((value + Zeros).substring(0, 66));
  56. }
  57. return value;
  58. }
  59. match = type.match(regexArray);
  60. if (match && Array.isArray(value)) {
  61. const baseType = match[1];
  62. const count = parseInt(match[2] || String(value.length));
  63. if (count != value.length) {
  64. logger.throwArgumentError(`invalid array length for ${type}`, "value", value);
  65. }
  66. const result = [];
  67. value.forEach(function (value) {
  68. result.push(_pack(baseType, value, true));
  69. });
  70. return concat(result);
  71. }
  72. return logger.throwArgumentError("invalid type", "type", type);
  73. }
  74. // @TODO: Array Enum
  75. export function pack(types, values) {
  76. if (types.length != values.length) {
  77. logger.throwArgumentError("wrong number of values; expected ${ types.length }", "values", values);
  78. }
  79. const tight = [];
  80. types.forEach(function (type, index) {
  81. tight.push(_pack(type, values[index]));
  82. });
  83. return hexlify(concat(tight));
  84. }
  85. export function keccak256(types, values) {
  86. return hashKeccak256(pack(types, values));
  87. }
  88. export function sha256(types, values) {
  89. return hashSha256(pack(types, values));
  90. }
  91. //# sourceMappingURL=index.js.map