Skip to main content

Tracking Smart Contract Interactions with Key-Value Store

Updated on
Sep 4, 2024

8 min read

Streams

Streams is available to all users with a QuickNode plan. For teams with unique requirements, we offer tailored datasets, dedicated support, and custom integrations. Contact our team for more information.

Overview

Tracking interactions with smart contracts on blockchains can provide valuable insights for developers and analysts. QuickNode's Key-Value Store, when combined with Streams, provides a robust solution for evaluating lists and key-value sets against both real-time and historical data streams.

In this guide, you will learn how to use QuickNode's Key-Value Store and Streams to create a dynamic list of wallet addresses interacting with a specific smart contract. This tutorial will serve as a foundation for building more complex applications. By the end of this tutorial, you will have a robust solution that tracks these interactions in real-time, and you will be well-equipped to explore the endless possibilities that QuickNode's data management solutions offer.

What You Will Do


  • Learn about QuickNode's Key-Value Store
  • Set up a Stream to get blockchain data on your desired chain
  • Filter incoming Stream data to detect new addresses to add a list
  • Get a dynamic list of interacted wallet addresses

What You Will Need


QuickNode's Key-Value Store

QuickNode's Key-Value Store is a data storage tool designed to manage extensive lists of data points, such as wallet addresses or transaction records. It enables developers to update and retrieve these lists and key-value sets on-demand, either through a REST API, within a Streams filter, or using Functions.

Key functionalities include:

  • Scalable Data Management: Manage and evaluate large datasets efficiently
  • Real-Time Updates: Update and access your data instantly
  • API Access: Interact with your lists and key-value sets via a REST API
  • QuickNode Product Integration: Seamless integration with Streams for real-time data processing and Functions for applying custom logic

Possible Use Cases of Key-Value Store

The Key-Value Store is useful for applications requiring real-time data tracking and evaluation. Some practical use cases include:

  • Wallet and Portfolio Management: Track the activity of a dynamic list of wallet addresses, allowing for real-time updates on transactions and portfolio changes
  • Token Holdings Monitoring: Maintain up-to-date records of token holdings across multiple wallets
  • Transaction Tracking and Alerts: Monitor transaction activity and set up alerts for specific conditions, such as large transfers or unusual activity patterns
  • Historical Data Analysis: Store and evaluate historical data to analyze trends and patterns over time

Using Key-Value Store with Streams Filters

Key-Value Store can be accessed and managed seamlessly within a Streams filter. You can create new lists and key-value sets, add and remove items from your lists, update key-value sets, and evaluate your Key-Value Store data against streaming blockchain data.

  • Lists: Use lists when you want to associate many values to one key. For instance, you could manage and evaluate a large list of wallet addresses by adding them as items to a list called "addresses" or you could filter only transactions related to addresses in a list you specify.

  • Key-Value Sets: Use key-value sets when you want to store data points for easy retrieval and updating. For example, you could calculate the average gas price in a block, store the value with the key "gasPrice" and then retrieve it in the next block to calculate the delta.

Key-Value Store functions work natively with your QuickNode account and Key-Value Store values are tied to your account, not to a specific Stream. So, if you have a list addressList, it will be accessible from any stream, function, or directy Key-Value Store REST API within your account.

For more detailed information on these functions, please refer to the QuickNode Key-Value Store documentation.

Explore More

Want to learn about the benefits of QuickNode Streams? Our blog post provides an in-depth look at its capabilities.

Creating a Dynamic List with Streams and Key-Value Store

In this section, we will filter the transactions that interact with the specified contract address (i.e., 1inch v5 Aggregation Router) and collect the interacting addresses in a list.

To get started, let's set up your environment.

Creating a Stream

First, set up a Stream on QuickNode to get transactions from the Ethereum Mainnet (or any other supported networks). Ensure your Stream is configured to capture the necessary transaction data.

If you haven't created a QuickNode account already, you can create an account here.

Navigate to your QuickNode dashboard, then navigate to the Streams tab and click Create Stream.

In the Stream Settings section, follow this configuration:

Stream Settings

  • Chain: Ethereum
  • Network: Mainnet
  • Dataset: Transactions
  • Stream start: 15894742 (The starting block number can be selected according to any date you want or according to the block where the contract is deployed in order to cover all interactions.)
  • Stream end: Leave unchecked (If you only want a list within a certain range and not an actively updated list, you can choose the ending block number.)
  • Stream payload: Modify the payload before streaming
  • Reorg Handling: Leave unchecked
tip

You can also copy and paste this QuickShare URL into your browser's address bar to automatically fill in the fields in your Stream settings according to this guide.

For any other fields not mentioned above, leave them as their default values.

Filtering the Stream Data

The following filter function processes incoming stream data to track wallet addresses that interact with a specific smart contract. This function will check each transaction in a block to see if it involves the target contract address and update a list of interacting addresses using QuickNode's Key-Value Store.

Since the cost in Streams is only based on the filtered data size, filtering eliminates dealing with unnecessary data and seriously reduces costs.

After selecting the modify the payload option, a code box appears to allow you to modify the payload. Paste the code below into the code box, then click the Run test button. You can select the testing block number as you wish.

In this function, we'll be using the following Key-Value Store functions:

  • qnContainsListItem: Checks if an item exists in a specific list in Key-Value Store.
  • qnUpsertList: Creates or updates a new list in Key-Value Store.
  • qnGetList: Retrieves all items from a specific list in Key-Value Store.

For a detailed explanation and a complete list of all available functions, please visit the QuickNode Key-Value Store documentation.

Filtering Function
function main(data) {
let results = {};
const contractAddress = "0x1111111254EEB25477B68fb85Ed929f73A960582"; // 1inch v5: Aggregation Router Contract Address on Ethereum
let newAdding = false;

// Helper function to check if an address exists in the list
function checkAddress(address) {
const result = qnContainsListItem("interactionList'", address);
return result;
}

// Helper function to add an address to the interaction list
function addAddress(address) {
if (!checkAddress(address)) {
qnUpsertList("interactionList", {
add_items: [address],
});
newAdding = true;
}
}

try {
// Process each transaction in the block
data.streamData.forEach((transaction) => {
// Check if the transaction involves the contract address
if (transaction.to && transaction.to === contractAddress.toLowerCase()) {
addAddress(transaction.from);
}
if (
transaction.from &&
transaction.from === contractAddress.toLowerCase()
) {
addAddress(transaction.to);
}
});

// Get the list of wallet addresses
results.addresses = qnGetList("interactionList");
} catch (error) {
results.error = error.message;
}

if (newAdding) {
return results;
} else {
return null;
}

return results;
}

Destination Settings

After clicking the Next button, choose Webhook for your Stream destination and type your webhook URL. Whenever the list is updated, the new list will be sent to this destination.

If you don't have a webhook URL, you can generate one for free at webhook.site or TypedWebhook.tools

Reviewing Results

After setting up the Stream, you can review the results by checking your webhook to ensure that wallet addresses interacting with the specified contract are correctly added to the list.

Results

More Resources


Conclusion

Using QuickNode's Key-Value Store with Streams provides a powerful way to manage and process blockchain data in real-time. This guide has shown you how to track wallet interactions with a smart contract, but the possibilities are vast.

Possible Ideas

  • Advanced Analytics: Extend this implementation to include analytics on transaction volumes and trends.
  • Alerting System: Create a system to alert you when significant interactions occur.
  • Historical Data Analysis: Combine real-time data processing with historical data analysis for more comprehensive insights.

If you have questions, please contact us directly. If you have any ideas or suggestions related to Streams, such as new destinations, features, metrics, or datasets, you want us to support.

Also, stay up to date with the latest by following us on Twitter and joining our Discord and Telegram announcement channel.

We ❤️ Feedback!

Let us know if you have any feedback or requests for new topics. We'd love to hear from you.

Share this guide