@0x/contracts-exchange-libs
: Convert generate-exchange-selectors
script to typescript.
This commit is contained in:
parent
f7f55cad43
commit
575842eab4
@ -22,129 +22,144 @@ pragma solidity ^0.5.5;
|
|||||||
contract LibExchangeSelectors {
|
contract LibExchangeSelectors {
|
||||||
// solhint-disable max-line-length
|
// solhint-disable max-line-length
|
||||||
|
|
||||||
// allowedOrderValidators(address,address)
|
// function allowedOrderValidators(address,address)
|
||||||
bytes4 constant internal ALLOWED_ORDER_VALIDATORS_SELECTOR = 0x3a0a355b;
|
bytes4 constant internal ALLOWED_ORDER_VALIDATORS_SELECTOR = 0x3a0a355b;
|
||||||
|
|
||||||
// allowedValidators(address,address)
|
// function allowedValidators(address,address)
|
||||||
bytes4 constant internal ALLOWED_VALIDATORS_SELECTOR = 0x7b8e3514;
|
bytes4 constant internal ALLOWED_VALIDATORS_SELECTOR = 0x7b8e3514;
|
||||||
|
|
||||||
// assetProxies(bytes4)
|
// function assetProxies(bytes4)
|
||||||
bytes4 constant internal ASSET_PROXIES_SELECTOR = 0x3fd3c997;
|
bytes4 constant internal ASSET_PROXIES_SELECTOR = 0x3fd3c997;
|
||||||
|
|
||||||
// batchCancelOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[])
|
// function batchCancelOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[])
|
||||||
bytes4 constant internal BATCH_CANCEL_ORDERS_SELECTOR = 0xdedfc1f1;
|
bytes4 constant internal BATCH_CANCEL_ORDERS_SELECTOR = 0xdedfc1f1;
|
||||||
|
|
||||||
// batchExecuteTransactions((uint256,address,bytes)[],bytes[])
|
// function batchExecuteTransactions((uint256,address,bytes)[],bytes[])
|
||||||
bytes4 constant internal BATCH_EXECUTE_TRANSACTIONS_SELECTOR = 0x970d970c;
|
bytes4 constant internal BATCH_EXECUTE_TRANSACTIONS_SELECTOR = 0x970d970c;
|
||||||
|
|
||||||
// batchFillOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256[],bytes[])
|
// function batchFillOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256[],bytes[])
|
||||||
bytes4 constant internal BATCH_FILL_ORDERS_SELECTOR = 0x9694a402;
|
bytes4 constant internal BATCH_FILL_ORDERS_SELECTOR = 0x9694a402;
|
||||||
|
|
||||||
// batchFillOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256[],bytes[])
|
// function batchFillOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256[],bytes[])
|
||||||
bytes4 constant internal BATCH_FILL_ORDERS_NO_THROW_SELECTOR = 0x8ea8dfe4;
|
bytes4 constant internal BATCH_FILL_ORDERS_NO_THROW_SELECTOR = 0x8ea8dfe4;
|
||||||
|
|
||||||
// batchFillOrKillOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256[],bytes[])
|
// function batchFillOrKillOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256[],bytes[])
|
||||||
bytes4 constant internal BATCH_FILL_OR_KILL_ORDERS_SELECTOR = 0xbeee2e14;
|
bytes4 constant internal BATCH_FILL_OR_KILL_ORDERS_SELECTOR = 0xbeee2e14;
|
||||||
|
|
||||||
// cancelled(bytes32)
|
// function cancelled(bytes32)
|
||||||
bytes4 constant internal CANCELLED_SELECTOR = 0x2ac12622;
|
bytes4 constant internal CANCELLED_SELECTOR = 0x2ac12622;
|
||||||
|
|
||||||
// cancelOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes))
|
// function cancelOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes))
|
||||||
bytes4 constant internal CANCEL_ORDER_SELECTOR = 0x2da62987;
|
bytes4 constant internal CANCEL_ORDER_SELECTOR = 0x2da62987;
|
||||||
|
|
||||||
// cancelOrdersUpTo(uint256)
|
// function cancelOrdersUpTo(uint256)
|
||||||
bytes4 constant internal CANCEL_ORDERS_UP_TO_SELECTOR = 0x4f9559b1;
|
bytes4 constant internal CANCEL_ORDERS_UP_TO_SELECTOR = 0x4f9559b1;
|
||||||
|
|
||||||
// currentContextAddress()
|
// function currentContextAddress()
|
||||||
bytes4 constant internal CURRENT_CONTEXT_ADDRESS_SELECTOR = 0xeea086ba;
|
bytes4 constant internal CURRENT_CONTEXT_ADDRESS_SELECTOR = 0xeea086ba;
|
||||||
|
|
||||||
// EIP712_EXCHANGE_DOMAIN_HASH()
|
// function EIP712_EXCHANGE_DOMAIN_HASH()
|
||||||
bytes4 constant internal EIP_712_EXCHANGE_DOMAIN_HASH_SELECTOR = 0xc26cfecd;
|
bytes4 constant internal EIP_712_EXCHANGE_DOMAIN_HASH_SELECTOR = 0xc26cfecd;
|
||||||
|
|
||||||
// EIP712_EXCHANGE_DOMAIN_NAME()
|
// function EIP712_EXCHANGE_DOMAIN_NAME()
|
||||||
bytes4 constant internal EIP_712_EXCHANGE_DOMAIN_NAME_SELECTOR = 0x63c4e8cc;
|
bytes4 constant internal EIP_712_EXCHANGE_DOMAIN_NAME_SELECTOR = 0x63c4e8cc;
|
||||||
|
|
||||||
// EIP712_EXCHANGE_DOMAIN_VERSION()
|
// function EIP712_EXCHANGE_DOMAIN_VERSION()
|
||||||
bytes4 constant internal EIP_712_EXCHANGE_DOMAIN_VERSION_SELECTOR = 0x0f01323b;
|
bytes4 constant internal EIP_712_EXCHANGE_DOMAIN_VERSION_SELECTOR = 0x0f01323b;
|
||||||
|
|
||||||
// executeTransaction((uint256,address,bytes),bytes)
|
// function executeTransaction((uint256,address,bytes),bytes)
|
||||||
bytes4 constant internal EXECUTE_TRANSACTION_SELECTOR = 0x965504f7;
|
bytes4 constant internal EXECUTE_TRANSACTION_SELECTOR = 0x965504f7;
|
||||||
|
|
||||||
// filled(bytes32)
|
// function filled(bytes32)
|
||||||
bytes4 constant internal FILLED_SELECTOR = 0x288cdc91;
|
bytes4 constant internal FILLED_SELECTOR = 0x288cdc91;
|
||||||
|
|
||||||
// fillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),uint256,bytes)
|
// function fillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),uint256,bytes)
|
||||||
bytes4 constant internal FILL_ORDER_SELECTOR = 0x9b44d556;
|
bytes4 constant internal FILL_ORDER_SELECTOR = 0x9b44d556;
|
||||||
|
|
||||||
// fillOrderNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),uint256,bytes)
|
// function fillOrderNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),uint256,bytes)
|
||||||
bytes4 constant internal FILL_ORDER_NO_THROW_SELECTOR = 0x01da61ae;
|
bytes4 constant internal FILL_ORDER_NO_THROW_SELECTOR = 0x01da61ae;
|
||||||
|
|
||||||
// fillOrKillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),uint256,bytes)
|
// function fillOrKillOrder((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),uint256,bytes)
|
||||||
bytes4 constant internal FILL_OR_KILL_ORDER_SELECTOR = 0xe14b58c4;
|
bytes4 constant internal FILL_OR_KILL_ORDER_SELECTOR = 0xe14b58c4;
|
||||||
|
|
||||||
// getAssetProxy(bytes4)
|
// function getAssetProxy(bytes4)
|
||||||
bytes4 constant internal GET_ASSET_PROXY_SELECTOR = 0x60704108;
|
bytes4 constant internal GET_ASSET_PROXY_SELECTOR = 0x60704108;
|
||||||
|
|
||||||
// getOrderHash((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes))
|
// function getOrderHash((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes))
|
||||||
bytes4 constant internal GET_ORDER_HASH_SELECTOR = 0xad3449bd;
|
bytes4 constant internal GET_ORDER_HASH_SELECTOR = 0xad3449bd;
|
||||||
|
|
||||||
// getOrderInfo((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes))
|
// function getOrderInfo((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes))
|
||||||
bytes4 constant internal GET_ORDER_INFO_SELECTOR = 0x9d3fa4b9;
|
bytes4 constant internal GET_ORDER_INFO_SELECTOR = 0x9d3fa4b9;
|
||||||
|
|
||||||
// getOrdersInfo((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[])
|
// function getOrdersInfo((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[])
|
||||||
bytes4 constant internal GET_ORDERS_INFO_SELECTOR = 0x9dfac06d;
|
bytes4 constant internal GET_ORDERS_INFO_SELECTOR = 0x9dfac06d;
|
||||||
|
|
||||||
// getTransactionHash((uint256,address,bytes))
|
// function getTransactionHash((uint256,address,bytes))
|
||||||
bytes4 constant internal GET_TRANSACTION_HASH_SELECTOR = 0x23872f55;
|
bytes4 constant internal GET_TRANSACTION_HASH_SELECTOR = 0x23872f55;
|
||||||
|
|
||||||
// isValidHashSignature(bytes32,address,bytes)
|
// function isValidHashSignature(bytes32,address,bytes)
|
||||||
bytes4 constant internal IS_VALID_HASH_SIGNATURE_SELECTOR = 0x8171c407;
|
bytes4 constant internal IS_VALID_HASH_SIGNATURE_SELECTOR = 0x8171c407;
|
||||||
|
|
||||||
// isValidOrderSignature((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),address,bytes)
|
// function isValidOrderSignature((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),address,bytes)
|
||||||
bytes4 constant internal IS_VALID_ORDER_SIGNATURE_SELECTOR = 0xf813e384;
|
bytes4 constant internal IS_VALID_ORDER_SIGNATURE_SELECTOR = 0xf813e384;
|
||||||
|
|
||||||
// marketBuyOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256,bytes[])
|
// function marketBuyOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256,bytes[])
|
||||||
bytes4 constant internal MARKET_BUY_ORDERS_SELECTOR = 0xdb702a9c;
|
bytes4 constant internal MARKET_BUY_ORDERS_SELECTOR = 0xdb702a9c;
|
||||||
|
|
||||||
// marketBuyOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256,bytes[])
|
// function marketBuyOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256,bytes[])
|
||||||
bytes4 constant internal MARKET_BUY_ORDERS_NO_THROW_SELECTOR = 0x78d29ac1;
|
bytes4 constant internal MARKET_BUY_ORDERS_NO_THROW_SELECTOR = 0x78d29ac1;
|
||||||
|
|
||||||
// marketSellOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256,bytes[])
|
// function marketSellOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256,bytes[])
|
||||||
bytes4 constant internal MARKET_SELL_ORDERS_SELECTOR = 0x52b3ca9e;
|
bytes4 constant internal MARKET_SELL_ORDERS_SELECTOR = 0x52b3ca9e;
|
||||||
|
|
||||||
// marketSellOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256,bytes[])
|
// function marketSellOrdersNoThrow((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes)[],uint256,bytes[])
|
||||||
bytes4 constant internal MARKET_SELL_ORDERS_NO_THROW_SELECTOR = 0x369da099;
|
bytes4 constant internal MARKET_SELL_ORDERS_NO_THROW_SELECTOR = 0x369da099;
|
||||||
|
|
||||||
// matchOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),bytes,bytes)
|
// function matchOrders((address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),(address,address,address,address,uint256,uint256,uint256,uint256,uint256,uint256,bytes,bytes,bytes,bytes),bytes,bytes)
|
||||||
bytes4 constant internal MATCH_ORDERS_SELECTOR = 0x88ec79fb;
|
bytes4 constant internal MATCH_ORDERS_SELECTOR = 0x88ec79fb;
|
||||||
|
|
||||||
// orderEpoch(address,address)
|
// function orderEpoch(address,address)
|
||||||
bytes4 constant internal ORDER_EPOCH_SELECTOR = 0xd9bfa73e;
|
bytes4 constant internal ORDER_EPOCH_SELECTOR = 0xd9bfa73e;
|
||||||
|
|
||||||
// owner()
|
// function owner()
|
||||||
bytes4 constant internal OWNER_SELECTOR = 0x8da5cb5b;
|
bytes4 constant internal OWNER_SELECTOR = 0x8da5cb5b;
|
||||||
|
|
||||||
// preSign(bytes32)
|
// function preSign(bytes32)
|
||||||
bytes4 constant internal PRE_SIGN_SELECTOR = 0x46c02d7a;
|
bytes4 constant internal PRE_SIGN_SELECTOR = 0x46c02d7a;
|
||||||
|
|
||||||
// preSigned(bytes32,address)
|
// function preSigned(bytes32,address)
|
||||||
bytes4 constant internal PRE_SIGNED_SELECTOR = 0x82c174d0;
|
bytes4 constant internal PRE_SIGNED_SELECTOR = 0x82c174d0;
|
||||||
|
|
||||||
// registerAssetProxy(address)
|
// function registerAssetProxy(address)
|
||||||
bytes4 constant internal REGISTER_ASSET_PROXY_SELECTOR = 0xc585bb93;
|
bytes4 constant internal REGISTER_ASSET_PROXY_SELECTOR = 0xc585bb93;
|
||||||
|
|
||||||
// setOrderValidatorApproval(address,bool)
|
// function setOrderValidatorApproval(address,bool)
|
||||||
bytes4 constant internal SET_ORDER_VALIDATOR_APPROVAL_SELECTOR = 0x5972957b;
|
bytes4 constant internal SET_ORDER_VALIDATOR_APPROVAL_SELECTOR = 0x5972957b;
|
||||||
|
|
||||||
// setSignatureValidatorApproval(address,bool)
|
// function setSignatureValidatorApproval(address,bool)
|
||||||
bytes4 constant internal SET_SIGNATURE_VALIDATOR_APPROVAL_SELECTOR = 0x77fcce68;
|
bytes4 constant internal SET_SIGNATURE_VALIDATOR_APPROVAL_SELECTOR = 0x77fcce68;
|
||||||
|
|
||||||
// transactions(bytes32)
|
// function transactions(bytes32)
|
||||||
bytes4 constant internal TRANSACTIONS_SELECTOR = 0x642f2eaf;
|
bytes4 constant internal TRANSACTIONS_SELECTOR = 0x642f2eaf;
|
||||||
|
|
||||||
// transferOwnership(address)
|
// function transferOwnership(address)
|
||||||
bytes4 constant internal TRANSFER_OWNERSHIP_SELECTOR = 0xf2fde38b;
|
bytes4 constant internal TRANSFER_OWNERSHIP_SELECTOR = 0xf2fde38b;
|
||||||
|
|
||||||
// VERSION()
|
// function VERSION()
|
||||||
bytes4 constant internal VERSION_SELECTOR = 0xffa1ad74;
|
bytes4 constant internal VERSION_SELECTOR = 0xffa1ad74;
|
||||||
|
|
||||||
|
// event AssetProxyRegistered(bytes4,address)
|
||||||
|
bytes32 constant internal EVENT_ASSETPROXYREGISTERED_SELECTOR = 0xd2c6b762299c609bdb96520b58a49bfb80186934d4f71a86a367571a15c03194;
|
||||||
|
|
||||||
|
// event Cancel(address,address,address,bytes32,bytes,bytes)
|
||||||
|
bytes32 constant internal EVENT_CANCEL_SELECTOR = 0xdc47b3613d9fe400085f6dbdc99453462279057e6207385042827ed6b1a62cf7;
|
||||||
|
|
||||||
|
// event CancelUpTo(address,address,uint256)
|
||||||
|
bytes32 constant internal EVENT_CANCELUPTO_SELECTOR = 0x82af639571738f4ebd4268fb0363d8957ebe1bbb9e78dba5ebd69eed39b154f0;
|
||||||
|
|
||||||
|
// event Fill(address,address,address,address,uint256,uint256,uint256,uint256,bytes32,bytes,bytes,bytes,bytes)
|
||||||
|
bytes32 constant internal EVENT_FILL_SELECTOR = 0xcb32b586b1d019abfd3dfc2d45e7275f145185e9d53359e9b99521ca88cea0e8;
|
||||||
|
|
||||||
|
// event SignatureValidatorApproval(address,address,bool)
|
||||||
|
bytes32 constant internal EVENT_SIGNATUREVALIDATORAPPROVAL_SELECTOR = 0xa8656e308026eeabce8f0bc18048433252318ab80ac79da0b3d3d8697dfba891;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
"test:circleci": "yarn test",
|
"test:circleci": "yarn test",
|
||||||
"contracts:gen": "contracts-gen",
|
"contracts:gen": "contracts-gen",
|
||||||
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
|
"lint-contracts": "solhint -c ../.solhint.json contracts/**/**/**/**/*.sol",
|
||||||
"generate-exchange-selectors": "node scripts/generate-exchange-selectors.js ../../exchange/generated-artifacts/Exchange.json ./contracts/src/LibExchangeSelectors.sol"
|
"generate-exchange-selectors": "node lib/scripts/generate-exchange-selectors.js ../../../exchange/generated-artifacts/Exchange.json ./contracts/src/LibExchangeSelectors.sol"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"abis": "./generated-artifacts/@(LibEIP712ExchangeDomain|LibFillResults|LibMath|LibOrder|LibZeroExTransaction|TestLibs).json",
|
"abis": "./generated-artifacts/@(LibEIP712ExchangeDomain|LibFillResults|LibMath|LibOrder|LibZeroExTransaction|TestLibs).json",
|
||||||
|
@ -1,110 +0,0 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
const ethUtil = require('ethereumjs-util');
|
|
||||||
const fs = require('fs');
|
|
||||||
const _ = require('lodash');
|
|
||||||
const path = require('path');
|
|
||||||
const process = require('process');
|
|
||||||
|
|
||||||
const keccak256 = ethUtil.keccak256 || ethUtil.sha3;
|
|
||||||
const ARGS = process.argv.slice(2);
|
|
||||||
const INDENT = ' ';
|
|
||||||
const LINEBREAK = '\n';
|
|
||||||
const VISIBILITY = 'internal';
|
|
||||||
|
|
||||||
(function () {
|
|
||||||
const [ exchangeArtifactsFile, outputFile ] = ARGS;
|
|
||||||
const exchangeArtifacts = require(exchangeArtifactsFile);
|
|
||||||
const contractName = path.basename(outputFile, '.sol');
|
|
||||||
const functionsByName = extractFunctions(
|
|
||||||
exchangeArtifacts.compilerOutput.abi,
|
|
||||||
);
|
|
||||||
const contractDefinition = defineContract(contractName, functionsByName);
|
|
||||||
const preamble = extractOutputFilePreamble(outputFile);
|
|
||||||
const outputFileContents = `${preamble}${contractDefinition}${LINEBREAK}`;
|
|
||||||
fs.writeFileSync(outputFile, outputFileContents);
|
|
||||||
console.log(`Wrote exchange selectors to "${path.resolve(outputFile)}."`);
|
|
||||||
})();
|
|
||||||
|
|
||||||
function extractFunctions(abi) {
|
|
||||||
const selectorsByName = {};
|
|
||||||
for (const method of abi) {
|
|
||||||
if (method.type !== 'function') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
const name = method.name;
|
|
||||||
const signature = `${name}(${encodeMethodInputs(method.inputs)})`;
|
|
||||||
const selector = `0x${keccak256(signature).slice(0, 4).toString('hex')}`;
|
|
||||||
if (!selectorsByName[name]) {
|
|
||||||
selectorsByName[name] = [];
|
|
||||||
}
|
|
||||||
selectorsByName[name].push({
|
|
||||||
selector,
|
|
||||||
signature,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return selectorsByName;
|
|
||||||
}
|
|
||||||
|
|
||||||
function defineContract(contractName, functionsByName) {
|
|
||||||
const constantDefinitions = [];
|
|
||||||
const sortedFunctionNames = _.sortBy(_.keys(functionsByName), name => name.toLowerCase());
|
|
||||||
for (const name of sortedFunctionNames) {
|
|
||||||
const fns = functionsByName[name];
|
|
||||||
for (let idx = 0; idx < fns.length; idx++) {
|
|
||||||
const constantLines = generateSelectorConstantDefinition(
|
|
||||||
name,
|
|
||||||
fns[idx],
|
|
||||||
idx,
|
|
||||||
fns.length,
|
|
||||||
);
|
|
||||||
constantDefinitions.push(constantLines);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return [
|
|
||||||
`contract ${contractName} {`,
|
|
||||||
`${INDENT}// solhint-disable max-line-length`,
|
|
||||||
'',
|
|
||||||
constantDefinitions
|
|
||||||
.map(lines => lines.map(line => `${INDENT}${line}`))
|
|
||||||
.map(lines => lines.join(LINEBREAK))
|
|
||||||
.join(`${LINEBREAK}${LINEBREAK}`),
|
|
||||||
`}`,
|
|
||||||
].join(LINEBREAK);
|
|
||||||
}
|
|
||||||
|
|
||||||
function extractOutputFilePreamble(outputFile) {
|
|
||||||
const preambleLines = [];
|
|
||||||
const outputFileLines = fs.readFileSync(outputFile, 'utf-8').split(/\r?\n/);
|
|
||||||
for (const line of outputFileLines) {
|
|
||||||
if (/^\s*contract\s+[a-zA-Z][a-zA-Z0-9_]+/.test(line)) {
|
|
||||||
preambleLines.push('');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
preambleLines.push(line);
|
|
||||||
}
|
|
||||||
return preambleLines.join(LINEBREAK);
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateSelectorConstantDefinition(name, selector, idx, total) {
|
|
||||||
const varName =
|
|
||||||
_.snakeCase(total == 1 ? name : `${name}_${idx+1}`).toUpperCase();
|
|
||||||
return [
|
|
||||||
`// ${selector.signature}`,
|
|
||||||
`bytes4 constant ${VISIBILITY} ${varName}_SELECTOR = ${selector.selector};`,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function encodeMethodInputs(inputs) {
|
|
||||||
const types = [];
|
|
||||||
for (const input of inputs) {
|
|
||||||
if (input.type === 'tuple') {
|
|
||||||
types.push(`(${encodeMethodInputs(input.components)})`);
|
|
||||||
} else if (input.type === 'tuple[]') {
|
|
||||||
types.push(`(${encodeMethodInputs(input.components)})[]`);
|
|
||||||
} else {
|
|
||||||
types.push(input.type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return types.join(',');
|
|
||||||
}
|
|
162
contracts/exchange-libs/scripts/generate-exchange-selectors.ts
Normal file
162
contracts/exchange-libs/scripts/generate-exchange-selectors.ts
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
import { AbiDefinition, ContractAbi, DataItem, EventAbi, MethodAbi } from 'ethereum-types';
|
||||||
|
import * as ethUtil from 'ethereumjs-util';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as _ from 'lodash';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as process from 'process';
|
||||||
|
|
||||||
|
const keccak256 = ethUtil.sha3;
|
||||||
|
const ARGS = process.argv.slice(2);
|
||||||
|
const INDENT = ' ';
|
||||||
|
const LINEBREAK = '\n';
|
||||||
|
const VISIBILITY = 'internal';
|
||||||
|
|
||||||
|
interface ParsedContract {
|
||||||
|
methods: {
|
||||||
|
[functionName: string]: Array<{
|
||||||
|
selector: string;
|
||||||
|
signature: string;
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
events: {
|
||||||
|
[eventName: string]: {
|
||||||
|
selector: string;
|
||||||
|
signature: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// tslint:disable: no-console
|
||||||
|
(() => {
|
||||||
|
const [exchangeArtifactsFile, outputFile] = ARGS;
|
||||||
|
const exchangeArtifacts = require(exchangeArtifactsFile);
|
||||||
|
const contractName = path.basename(outputFile, '.sol');
|
||||||
|
const parsedContract = parseContract(exchangeArtifacts.compilerOutput.abi);
|
||||||
|
const contractDefinition = defineContract(contractName, parsedContract);
|
||||||
|
const preamble = extractOutputFilePreamble(outputFile);
|
||||||
|
const outputFileContents = `${preamble}${contractDefinition}${LINEBREAK}`;
|
||||||
|
fs.writeFileSync(outputFile, outputFileContents);
|
||||||
|
console.log(`Wrote exchange selectors to "${path.resolve(outputFile)}."`);
|
||||||
|
})();
|
||||||
|
|
||||||
|
function parseContract(abi: ContractAbi): ParsedContract {
|
||||||
|
const parsedContract: ParsedContract = {
|
||||||
|
methods: {},
|
||||||
|
events: {},
|
||||||
|
};
|
||||||
|
for (const abiItem of abi) {
|
||||||
|
if (isMethodAbi(abiItem)) {
|
||||||
|
const name = abiItem.name;
|
||||||
|
const signature = `${name}(${encodeMethodInputs(abiItem.inputs)})`;
|
||||||
|
const selector = `0x${keccak256(signature)
|
||||||
|
.slice(0, 4)
|
||||||
|
.toString('hex')}`;
|
||||||
|
if (parsedContract.methods[name] === undefined) {
|
||||||
|
parsedContract.methods[name] = [];
|
||||||
|
}
|
||||||
|
parsedContract.methods[name].push({
|
||||||
|
selector,
|
||||||
|
signature,
|
||||||
|
});
|
||||||
|
} else if (isEventAbi(abiItem)) {
|
||||||
|
const name = abiItem.name;
|
||||||
|
const signature = `${name}(${encodeMethodInputs(abiItem.inputs)})`;
|
||||||
|
const selector = `0x${keccak256(signature).toString('hex')}`;
|
||||||
|
parsedContract.events[name] = {
|
||||||
|
selector,
|
||||||
|
signature,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return parsedContract;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMethodAbi(abiItem: AbiDefinition): abiItem is MethodAbi {
|
||||||
|
return abiItem.type === 'function';
|
||||||
|
}
|
||||||
|
|
||||||
|
function isEventAbi(abiItem: AbiDefinition): abiItem is EventAbi {
|
||||||
|
return abiItem.type === 'event';
|
||||||
|
}
|
||||||
|
|
||||||
|
function defineContract(contractName: string, parsedContract: ParsedContract): string {
|
||||||
|
const constantDefinitions = [];
|
||||||
|
// Define function selectors.
|
||||||
|
const sortedMethodNames = _.sortBy(_.keys(parsedContract.methods), name => name.toLowerCase());
|
||||||
|
for (const name of sortedMethodNames) {
|
||||||
|
const methods = parsedContract.methods[name];
|
||||||
|
for (let idx = 0; idx < methods.length; idx++) {
|
||||||
|
const constantLines = generateFunctionSelectorConstantDefinition(
|
||||||
|
name,
|
||||||
|
methods[idx].signature,
|
||||||
|
methods[idx].selector,
|
||||||
|
idx,
|
||||||
|
methods.length,
|
||||||
|
);
|
||||||
|
constantDefinitions.push(constantLines);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Define event selectors.
|
||||||
|
const sortedEventNames = _.sortBy(_.keys(parsedContract.events), name => name.toLowerCase());
|
||||||
|
for (const name of sortedEventNames) {
|
||||||
|
const event = parsedContract.events[name];
|
||||||
|
const constantLines = generateEventSelectorConstantDefinition(name, event.signature, event.selector);
|
||||||
|
constantDefinitions.push(constantLines);
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
`contract ${contractName} {`,
|
||||||
|
`${INDENT}// solhint-disable max-line-length`,
|
||||||
|
'',
|
||||||
|
constantDefinitions
|
||||||
|
.map(lines => lines.map(line => `${INDENT}${line}`))
|
||||||
|
.map(lines => lines.join(LINEBREAK))
|
||||||
|
.join(`${LINEBREAK}${LINEBREAK}`),
|
||||||
|
`}`,
|
||||||
|
].join(LINEBREAK);
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractOutputFilePreamble(outputFile: string): string {
|
||||||
|
const preambleLines = [];
|
||||||
|
const outputFileLines = fs.readFileSync(outputFile, 'utf-8').split(/\r?\n/);
|
||||||
|
for (const line of outputFileLines) {
|
||||||
|
if (/^\s*contract\s+[a-zA-Z][a-zA-Z0-9_]+/.test(line)) {
|
||||||
|
preambleLines.push('');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
preambleLines.push(line);
|
||||||
|
}
|
||||||
|
return preambleLines.join(LINEBREAK);
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateFunctionSelectorConstantDefinition(
|
||||||
|
name: string,
|
||||||
|
signature: string,
|
||||||
|
selector: string,
|
||||||
|
idx: number,
|
||||||
|
total: number,
|
||||||
|
): string[] {
|
||||||
|
const varName = _.snakeCase(total === 1 ? name : `${name}_${idx + 1}`).toUpperCase();
|
||||||
|
return [`// function ${signature}`, `bytes4 constant ${VISIBILITY} ${varName}_SELECTOR = ${selector};`];
|
||||||
|
}
|
||||||
|
|
||||||
|
function generateEventSelectorConstantDefinition(name: string, signature: string, selector: string): string[] {
|
||||||
|
const varName = _.snakeCase(name).toUpperCase();
|
||||||
|
return [`// event ${signature}`, `bytes32 constant ${VISIBILITY} EVENT_${varName}_SELECTOR = ${selector};`];
|
||||||
|
}
|
||||||
|
|
||||||
|
function encodeMethodInputs(inputs?: DataItem[]): string {
|
||||||
|
if (inputs === undefined) {
|
||||||
|
throw new Error('encodeMethodInputs: inputs are undefined');
|
||||||
|
}
|
||||||
|
const types = [];
|
||||||
|
for (const input of inputs) {
|
||||||
|
if (input.type === 'tuple') {
|
||||||
|
types.push(`(${encodeMethodInputs(input.components)})`);
|
||||||
|
} else if (input.type === 'tuple[]') {
|
||||||
|
types.push(`(${encodeMethodInputs(input.components)})[]`);
|
||||||
|
} else {
|
||||||
|
types.push(input.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return types.join(',');
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"extends": "../../tsconfig",
|
"extends": "../../tsconfig",
|
||||||
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
||||||
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
"include": ["./src/**/*", "./test/**/*", "./scripts/**/*", "./generated-wrappers/**/*"],
|
||||||
"files": [
|
"files": [
|
||||||
"generated-artifacts/LibEIP712ExchangeDomain.json",
|
"generated-artifacts/LibEIP712ExchangeDomain.json",
|
||||||
"generated-artifacts/LibFillResults.json",
|
"generated-artifacts/LibFillResults.json",
|
||||||
|
@ -2,8 +2,5 @@
|
|||||||
"extends": ["@0x/tslint-config"],
|
"extends": ["@0x/tslint-config"],
|
||||||
"rules": {
|
"rules": {
|
||||||
"custom-no-magic-numbers": false
|
"custom-no-magic-numbers": false
|
||||||
},
|
|
||||||
"linterOptions": {
|
|
||||||
"exclude": ["./scripts/**.js"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user