sign.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. function toEthSignedMessageHash(messageHex) {
  2. const messageBuffer = Buffer.from(messageHex.substring(2), 'hex');
  3. const prefix = Buffer.from(`\u0019Ethereum Signed Message:\n${messageBuffer.length}`);
  4. return web3.utils.sha3(Buffer.concat([prefix, messageBuffer]));
  5. }
  6. /**
  7. * Create a signed data with intended validator according to the version 0 of EIP-191
  8. * @param validatorAddress The address of the validator
  9. * @param dataHex The data to be concatenated with the prefix and signed
  10. */
  11. function toDataWithIntendedValidatorHash(validatorAddress, dataHex) {
  12. const validatorBuffer = Buffer.from(web3.utils.hexToBytes(validatorAddress));
  13. const dataBuffer = Buffer.from(web3.utils.hexToBytes(dataHex));
  14. const preambleBuffer = Buffer.from('\x19');
  15. const versionBuffer = Buffer.from('\x00');
  16. const ethMessage = Buffer.concat([preambleBuffer, versionBuffer, validatorBuffer, dataBuffer]);
  17. return web3.utils.sha3(ethMessage);
  18. }
  19. /**
  20. * Create a signer between a contract and a signer for a voucher of method, args, and redeemer
  21. * Note that `method` is the web3 method, not the truffle-contract method
  22. * @param contract TruffleContract
  23. * @param signer address
  24. * @param redeemer address
  25. * @param methodName string
  26. * @param methodArgs any[]
  27. */
  28. const getSignFor =
  29. (contract, signer) =>
  30. (redeemer, methodName, methodArgs = []) => {
  31. const parts = [contract.address, redeemer];
  32. const REAL_SIGNATURE_SIZE = 2 * 65; // 65 bytes in hexadecimal string length
  33. const PADDED_SIGNATURE_SIZE = 2 * 96; // 96 bytes in hexadecimal string length
  34. const DUMMY_SIGNATURE = `0x${web3.utils.padLeft('', REAL_SIGNATURE_SIZE)}`;
  35. // if we have a method, add it to the parts that we're signing
  36. if (methodName) {
  37. if (methodArgs.length > 0) {
  38. parts.push(
  39. contract.contract.methods[methodName](...methodArgs.concat([DUMMY_SIGNATURE]))
  40. .encodeABI()
  41. .slice(0, -1 * PADDED_SIGNATURE_SIZE),
  42. );
  43. } else {
  44. const abi = contract.abi.find(abi => abi.name === methodName);
  45. parts.push(abi.signature);
  46. }
  47. }
  48. // return the signature of the "Ethereum Signed Message" hash of the hash of `parts`
  49. const messageHex = web3.utils.soliditySha3(...parts);
  50. return web3.eth.sign(messageHex, signer);
  51. };
  52. module.exports = {
  53. toEthSignedMessageHash,
  54. toDataWithIntendedValidatorHash,
  55. getSignFor,
  56. };