Skip to content

Store and Retrieve Data on the Bulletin Chain

The Bulletin Chain is a specialized storage chain in the Polkadot ecosystem that provides decentralized data storage with IPFS-compatible content addressing. You can use it to store static sites, images, media assets, application data, or any other files that benefit from availability and censorship-resistance.

In this tutorial, you'll walk through a common developer scenario: storing an image using the Bulletin Chain's decentralized storage and obtaining its CID (Content Identifier) so it can be referenced from a dApp, NFT metadata, or any IPFS-compatible system. The same steps apply to any file type — documents, JSON configs, HTML pages, and more.

  • A Polkadot account (SS58 format) — see Create an Account if you need one
  • A browser wallet extension (Polkadot.js, Talisman, SubWallet, or Fearless)
  • An image or file to store (at most 2 MiB per transaction; for larger files, you can chunk your data — see Size Limits)
  • Authorization to store data on the Bulletin Chain (covered in the next section)
  • For the PAPI method: Node.js v18 or higher

The Bulletin Chain has no token balances — you need authorization before you can store data. Authorization grants your account a specific number of transactions and bytes that you can use for storage.

For this tutorial, we're going to use the testnet faucet for authorizations.

  1. Navigate to the Bulletin Chain Console and click Connect to connect your wallet.

  2. Go to the Faucet page and select the Storage Faucet tab.

  3. Under Authorize Account, enter the desired number of Transactions and Bytes for your storage needs, then click Authorize Account.

  4. Approve the transaction in your wallet extension. You should see a success confirmation.

  5. To verify your authorization, switch to the Accounts tab to view your remaining transactions, bytes, and expiration block.

Now that your account is authorized, you can store your image on-chain. Choose the method that best fits your workflow.

  1. Navigate to the Upload page in the Bulletin Chain Console. You can see your account's storage usage and authorization quota on the right side panel.

  2. Select the File tab, then drag and drop your image or click to browse. The UI shows the file name and size.

  3. Leave the CID Configuration at the defaults (Blake2b-256 hash, Raw codec) unless you have specific requirements.

  4. Click Upload to Bulletin Chain and approve the transaction in your wallet extension.

  5. On success, the UI displays your CID, Block Number, and Transaction Index.

After storing your image, you can verify it was successfully recorded using the Explorer in the Console UI. Navigate to the block number where your image was stored, shown on the Upload page or printed by the store script, to see the TransactionStorage.Stored event with the content hash and CID.

The Bulletin Chain follows a "write-to-chain, read-from-network" architecture — you retrieve data from collator nodes using the CID. For a full overview of retrieval methods, see the reference page.

  1. Navigate to the Download page in the Bulletin Chain Console.

  2. Choose a retrieval method:

    • P2P Connection: Connects directly to Bulletin Chain collator nodes (decentralized, recommended).
    • IPFS Gateway: Uses the Bulletin Chain's IPFS gateway at https://paseo-bulletin-next-ipfs.polkadot.io.
  3. Enter your CID in the "Fetch by CID" field — you can use either the bafk2bzace... format or the hex-encoded 0x0155a0e4... format.

  4. Click Fetch Data to retrieve your content. The UI also generates a direct Gateway Link you can open in your browser.

Stored data is retained for a limited period (~2 weeks on Polkadot TestNet). If you need your image to remain available beyond the retention period, renew it before it expires.

  1. Navigate to the Renew page in the Bulletin Chain Console and connect your wallet.
  2. Find your data in one of the following ways:
    • On the By CID tab, enter your CID and click Resolve CID.
    • On the By Block + Index tab, enter the Block Number and Transaction Index and click Lookup Transaction.
  3. Check the expiration status, then choose an action and approve the transaction in your wallet extension:
    • Renew: Schedules one renewal that takes effect when the current retention period ends. This is the renew call in the PAPI tab.
    • Renew immediately: Renews the data now, and the full retention period restarts from the current block. This is the force_renew call.
    • Enable auto-renew: Renews the data at the end of every retention period. The first renewal is prepaid, and later renewals use your authorization until it runs out. This is the enable_auto_renew call.

The renew call registers a one-time renewal. When the retention period of your data ends, the chain stores the data again, so it stays available for another full retention period. The renewal is paid from your authorization when you register it. Each content hash can have only one registered renewal at a time, so registering again before this one takes effect fails with RenewalAlreadyEnabled.

The DataRenewal pallet also provides the following alternatives:

  • force_renew: Renews the data immediately. It takes the same entry argument as renew.
  • enable_auto_renew: Renews the data at the end of every retention period. It takes the data's content hash. Each renewal after the first is charged to your authorization, and recurring renewal stops if your authorization cannot cover it.
  • Data Storage Reference


    Explore the full technical reference for the Bulletin Chain, including all extrinsics, storage items, and events.

    → Reference

Last updated: