Basic EIP712 encoder
This commit is contained in:
		@@ -26,21 +26,22 @@ export class TransactionFactory {
 | 
				
			|||||||
    public newSignedTransaction(data: string, signatureType: SignatureType = SignatureType.EthSign): SignedTransaction {
 | 
					    public newSignedTransaction(data: string, signatureType: SignatureType = SignatureType.EthSign): SignedTransaction {
 | 
				
			||||||
        const executeTransactionSchemaHashBuff = EIP712Utils.compileSchema(EIP712_EXECUTE_TRANSACTION_SCHEMA);
 | 
					        const executeTransactionSchemaHashBuff = EIP712Utils.compileSchema(EIP712_EXECUTE_TRANSACTION_SCHEMA);
 | 
				
			||||||
        const salt = generatePseudoRandomSalt();
 | 
					        const salt = generatePseudoRandomSalt();
 | 
				
			||||||
        const dataHash = crypto.solSHA3([ethUtil.toBuffer(data)]);
 | 
					        const signer = `0x${this._signerBuff.toString('hex')}`;
 | 
				
			||||||
        const executeTransactionDataHash = crypto.solSHA3([
 | 
					        const executeTransactionData = {
 | 
				
			||||||
            executeTransactionSchemaHashBuff,
 | 
					 | 
				
			||||||
            salt,
 | 
					            salt,
 | 
				
			||||||
            EIP712Utils.pad32Buffer(this._signerBuff),
 | 
					            signer,
 | 
				
			||||||
            dataHash,
 | 
					            data,
 | 
				
			||||||
        ]);
 | 
					        };
 | 
				
			||||||
        const txHash = EIP712Utils.createEIP712Message(executeTransactionDataHash, this._exchangeAddress);
 | 
					        const executeTransactionHashBuff = EIP712Utils.structHash(
 | 
				
			||||||
 | 
					            EIP712_EXECUTE_TRANSACTION_SCHEMA,
 | 
				
			||||||
 | 
					            executeTransactionData,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        const txHash = EIP712Utils.createEIP712Message(executeTransactionHashBuff, this._exchangeAddress);
 | 
				
			||||||
        const signature = signingUtils.signMessage(txHash, this._privateKey, signatureType);
 | 
					        const signature = signingUtils.signMessage(txHash, this._privateKey, signatureType);
 | 
				
			||||||
        const signedTx = {
 | 
					        const signedTx = {
 | 
				
			||||||
            exchangeAddress: this._exchangeAddress,
 | 
					            exchangeAddress: this._exchangeAddress,
 | 
				
			||||||
            salt,
 | 
					 | 
				
			||||||
            signer: `0x${this._signerBuff.toString('hex')}`,
 | 
					 | 
				
			||||||
            data,
 | 
					 | 
				
			||||||
            signature: `0x${signature.toString('hex')}`,
 | 
					            signature: `0x${signature.toString('hex')}`,
 | 
				
			||||||
 | 
					            ...executeTransactionData,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        return signedTx;
 | 
					        return signedTx;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ import { BigNumber } from '@0xproject/utils';
 | 
				
			|||||||
import ethUtil = require('ethereumjs-util');
 | 
					import ethUtil = require('ethereumjs-util');
 | 
				
			||||||
import * as _ from 'lodash';
 | 
					import * as _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import { assetProxyUtils } from './asset_proxy_utils';
 | 
				
			||||||
import { crypto } from './crypto';
 | 
					import { crypto } from './crypto';
 | 
				
			||||||
import { EIP712Schema } from './types';
 | 
					import { EIP712Schema } from './types';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -19,6 +20,14 @@ const EIP712_DOMAIN_SCHEMA: EIP712Schema = {
 | 
				
			|||||||
    ],
 | 
					    ],
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum EIP712Types {
 | 
				
			||||||
 | 
					    String = 'string',
 | 
				
			||||||
 | 
					    Bytes = 'bytes',
 | 
				
			||||||
 | 
					    Address = 'address',
 | 
				
			||||||
 | 
					    Bytes32 = 'bytes32',
 | 
				
			||||||
 | 
					    Uint256 = 'uint256',
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const EIP712Utils = {
 | 
					export const EIP712Utils = {
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * Compiles the EIP712Schema and returns the hash of the schema.
 | 
					     * Compiles the EIP712Schema and returns the hash of the schema.
 | 
				
			||||||
@@ -26,9 +35,7 @@ export const EIP712Utils = {
 | 
				
			|||||||
     * @return  The hash of the compiled schema
 | 
					     * @return  The hash of the compiled schema
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    compileSchema(schema: EIP712Schema): Buffer {
 | 
					    compileSchema(schema: EIP712Schema): Buffer {
 | 
				
			||||||
        const namedTypes = _.map(schema.parameters, parameter => `${parameter.type} ${parameter.name}`);
 | 
					        const eip712Schema = EIP712Utils._encodeType(schema);
 | 
				
			||||||
        const namedTypesJoined = namedTypes.join(',');
 | 
					 | 
				
			||||||
        const eip712Schema = `${schema.name}(${namedTypesJoined})`;
 | 
					 | 
				
			||||||
        const eip712SchemaHashBuffer = crypto.solSHA3([eip712Schema]);
 | 
					        const eip712SchemaHashBuffer = crypto.solSHA3([eip712Schema]);
 | 
				
			||||||
        return eip712SchemaHashBuffer;
 | 
					        return eip712SchemaHashBuffer;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
@@ -57,14 +64,44 @@ export const EIP712Utils = {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    _getDomainSeparatorHashBuffer(exchangeAddress: string): Buffer {
 | 
					    _getDomainSeparatorHashBuffer(exchangeAddress: string): Buffer {
 | 
				
			||||||
        const domainSeparatorSchemaBuffer = EIP712Utils._getDomainSeparatorSchemaBuffer();
 | 
					        const domainSeparatorSchemaBuffer = EIP712Utils._getDomainSeparatorSchemaBuffer();
 | 
				
			||||||
        const nameHash = crypto.solSHA3([EIP712_DOMAIN_NAME]);
 | 
					        const encodedData = EIP712Utils._encodeData(EIP712_DOMAIN_SCHEMA, {
 | 
				
			||||||
        const versionHash = crypto.solSHA3([EIP712_DOMAIN_VERSION]);
 | 
					            name: EIP712_DOMAIN_NAME,
 | 
				
			||||||
        const domainSeparatorHashBuff = crypto.solSHA3([
 | 
					            version: EIP712_DOMAIN_VERSION,
 | 
				
			||||||
            domainSeparatorSchemaBuffer,
 | 
					            contract: exchangeAddress,
 | 
				
			||||||
            nameHash,
 | 
					        });
 | 
				
			||||||
            versionHash,
 | 
					        const domainSeparatorHashBuff2 = crypto.solSHA3([domainSeparatorSchemaBuffer, ...encodedData]);
 | 
				
			||||||
            EIP712Utils.pad32Address(exchangeAddress),
 | 
					        return domainSeparatorHashBuff2;
 | 
				
			||||||
        ]);
 | 
					    },
 | 
				
			||||||
        return domainSeparatorHashBuff;
 | 
					    _encodeType(schema: EIP712Schema): string {
 | 
				
			||||||
 | 
					        const namedTypes = _.map(schema.parameters, ({ name, type }) => `${type} ${name}`);
 | 
				
			||||||
 | 
					        const namedTypesJoined = namedTypes.join(',');
 | 
				
			||||||
 | 
					        const encodedType = `${schema.name}(${namedTypesJoined})`;
 | 
				
			||||||
 | 
					        return encodedType;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    _encodeData(schema: EIP712Schema, data: { [key: string]: any }): any {
 | 
				
			||||||
 | 
					        const encodedTypes = [];
 | 
				
			||||||
 | 
					        const encodedValues = [];
 | 
				
			||||||
 | 
					        for (const parameter of schema.parameters) {
 | 
				
			||||||
 | 
					            const value = data[parameter.name];
 | 
				
			||||||
 | 
					            if (parameter.type === EIP712Types.String || parameter.type === EIP712Types.Bytes) {
 | 
				
			||||||
 | 
					                encodedTypes.push(EIP712Types.Bytes32);
 | 
				
			||||||
 | 
					                encodedValues.push(crypto.solSHA3([ethUtil.toBuffer(value)]));
 | 
				
			||||||
 | 
					            } else if (parameter.type === EIP712Types.Uint256) {
 | 
				
			||||||
 | 
					                encodedTypes.push(EIP712Types.Uint256);
 | 
				
			||||||
 | 
					                encodedValues.push(value);
 | 
				
			||||||
 | 
					            } else if (parameter.type === EIP712Types.Address) {
 | 
				
			||||||
 | 
					                encodedTypes.push(EIP712Types.Address);
 | 
				
			||||||
 | 
					                encodedValues.push(EIP712Utils.pad32Address(value));
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                throw new Error(`Unable to encode ${parameter.type}`);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return encodedValues;
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    structHash(schema: EIP712Schema, data: { [key: string]: any }): Buffer {
 | 
				
			||||||
 | 
					        const encodedData = EIP712Utils._encodeData(schema, data);
 | 
				
			||||||
 | 
					        const schemaHash = EIP712Utils.compileSchema(schema);
 | 
				
			||||||
 | 
					        const hashBuffer = crypto.solSHA3([schemaHash, ...encodedData]);
 | 
				
			||||||
 | 
					        return hashBuffer;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -75,24 +75,7 @@ export const orderHashUtils = {
 | 
				
			|||||||
     * @return  The resulting orderHash from hashing the supplied order as a Buffer
 | 
					     * @return  The resulting orderHash from hashing the supplied order as a Buffer
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    getOrderHashBuffer(order: SignedOrder | Order): Buffer {
 | 
					    getOrderHashBuffer(order: SignedOrder | Order): Buffer {
 | 
				
			||||||
        const makerAssetDataHash = crypto.solSHA3([ethUtil.toBuffer(order.makerAssetData)]);
 | 
					        const orderParamsHashBuff = EIP712Utils.structHash(EIP712_ORDER_SCHEMA, order);
 | 
				
			||||||
        const takerAssetDataHash = crypto.solSHA3([ethUtil.toBuffer(order.takerAssetData)]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const orderParamsHashBuff = crypto.solSHA3([
 | 
					 | 
				
			||||||
            orderHashUtils._getOrderSchemaBuffer(),
 | 
					 | 
				
			||||||
            EIP712Utils.pad32Address(order.makerAddress),
 | 
					 | 
				
			||||||
            EIP712Utils.pad32Address(order.takerAddress),
 | 
					 | 
				
			||||||
            EIP712Utils.pad32Address(order.feeRecipientAddress),
 | 
					 | 
				
			||||||
            EIP712Utils.pad32Address(order.senderAddress),
 | 
					 | 
				
			||||||
            order.makerAssetAmount,
 | 
					 | 
				
			||||||
            order.takerAssetAmount,
 | 
					 | 
				
			||||||
            order.makerFee,
 | 
					 | 
				
			||||||
            order.takerFee,
 | 
					 | 
				
			||||||
            order.expirationTimeSeconds,
 | 
					 | 
				
			||||||
            order.salt,
 | 
					 | 
				
			||||||
            makerAssetDataHash,
 | 
					 | 
				
			||||||
            takerAssetDataHash,
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
        const orderHashBuff = EIP712Utils.createEIP712Message(orderParamsHashBuff, order.exchangeAddress);
 | 
					        const orderHashBuff = EIP712Utils.createEIP712Message(orderParamsHashBuff, order.exchangeAddress);
 | 
				
			||||||
        return orderHashBuff;
 | 
					        return orderHashBuff;
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user