LogoLogo
  • Entangle
    • Overview
    • Security Audits
  • Universal Interoperability Protocol
    • Overview
    • Architecture
      • Scalability and Network Stability
        • L2 Utility Blockchains
        • Transmitter Groups
      • Security and Consensus Mechanism
      • Finality
      • Execution Latency
      • Compatibility and Interoperability
    • Developer Guides
      • Getting Started
      • Solidity
        • Simple Abstract Messenger Example
        • Deploying Your Custom EVM Protocol
        • Bridging Tokens with UIP
        • Become an EVM Transmitter
      • Solana
        • Simple Abstract Messenger Example
        • Deploying Your Custom Solana Protocol
        • Become a Solana Transmitter
      • Calculate Cross-Chain Transaction Cost
      • Customizable Message Transmission Options
      • How to Debug Sent Messages
      • SDK Setup
      • Revenue Sharing for Transmitters
      • How to Become a Super Transmitter
    • Endpoints
  • Universal Data Feeds
    • Overview
    • Architecture
      • Data Delivery Methods
        • Pull Model
        • Push Model
      • Oracle Contract & User Interaction
    • Developer Guides
      • Custom Data Feeds
      • Fetch Data via Pull Model (PAYG)
        • EVM Smart Contracts
        • Solana Smart Contracts
      • Fetch Data via Pull Model (Subscriptions)
        • EVM Smart Contracts
        • Solana Smart Contracts
      • Fetch Data via Push Model
        • EVM Smart Contracts
        • Solana Smart Contracts
    • User Guides
      • Accessing Feeds
      • Subscribe to a Data Feed
      • Check Subscription
      • Manage Subscription
      • Renew Subscription
    • Data Endpoints
  • Universal Token Standard
    • Overview
    • Architecture
      • Fee Components
    • Developer Guides
      • Manual Deploy
        • Token Deployment Types
        • Create a Custom Token
        • Factory Blueprint Deployment
        • Examples
          • Initial Setup
          • UTS Connector
            • Mint & Burn Connector Scheme
            • Lock & Unlock Connector Scheme
            • Connector Over Native Currency
          • UTS Token
            • Simple Token
            • Token with Messages
      • Bridge SDK
      • Token Verification
      • Fees Calculation & Gas Estimation Logic
      • Estimations
    • User Guides
      • Launch Universal Token
      • Create a Liquidity Pool
      • Expand Existing Token
      • Transfer Liquidity to Connector
      • Bridging
    • Contract Addresses
  • Entangle Interoperable Blockchain
    • Overview
    • Architecture
    • Developer Guides
      • Set up a Validator Node
      • Delegating to Validators
      • Undelegating from Validators
      • Supported Accounts
  • More
    • Media Kit
    • FAQ
    • Report an Issue
    • Become a Partner
Powered by GitBook
On this page
  • Step 1: Initialize hardhat project
  • Step 2: Create PushReader contract and hardhat ignition script
  • Step 3: Deploy PushReader
  • Step 4: Create Push Subscribtion
  • Step 5: Execute PushConsumer.consumePrice transaction

Was this helpful?

Export as PDF
  1. Universal Data Feeds
  2. Developer Guides
  3. Fetch Data via Push Model

EVM Smart Contracts

Using the Push model means retrieving data from on-chain contract storage. This requires the data to exist in the on-chain contract storage, uploaded by a publisher or node operator beforehand. UDF maintains a node that continuously publishes updates for supported assets, but anyone is free to run their own node instance to ensure redundancy or customize their setup.

To utilize an update in your contract, you can read the value of the asset of interest from the PushMarketplace contract deployed on each supported chain. For demonstration purposes, in this guide we will create a consumer contract whose logic depends on the BTC/USD price.

Step 1: Initialize hardhat project

First of all, let's create new project and initialize hardhat in it.

mkdir push-consumer && cd push-consumer
yarn init -y
# Yarn initialization
yarn add --dev hardhat
yarn hardhat init
# Hardhat initialization flow(select TypeScript project)

Step 2: Create PushReader contract and hardhat ignition script

Next, let's create our consumer contract. The consumer contract, referred to as the PushReader, will retrieve data stored in PushMarketplace, which assumes the availability of verified updates pushed on-chain beforehand.

In this example, the contract will read the latest stored price of the BTC/USD asset and store it. To achieve this, we'll use the getFeedPrice function, a free data retrieval method for previously subscribed readers.

This contract should already be in subscription so it can have access for verification. The subscription can be purchased from the marketplace and the consumer contract needs to be added as an authorized address for the subscription.

For convenience, this function returns both the price and the timestamp in a single call. Providing both values ensures that users can verify the freshness of the data, which is critical for applications where price accuracy and timing are essential for decision-making.

./contracts/PushReader.sol
// SPDX-License-Identifier: BSL1.1
pragma solidity ^0.8.20;
interface IPushMarketplace  { 

   function getFeedPrice(
        bytes32 feed
    ) external returns (uint256 price, uint256 timestamp);
}
contract PushReader {
    IPushMarketplace public pushMarketplace;
    uint public latestPrice;
    uint public latestTimestamp;
    constructor(address _pushMarketplace){
        pushMarketplace = IPushMarketplace(_pushMarketplace);
    }
    function getData(bytes32 feedKey) external{
        (latestPrice, latestTimestamp) = pushMarketplace.getFeedPrice(feedKey);
    }
}

Next, create an ignition script to help with deployment of the new PushReader contract.

./ignition/modules/PushReader.ts
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";

// PushMarketplace address on Eth Sepolia network
const PushMarketplaceAddress = "0x48A10FF4ea77A099Cc966b537b5efC5b15c1060A"

const PushReaderModule = buildModule("PushReaderModule", (m) => {
  const consumer = m.contract("PushReader", [PushMarketplaceAddress]);

  return { consumer };
});

export default PushReaderModule;

Step 3: Deploy PushReader

Now let's modify the hardhat configuration file to add the eth_sepolia network.

./hardhat.config.ts
import { HardhatUserConfig } from "hardhat/config";
import "@nomicfoundation/hardhat-toolbox";

const config: HardhatUserConfig = {
  solidity: "0.8.28",
  networks: {
    eth_sepolia: {
        chainId: 11155111,
        // or http://127.0.0.1:8545, if you forked it locally
        url: "https://ethereum-sepolia-rpc.publicnode.com",
        accounts: [ "0x" ], // TODO: Set deployer private key
    },
  },
};

export default config;

Now we can deploy the PushReader contract by running the command below.

yarn hardhat ignition deploy ./ignition/modules/PushReader.ts --network eth_sepolia
Expected Result
✔ Confirm deploy to network eth_sepolia (11155111)? … yes
Compiled 1 Solidity file successfully (evm target: paris).
Hardhat Ignition 🚀

Deploying [ PushReaderModule]

Batch #1
  Executed PushReaderModule#PushReader

[ PushReaderModule] successfully deployed 🚀

Deployed Addresses

PushConsumerModule#PushConsumer - 0xe23650424625B602c0f996F25b287203632A3f16

Step 4: Create Push Subscribtion

Now we should add deployed PushConsumer(PushReader) contract as allowed address to our subscribtion.

Step 5: Execute PushConsumer.consumePrice transaction

To validate that we have our price, we will write an example backend script that send transaction to execute PushConsumer.consumePrice.

Let's create a separate directory called "scripts" and create a new script consumePrice.ts in it.

mkdir scripts && touch ./scripts/consumePrice.ts
./scripts/consumePrice.ts
import {
  PushReader,
} from "../typechain-types";
import { ethers } from "hardhat";

// PushConsumer address we got from the deployment
const PushReaderAddress = "0xe23650424625B602c0f996F25b287203632A3f16";

async function main() {  
  const pushConsumer = await ethers.getContractAt(
    "PushReader",
    PushReaderAddress
  ) as PushReader
;
  const feedKey = ethers.encodeBytes32String("BTC/USD");
  let tx = await pushReader.getFeedPrice(feedKey);
  await tx.wait();

  console.log("sent PushReader.getData tx", tx.hash);
  let price = await pushReader.latestPrice();
  let timestamp = await pushReader.latestTimestamp();
  console.log("price:", price );
  console.log("timestamp:", timestamp );
}

main()
  .then(() => process.exit(0))
  .catch(error => {
    console.error(error);
    process.exit(1);
  });

Change the PushReaderAddress to the address you got from deployment and execute the script to send the transaction to the blockchain.

yarn hardhat run ./scripts/consumePrice.ts --network eth_sepolia
Expected Result
sent PushReader.getData tx 0x8c9c7abdfc243500d8f20dafd69cb6b2f9b5c41a1bb5f8a374bb04a31e43dc94
price: 76660817492475224330633n
timestamp: 1744027000n

You can use cast to examine the transaction call trace and logs. The emitted event shows the latest update that we read. Note that gas usage may vary depending on the result and the version of the library in use.

cast run 0x8c9c7abdfc243500d8f20dafd69cb6b2f9b5c41a1bb5f8a374bb04a31e43dc94 -r https://eth-sepolia.public.blastapi.io
Expected Result
Executing previous transactions from the block.
Traces:
  [70570] 0xe23650424625B602c0f996F25b287203632A3f16::getData(0x4254432f55534400000000000000000000000000000000000000000000000000)
    ├─ [20482] 0x48A10FF4ea77A099Cc966b537b5efC5b15c1060A::getFeedPrice(0x4254432f55534400000000000000000000000000000000000000000000000000)
    │   ├─ [15586] 0x9E5953C651932937e5a9185404B925030F5cCF3a::getFeedPrice(0x4254432f55534400000000000000000000000000000000000000000000000000) [delegatecall]
    │   │   ├─  emit topic 0: 0x3aa8c2e667a2fabc8ac13b12611dabfd9bdd2f66210ad437122a7ab032ddf011
    │   │   │           data: 0x000000000000000000000000e23650424625b602c0f996f25b287203632a3f164254432f55534400000000000000000000000000000000000000000000000000
    │   │   └─ ← [Return] 0x00000000000000000000000000000000000000000000103bca8eeefcd59d11890000000000000000000000000000000000000000000000000000000067f3bd78
    │   └─ ← [Return] 0x00000000000000000000000000000000000000000000103bca8eeefcd59d11890000000000000000000000000000000000000000000000000000000067f3bd78
    └─ ← [Stop] 


Transaction successfully executed.
Gas used: 91846
PreviousFetch Data via Push ModelNextSolana Smart Contracts

Last updated 1 month ago

Was this helpful?

To deploy your contract on testnet, you'll need ETH eth_sepolia testnet tokens. You can obtain funds from public faucets (, , , , ).

for desired feed and with desired parameters and put deployed PushConsumer contract as address that can read the contract.

Option 1
Option 2
Option 3
Option 4
Option 5
Subscribe to a push datafeed