import { AwaitTransactionSuccessOpts, EncoderOverrides, ContractFunctionObj, ContractTxFunctionObj, SendTransactionOpts, BaseContract, PromiseWithTransactionHash, methodAbiToFunctionSignature, linkLibrariesInBytecode, } from '@0x/base-contract'; import { schemas } from '@0x/json-schemas'; import { BlockParam, BlockParamLiteral, BlockRange, CallData, ContractAbi, ContractArtifact, DecodedLogArgs, MethodAbi, TransactionReceiptWithDecodedLogs, TxData, TxDataPayable, TxAccessListWithGas, SupportedProvider, } from 'ethereum-types'; import { AbiEncoder, BigNumber, classUtils, EncodingRules, hexUtils, logUtils, providerUtils } from '@0x/utils'; import { EventCallback, IndexedFilterValues, SimpleContractArtifact } from '@0x/types'; import { Web3Wrapper } from '@0x/web3-wrapper'; import { assert } from '@0x/assert'; import * as ethers from 'ethers'; /* istanbul ignore next */ export class GodsUnchainedValidatorContract extends BaseContract { /** * @ignore */ public static deployedBytecode: string | undefined; public static contractName = 'GodsUnchainedValidator'; private readonly _methodABIIndex: { [name: string]: number } = {}; public static async deployFrom0xArtifactAsync( artifact: ContractArtifact | SimpleContractArtifact, supportedProvider: SupportedProvider, txDefaults: Partial, logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact }, _godsUnchained: string, ): Promise { assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema); if (artifact.compilerOutput === undefined) { throw new Error('Compiler output not found in the artifact file'); } const provider = providerUtils.standardizeOrThrow(supportedProvider); const bytecode = artifact.compilerOutput.evm.bytecode.object; 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; } } return GodsUnchainedValidatorContract.deployAsync( bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, _godsUnchained, ); } public static async deployWithLibrariesFrom0xArtifactAsync( artifact: ContractArtifact, libraryArtifacts: { [libraryName: string]: ContractArtifact }, supportedProvider: SupportedProvider, txDefaults: Partial, logDecodeDependencies: { [contractName: string]: ContractArtifact | SimpleContractArtifact }, _godsUnchained: string, ): Promise { assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema); 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 GodsUnchainedValidatorContract._deployLibrariesAsync( artifact, libraryArtifacts, new Web3Wrapper(provider), txDefaults, ); const bytecode = linkLibrariesInBytecode(artifact, libraryAddresses); return GodsUnchainedValidatorContract.deployAsync( bytecode, abi, provider, txDefaults, logDecodeDependenciesAbiOnly, _godsUnchained, ); } public static async deployAsync( bytecode: string, abi: ContractAbi, supportedProvider: SupportedProvider, txDefaults: Partial, logDecodeDependencies: { [contractName: string]: ContractAbi }, _godsUnchained: string, ): Promise { assert.isHexString('bytecode', bytecode); assert.doesConformToSchema('txDefaults', txDefaults, schemas.txDataSchema); const provider = providerUtils.standardizeOrThrow(supportedProvider); const constructorAbi = BaseContract._lookupConstructorAbi(abi); [_godsUnchained] = BaseContract._formatABIDataItemList( constructorAbi.inputs, [_godsUnchained], BaseContract._bigNumberToString, ); const iface = new ethers.utils.Interface(abi); const deployInfo = iface.deployFunction; const txData = deployInfo.encode(bytecode, [_godsUnchained]); const web3Wrapper = new Web3Wrapper(provider); const txDataWithDefaults = await BaseContract._applyDefaultsToContractTxDataAsync( { data: txData, ...txDefaults, }, web3Wrapper.estimateGasAsync.bind(web3Wrapper), ); const txHash = await web3Wrapper.sendTransactionAsync(txDataWithDefaults); logUtils.log(`transactionHash: ${txHash}`); const txReceipt = await web3Wrapper.awaitTransactionSuccessAsync(txHash); logUtils.log(`GodsUnchainedValidator successfully deployed at ${txReceipt.contractAddress}`); const contractInstance = new GodsUnchainedValidatorContract( txReceipt.contractAddress as string, provider, txDefaults, logDecodeDependencies, ); contractInstance.constructorArgs = [_godsUnchained]; return contractInstance; } /** * @returns The contract ABI */ public static ABI(): ContractAbi { const abi = [ { inputs: [ { name: '_godsUnchained', type: 'address', }, ], outputs: [], payable: false, stateMutability: 'nonpayable', type: 'constructor', }, { constant: true, inputs: [ { name: 'tokenId', type: 'uint256', }, { name: 'propertyData', type: 'bytes', }, ], name: 'checkBrokerAsset', outputs: [], payable: false, stateMutability: 'view', type: 'function', }, ] as ContractAbi; return abi; } protected static async _deployLibrariesAsync( artifact: ContractArtifact, libraryArtifacts: { [libraryName: string]: ContractArtifact }, web3Wrapper: Web3Wrapper, txDefaults: Partial, 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 GodsUnchainedValidatorContract._deployLibrariesAsync( libraryArtifact, libraryArtifacts, web3Wrapper, txDefaults, libraryAddresses, ); // Deploy this library. const linkedLibraryBytecode = linkLibrariesInBytecode(libraryArtifact, libraryAddresses); 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 = GodsUnchainedValidatorContract.ABI()[index] as MethodAbi; const functionSignature = methodAbiToFunctionSignature(methodAbi); return functionSignature; } public getABIDecodedTransactionData(methodName: string, callData: string): T { const functionSignature = this.getFunctionSignature(methodName); const self = (this as any) as GodsUnchainedValidatorContract; const abiEncoder = self._lookupAbiEncoder(functionSignature); const abiDecodedCallData = abiEncoder.strictDecode(callData); return abiDecodedCallData; } public getABIDecodedReturnData(methodName: string, callData: string): T { if (this._encoderOverrides.decodeOutput) { return this._encoderOverrides.decodeOutput(methodName, callData); } const functionSignature = this.getFunctionSignature(methodName); const self = (this as any) as GodsUnchainedValidatorContract; const abiEncoder = self._lookupAbiEncoder(functionSignature); const abiDecodedCallData = abiEncoder.strictDecodeReturnValue(callData); return abiDecodedCallData; } public getSelector(methodName: string): string { const functionSignature = this.getFunctionSignature(methodName); const self = (this as any) as GodsUnchainedValidatorContract; const abiEncoder = self._lookupAbiEncoder(functionSignature); return abiEncoder.getSelector(); } /** * Checks that the given card (encoded as assetData) has the proto and quality encoded in `propertyData`. * Reverts if the card doesn't match the specified proto and quality. * @param tokenId The ERC721 tokenId of the card to check. * @param propertyData Encoded proto and quality that the card is expected to * have. */ public checkBrokerAsset(tokenId: BigNumber, propertyData: string): ContractFunctionObj { const self = (this as any) as GodsUnchainedValidatorContract; assert.isBigNumber('tokenId', tokenId); assert.isString('propertyData', propertyData); const functionSignature = 'checkBrokerAsset(uint256,bytes)'; return { selector: self._lookupAbiEncoder(functionSignature).getSelector(), async callAsync(callData: Partial = {}, defaultBlock?: BlockParam): Promise { BaseContract._assertCallParams(callData, defaultBlock); const rawCallResult = await self._performCallAsync( { data: this.getABIEncodedTransactionData(), ...callData }, defaultBlock, ); const abiEncoder = self._lookupAbiEncoder(functionSignature); BaseContract._throwIfUnexpectedEmptyCallResult(rawCallResult, abiEncoder); return abiEncoder.strictDecodeReturnValue(rawCallResult); }, getABIEncodedTransactionData(): string { return self._strictEncodeArguments(functionSignature, [tokenId, propertyData]); }, }; } constructor( address: string, supportedProvider: SupportedProvider, txDefaults?: Partial, logDecodeDependencies?: { [contractName: string]: ContractAbi }, deployedBytecode: string | undefined = GodsUnchainedValidatorContract.deployedBytecode, encoderOverrides?: Partial, ) { super( 'GodsUnchainedValidator', GodsUnchainedValidatorContract.ABI(), address, supportedProvider, txDefaults, logDecodeDependencies, deployedBytecode, encoderOverrides, ); classUtils.bindAll(this, ['_abiEncoderByFunctionSignature', 'address', '_web3Wrapper']); GodsUnchainedValidatorContract.ABI().forEach((item, index) => { if (item.type === 'function') { const methodAbi = item as MethodAbi; this._methodABIIndex[methodAbi.name] = index; } }); } }