Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions db/migrations/19_evm_transactions.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-- Support for indexing Ethereum transactions submitted through `revive.ethTransact`.
--
-- The `evm_transactions` and `evm_account_mappings` tables, along with the `EvmCallKindEnum` type,
-- are created by the node from `schema.graphql`. Only the two pre-existing tables need altering.

alter table "extrinsics" add column if not exists "eth_address" text;
alter table "extrinsics" add column if not exists "eth_tx_hash" text;

create index if not exists data_extrinsic_eth_address on extrinsics (eth_address);
create index if not exists data_extrinsic_eth_tx_hash on extrinsics (eth_tx_hash);

-- Every account indexed before this change was a substrate key. Ethereum keys were never
-- attributed, so there is nothing to reclassify.
alter table "accounts" add column if not exists "key_type" text;
update "accounts" set "key_type" = 'substrate' where "key_type" is null;
alter table "accounts" alter column "key_type" set not null;

-- `evm_address` needs keccak256 to derive for a substrate key, which postgres has no built in for.
-- Existing rows are left null and are populated as they are next updated.
alter table "accounts" add column if not exists "evm_address" text;

create index if not exists data_account_evm_address on accounts (evm_address);
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"project.yaml"
],
"dependencies": {
"@ethereumjs/rlp": "^5.0.2",
"@polkadot/api": "^16.5.2",
"@polkadot/types-support": "^16.5.2",
"@polymeshassociation/polymesh-types": "^7.4.0",
Expand Down
85 changes: 85 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -1806,9 +1806,90 @@ type Extrinsic @entity {
success: Int! @index(unique: false)
nonce: Int
extrinsicHash: String @index(unique: false)
"""
Checksummed Ethereum address of the key that signed this `revive.eth_transact` extrinsic. `null` for every other extrinsic.

The equivalent SS58 address, formed by padding this address with 12 `0xEE` bytes, is stored in `address`
"""
ethAddress: String @index(unique: false)
"The keccak256 of the RLP payload, i.e. the transaction hash an Ethereum wallet reports"
ethTxHash: String @index(unique: false)
specVersionId: Int!
}

"""
The `revive` call an `eth_transact` extrinsic is transformed into by the runtime
"""
enum EvmCallKindEnum {
"`revive.eth_call` - a call to a contract or precompile"
call
"`revive.eth_instantiate_with_code` - a contract deployment"
instantiate
"`revive.eth_substrate_call` - a native runtime call, dispatched by targeting the `modlpy/paddr` address"
substrateCall
}

"""
An Ethereum transaction submitted through `revive.ethTransact`, decoded from the RLP payload of the extrinsic.

The chain includes these as unsigned extrinsics, so the signer, the dispatched call and whether the transaction reverted are all recovered by the indexer
"""
type EvmTransaction @entity {
"Same ID as the `Extrinsic` that carried this transaction"
id: ID!
extrinsic: Extrinsic!
block: Block! @index(unique: false)
"The keccak256 of the RLP payload, i.e. the transaction hash an Ethereum wallet reports"
ethTxHash: String! @index(unique: false)
"0 for legacy, 1 for EIP-2930, 2 for EIP-1559"
ethTxType: Int!
callKind: EvmCallKindEnum!
"Checksummed Ethereum address that signed the transaction"
fromEthAddress: String! @index(unique: false)
"SS58 encoding of the `0xEE` padded account the runtime dispatched the call as"
fromAddress: String! @index(unique: false)
"`null` for a contract deployment"
toEthAddress: String @index(unique: false)
"Address of the deployed contract, taken from `revive.Instantiated`"
contractAddress: String @index(unique: false)
value: String!
ethNonce: BigInt!
gasLimit: String!
"Only set for legacy and EIP-2930 transactions"
gasPrice: String
"Only set for EIP-1559 transactions"
maxFeePerGas: String
"Only set for EIP-1559 transactions"
maxPriorityFeePerGas: String
chainId: String
"Hex encoded calldata. For a `substrateCall` this is the SCALE encoded runtime call"
input: String!
"An Ethereum transaction always succeeds at the extrinsic level. This flags the ones that reverted"
reverted: Boolean! @index(unique: false)
revertReason: String
datetime: Date!
createdBlock: Block!
updatedBlock: Block!
}

"""
Mapping between an Ethereum address and its original `AccountId32`, registered with `revive.mapAccount`
"""
type EvmAccountMapping @entity {
"Same ID as `evmAddress`"
id: ID!
"Checksummed Ethereum address the account is reachable at inside `pallet_revive`. Same value as `id`"
evmAddress: String!
"SS58 address of the account that registered the mapping"
address: String! @index(unique: true)
account: Account
"`false` once the mapping has been removed with `revive.unmapAccount`"
mapped: Boolean!
datetime: Date!
createdBlock: Block!
updatedBlock: Block!
}

"""
Information of a chain state transition on. For most use cases a more specific entity should be queried
"""
Expand Down Expand Up @@ -1883,6 +1964,10 @@ Before an Account can sign most Extrinsics it must first be attached to an Ident
type Account @entity {
id: ID!
address: String! @index(unique: true)
"`substrate` for a regular key, `ethereum` for the `0xEE` padded account of an Ethereum key"
keyType: String!
"Checksummed Ethereum address this account is reachable at inside `pallet_revive`"
evmAddress: String @index(unique: false)
identity: Identity
permissions: Permissions
eventId: EventIdEnum!
Expand Down
Loading
Loading