Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

Commit

Permalink
add local evm for pure functions
Browse files Browse the repository at this point in the history
  • Loading branch information
xianny committed Aug 28, 2019
1 parent ad83b17 commit c1322c5
Show file tree
Hide file tree
Showing 17 changed files with 335 additions and 504 deletions.
4 changes: 4 additions & 0 deletions packages/0x.js/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ module.exports = {
}),
],
},
// HACK: Temporary fix for this issue: https://github.com/trufflesuite/ganache-core/issues/84
node: {
fs: 'empty',
},
module: {
rules: [
{
Expand Down
4 changes: 2 additions & 2 deletions packages/abi-gen/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@
"clean": "shx rm -rf lib && yarn test_cli:clean",
"build": "tsc -b && yarn generate_contract_wrappers && yarn prettier_contract_wrappers && yarn test_cli:build",
"build:ci": "yarn build",
"test": "yarn run_mocha && yarn test_cli",
"test": "run-p run_mocha && yarn test_cli",
"test:circleci": "yarn test:coverage && yarn test_cli",
"run_mocha": "(uname -s | grep -q Darwin && echo 'HACK! skipping mocha run due to https://github.com/0xProject/0x-monorepo/issues/2000') || mocha --require source-map-support/register --require make-promises-safe lib/test/*_test.js --timeout 100000 --bail --exit",
"test:coverage": "nyc npm run test --all && yarn coverage:report:lcov",
"coverage:report:lcov": "nyc report --reporter=text-lcov > coverage/lcov.info",
"test_cli": "run-p test_cli:test_typescript diff_contract_wrappers",
"test_cli": "run-s test_cli:test_typescript diff_contract_wrappers",
"test_cli:clean": "rm -rf test-cli/test_typescript/lib",
"test_cli:build": "tsc --project test-cli/tsconfig.json",
"test_cli:test_typescript": "mocha --require source-map-support/register --require make-promises-safe test-cli/test_typescript/lib/**/*_test.js --timeout 100000 --bail --exit",
Expand Down
19 changes: 12 additions & 7 deletions packages/abi-gen/templates/TypeScript/contract.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,18 @@ export class {{contractName}}Contract extends BaseContract {
/**
* {{formatDocstringForMethodTs this.devdoc.details}}
*/
{{/if}}
{{#this.constant}}
{{> call contractName=../contractName}}
{{/this.constant}}
{{^this.constant}}
{{> tx contractName=../contractName}}
{{/this.constant}}
{{/if}}
public {{languageSpecificName}} = {
{{^this.constant}}
{{> method_tx contractName=../contractName}}
{{/this.constant}}
{{#ifEquals this.stateMutability "pure"}}
{{> method_call_pure contractName=../contractName}}
{{else}}
{{> method_call contractName=../contractName}}
{{/ifEquals}}
{{> method_abi_helper contractName=../contractName}}
};
{{/each}}
{{#if events}}private readonly _subscriptionManager: SubscriptionManager<{{contractName}}EventArgs, {{contractName}}Events>;
{{/if}}public static async deployFrom0xArtifactAsync(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Returns the ABI encoded transaction data needed to send an Ethereum transaction calling this method. Before
* sending the Ethereum tx, this encoded tx data can first be sent to a separate signing service or can be used
* to create a 0x transaction (see protocol spec for more details).
{{> params_docstring inputs=inputs docstrings=devdoc.params}}
*/
getABIEncodedTransactionData(
{{> typed_params inputs=inputs}}
): string {
{{#each inputs}}
{{#assertionType name type}}{{/assertionType}}
{{/each}}
const self = this as any as {{contractName}}Contract;
const abiEncodedTransactionData = self._strictEncodeArguments('{{this.functionSignature}}', [{{> normalized_params inputs=inputs}}]);
return abiEncodedTransactionData;
},
getABIDecodedTransactionData(
callData: string
): ({{> return_type inputs=inputs ~}}) {
const self = this as any as {{contractName}}Contract;
const abiEncoder = self._lookupAbiEncoder('{{this.functionSignature}}');
// tslint:disable boolean-naming
const abiDecodedCallData = abiEncoder.strictDecode<{{> return_type inputs=inputs}}>(callData);
return abiDecodedCallData;
},
getABIDecodedReturnData(
returnData: string
): ({{> return_type outputs=outputs ~}}) {
const self = this as any as {{contractName}}Contract;
const abiEncoder = self._lookupAbiEncoder('{{this.functionSignature}}');
// tslint:disable boolean-naming
const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<{{> return_type outputs=outputs}}>(returnData);
return abiDecodedReturnData;
},
Original file line number Diff line number Diff line change
Expand Up @@ -43,37 +43,3 @@ async callAsync(
// tslint:enable boolean-naming
return result;
},
/**
* Returns the ABI encoded transaction data needed to send an Ethereum transaction calling this method. Before
* sending the Ethereum tx, this encoded tx data can first be sent to a separate signing service or can be used
* to create a 0x transaction (see protocol spec for more details).
{{> params_docstring inputs=inputs docstrings=devdoc.params}}
*/
getABIEncodedTransactionData(
{{> typed_params inputs=inputs}}
): string {
{{#each inputs}}
{{#assertionType name type}}{{/assertionType}}
{{/each}}
const self = this as any as {{contractName}}Contract;
const abiEncodedTransactionData = self._strictEncodeArguments('{{this.functionSignature}}', [{{> normalized_params inputs=inputs}}]);
return abiEncodedTransactionData;
},
getABIDecodedTransactionData(
callData: string
): ({{> return_type inputs=inputs ~}}) {
const self = this as any as {{contractName}}Contract;
const abiEncoder = self._lookupAbiEncoder('{{this.functionSignature}}');
// tslint:disable boolean-naming
const abiDecodedCallData = abiEncoder.strictDecode<{{> return_type inputs=inputs}}>(callData);
return abiDecodedCallData;
},
getABIDecodedReturnData(
returnData: string
): ({{> return_type outputs=outputs ~}}) {
const self = this as any as {{contractName}}Contract;
const abiEncoder = self._lookupAbiEncoder('{{this.functionSignature}}');
// tslint:disable boolean-naming
const abiDecodedReturnData = abiEncoder.strictDecodeReturnValue<{{> return_type outputs=outputs}}>(returnData);
return abiDecodedReturnData;
},
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Sends a read-only call to the contract method. Returns the result that would happen if one were to send an
* Ethereum transaction to this method, given the current state of the blockchain. Calls do not cost gas
* since they don't modify state.
{{> params_docstring inputs=inputs docstrings=devdoc.params}}
{{#if devdoc.return}}
* @returns {{devdoc.return}}
{{/if}}
*/
async callAsync(
{{> typed_params inputs=inputs}}
callData: Partial<CallData> = {},
defaultBlock?: BlockParam,
): Promise<{{> return_type outputs=outputs}}> {
{{#each inputs}}
{{#assertionType name type}}{{/assertionType}}
{{/each}}
assert.doesConformToSchema('callData', callData, schemas.callDataSchema, [
schemas.addressSchema,
schemas.numberSchema,
schemas.jsNumber,
]);
if (defaultBlock !== undefined) {
assert.isBlockParam('defaultBlock', defaultBlock);
}
const self = this as any as {{contractName}}Contract;
const encodedData = self._strictEncodeArguments('{{this.functionSignature}}', [{{> normalized_params inputs=inputs}}]);
const encodedDataBytes = Buffer.from(encodedData.substr(2), 'hex');

const rawCallResult = await self.evmExecAsync(encodedDataBytes);
BaseContract._throwIfRevertWithReasonCallResult(rawCallResult);
const abiEncoder = self._lookupAbiEncoder('{{this.functionSignature}}');
// tslint:disable boolean-naming
const result = abiEncoder.strictDecodeReturnValue<{{> return_type outputs=outputs}}>(rawCallResult);
// tslint:enable boolean-naming
return result;
},
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
public {{languageSpecificName}} = {
/**
* Sends an Ethereum transaction executing this method with the supplied parameters. This is a read/write
* Ethereum operation and will cost gas.
{{> params_docstring inputs=inputs docstrings=devdoc.params}}
* @param txData Additional data for transaction
* @returns The hash of the transaction
*/
async sendTransactionAsync(
{{> typed_params inputs=inputs}}
txData?: Partial<TxData> | undefined,
): Promise<string> {
/**
* Sends an Ethereum transaction executing this method with the supplied parameters. This is a read/write
* Ethereum operation and will cost gas.
{{> params_docstring inputs=inputs docstrings=devdoc.params}}
* @param txData Additional data for transaction
* @returns The hash of the transaction
*/
async sendTransactionAsync(
{{> typed_params inputs=inputs}}
txData?: Partial<TxData> | undefined,
): Promise<string> {
{{#each inputs}}
{{#assertionType name type}}{{/assertionType}}
{{/each}}
Expand All @@ -33,21 +32,21 @@ public {{languageSpecificName}} = {

const txHash = await self._web3Wrapper.sendTransactionAsync(txDataWithDefaults);
return txHash;
},
/**
* Sends an Ethereum transaction and waits until the transaction has been successfully mined without reverting.
* If the transaction was mined, but reverted, an error is thrown.
{{> params_docstring inputs=inputs docstrings=devdoc.params}}
* @param txData Additional data for transaction
* @param pollingIntervalMs Interval at which to poll for success
* @returns A promise that resolves when the transaction is successful
*/
awaitTransactionSuccessAsync(
{{> typed_params inputs=inputs}}
txData?: Partial<TxData>,
pollingIntervalMs?: number,
timeoutMs?: number,
): PromiseWithTransactionHash<TransactionReceiptWithDecodedLogs> {
},
/**
* Sends an Ethereum transaction and waits until the transaction has been successfully mined without reverting.
* If the transaction was mined, but reverted, an error is thrown.
{{> params_docstring inputs=inputs docstrings=devdoc.params}}
* @param txData Additional data for transaction
* @param pollingIntervalMs Interval at which to poll for success
* @returns A promise that resolves when the transaction is successful
*/
awaitTransactionSuccessAsync(
{{> typed_params inputs=inputs}}
txData?: Partial<TxData>,
pollingIntervalMs?: number,
timeoutMs?: number,
): PromiseWithTransactionHash<TransactionReceiptWithDecodedLogs> {
{{#each inputs}}
{{#assertionType name type}}{{/assertionType}}
{{/each}}
Expand All @@ -68,17 +67,17 @@ public {{languageSpecificName}} = {
);
})(),
);
},
/**
* Estimates the gas cost of sending an Ethereum transaction calling this method with these arguments.
{{> params_docstring inputs=inputs docstrings=devdoc.params}}
* @param txData Additional data for transaction
* @returns The hash of the transaction
*/
async estimateGasAsync(
{{> typed_params inputs=inputs}}
txData?: Partial<TxData> | undefined,
): Promise<number> {
},
/**
* Estimates the gas cost of sending an Ethereum transaction calling this method with these arguments.
{{> params_docstring inputs=inputs docstrings=devdoc.params}}
* @param txData Additional data for transaction
* @returns The hash of the transaction
*/
async estimateGasAsync(
{{> typed_params inputs=inputs}}
txData?: Partial<TxData> | undefined,
): Promise<number> {
{{#each inputs}}
{{#assertionType name type}}{{/assertionType}}
{{/each}}
Expand All @@ -95,27 +94,25 @@ public {{languageSpecificName}} = {
if (txDataWithDefaults.from !== undefined) {
txDataWithDefaults.from = txDataWithDefaults.from.toLowerCase();
}

const gas = await self._web3Wrapper.estimateGasAsync(txDataWithDefaults);
return gas;
},
{{> callAsync}}
async validateAndSendTransactionAsync(
{{> typed_params inputs=inputs}}
txData?: Partial<TxData> | undefined,
): Promise<string> {
await (this as any).{{languageSpecificName}}.callAsync(
{{#each inputs~}}
{{name}},
{{/each~}}
txData,
);
const txHash = await (this as any).{{languageSpecificName}}.sendTransactionAsync(
{{#each inputs~}}
{{name}},
{{/each~}}
txData,
);
return txHash;
}
};
},
async validateAndSendTransactionAsync(
{{> typed_params inputs=inputs}}
txData?: Partial<TxData> | undefined,
): Promise<string> {
await (this as any).{{languageSpecificName}}.callAsync(
{{#each inputs~}}
{{name}},
{{/each~}}
txData,
);
const txHash = await (this as any).{{languageSpecificName}}.sendTransactionAsync(
{{#each inputs~}}
{{name}},
{{/each~}}
txData,
);
return txHash;
},
Loading

0 comments on commit c1322c5

Please sign in to comment.