Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

111 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Compact indexer

Indexes NEAR blockchain actions and store them in a ClickHouse DB.

Create ClickHouse table

-- This is a ClickHouse table.
CREATE TABLE near.repl_actions_tx on CLUSTER cluster1
(
    block_height UInt64 COMMENT 'Block height',
    block_hash String COMMENT 'Block hash',
    block_timestamp DateTime64(9, 'UTC') COMMENT 'Block timestamp in UTC',
    transaction_hash String COMMENT 'Transaction hash',
    receipt_id String COMMENT 'Receipt hash',
    receipt_index UInt16 COMMENT 'Index of the receipt that appears in the block across all shards',
    action_index UInt8 COMMENT 'Index of the actions within the receipt',
    signer_id String COMMENT 'The account ID of the transaction signer',
    signer_public_key String COMMENT 'The public key of the transaction signer',
    predecessor_id String COMMENT 'The account ID of the receipt predecessor',
    account_id String COMMENT 'The account ID of where the receipt is executed',
    status Enum('FAILURE', 'SUCCESS') COMMENT 'The status of the receipt execution, either SUCCESS or FAILURE',
    action Enum('CREATE_ACCOUNT', 'DEPLOY_CONTRACT', 'FUNCTION_CALL', 'TRANSFER', 'STAKE', 'ADD_KEY', 'DELETE_KEY', 'DELETE_ACCOUNT', 'DELEGATE') COMMENT 'The action type',
    contract_hash Nullable(String) COMMENT 'The hash of the contract if the action is DEPLOY_CONTRACT',
    public_key Nullable(String) COMMENT 'The public key used in the action if the action is ADD_KEY or DELETE_KEY',
    access_key_contract_id Nullable(String) COMMENT 'The contract ID of the limited access key if the action is ADD_KEY and not a full access key',
    deposit Nullable(UInt128) COMMENT 'The amount of attached deposit in yoctoNEAR if the action is FUNCTION_CALL, STAKE or TRANSFER',
    gas_price UInt128 COMMENT 'The gas price in yoctoNEAR for the receipt',
    attached_gas Nullable(UInt64) COMMENT 'The amount of attached gas if the action is FUNCTION_CALL',
    gas_burnt UInt64 COMMENT 'The amount of burnt gas for the execution of the whole receipt',
    tokens_burnt UInt128 COMMENT 'The amount of tokens in yoctoNEAR burnt for the execution of the whole receipt',
    method_name Nullable(String) COMMENT 'The method name if the action is FUNCTION_CALL',
    args_account_id Nullable(String) COMMENT '`account_id` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_new_account_id Nullable(String) COMMENT '`new_account_id` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_owner_id Nullable(String) COMMENT '`owner_id` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_receiver_id Nullable(String) COMMENT '`receiver_id` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_sender_id Nullable(String) COMMENT '`sender_id` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_token_id Nullable(String) COMMENT '`token_id` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_amount Nullable(UInt128) COMMENT '`amount` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_balance Nullable(UInt128) COMMENT '`balance` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_nft_contract_id Nullable(String) COMMENT '`nft_contract_id` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_nft_token_id Nullable(String) COMMENT '`nft_token_id` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_utm_source Nullable(String) COMMENT '`_utm_source` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_utm_medium Nullable(String) COMMENT '`_utm_medium` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_utm_campaign Nullable(String) COMMENT '`_utm_campaign` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_utm_term Nullable(String) COMMENT '`_utm_term` argument from the JSON arguments if the action is FUNCTION_CALL',
    args_utm_content Nullable(String) COMMENT '`_utm_content` argument from the JSON arguments if the action is FUNCTION_CALL',
    return_value_int Nullable(UInt128) COMMENT 'The parsed integer string from the returned value of the FUNCTION_CALL action',

    INDEX block_height_minmax_idx block_height TYPE minmax GRANULARITY 1,
    INDEX account_id_bloom_index account_id TYPE bloom_filter() GRANULARITY 1,
    INDEX signer_id_bloom_index signer_id TYPE bloom_filter() GRANULARITY 1,
    INDEX block_hash_bloom_index block_hash TYPE bloom_filter() GRANULARITY 1,
    INDEX transaction_hash_bloom_index transaction_hash TYPE bloom_filter() GRANULARITY 1,
    INDEX receipt_hash_bloom_index receipt_hash TYPE bloom_filter() GRANULARITY 1,
    INDEX precise_public_key_bloom_index public_key TYPE bloom_filter(0.001) GRANULARITY 1,
    INDEX predecessor_id_bloom_index predecessor_id TYPE bloom_filter() GRANULARITY 1,
    INDEX method_name_index method_name TYPE set(0) GRANULARITY 1,
    INDEX args_account_id_bloom_index args_account_id TYPE bloom_filter() GRANULARITY 1,
    INDEX args_new_account_id_bloom_index args_new_account_id TYPE bloom_filter() GRANULARITY 1,
    INDEX args_owner_id_bloom_index args_owner_id TYPE bloom_filter() GRANULARITY 1,
    INDEX args_receiver_id_bloom_index args_receiver_id TYPE bloom_filter() GRANULARITY 1,
    INDEX args_sender_id_bloom_index args_sender_id TYPE bloom_filter() GRANULARITY 1,
)
    ENGINE = ReplicatedReplacingMergeTree
PRIMARY KEY (block_timestamp, account_id)
ORDER BY (block_timestamp, account_id, receipt_index, action_index)
                               
CREATE TABLE actions_tx AS near.repl_actions_tx
ENGINE = Distributed(cluster1, near, repl_actions_tx)

CREATE TABLE near.repl_events ON CLUSTER cluster1
(
    block_height UInt64 COMMENT 'Block height',
    block_hash String COMMENT 'Block hash',
    block_timestamp DateTime64(9, 'UTC') COMMENT 'Block timestamp in UTC',
    transaction_hash String COMMENT 'Transaction hash',
    receipt_id String COMMENT 'Receipt hash',
    receipt_index UInt16 COMMENT 'Index of the receipt that appears in the block across all shards',
    log_index UInt16 COMMENT 'Index of the log within the receipt',
    signer_id String COMMENT 'The account ID of the transaction signer',
    signer_public_key String COMMENT 'The public key of the transaction signer',
    predecessor_id String COMMENT 'The account ID of the receipt predecessor',
    account_id String COMMENT 'The account ID of where the receipt is executed',
    status Enum('FAILURE', 'SUCCESS') COMMENT 'The status of the receipt execution, either SUCCESS or FAILURE',
    
    version Nullable(String) COMMENT '`version` field from the JSON event',
    standard Nullable(String) COMMENT '`standard` field from the JSON event',
    event Nullable(String) COMMENT '`event` field from the JSON event',
    data_account_id Nullable(String) COMMENT '`account_id` field from the first data object in the JSON event',
    data_owner_id Nullable(String) COMMENT '`owner_id` field from the first data object in the JSON event',
    data_old_owner_id Nullable(String) COMMENT '`old_owner_id` field from the first data object in the JSON event',
    data_new_owner_id Nullable(String) COMMENT '`new_owner_id` field from the first data object in the JSON event',
    data_liquidation_account_id Nullable(String) COMMENT '`liquidation_account_id` field from the first data object in the JSON event',
    data_authorized_id Nullable(String) COMMENT '`authorized_id` field from the first data object in the JSON event',
    data_token_ids Array(String) COMMENT '`token_ids` field from the first data object in the JSON event',
    data_token_id Nullable(String) COMMENT '`token_id` field from the first data object in the JSON event',
    data_position Nullable(String) COMMENT '`position` field from the first data object in the JSON event',
    data_amount Nullable(UInt128) COMMENT '`amount` field from the first data object in the JSON event',

    INDEX block_height_minmax_idx block_height TYPE minmax GRANULARITY 1,
    INDEX account_id_bloom_index account_id TYPE bloom_filter() GRANULARITY 1,
    INDEX event_set_index event TYPE set(0) GRANULARITY 1,
    INDEX data_account_id_bloom_index data_account_id TYPE bloom_filter() GRANULARITY 1,
    INDEX data_owner_id_bloom_index data_owner_id TYPE bloom_filter() GRANULARITY 1,
    INDEX data_old_owner_id_bloom_index data_old_owner_id TYPE bloom_filter() GRANULARITY 1,
    INDEX data_new_owner_id_bloom_index data_new_owner_id TYPE bloom_filter() GRANULARITY 1,
    )
ENGINE = ReplicatedReplacingMergeTree
PRIMARY KEY (block_timestamp, account_id)
ORDER BY (block_timestamp, account_id, receipt_index, log_index)

CREATE TABLE events AS near.repl_events
ENGINE = Distributed(cluster1, near, repl_events)

To run

Create .env file and fill details:

DATABASE_URL=https://FOOBAR.clickhouse.cloud:8443
DATABASE_USER=default
DATABASE_PASSWORD=PASSWORD
DATABASE_DATABASE=default

Follow a NEAR RPC node setup instructions to get a node running.

cargo build --release
./target/release/compact-indexer run

About

Rust-based Indexer for a NEAR blockchain

Resources

Stars

15 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages