1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- const { web3 } = require('@openzeppelin/test-environment');
- function toEthSignedMessageHash (messageHex) {
- const messageBuffer = Buffer.from(messageHex.substring(2), 'hex');
- const prefix = Buffer.from(`\u0019Ethereum Signed Message:\n${messageBuffer.length}`);
- return web3.utils.sha3(Buffer.concat([prefix, messageBuffer]));
- }
- function fixSignature (signature) {
- // in geth its always 27/28, in ganache its 0/1. Change to 27/28 to prevent
- // signature malleability if version is 0/1
- // see https://github.com/ethereum/go-ethereum/blob/v1.8.23/internal/ethapi/api.go#L465
- let v = parseInt(signature.slice(130, 132), 16);
- if (v < 27) {
- v += 27;
- }
- const vHex = v.toString(16);
- return signature.slice(0, 130) + vHex;
- }
- // signs message in node (ganache auto-applies "Ethereum Signed Message" prefix)
- async function signMessage (signer, messageHex = '0x') {
- return fixSignature(await web3.eth.sign(messageHex, signer));
- };
- /**
- * Create a signer between a contract and a signer for a voucher of method, args, and redeemer
- * Note that `method` is the web3 method, not the truffle-contract method
- * @param contract TruffleContract
- * @param signer address
- * @param redeemer address
- * @param methodName string
- * @param methodArgs any[]
- */
- const getSignFor = (contract, signer) => (redeemer, methodName, methodArgs = []) => {
- const parts = [
- contract.address,
- redeemer,
- ];
- const REAL_SIGNATURE_SIZE = 2 * 65; // 65 bytes in hexadecimal string length
- const PADDED_SIGNATURE_SIZE = 2 * 96; // 96 bytes in hexadecimal string length
- const DUMMY_SIGNATURE = `0x${web3.utils.padLeft('', REAL_SIGNATURE_SIZE)}`;
- // if we have a method, add it to the parts that we're signing
- if (methodName) {
- if (methodArgs.length > 0) {
- parts.push(
- contract.contract.methods[methodName](...methodArgs.concat([DUMMY_SIGNATURE])).encodeABI()
- .slice(0, -1 * PADDED_SIGNATURE_SIZE)
- );
- } else {
- const abi = contract.abi.find(abi => abi.name === methodName);
- parts.push(abi.signature);
- }
- }
- // return the signature of the "Ethereum Signed Message" hash of the hash of `parts`
- const messageHex = web3.utils.soliditySha3(...parts);
- return signMessage(signer, messageHex);
- };
- module.exports = {
- signMessage,
- toEthSignedMessageHash,
- fixSignature,
- getSignFor,
- };
|