Cherry pick library linking code from #2456
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
export { artifacts } from './artifacts';
|
||||
export { DevUtilsContract } from './wrappers';
|
||||
export { DevUtilsContract, LibAssetDataContract, LibTransactionDecoderContract } from './wrappers';
|
||||
export {
|
||||
ContractArtifact,
|
||||
ContractChains,
|
||||
|
@@ -1,4 +1,13 @@
|
||||
[
|
||||
{
|
||||
"version": "5.2.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Support deploying contracts with unliked libraries through `deployWithLibrariesFrom0xArtifactAsync()`",
|
||||
"pr": 2463
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1580988106,
|
||||
"version": "5.1.2",
|
||||
|
@@ -10,6 +10,7 @@ import {
|
||||
{{#if events~}}SubscriptionManager,{{/if~}}
|
||||
PromiseWithTransactionHash,
|
||||
methodAbiToFunctionSignature,
|
||||
linkLibrariesInBytecode,
|
||||
} from '@0x/base-contract';
|
||||
import { schemas } from '@0x/json-schemas';
|
||||
import {
|
||||
@@ -27,7 +28,7 @@ import {
|
||||
TxDataPayable,
|
||||
SupportedProvider,
|
||||
} from 'ethereum-types';
|
||||
import { BigNumber, classUtils, logUtils, providerUtils } from '@0x/utils';
|
||||
import { BigNumber, classUtils, hexUtils, logUtils, providerUtils } from '@0x/utils';
|
||||
import { EventCallback, IndexedFilterValues, SimpleContractArtifact } from '@0x/types';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { assert } from '@0x/assert';
|
||||
@@ -97,6 +98,47 @@ export class {{contractName}}Contract extends BaseContract {
|
||||
}
|
||||
return {{contractName}}Contract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, {{> params inputs=ctor.inputs}});
|
||||
}
|
||||
|
||||
public static async deployWithLibrariesFrom0xArtifactAsync(
|
||||
artifact: ContractArtifact,
|
||||
libraryArtifacts: { [libraryName: string]: ContractArtifact },
|
||||
supportedProvider: SupportedProvider,
|
||||
txDefaults: Partial<TxData>,
|
||||
logDecodeDependencies: { [contractName: string]: (ContractArtifact | SimpleContractArtifact) },
|
||||
{{> typed_params inputs=ctor.inputs}}
|
||||
): Promise<{{contractName}}Contract> {
|
||||
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
|
||||
schemas.addressSchema,
|
||||
schemas.numberSchema,
|
||||
schemas.jsNumber,
|
||||
]);
|
||||
if (artifact.compilerOutput === undefined) {
|
||||
throw new Error('Compiler output not found in the artifact file');
|
||||
}
|
||||
const provider = providerUtils.standardizeOrThrow(supportedProvider);
|
||||
const abi = artifact.compilerOutput.abi;
|
||||
const logDecodeDependenciesAbiOnly: { [contractName: string]: ContractAbi } = {};
|
||||
if (Object.keys(logDecodeDependencies) !== undefined) {
|
||||
for (const key of Object.keys(logDecodeDependencies)) {
|
||||
logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi;
|
||||
}
|
||||
}
|
||||
const libraryAddresses = await {{contractName}}Contract._deployLibrariesAsync(
|
||||
artifact,
|
||||
libraryArtifacts,
|
||||
new Web3Wrapper(provider),
|
||||
txDefaults
|
||||
);
|
||||
const bytecode = linkLibrariesInBytecode(
|
||||
artifact.compilerOutput.evm.bytecode,
|
||||
libraryAddresses,
|
||||
);
|
||||
if (!hexUtils.isHex(bytecode)) {
|
||||
throw new Error(`Bytecode for "${artifact.contractName}" was not fully linked.`);
|
||||
}
|
||||
return {{contractName}}Contract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, {{> params inputs=ctor.inputs}});
|
||||
}
|
||||
|
||||
public static async deployAsync(
|
||||
bytecode: string,
|
||||
abi: ContractAbi,
|
||||
@@ -138,7 +180,6 @@ export class {{contractName}}Contract extends BaseContract {
|
||||
return contractInstance;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @returns The contract ABI
|
||||
*/
|
||||
@@ -168,12 +209,64 @@ export class {{contractName}}Contract extends BaseContract {
|
||||
return abi;
|
||||
}
|
||||
|
||||
protected static async _deployLibrariesAsync(
|
||||
artifact: ContractArtifact,
|
||||
libraryArtifacts: { [libraryName: string]: ContractArtifact },
|
||||
web3Wrapper: Web3Wrapper,
|
||||
txDefaults: Partial<TxData>,
|
||||
libraryAddresses: { [libraryName: string]: string } = {},
|
||||
): Promise<{ [libraryName: string]: string }> {
|
||||
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
|
||||
// Go through all linked libraries, recursively deploying them if necessary.
|
||||
for (const link of Object.values(links)) {
|
||||
for (const libraryName of Object.keys(link)) {
|
||||
if (!libraryAddresses[libraryName]) {
|
||||
// Library not yet deployed.
|
||||
const libraryArtifact = libraryArtifacts[libraryName];
|
||||
if (!libraryArtifact) {
|
||||
throw new Error(`Missing artifact for linked library "${libraryName}"`);
|
||||
}
|
||||
// Deploy any dependent libraries used by this library.
|
||||
await {{contractName}}Contract._deployLibrariesAsync(
|
||||
libraryArtifact,
|
||||
libraryArtifacts,
|
||||
web3Wrapper,
|
||||
txDefaults,
|
||||
libraryAddresses,
|
||||
);
|
||||
// Deploy this library.
|
||||
const linkedLibraryBytecode = linkLibrariesInBytecode(
|
||||
libraryArtifact.compilerOutput.evm.bytecode,
|
||||
libraryAddresses,
|
||||
);
|
||||
if (!hexUtils.isHex(linkedLibraryBytecode)) {
|
||||
throw new Error(`Bytecode for library "${libraryArtifact.contractName}" was not fully linked.`);
|
||||
}
|
||||
const txDataWithDefaults = await BaseContract._applyDefaultsToContractTxDataAsync(
|
||||
{
|
||||
data: linkedLibraryBytecode,
|
||||
...txDefaults,
|
||||
},
|
||||
web3Wrapper.estimateGasAsync.bind(web3Wrapper),
|
||||
);
|
||||
const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults);
|
||||
logUtils.log(`transactionHash: ${txHash}`);
|
||||
const { contractAddress } = await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
logUtils.log(`${libraryArtifact.contractName} successfully deployed at ${contractAddress}`);
|
||||
libraryAddresses[libraryArtifact.contractName] = contractAddress as string;
|
||||
}
|
||||
}
|
||||
}
|
||||
return libraryAddresses;
|
||||
}
|
||||
|
||||
public getFunctionSignature(methodName: string): string {
|
||||
const index = this._methodABIIndex[methodName];
|
||||
const methodAbi = {{contractName}}Contract.ABI()[index] as MethodAbi; // tslint:disable-line:no-unnecessary-type-assertion
|
||||
const functionSignature = methodAbiToFunctionSignature(methodAbi);
|
||||
return functionSignature;
|
||||
}
|
||||
|
||||
public getABIDecodedTransactionData<T>(methodName: string, callData: string): T {
|
||||
const functionSignature = this.getFunctionSignature(methodName);
|
||||
const self = (this as any) as {{contractName}}Contract;
|
||||
@@ -181,6 +274,7 @@ export class {{contractName}}Contract extends BaseContract {
|
||||
const abiDecodedCallData = abiEncoder.strictDecode<T>(callData);
|
||||
return abiDecodedCallData;
|
||||
}
|
||||
|
||||
public getABIDecodedReturnData<T>(methodName: string, callData: string): T {
|
||||
const functionSignature = this.getFunctionSignature(methodName);
|
||||
const self = (this as any) as {{contractName}}Contract;
|
||||
@@ -188,6 +282,7 @@ export class {{contractName}}Contract extends BaseContract {
|
||||
const abiDecodedCallData = abiEncoder.strictDecodeReturnValue<T>(callData);
|
||||
return abiDecodedCallData;
|
||||
}
|
||||
|
||||
public getSelector(methodName: string): string {
|
||||
const functionSignature = this.getFunctionSignature(methodName);
|
||||
const self = (this as any) as {{contractName}}Contract;
|
||||
@@ -254,6 +349,7 @@ export class {{contractName}}Contract extends BaseContract {
|
||||
);
|
||||
return subscriptionToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel a subscription
|
||||
* @param subscriptionToken Subscription token returned by `subscribe()`
|
||||
@@ -261,12 +357,14 @@ export class {{contractName}}Contract extends BaseContract {
|
||||
public unsubscribe(subscriptionToken: string): void {
|
||||
this._subscriptionManager.unsubscribe(subscriptionToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels all existing subscriptions
|
||||
*/
|
||||
public unsubscribeAll(): void {
|
||||
this._subscriptionManager.unsubscribeAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets historical logs without creating a subscription
|
||||
* @param eventName The {{contractName}} contract event you would like to subscribe to.
|
||||
@@ -292,6 +390,7 @@ export class {{contractName}}Contract extends BaseContract {
|
||||
);
|
||||
return logs;
|
||||
}{{/if}}
|
||||
|
||||
constructor(
|
||||
address: string,
|
||||
supportedProvider: SupportedProvider,
|
||||
|
@@ -3,8 +3,13 @@ async callAsync(
|
||||
defaultBlock?: BlockParam,
|
||||
): Promise<{{> return_type outputs=outputs}}> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
{{#ifEquals this.stateMutability "pure"}}
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
{{#ifEquals this.stateMutability "pure" }}
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync({ ...callData, data: this.getABIEncodedTransactionData() }, defaultBlock);
|
||||
}
|
||||
{{else}}
|
||||
const rawCallResult = await self._performCallAsync({ ...callData, data: this.getABIEncodedTransactionData() }, defaultBlock);
|
||||
{{/ifEquals}}
|
||||
|
@@ -10,6 +10,7 @@ import {
|
||||
SubscriptionManager,
|
||||
PromiseWithTransactionHash,
|
||||
methodAbiToFunctionSignature,
|
||||
linkLibrariesInBytecode,
|
||||
} from '@0x/base-contract';
|
||||
import { schemas } from '@0x/json-schemas';
|
||||
import {
|
||||
@@ -27,7 +28,7 @@ import {
|
||||
TxDataPayable,
|
||||
SupportedProvider,
|
||||
} from 'ethereum-types';
|
||||
import { BigNumber, classUtils, logUtils, providerUtils } from '@0x/utils';
|
||||
import { BigNumber, classUtils, hexUtils, logUtils, providerUtils } from '@0x/utils';
|
||||
import { EventCallback, IndexedFilterValues, SimpleContractArtifact } from '@0x/types';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { assert } from '@0x/assert';
|
||||
@@ -88,6 +89,43 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
}
|
||||
return AbiGenDummyContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly);
|
||||
}
|
||||
|
||||
public static async deployWithLibrariesFrom0xArtifactAsync(
|
||||
artifact: ContractArtifact,
|
||||
libraryArtifacts: { [libraryName: string]: ContractArtifact },
|
||||
supportedProvider: SupportedProvider,
|
||||
txDefaults: Partial<TxData>,
|
||||
logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact },
|
||||
): Promise<AbiGenDummyContract> {
|
||||
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
|
||||
schemas.addressSchema,
|
||||
schemas.numberSchema,
|
||||
schemas.jsNumber,
|
||||
]);
|
||||
if (artifact.compilerOutput === undefined) {
|
||||
throw new Error('Compiler output not found in the artifact file');
|
||||
}
|
||||
const provider = providerUtils.standardizeOrThrow(supportedProvider);
|
||||
const abi = artifact.compilerOutput.abi;
|
||||
const logDecodeDependenciesAbiOnly: { [contractName: string]: ContractAbi } = {};
|
||||
if (Object.keys(logDecodeDependencies) !== undefined) {
|
||||
for (const key of Object.keys(logDecodeDependencies)) {
|
||||
logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi;
|
||||
}
|
||||
}
|
||||
const libraryAddresses = await AbiGenDummyContract._deployLibrariesAsync(
|
||||
artifact,
|
||||
libraryArtifacts,
|
||||
new Web3Wrapper(provider),
|
||||
txDefaults,
|
||||
);
|
||||
const bytecode = linkLibrariesInBytecode(artifact.compilerOutput.evm.bytecode, libraryAddresses);
|
||||
if (!hexUtils.isHex(bytecode)) {
|
||||
throw new Error(`Bytecode for "${artifact.contractName}" was not fully linked.`);
|
||||
}
|
||||
return AbiGenDummyContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly);
|
||||
}
|
||||
|
||||
public static async deployAsync(
|
||||
bytecode: string,
|
||||
abi: ContractAbi,
|
||||
@@ -869,12 +907,64 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return abi;
|
||||
}
|
||||
|
||||
protected static async _deployLibrariesAsync(
|
||||
artifact: ContractArtifact,
|
||||
libraryArtifacts: { [libraryName: string]: ContractArtifact },
|
||||
web3Wrapper: Web3Wrapper,
|
||||
txDefaults: Partial<TxData>,
|
||||
libraryAddresses: { [libraryName: string]: string } = {},
|
||||
): Promise<{ [libraryName: string]: string }> {
|
||||
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
|
||||
// Go through all linked libraries, recursively deploying them if necessary.
|
||||
for (const link of Object.values(links)) {
|
||||
for (const libraryName of Object.keys(link)) {
|
||||
if (!libraryAddresses[libraryName]) {
|
||||
// Library not yet deployed.
|
||||
const libraryArtifact = libraryArtifacts[libraryName];
|
||||
if (!libraryArtifact) {
|
||||
throw new Error(`Missing artifact for linked library "${libraryName}"`);
|
||||
}
|
||||
// Deploy any dependent libraries used by this library.
|
||||
await AbiGenDummyContract._deployLibrariesAsync(
|
||||
libraryArtifact,
|
||||
libraryArtifacts,
|
||||
web3Wrapper,
|
||||
txDefaults,
|
||||
libraryAddresses,
|
||||
);
|
||||
// Deploy this library.
|
||||
const linkedLibraryBytecode = linkLibrariesInBytecode(
|
||||
libraryArtifact.compilerOutput.evm.bytecode,
|
||||
libraryAddresses,
|
||||
);
|
||||
if (!hexUtils.isHex(linkedLibraryBytecode)) {
|
||||
throw new Error(`Bytecode for library "${libraryArtifact.contractName}" was not fully linked.`);
|
||||
}
|
||||
const txDataWithDefaults = await BaseContract._applyDefaultsToContractTxDataAsync(
|
||||
{
|
||||
data: linkedLibraryBytecode,
|
||||
...txDefaults,
|
||||
},
|
||||
web3Wrapper.estimateGasAsync.bind(web3Wrapper),
|
||||
);
|
||||
const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults);
|
||||
logUtils.log(`transactionHash: ${txHash}`);
|
||||
const { contractAddress } = await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
logUtils.log(`${libraryArtifact.contractName} successfully deployed at ${contractAddress}`);
|
||||
libraryAddresses[libraryArtifact.contractName] = contractAddress as string;
|
||||
}
|
||||
}
|
||||
}
|
||||
return libraryAddresses;
|
||||
}
|
||||
|
||||
public getFunctionSignature(methodName: string): string {
|
||||
const index = this._methodABIIndex[methodName];
|
||||
const methodAbi = AbiGenDummyContract.ABI()[index] as MethodAbi; // tslint:disable-line:no-unnecessary-type-assertion
|
||||
const functionSignature = methodAbiToFunctionSignature(methodAbi);
|
||||
return functionSignature;
|
||||
}
|
||||
|
||||
public getABIDecodedTransactionData<T>(methodName: string, callData: string): T {
|
||||
const functionSignature = this.getFunctionSignature(methodName);
|
||||
const self = (this as any) as AbiGenDummyContract;
|
||||
@@ -882,6 +972,7 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
const abiDecodedCallData = abiEncoder.strictDecode<T>(callData);
|
||||
return abiDecodedCallData;
|
||||
}
|
||||
|
||||
public getABIDecodedReturnData<T>(methodName: string, callData: string): T {
|
||||
const functionSignature = this.getFunctionSignature(methodName);
|
||||
const self = (this as any) as AbiGenDummyContract;
|
||||
@@ -889,6 +980,7 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
const abiDecodedCallData = abiEncoder.strictDecodeReturnValue<T>(callData);
|
||||
return abiDecodedCallData;
|
||||
}
|
||||
|
||||
public getSelector(methodName: string): string {
|
||||
const functionSignature = this.getFunctionSignature(methodName);
|
||||
const self = (this as any) as AbiGenDummyContract;
|
||||
@@ -908,7 +1000,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
@@ -926,7 +1026,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
@@ -964,7 +1072,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
dolor: string;
|
||||
}> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<{
|
||||
@@ -1001,7 +1117,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<string> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<string>(rawCallResult);
|
||||
@@ -1072,8 +1196,17 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
},
|
||||
getABIEncodedTransactionData(): string {
|
||||
@@ -1096,8 +1229,17 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
},
|
||||
getABIEncodedTransactionData(): string {
|
||||
@@ -1119,7 +1261,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
Array<{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }>
|
||||
> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<
|
||||
@@ -1138,7 +1288,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<[BigNumber, string]> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<[BigNumber, string]>(rawCallResult);
|
||||
@@ -1160,7 +1318,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
defaultBlock?: BlockParam,
|
||||
): Promise<{ innerStruct: { aField: BigNumber } }> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<{ innerStruct: { aField: BigNumber } }>(rawCallResult);
|
||||
@@ -1190,7 +1356,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
defaultBlock?: BlockParam,
|
||||
): Promise<[string, string, string]> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<[string, string, string]>(rawCallResult);
|
||||
@@ -1216,7 +1390,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
@@ -1242,7 +1424,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
description: string;
|
||||
}> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<{
|
||||
@@ -1270,7 +1460,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
@@ -1290,7 +1488,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<BigNumber> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<BigNumber>(rawCallResult);
|
||||
@@ -1400,7 +1606,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
@@ -1418,7 +1632,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
@@ -1435,7 +1657,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<BigNumber> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<BigNumber>(rawCallResult);
|
||||
@@ -1452,7 +1682,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
@@ -1469,7 +1707,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
@@ -1490,7 +1736,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
@@ -1511,7 +1765,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<BigNumber> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<BigNumber>(rawCallResult);
|
||||
@@ -1528,7 +1790,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<BigNumber> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<BigNumber>(rawCallResult);
|
||||
@@ -1546,7 +1816,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<BigNumber> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<BigNumber>(rawCallResult);
|
||||
@@ -1563,7 +1841,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
@@ -1580,7 +1866,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
@@ -1603,7 +1897,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<void> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<void>(rawCallResult);
|
||||
@@ -1632,7 +1934,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
defaultBlock?: BlockParam,
|
||||
): Promise<{ someBytes: string; anInteger: number; aDynamicArrayOfBytes: string[]; aString: string }> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<{
|
||||
@@ -1665,7 +1975,15 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<string> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<string>(rawCallResult);
|
||||
@@ -1753,6 +2071,7 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
);
|
||||
return subscriptionToken;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel a subscription
|
||||
* @param subscriptionToken Subscription token returned by `subscribe()`
|
||||
@@ -1760,12 +2079,14 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
public unsubscribe(subscriptionToken: string): void {
|
||||
this._subscriptionManager.unsubscribe(subscriptionToken);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels all existing subscriptions
|
||||
*/
|
||||
public unsubscribeAll(): void {
|
||||
this._subscriptionManager.unsubscribeAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets historical logs without creating a subscription
|
||||
* @param eventName The AbiGenDummy contract event you would like to subscribe to.
|
||||
@@ -1791,6 +2112,7 @@ export class AbiGenDummyContract extends BaseContract {
|
||||
);
|
||||
return logs;
|
||||
}
|
||||
|
||||
constructor(
|
||||
address: string,
|
||||
supportedProvider: SupportedProvider,
|
||||
|
@@ -9,6 +9,7 @@ import {
|
||||
BaseContract,
|
||||
PromiseWithTransactionHash,
|
||||
methodAbiToFunctionSignature,
|
||||
linkLibrariesInBytecode,
|
||||
} from '@0x/base-contract';
|
||||
import { schemas } from '@0x/json-schemas';
|
||||
import {
|
||||
@@ -25,7 +26,7 @@ import {
|
||||
TxDataPayable,
|
||||
SupportedProvider,
|
||||
} from 'ethereum-types';
|
||||
import { BigNumber, classUtils, logUtils, providerUtils } from '@0x/utils';
|
||||
import { BigNumber, classUtils, hexUtils, logUtils, providerUtils } from '@0x/utils';
|
||||
import { EventCallback, IndexedFilterValues, SimpleContractArtifact } from '@0x/types';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { assert } from '@0x/assert';
|
||||
@@ -67,6 +68,43 @@ export class LibDummyContract extends BaseContract {
|
||||
}
|
||||
return LibDummyContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly);
|
||||
}
|
||||
|
||||
public static async deployWithLibrariesFrom0xArtifactAsync(
|
||||
artifact: ContractArtifact,
|
||||
libraryArtifacts: { [libraryName: string]: ContractArtifact },
|
||||
supportedProvider: SupportedProvider,
|
||||
txDefaults: Partial<TxData>,
|
||||
logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact },
|
||||
): Promise<LibDummyContract> {
|
||||
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
|
||||
schemas.addressSchema,
|
||||
schemas.numberSchema,
|
||||
schemas.jsNumber,
|
||||
]);
|
||||
if (artifact.compilerOutput === undefined) {
|
||||
throw new Error('Compiler output not found in the artifact file');
|
||||
}
|
||||
const provider = providerUtils.standardizeOrThrow(supportedProvider);
|
||||
const abi = artifact.compilerOutput.abi;
|
||||
const logDecodeDependenciesAbiOnly: { [contractName: string]: ContractAbi } = {};
|
||||
if (Object.keys(logDecodeDependencies) !== undefined) {
|
||||
for (const key of Object.keys(logDecodeDependencies)) {
|
||||
logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi;
|
||||
}
|
||||
}
|
||||
const libraryAddresses = await LibDummyContract._deployLibrariesAsync(
|
||||
artifact,
|
||||
libraryArtifacts,
|
||||
new Web3Wrapper(provider),
|
||||
txDefaults,
|
||||
);
|
||||
const bytecode = linkLibrariesInBytecode(artifact.compilerOutput.evm.bytecode, libraryAddresses);
|
||||
if (!hexUtils.isHex(bytecode)) {
|
||||
throw new Error(`Bytecode for "${artifact.contractName}" was not fully linked.`);
|
||||
}
|
||||
return LibDummyContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly);
|
||||
}
|
||||
|
||||
public static async deployAsync(
|
||||
bytecode: string,
|
||||
abi: ContractAbi,
|
||||
@@ -116,12 +154,64 @@ export class LibDummyContract extends BaseContract {
|
||||
return abi;
|
||||
}
|
||||
|
||||
protected static async _deployLibrariesAsync(
|
||||
artifact: ContractArtifact,
|
||||
libraryArtifacts: { [libraryName: string]: ContractArtifact },
|
||||
web3Wrapper: Web3Wrapper,
|
||||
txDefaults: Partial<TxData>,
|
||||
libraryAddresses: { [libraryName: string]: string } = {},
|
||||
): Promise<{ [libraryName: string]: string }> {
|
||||
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
|
||||
// Go through all linked libraries, recursively deploying them if necessary.
|
||||
for (const link of Object.values(links)) {
|
||||
for (const libraryName of Object.keys(link)) {
|
||||
if (!libraryAddresses[libraryName]) {
|
||||
// Library not yet deployed.
|
||||
const libraryArtifact = libraryArtifacts[libraryName];
|
||||
if (!libraryArtifact) {
|
||||
throw new Error(`Missing artifact for linked library "${libraryName}"`);
|
||||
}
|
||||
// Deploy any dependent libraries used by this library.
|
||||
await LibDummyContract._deployLibrariesAsync(
|
||||
libraryArtifact,
|
||||
libraryArtifacts,
|
||||
web3Wrapper,
|
||||
txDefaults,
|
||||
libraryAddresses,
|
||||
);
|
||||
// Deploy this library.
|
||||
const linkedLibraryBytecode = linkLibrariesInBytecode(
|
||||
libraryArtifact.compilerOutput.evm.bytecode,
|
||||
libraryAddresses,
|
||||
);
|
||||
if (!hexUtils.isHex(linkedLibraryBytecode)) {
|
||||
throw new Error(`Bytecode for library "${libraryArtifact.contractName}" was not fully linked.`);
|
||||
}
|
||||
const txDataWithDefaults = await BaseContract._applyDefaultsToContractTxDataAsync(
|
||||
{
|
||||
data: linkedLibraryBytecode,
|
||||
...txDefaults,
|
||||
},
|
||||
web3Wrapper.estimateGasAsync.bind(web3Wrapper),
|
||||
);
|
||||
const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults);
|
||||
logUtils.log(`transactionHash: ${txHash}`);
|
||||
const { contractAddress } = await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
logUtils.log(`${libraryArtifact.contractName} successfully deployed at ${contractAddress}`);
|
||||
libraryAddresses[libraryArtifact.contractName] = contractAddress as string;
|
||||
}
|
||||
}
|
||||
}
|
||||
return libraryAddresses;
|
||||
}
|
||||
|
||||
public getFunctionSignature(methodName: string): string {
|
||||
const index = this._methodABIIndex[methodName];
|
||||
const methodAbi = LibDummyContract.ABI()[index] as MethodAbi; // tslint:disable-line:no-unnecessary-type-assertion
|
||||
const functionSignature = methodAbiToFunctionSignature(methodAbi);
|
||||
return functionSignature;
|
||||
}
|
||||
|
||||
public getABIDecodedTransactionData<T>(methodName: string, callData: string): T {
|
||||
const functionSignature = this.getFunctionSignature(methodName);
|
||||
const self = (this as any) as LibDummyContract;
|
||||
@@ -129,6 +219,7 @@ export class LibDummyContract extends BaseContract {
|
||||
const abiDecodedCallData = abiEncoder.strictDecode<T>(callData);
|
||||
return abiDecodedCallData;
|
||||
}
|
||||
|
||||
public getABIDecodedReturnData<T>(methodName: string, callData: string): T {
|
||||
const functionSignature = this.getFunctionSignature(methodName);
|
||||
const self = (this as any) as LibDummyContract;
|
||||
@@ -136,6 +227,7 @@ export class LibDummyContract extends BaseContract {
|
||||
const abiDecodedCallData = abiEncoder.strictDecodeReturnValue<T>(callData);
|
||||
return abiDecodedCallData;
|
||||
}
|
||||
|
||||
public getSelector(methodName: string): string {
|
||||
const functionSignature = this.getFunctionSignature(methodName);
|
||||
const self = (this as any) as LibDummyContract;
|
||||
|
@@ -9,6 +9,7 @@ import {
|
||||
BaseContract,
|
||||
PromiseWithTransactionHash,
|
||||
methodAbiToFunctionSignature,
|
||||
linkLibrariesInBytecode,
|
||||
} from '@0x/base-contract';
|
||||
import { schemas } from '@0x/json-schemas';
|
||||
import {
|
||||
@@ -25,7 +26,7 @@ import {
|
||||
TxDataPayable,
|
||||
SupportedProvider,
|
||||
} from 'ethereum-types';
|
||||
import { BigNumber, classUtils, logUtils, providerUtils } from '@0x/utils';
|
||||
import { BigNumber, classUtils, hexUtils, logUtils, providerUtils } from '@0x/utils';
|
||||
import { EventCallback, IndexedFilterValues, SimpleContractArtifact } from '@0x/types';
|
||||
import { Web3Wrapper } from '@0x/web3-wrapper';
|
||||
import { assert } from '@0x/assert';
|
||||
@@ -68,6 +69,43 @@ export class TestLibDummyContract extends BaseContract {
|
||||
}
|
||||
return TestLibDummyContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly);
|
||||
}
|
||||
|
||||
public static async deployWithLibrariesFrom0xArtifactAsync(
|
||||
artifact: ContractArtifact,
|
||||
libraryArtifacts: { [libraryName: string]: ContractArtifact },
|
||||
supportedProvider: SupportedProvider,
|
||||
txDefaults: Partial<TxData>,
|
||||
logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact },
|
||||
): Promise<TestLibDummyContract> {
|
||||
assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema, [
|
||||
schemas.addressSchema,
|
||||
schemas.numberSchema,
|
||||
schemas.jsNumber,
|
||||
]);
|
||||
if (artifact.compilerOutput === undefined) {
|
||||
throw new Error('Compiler output not found in the artifact file');
|
||||
}
|
||||
const provider = providerUtils.standardizeOrThrow(supportedProvider);
|
||||
const abi = artifact.compilerOutput.abi;
|
||||
const logDecodeDependenciesAbiOnly: { [contractName: string]: ContractAbi } = {};
|
||||
if (Object.keys(logDecodeDependencies) !== undefined) {
|
||||
for (const key of Object.keys(logDecodeDependencies)) {
|
||||
logDecodeDependenciesAbiOnly[key] = logDecodeDependencies[key].compilerOutput.abi;
|
||||
}
|
||||
}
|
||||
const libraryAddresses = await TestLibDummyContract._deployLibrariesAsync(
|
||||
artifact,
|
||||
libraryArtifacts,
|
||||
new Web3Wrapper(provider),
|
||||
txDefaults,
|
||||
);
|
||||
const bytecode = linkLibrariesInBytecode(artifact.compilerOutput.evm.bytecode, libraryAddresses);
|
||||
if (!hexUtils.isHex(bytecode)) {
|
||||
throw new Error(`Bytecode for "${artifact.contractName}" was not fully linked.`);
|
||||
}
|
||||
return TestLibDummyContract.deployAsync(bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly);
|
||||
}
|
||||
|
||||
public static async deployAsync(
|
||||
bytecode: string,
|
||||
abi: ContractAbi,
|
||||
@@ -156,12 +194,64 @@ export class TestLibDummyContract extends BaseContract {
|
||||
return abi;
|
||||
}
|
||||
|
||||
protected static async _deployLibrariesAsync(
|
||||
artifact: ContractArtifact,
|
||||
libraryArtifacts: { [libraryName: string]: ContractArtifact },
|
||||
web3Wrapper: Web3Wrapper,
|
||||
txDefaults: Partial<TxData>,
|
||||
libraryAddresses: { [libraryName: string]: string } = {},
|
||||
): Promise<{ [libraryName: string]: string }> {
|
||||
const links = artifact.compilerOutput.evm.bytecode.linkReferences;
|
||||
// Go through all linked libraries, recursively deploying them if necessary.
|
||||
for (const link of Object.values(links)) {
|
||||
for (const libraryName of Object.keys(link)) {
|
||||
if (!libraryAddresses[libraryName]) {
|
||||
// Library not yet deployed.
|
||||
const libraryArtifact = libraryArtifacts[libraryName];
|
||||
if (!libraryArtifact) {
|
||||
throw new Error(`Missing artifact for linked library "${libraryName}"`);
|
||||
}
|
||||
// Deploy any dependent libraries used by this library.
|
||||
await TestLibDummyContract._deployLibrariesAsync(
|
||||
libraryArtifact,
|
||||
libraryArtifacts,
|
||||
web3Wrapper,
|
||||
txDefaults,
|
||||
libraryAddresses,
|
||||
);
|
||||
// Deploy this library.
|
||||
const linkedLibraryBytecode = linkLibrariesInBytecode(
|
||||
libraryArtifact.compilerOutput.evm.bytecode,
|
||||
libraryAddresses,
|
||||
);
|
||||
if (!hexUtils.isHex(linkedLibraryBytecode)) {
|
||||
throw new Error(`Bytecode for library "${libraryArtifact.contractName}" was not fully linked.`);
|
||||
}
|
||||
const txDataWithDefaults = await BaseContract._applyDefaultsToContractTxDataAsync(
|
||||
{
|
||||
data: linkedLibraryBytecode,
|
||||
...txDefaults,
|
||||
},
|
||||
web3Wrapper.estimateGasAsync.bind(web3Wrapper),
|
||||
);
|
||||
const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults);
|
||||
logUtils.log(`transactionHash: ${txHash}`);
|
||||
const { contractAddress } = await web3Wrapper.awaitTransactionSuccessAsync(txHash);
|
||||
logUtils.log(`${libraryArtifact.contractName} successfully deployed at ${contractAddress}`);
|
||||
libraryAddresses[libraryArtifact.contractName] = contractAddress as string;
|
||||
}
|
||||
}
|
||||
}
|
||||
return libraryAddresses;
|
||||
}
|
||||
|
||||
public getFunctionSignature(methodName: string): string {
|
||||
const index = this._methodABIIndex[methodName];
|
||||
const methodAbi = TestLibDummyContract.ABI()[index] as MethodAbi; // tslint:disable-line:no-unnecessary-type-assertion
|
||||
const functionSignature = methodAbiToFunctionSignature(methodAbi);
|
||||
return functionSignature;
|
||||
}
|
||||
|
||||
public getABIDecodedTransactionData<T>(methodName: string, callData: string): T {
|
||||
const functionSignature = this.getFunctionSignature(methodName);
|
||||
const self = (this as any) as TestLibDummyContract;
|
||||
@@ -169,6 +259,7 @@ export class TestLibDummyContract extends BaseContract {
|
||||
const abiDecodedCallData = abiEncoder.strictDecode<T>(callData);
|
||||
return abiDecodedCallData;
|
||||
}
|
||||
|
||||
public getABIDecodedReturnData<T>(methodName: string, callData: string): T {
|
||||
const functionSignature = this.getFunctionSignature(methodName);
|
||||
const self = (this as any) as TestLibDummyContract;
|
||||
@@ -176,6 +267,7 @@ export class TestLibDummyContract extends BaseContract {
|
||||
const abiDecodedCallData = abiEncoder.strictDecodeReturnValue<T>(callData);
|
||||
return abiDecodedCallData;
|
||||
}
|
||||
|
||||
public getSelector(methodName: string): string {
|
||||
const functionSignature = this.getFunctionSignature(methodName);
|
||||
const self = (this as any) as TestLibDummyContract;
|
||||
@@ -191,7 +283,15 @@ export class TestLibDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<BigNumber> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<BigNumber>(rawCallResult);
|
||||
@@ -209,7 +309,15 @@ export class TestLibDummyContract extends BaseContract {
|
||||
return {
|
||||
async callAsync(callData: Partial<CallData> = {}, defaultBlock?: BlockParam): Promise<BigNumber> {
|
||||
BaseContract._assertCallParams(callData, defaultBlock);
|
||||
const rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
let rawCallResult;
|
||||
if (self._deployedBytecodeIfExists) {
|
||||
rawCallResult = await self._evmExecAsync(this.getABIEncodedTransactionData());
|
||||
} else {
|
||||
rawCallResult = await self._performCallAsync(
|
||||
{ ...callData, data: this.getABIEncodedTransactionData() },
|
||||
defaultBlock,
|
||||
);
|
||||
}
|
||||
const abiEncoder = self._lookupAbiEncoder(functionSignature);
|
||||
BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder);
|
||||
return abiEncoder.strictDecodeReturnValue<BigNumber>(rawCallResult);
|
||||
|
@@ -1,4 +1,17 @@
|
||||
[
|
||||
{
|
||||
"version": "6.2.0",
|
||||
"changes": [
|
||||
{
|
||||
"note": "Ignore bytecode with unlinked library references in constructor",
|
||||
"pr": 2463
|
||||
},
|
||||
{
|
||||
"note": "Add exported function `linkLibrariesInBytecode()`",
|
||||
"pr": 2463
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"timestamp": 1580988106,
|
||||
"version": "6.1.2",
|
||||
|
@@ -30,7 +30,7 @@ import * as util from 'ethereumjs-util';
|
||||
import { default as VM } from 'ethereumjs-vm';
|
||||
import PStateManager from 'ethereumjs-vm/dist/state/promisified';
|
||||
|
||||
export { methodAbiToFunctionSignature } from './utils';
|
||||
export { linkLibrariesInBytecode, methodAbiToFunctionSignature } from './utils';
|
||||
|
||||
import { AwaitTransactionSuccessOpts } from './types';
|
||||
import { formatABIDataItem } from './utils';
|
||||
@@ -77,6 +77,9 @@ export class PromiseWithTransactionHash<T> implements Promise<T> {
|
||||
public catch<TResult>(onRejected?: (reason: any) => Promise<TResult>): Promise<TResult | T> {
|
||||
return this._promise.catch(onRejected);
|
||||
}
|
||||
public finally(onFinally?: (() => void) | null): Promise<T> {
|
||||
return this._promise.finally(onFinally);
|
||||
}
|
||||
// tslint:enable:promise-function-async
|
||||
// tslint:enable:async-suffix
|
||||
get [Symbol.toStringTag](): 'Promise' {
|
||||
@@ -359,8 +362,17 @@ export class BaseContract {
|
||||
assert.isString('contractName', contractName);
|
||||
assert.isETHAddressHex('address', address);
|
||||
if (deployedBytecode !== undefined && deployedBytecode !== '') {
|
||||
assert.isHexString('deployedBytecode', deployedBytecode);
|
||||
this._deployedBytecodeIfExists = Buffer.from(deployedBytecode.substr(2), 'hex');
|
||||
// `deployedBytecode` might contain references to
|
||||
// unlinked libraries and, hence, would not be a hex string. We'll just
|
||||
// leave `_deployedBytecodeIfExists` empty if this is the case.
|
||||
// TODO(dorothy-zbornak): We should link the `deployedBytecode`
|
||||
// beforehand in the generated wrappers.
|
||||
try {
|
||||
assert.isHexString('deployedBytecode', deployedBytecode);
|
||||
this._deployedBytecodeIfExists = Buffer.from(deployedBytecode.substr(2), 'hex');
|
||||
} catch (err) {
|
||||
// Do nothing.
|
||||
}
|
||||
}
|
||||
const provider = providerUtils.standardizeOrThrow(supportedProvider);
|
||||
if (callAndTxnDefaults !== undefined) {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
import { AbiEncoder } from '@0x/utils';
|
||||
import { DataItem, MethodAbi } from 'ethereum-types';
|
||||
import { DataItem, EvmBytecodeOutput, MethodAbi } from 'ethereum-types';
|
||||
|
||||
// tslint:disable-next-line:completed-docs
|
||||
export function formatABIDataItem(abi: DataItem, value: any, formatter: (type: string, value: any) => any): any {
|
||||
@@ -38,3 +38,30 @@ export function methodAbiToFunctionSignature(methodAbi: MethodAbi): string {
|
||||
const method = AbiEncoder.createMethod(methodAbi.name, methodAbi.inputs);
|
||||
return method.getSignature();
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces unliked library references in bytecode with real addresses
|
||||
* and returns the bytecode.
|
||||
*/
|
||||
export function linkLibrariesInBytecode(
|
||||
bytecodeArtifact: EvmBytecodeOutput,
|
||||
libraryAddresses: { [libraryName: string]: string },
|
||||
): string {
|
||||
let bytecode = bytecodeArtifact.object.substr(2);
|
||||
for (const link of Object.values(bytecodeArtifact.linkReferences)) {
|
||||
for (const [libraryName, libraryRefs] of Object.entries(link)) {
|
||||
const libraryAddress = libraryAddresses[libraryName];
|
||||
if (!libraryAddress) {
|
||||
continue;
|
||||
}
|
||||
for (const ref of libraryRefs) {
|
||||
bytecode = [
|
||||
bytecode.substring(0, ref.start * 2),
|
||||
libraryAddress.toLowerCase().substr(2),
|
||||
bytecode.substring((ref.start + ref.length) * 2),
|
||||
].join('');
|
||||
}
|
||||
}
|
||||
}
|
||||
return `0x${bytecode}`;
|
||||
}
|
||||
|
Reference in New Issue
Block a user