Skip to main content

PreContractCall

Introduction

The PreContractCall join point occurs during the DeliverTx phase of the Transaction lifecycle.
This join point will be invoked before the contract call is executed. Below is call graph:

At this stage, the account state remains pristine, allowing Aspect to preload information as necessary.

Interface

interface IPreContractCallJP extends IAspectBase {
preContractCall(input: PreContractCallInput): void;
}
  • Parameter

    • input: PostContractCallInput; The base layer will deliver the PostContractCallInput object to Aspect in this join point.
      • input.block.number: current block number.
      • input.call.from: caller of the contract call.
      • input.call.to: to address of the contract call.
      • input.call.data: input bytes of the contract call.
      • input.call.gas: gas limit of the contract call.
      • input.call.index: index of the contract call.
      • input.call.value: transfer value of the contract call.
  • Returns

    • void; If Aspect returns normally, the transaction will continue to execute. If Aspect calls sys.revert to revert the transaction, the base layer will revert the transaction.

Example


/**
* preContractCall is a join-point that gets invoked before the execution of a contract call.
*
* @param input Input of the given join-point
* @return void
*/
preContractCall(input: PreContractCallInput): void {
// call to a method 'save', with value of 100
let callData = ethereum.abiEncode('save', [
ethereum.Number.fromU32(100, 32)
]);

let sender = hexToUint8Array("0xE2AF7C239b4F2800a2F742d406628b4fc4b8a0d4");
let request = JitCallBuilder.simple(
sender,
input.call!.to,
hexToUint8Array(callData)
).build();

// Submit the JIT call
let response = sys.hostApi.evmCall.jitCall(request);
if (!response.success) {
sys.revert(response.errorMsg);
}
}

Programming Guide

There are two programming modes that can be used in this method:

  1. By utilizing the 'input' input argument, it provides essential insights into transactions and block processing. see how to use input.

  2. Using the 'sys' namespace, it provides both hight level API and low-level API access to system data and contextual information generated during blockchain runtime, including details about the environment, blocks, transactions, and utility classes such as crypto and ABI encoding/decoding. see more details.

Important point: Since the join point is in the EVM execution process, using sys.revert(), sys.require() in this join point will actually revert the transaction.

Host APIs

For a comprehensive overview of all APIs and their usage see API References.

Each join-point has access to different host APIs, and the host APIs available within the current breakpoint can be found at the following table.

System APIsAvailabilityDescription
sys.revertForces the current transaction to fail.
sys.requireChecks if certain conditions are met; if not, forces the entire transaction to fail.
sys.logA wrapper for sys.hostApi.util.log, prints log messages to Artela output for debugging on the localnet.
sys.aspect.idRetrieves the ID of the aspect.
sys.aspect.version Retrieves the version of the aspect.
sys.aspect.mutableStateA wrapper for sys.hostApi.aspectState that facilitates easier reading or writing of values of a specified type to aspect state.
sys.aspect.propertyA wrapper for sys.hostApi.aspectProperty that facilitates easier reading of values of a specified type from aspect property.
sys.aspect.readonlyStateA wrapper for sys.hostApi.aspectState that facilitates easier reading of values of a specified type from aspect state.
sys.aspect.transientStorageA wrapper for sys.hostApi.aspectTransientStorage that facilitates easier reading or writing of values of a specified type to aspect transient storage.
sys.hostApi.aspectPropertyRetrieves the property of the aspect as written in aspect deployment.
sys.hostApi.aspectStateRetrieves or writes the state of the aspect.
sys.hostApi.aspectTransientStorageRetrieves or writes to the transient storage of the aspect. This storage is only valid within the current transaction lifecycle.
sys.hostApi.crypto.ecRecoverCalls crypto methods ecRecover.
sys.hostApi.crypto.keccakCalls crypto methods keccak.
sys.hostApi.crypto.ripemd160Calls crypto methods ripemd160.
sys.hostApi.crypto.sha256Calls crypto methods sha256.
sys.hostApi.runtimeContextRetrieves runtime context by the key. Refer to the runtime context to see which keys can be accessed by the current join point.
sys.hostApi.stateDb.balanceGets the balance of the specified address from the EVM state database.
sys.hostApi.stateDb.codeHashGets the hash of the code from the EVM state database.
sys.hostApi.stateDb.codeSizeGets the size of the code from the EVM state database.
sys.hostApi.stateDb.hasSuicidedGets the codehash from the EVM state database.
sys.hostApi.stateDb.nonceChecks if the contract at the specified address is suicided in the current transactions.
sys.hostApi.stateDb.stateAtGets the state at a specific point.
sys.hostApi.evmCall.jitCallCreates a contract call and executes it immediately.
sys.hostApi.evmCall.staticCallCreates a static call and executes it immediately.
sys.hostApi.trace.queryCallTreeReturns the call tree of EVM execution.
sys.hostApi.trace.queryStateChangeReturns the state change in EVM execution for the specified key.

Runtime context

The Aspect Runtime Context encapsulates data generated through the consensus process. With the acquired Runtime Context object, retrieve specific data by specifying the relevant Context Key. Each Context Key is associated with a particular type of data or information.

Usage

const chainId = sys.hostApi.runtimeContext.get('env.chain.chainId');
//decode UintData
const chainIdData = Protobuf.decode<UintData>(chainId, UintData.decode);
sys.log('env.chain.chainId' + ' ' + chainIdData.data.toString(10));

const enableCall = sys.hostApi.runtimeContext.get('env.enableCall');
//decode boolData
const enableCallData = Protobuf.decode<BoolData>(enableCall, BoolData.decode);
sys.log('env.enableCall' + ' ' + enableCallData.data.toString());

Key table

Context keyValue typeDescription
isCallBoolDataGet the current transaction is Call or Send. If it is Call, return true.
tx.typeUintDataReturns the transaction type id. LegacyTxType=0x00 AccessListTxType=0x01 DynamicFeeTxType=0x02 BlobTxType=0x03
tx.chainIdBytesDataReturns the EIP155 chain ID of the transaction. The return value will always be non-nil. For legacy transactions which are not replay-protected, the return value is zero.
tx.accessListEthAccessListAccessListTx is the data of EIP-2930 access list transactions.
tx.nonceUintDataReturns the sender account nonce of the transaction.
tx.gasPriceBytesDataReturns the gas price of the transaction.
tx.gasUintDataReturns the gas limit of the transaction.
tx.gasTipCapBytesDataReturns the gasTipCap per gas of the transaction.
tx.gasFeeCapBytesDataReturns the fee cap per gas of the transaction.
tx.toBytesDataReturns the recipient address of the transaction. For contract-creation transactions, To returns nil.
tx.valueBytesDataReturns the ether amount of the transaction.
tx.dataBytesDataReturns the input data of the transaction.
tx.bytesBytesDataReturns the transaction marshal binary.
tx.hashBytesDataReturns the transaction hash.
tx.unsigned.bytesBytesDataReturns the unsigned transaction marshal binary.
tx.unsigned.hashBytesDataReturns the unsigned transaction hash.
tx.sig.vBytesDataReturns the V signature values of the transaction.
tx.sig.rBytesDataReturns the R signature values of the transaction.
tx.sig.sBytesDataReturns the S signature values of the transaction.
tx.fromBytesDataReturns the from address of the transaction.
tx.indexUintDataReturns the transaction index of current block.
block.header.parentHashBytesDataGet the current block header parent hash.
block.header.minerBytesDataGet the current block header miner.
block.header.transactionsRootBytesDataGet the current block TransactionsRoot hash.
block.header.numberUintDataGet the current block number.
block.header.timestampUintDataGet the current block header timestamp.
env.extraEIPsIntArrayDataRetrieve the EVM module parameters for the 'extra_eips': defines the additional EIPs for the vm.Config.
env.enableCreateBoolDataRetrieve the EVM module parameters for the 'enable_create': toggles states transitions that use the vm.Create function.
env.enableCallBoolDataRetrieve the EVM module parameters for the 'enable_call': toggles states transitions that use the vm.Call function.
env.allowUnprotectedTxsBoolDataRetrieve the EVM module parameters for the 'allow_unprotected_txs': defines if replay-protected (i.e non EIP155 // signed) transactions can be executed on the states machine.
env.chain.chainIdUintDataRetrieve the Ethereum chain config id.
env.chain.homesteadBlockUintDataRetrieve the Ethereum chain configuration for the 'homestead_block': switch (nil no fork, 0 = already homestead)
env.chain.daoForkBlockUintDataRetrieve the Ethereum chain configuration for the 'dao_fork_block': corresponds to TheDAO hard-fork switch block (nil no fork)
env.chain.daoForkSupportBoolDataRetrieve the Ethereum chain configuration for the 'dao_fork_support': defines whether the nodes supports or opposes the DAO hard-fork
env.chain.eip150BlockUintDataRetrieve the Ethereum chain configuration for the 'eip150_block': EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150) EIP150 HF block (nil no fork)
env.chain.eip155BlockUintDataRetrieve the Ethereum chain configuration for the 'eip155_block'.
env.chain.eip158BlockUintDataRetrieve the Ethereum chain configuration for the 'eip158_block'.
env.chain.byzantiumBlockUintDataRetrieve the Ethereum chain configuration for the 'byzantium_block': Byzantium switch block (nil no fork, 0 =already on byzantium)
env.chain.constantinopleBlockUintDataRetrieve the Ethereum chain configuration for the 'constantinople_block': Constantinople switch block (nil no fork, 0 = already activated)
env.chain.petersburgBlockUintDataRetrieve the Ethereum chain configuration for the 'petersburg_block': Petersburg switch block (nil no fork, 0 = already activated)
env.chain.istanbulBlockUintDataRetrieve the Ethereum chain configuration for the 'istanbul_block': Istanbul switch block (nil no fork, 0 = already on istanbul)
env.chain.muirGlacierBlockUintDataRetrieve the Ethereum chain configuration for the 'muir_glacier_block': Eip-2384 (bomb delay) switch block ( nil no fork, 0 = already activated).
env.chain.berlinBlockUintDataRetrieve the Ethereum chain configuration for the 'berlin_block': Berlin switch block (nil = no fork, 0 = already on berlin)
env.chain.londonBlockUintDataRetrieve the Ethereum chain configuration for the 'london_block': London switch block (nil = no fork, 0 = already on london)
env.chain.arrowGlacierBlockUintDataRetrieve the Ethereum chain configuration for the 'arrow_glacier_block': Eip-4345 (bomb delay) switch block (nil = no fork, 0 = already activated)
env.chain.grayGlacierBlockUintDataRetrieve the Ethereum chain configuration for the 'gray_glacier_block': EIP-5133 (bomb delay) switch block (nil = no fork, 0 = already activated)
env.chain.mergeNetSplitBlockUintDataRetrieve the Ethereum chain configuration for the 'merge_netsplit_block': Virtual fork after The Merge to use as a network splitter.
env.chain.shanghaiTimeUintDataRetrieve the Ethereum chain configuration for the 'shanghaiTime': Shanghai switch time (nil = no fork, 0 = already on shanghai).
env.chain.cancunTimeUintDataRetrieve the Ethereum chain configuration for the 'CancunTime': Cancun switch time (nil = no fork, 0 = already on cancun).
env.chain.pragueTimeUintDataRetrieve the Ethereum chain configuration for the 'PragueTime': Prague switch time (nil = no fork, 0 = already on prague).
env.consensusParams.block.maxGasIntDataRetrieve the max gas per block.
env.consensusParams.block.maxBytesIntDataRetrieve the max block size, in bytes.
env.consensusParams.evidence.maxAgeDurationIntDataRetrieve the max age duration.It should correspond with an app's "unbonding period" or other similar mechanism for handling.
env.consensusParams.evidence.maxAgeNumBlocksIntDataThe basic formula for calculating this is: MaxAgeDuration / {average block time}.
env.consensusParams.evidence.maxBytesIntDataRetrieve the maximum size of total evidence in bytes that can be committed in a single block.
env.consensusParams.validator.pubKeyTypesStringArrayDataRestrict the public key types validators can use.
env.consensusParams.appVersionUintDataGet the ABCI application version.
aspect.idBytesDataReturns current aspect id.
aspect.versionUintDataReturns current aspect version.
msg.fromBytesDataReturns the sender address of the EVM call message.
msg.toBytesDataReturns the recipient address of the EVM call message.
msg.valueBytesDataReturns the ether amount of the EVM call message.
msg.gasUintDataReturns the gas limit of the EVM call message.
msg.inputBytesDataReturns the input data of the EVM call message.
msg.indexUintDataReturns the index of the EVM call message.
msg.result.retBytesDataReturns the result of the EVM call.
msg.result.gasUsedUintDataReturns the gas used of the EVM call.
msg.result.errorStringDataReturns the result error message of the EVM call.