<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Lady_in_Stem</title>
        <link>https://paragraph.com/@devsaisa</link>
        <description>undefined</description>
        <lastBuildDate>Thu, 16 Apr 2026 12:36:24 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[Understanding SSZ Proofs in Lodestar: A Beginner’s Guide]]></title>
            <link>https://paragraph.com/@devsaisa/understanding-ssz-proofs-in-lodestar-a-beginners-guide</link>
            <guid>6FWz1vlA31MGtkyurkBd</guid>
            <pubDate>Wed, 08 Oct 2025 07:33:33 GMT</pubDate>
            <description><![CDATA[So far, you’ve learned that every SSZ View in Lodestar is backed by a Merkle tree — a structure that allows you to represent and verify data efficiently. But what if you only need to prove or verify part of an SSZ object — like a specific field inside a large Ethereum state object? That’s where proofs come in. 1. What Is a Merkle Proof?A Merkle proof is a compact, cryptographic way to prove that a specific piece of data exists inside a larger dataset — without revealing the entire dataset. It...]]></description>
            <content:encoded><![CDATA[<br><p>So far, you’ve learned that every SSZ <strong>View</strong> in Lodestar is backed by a <strong>Merkle tree</strong> — a structure that allows you to represent and verify data efficiently.</p><p>But what if you only need to prove or verify <strong>part</strong> of an SSZ object — like a specific field inside a large Ethereum state object?</p><p>That’s where <strong>proofs</strong> come in.</p><hr><h2 id="h-1-what-is-a-merkle-proof" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> 1. What Is a Merkle Proof?</h2><p>A <strong>Merkle proof</strong> is a compact, cryptographic way to prove that <em>a specific piece of data exists inside a larger dataset</em> — without revealing the entire dataset.</p><p>It’s built using a <strong>Merkle tree</strong>, where:</p><ul><li><p>Every leaf node represents a piece of data (e.g. a field value)</p></li><li><p>Every parent node represents the hash of its two children</p></li><li><p>The top node (root) represents the entire dataset</p></li></ul><p>To verify a proof, you only need:</p><ul><li><p>The <strong>root hash</strong> of the full dataset, and</p></li><li><p>The <strong>proof</strong> (a minimal set of sibling hashes + the leaf value)</p></li></ul><p>If the proof recomputes the same root, the data is valid </p><hr><h2 id="h-2-proofs-in-ssz-and-lodestar" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> 2. Proofs in SSZ and Lodestar</h2><p>In <strong>Lodestar SSZ</strong>, proofs let you:</p><ul><li><p>Generate a Merkle proof for selected fields</p></li><li><p>Send or store <em>only</em> those parts (great for light clients)</p></li><li><p>Verify or reconstruct the partial object later</p></li></ul><p>Every <strong>View</strong> in Lodestar comes with methods for working with proofs.</p><table style="min-width: 50px"><colgroup><col><col></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>Method</p></th><th colspan="1" rowspan="1"><p>Purpose</p></th></tr><tr><td colspan="1" rowspan="1"><p><code>view.createProof(paths)</code></p></td><td colspan="1" rowspan="1"><p>Create a proof for selected subfields</p></td></tr><tr><td colspan="1" rowspan="1"><p><code>Type.createFromProof(proof)</code></p></td><td colspan="1" rowspan="1"><p>Reconstruct a partial view from a proof</p></td></tr></tbody></table><hr><h2 id="h-3-creating-a-proof" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> 3. Creating a Proof</h2><p>Let’s create a proof for an SSZ type — the <strong>Attestation</strong> object.</p><pre data-type="codeBlock" text="import { ssz } from &quot;@lodestar/types&quot;;

// Create a tree-backed view
const attestation = ssz.phase0.Attestation.defaultView();

// Update a field
attestation.data.source.epoch = 100;
attestation.data.target.epoch = 120;

// Create a proof for only specific subfields
const proof = attestation.createProof([
  ['data', 'source', 'epoch'],
  ['data', 'target', 'epoch'],
]);

console.log(proof);
"><code><span class="hljs-keyword">import</span> { <span class="hljs-title">ssz</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">"@lodestar/types"</span>;

<span class="hljs-comment">// Create a tree-backed view</span>
const attestation <span class="hljs-operator">=</span> ssz.phase0.Attestation.defaultView();

<span class="hljs-comment">// Update a field</span>
attestation.data.source.epoch <span class="hljs-operator">=</span> <span class="hljs-number">100</span>;
attestation.data.target.epoch <span class="hljs-operator">=</span> <span class="hljs-number">120</span>;

<span class="hljs-comment">// Create a proof for only specific subfields</span>
const proof <span class="hljs-operator">=</span> attestation.createProof([
  [<span class="hljs-string">'data'</span>, <span class="hljs-string">'source'</span>, <span class="hljs-string">'epoch'</span>],
  [<span class="hljs-string">'data'</span>, <span class="hljs-string">'target'</span>, <span class="hljs-string">'epoch'</span>],
]);

console.log(proof);
</code></pre><p> <strong>What this does:</strong></p><ul><li><p>The proof includes only the paths to those two fields (<code>source.epoch</code>, <code>target.epoch</code>)</p></li><li><p>Lodestar automatically collects the necessary sibling hashes</p></li><li><p>You can now send this <code>proof</code> object to someone else who just needs to verify those fields</p></li></ul><hr><h2 id="h-4-reconstructing-from-a-proof" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> 4. Reconstructing from a Proof</h2><p>Later, someone else can use that proof to reconstruct a <strong>partial view</strong> of the object:</p><pre data-type="codeBlock" text="const partialAttestation = ssz.phase0.Attestation.createFromProof(proof);

// Access included fields
console.log(partialAttestation.data.source.epoch); //  Works

// Access excluded fields
try {
  console.log(partialAttestation.aggregationBits);
} catch (e) {
  console.error(&quot; Field not included in proof&quot;);
}
"><code>const partialAttestation <span class="hljs-operator">=</span> ssz.phase0.Attestation.createFromProof(proof);

<span class="hljs-comment">// Access included fields</span>
console.log(partialAttestation.data.source.epoch); <span class="hljs-comment">//  Works</span>

<span class="hljs-comment">// Access excluded fields</span>
<span class="hljs-keyword">try</span> {
  console.log(partialAttestation.aggregationBits);
} <span class="hljs-keyword">catch</span> (e) {
  console.error(<span class="hljs-string">" Field not included in proof"</span>);
}
</code></pre><p>The partial view only contains the fields included in the proof — accessing anything else throws an error.</p><hr><h2 id="h-5-anatomy-of-a-proof" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> 5. Anatomy of a Proof</h2><p>A Lodestar SSZ proof is an object that contains:</p><ul><li><p><code>type</code> – the SSZ type definition</p></li><li><p><code>gindices</code> – generalized indices for each field (tree positions)</p></li><li><p><code>leaves</code> – serialized field values</p></li><li><p><code>witnesses</code> – sibling hashes needed to recompute the root</p></li></ul><p>You rarely need to inspect these manually, but here’s a conceptual breakdown:</p><pre data-type="codeBlock" text="Proof {
  type: Attestation,
  leaves: [
    { path: ['data', 'source', 'epoch'], value: 100 },
    { path: ['data', 'target', 'epoch'], value: 120 }
  ],
  witnesses: [ &lt;hash1&gt;, &lt;hash2&gt;, ... ]
}
"><code>Proof {
  <span class="hljs-keyword">type</span>: Attestation,
  leaves: [
    { path: [<span class="hljs-string">'data'</span>, <span class="hljs-string">'source'</span>, <span class="hljs-string">'epoch'</span>], <span class="hljs-built_in">value</span>: <span class="hljs-number">100</span> },
    { path: [<span class="hljs-string">'data'</span>, <span class="hljs-string">'target'</span>, <span class="hljs-string">'epoch'</span>], <span class="hljs-built_in">value</span>: <span class="hljs-number">120</span> }
  ],
  witnesses: [ <span class="hljs-operator">&lt;</span>hash1<span class="hljs-operator">&gt;</span>, <span class="hljs-operator">&lt;</span>hash2<span class="hljs-operator">&gt;</span>, ... ]
}
</code></pre><hr><h2 id="h-6-verifying-a-proof" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> 6. Verifying a Proof</h2><p>To verify a proof, Lodestar recomputes the Merkle root from the provided values and sibling hashes, then compares it to the expected root.</p><pre data-type="codeBlock" text="const root = attestation.hashTreeRoot();
const proofRoot = partialAttestation.hashTreeRoot();

console.log(root.equals(proofRoot)); // ✅ true if proof is valid
"><code>const root <span class="hljs-operator">=</span> attestation.hashTreeRoot();
const proofRoot <span class="hljs-operator">=</span> partialAttestation.hashTreeRoot();

console.log(root.equals(proofRoot)); <span class="hljs-comment">// ✅ true if proof is valid</span>
</code></pre><p>This is the same logic that Ethereum’s <strong>light clients</strong> and <strong>consensus layer</strong> use to verify data efficiently without downloading the whole chain.</p><hr><h2 id="h-7-common-proof-use-cases" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> 7. Common Proof Use Cases</h2><table style="min-width: 50px"><colgroup><col><col></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>Use Case</p></th><th colspan="1" rowspan="1"><p>Description</p></th></tr><tr><td colspan="1" rowspan="1"><p><strong>Light Clients</strong></p></td><td colspan="1" rowspan="1"><p>Verify only specific parts of Ethereum state without syncing everything</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Cross-client communication</strong></p></td><td colspan="1" rowspan="1"><p>Pass compact, verifiable data between nodes</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Data availability checks</strong></p></td><td colspan="1" rowspan="1"><p>Confirm inclusion of a field without revealing the rest</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Testing &amp; debugging</strong></p></td><td colspan="1" rowspan="1"><p>Check integrity of partial SSZ objects</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Optimized syncs</strong></p></td><td colspan="1" rowspan="1"><p>Send proofs instead of full objects to reduce bandwidth</p></td></tr></tbody></table><hr><h2 id="h-8-proofs-views-working-together" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> 8. Proofs + Views: Working Together</h2><p>Since each <strong>Subview</strong> in Lodestar represents a subtree, you can create proofs for any nested field simply by specifying the path.</p><p>Example:</p><pre data-type="codeBlock" text="const proof = attestation.createProof([
  ['data', 'source'],
  ['data', 'target', 'root'],
]);
"><code>const <span class="hljs-attr">proof</span> = attestation.createProof([
  [<span class="hljs-string">'data'</span>, <span class="hljs-string">'source'</span>],
  [<span class="hljs-string">'data'</span>, <span class="hljs-string">'target'</span>, <span class="hljs-string">'root'</span>],
])<span class="hljs-comment">;</span>
</code></pre><ul><li><p><code>['data', 'source']</code> → proves the whole <code>source</code> container</p></li><li><p><code>['data', 'target', 'root']</code> → proves only one field from <code>target</code></p></li></ul><p>Subviews make it intuitive to target exactly what you need to prove — no manual Merkle math required.</p><hr><h2 id="h-9-tips-and-gotchas" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> 9. Tips &amp; Gotchas</h2><table style="min-width: 50px"><colgroup><col><col></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>Pitfall</p></th><th colspan="1" rowspan="1"><p>Explanation</p></th></tr><tr><td colspan="1" rowspan="1"><p>Trying to access fields not in proof</p></td><td colspan="1" rowspan="1"><p>Will throw an error — the partial view doesn’t have that data</p></td></tr><tr><td colspan="1" rowspan="1"><p>Modifying a partial view</p></td><td colspan="1" rowspan="1"><p>Possible, but rehashing won’t match the original root unless recomputed properly</p></td></tr><tr><td colspan="1" rowspan="1"><p>Proof ≠ Serialization</p></td><td colspan="1" rowspan="1"><p>A proof includes only paths + hashes, not full byte data</p></td></tr><tr><td colspan="1" rowspan="1"><p>Order matters</p></td><td colspan="1" rowspan="1"><p>Paths are hierarchical — <code>['data','source','epoch']</code> is not the same as <code>['data','epoch']</code></p></td></tr></tbody></table><hr><h2 id="h-summary" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> Summary</h2><table style="min-width: 50px"><colgroup><col><col></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>Concept</p></th><th colspan="1" rowspan="1"><p>Meaning</p></th></tr><tr><td colspan="1" rowspan="1"><p><strong>Proof</strong></p></td><td colspan="1" rowspan="1"><p>A compact structure that proves specific fields exist in an SSZ object</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>View</strong></p></td><td colspan="1" rowspan="1"><p>A Merkle-aware SSZ object that can create proofs</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Partial View</strong></p></td><td colspan="1" rowspan="1"><p>A reconstructed object from a proof containing only the proved fields</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Why it matters</strong></p></td><td colspan="1" rowspan="1"><p>Enables lightweight, verifiable data syncing (like light clients)</p></td></tr></tbody></table><hr><h3 id="h-key-takeaway" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Key Takeaway</h3><blockquote><p>SSZ proofs let you <em>prove data, not trust it</em>.</p><p>With just a few lines of Lodestar code, you can generate and verify Merkle proofs for any part of an Ethereum consensus object — from validator sets to attestations — without handling the full state.</p></blockquote><br>]]></content:encoded>
            <author>devsaisa@newsletter.paragraph.com (Lady.In.Stem)</author>
        </item>
        <item>
            <title><![CDATA[Understanding Subviews in Lodestar SSZ: A Beginner’s Guide]]></title>
            <link>https://paragraph.com/@devsaisa/understanding-subviews-in-lodestar-ssz-a-beginners-guide</link>
            <guid>n9N4oYbJyGHtBSE7bedf</guid>
            <pubDate>Sun, 05 Oct 2025 21:08:33 GMT</pubDate>
            <description><![CDATA[If you’re exploring Lodestar’s SSZ library and you’ve come across terms like view, subview, or TreeView, you might be wondering — what exactly is a subview and why do I need it? Let’s break it down step-by-step, starting from the basics.Step 1: What is SSZ?SSZ (Simple Serialize) is Ethereum’s serialization format. It defines how Ethereum’s consensus data (like blocks, states, attestations) are stored, hashed, and transmitted. In Lodestar (a TypeScript implementation of Ethereum’s consensus la...]]></description>
            <content:encoded><![CDATA[<p>If you’re exploring <strong>Lodestar’s SSZ library</strong> and you’ve come across terms like <code>view</code>, <code>subview</code>, or <code>TreeView</code>, you might be wondering — <em>what exactly is a subview and why do I need it?</em></p><p>Let’s break it down step-by-step, starting from the basics.</p><hr><h2 id="h-step-1-what-is-ssz" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Step 1: What is SSZ?</h2><p><strong>SSZ (Simple Serialize)</strong> is Ethereum’s serialization format.<br>It defines <strong>how Ethereum’s consensus data (like blocks, states, attestations)</strong> are stored, hashed, and transmitted.</p><p>In Lodestar (a TypeScript implementation of Ethereum’s consensus layer), SSZ data isn’t stored as plain JavaScript objects.<br>Instead, Lodestar uses <strong>Views</strong> — special objects that represent SSZ data <strong>along with its Merkle tree</strong>.</p><p>This helps:</p><ul><li><p>Make updates efficient (only re-hash the changed part of the tree)</p></li><li><p>Support proofs (Merkle branches)</p></li><li><p>Keep large data structures consistent</p></li></ul><hr><h2 id="h-step-2-what-is-a-view" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Step 2: What is a View?</h2><p>A <strong>View</strong> is Lodestar’s in-memory representation of an SSZ value.</p><ul><li><p>It behaves <em>like</em> a normal JavaScript object (you can get/set properties).</p></li><li><p>But under the hood, it’s backed by a <strong>Merkle tree</strong> (a hash-based data structure).</p><p>(If you are not sure what merkle trees are or merkleization , I will post a beginner friendly article explaining those concepts in details.)</p></li></ul><p>There are two main kinds:</p><table style="min-width: 50px"><colgroup><col><col></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>View Type</p></th><th colspan="1" rowspan="1"><p>Description</p></th></tr><tr><td colspan="1" rowspan="1"><p><strong>TreeView</strong></p></td><td colspan="1" rowspan="1"><p>Tree-backed view; any changes are immediately committed to the tree.</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>TreeViewDU</strong></p></td><td colspan="1" rowspan="1"><p>“Delayed Update” view; changes are cached and committed only when you call <code>.commit()</code>.</p></td></tr></tbody></table><p>You create views like this:</p><pre data-type="codeBlock" text="import { ssz } from &quot;@lodestar/types&quot;;

const attestation = ssz.phase0.Attestation.defaultView();
"><code><span class="hljs-keyword">import</span> { <span class="hljs-title">ssz</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">"@lodestar/types"</span>;

const attestation <span class="hljs-operator">=</span> ssz.phase0.Attestation.defaultView();
</code></pre><p>Now <code>attestation</code> is a <strong>View</strong> of type <code>Attestation</code>.</p><hr><h2 id="h-step-3-what-is-a-subview" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Step 3: What is a Subview?</h2><p>A <strong>Subview</strong> is a <em>nested view</em> — a field inside another view that’s itself a complex SSZ object.<br>Think of it as a <strong>branch</strong> inside a bigger Merkle tree.</p><p>Example:</p><pre data-type="codeBlock" text="const attestation = ssz.phase0.Attestation.defaultView(); //the main view

attestation.data      // ← This is a subview
attestation.data.source  // ← Another subview
attestation.signature // ← Not a subview (it's a byte vector)
"><code>const attestation <span class="hljs-operator">=</span> ssz.phase0.Attestation.defaultView(); <span class="hljs-comment">//the main view</span>

attestation.data      <span class="hljs-comment">// ← This is a subview</span>
attestation.data.source  <span class="hljs-comment">// ← Another subview</span>
attestation.signature <span class="hljs-comment">// ← Not a subview (it's a byte vector)</span>
</code></pre><p>Visually, you can think of it like this:</p><pre data-type="codeBlock" text="Attestation (root view)
├── aggregationBits (basic type)
├── data (Subview)
│   ├── source (Subview)
│   │   ├── epoch (basic type)
│   │   └── root (basic type)
│   └── target (Subview)
└── signature (basic type)
"><code>Attestation (root view)
├── aggregationBits (basic type)
├── data (Subview)
│   ├── source (Subview)
│   │   ├── epoch (basic type)
│   │   └── root (basic type)
│   └── target (Subview)
└── signature (basic type)
</code></pre><p>In Lodestar, <strong>each nested SSZ type (like a container, list, or vector)</strong> automatically becomes a subview.</p><hr><h2 id="h-step-4-why-do-we-need-subviews" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Step 4: Why Do We Need Subviews?</h2><p>Subviews make it possible to <strong>work with parts of large SSZ structures efficiently</strong> — without touching or re-hashing the entire thing.</p><p>Let’s see what this means in practice.</p><h3 id="h-work-with-nested-data-efficiently" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0"><span data-name="one" class="emoji" data-type="emoji">1⃣</span> Work with Nested Data Efficiently</h3><p>Instead of treating an entire object as a single blob, you can zoom into just one part.</p><pre data-type="codeBlock" text="// Create an attestation view
const att = ssz.phase0.Attestation.defaultView();

// Change a nested field deep inside
att.data.source.epoch = 10;
"><code><span class="hljs-comment">// Create an attestation view</span>
const att <span class="hljs-operator">=</span> ssz.phase0.Attestation.defaultView();

<span class="hljs-comment">// Change a nested field deep inside</span>
att.data.source.epoch <span class="hljs-operator">=</span> <span class="hljs-number">10</span>;
</code></pre><p>Under the hood, Lodestar:</p><ul><li><p>Updates only the <code>source</code> branch of the tree</p></li><li><p>Re-hashes just the affected nodes</p></li><li><p>Updates the root automatically</p></li></ul><p>No need to rebuild the whole object.</p><hr><h3 id="h-replace-or-reuse-subtrees" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0"><span data-name="two" class="emoji" data-type="emoji">2⃣</span> Replace or Reuse Subtrees</h3><p>Subviews let you <strong>copy or replace</strong> entire parts of a structure easily.</p><p>Example:</p><pre data-type="codeBlock" text="const att1 = ssz.phase0.Attestation.defaultView();
const att2 = ssz.phase0.Attestation.defaultView();

// Copy `data` from att1 to att2
att2.data = att1.data;
"><code>const att1 <span class="hljs-operator">=</span> ssz.phase0.Attestation.defaultView();
const att2 <span class="hljs-operator">=</span> ssz.phase0.Attestation.defaultView();

<span class="hljs-comment">// Copy `data` from att1 to att2</span>
att2.data <span class="hljs-operator">=</span> att1.data;
</code></pre><p>Here you replaced the entire <code>data</code> subtree — including <code>source</code>, <code>target</code>, and everything under it — in one line.<br>This is much faster than serializing/deserializing plain JS objects.</p><hr><h3 id="h-3-support-for-merkle-proofs" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">3 Support for Merkle Proofs</h3><p>Subviews are essential for <strong>Merkle proofs</strong>, since they represent subtrees.</p><p>For example:</p><pre data-type="codeBlock" text="const proof = attestation.createProof([
  ['data', 'source', 'epoch']
]);
"><code>const <span class="hljs-attr">proof</span> = attestation.createProof([
  [<span class="hljs-string">'data'</span>, <span class="hljs-string">'source'</span>, <span class="hljs-string">'epoch'</span>]
])<span class="hljs-comment">;</span>
</code></pre><p>Here, Lodestar knows exactly how to navigate the tree to isolate <code>data → source → epoch</code> — because each is a subview pointing to a subtree.</p><hr><h2 id="h-step-5-subview-independence-view-vs-viewdu" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> Step 5: Subview Independence — View vs ViewDU</h2><p>There’s a subtle but important behavior difference between <strong>TreeView</strong> and <strong>TreeViewDU</strong> when it comes to subviews.</p><h3 id="h-treeview-immediate-update" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0"> TreeView (Immediate Update)</h3><p>Each subview is <strong>independent</strong>.<br>If you assign one subview to another, Lodestar copies the data, but they don’t stay linked.</p><pre data-type="codeBlock" text="const c1 = C.toView({ a: [0, 0] });
const c2 = C.toView({ a: [1, 1] });

// Copies data — not linked
c1.a = c2.a;

// Changing c1 doesn’t affect c2
c1.a.set(0, 5);
console.log(c2.a.get(0)); // still 1
"><code>const c1 <span class="hljs-operator">=</span> C.toView({ a: [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>] });
const c2 <span class="hljs-operator">=</span> C.toView({ a: [<span class="hljs-number">1</span>, <span class="hljs-number">1</span>] });

<span class="hljs-comment">// Copies data — not linked</span>
c1.a <span class="hljs-operator">=</span> c2.a;

<span class="hljs-comment">// Changing c1 doesn’t affect c2</span>
c1.a.set(<span class="hljs-number">0</span>, <span class="hljs-number">5</span>);
console.log(c2.a.get(<span class="hljs-number">0</span>)); <span class="hljs-comment">// still 1</span>
</code></pre><br><h3 id="h-treeviewdu-linked-cache" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0"> TreeViewDU (Linked Cache)</h3><p>In <code>TreeViewDU</code>, subviews share <strong>mutable caches</strong> for performance.<br>So assigning one subview to another links them until you commit.</p><pre data-type="codeBlock" text="const c1 = C.toViewDU({ a: [0, 0] });
const c2 = C.toViewDU({ a: [1, 1] });

// Now both reference the same cache
c1.a = c2.a;

// Mutations affect both
c1.a.set(0, 5);
console.log(c2.a.get(0)); // 5
"><code>const c1 <span class="hljs-operator">=</span> C.toViewDU({ a: [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>] });
const c2 <span class="hljs-operator">=</span> C.toViewDU({ a: [<span class="hljs-number">1</span>, <span class="hljs-number">1</span>] });

<span class="hljs-comment">// Now both reference the same cache</span>
c1.a <span class="hljs-operator">=</span> c2.a;

<span class="hljs-comment">// Mutations affect both</span>
c1.a.set(<span class="hljs-number">0</span>, <span class="hljs-number">5</span>);
console.log(c2.a.get(<span class="hljs-number">0</span>)); <span class="hljs-comment">// 5</span>
</code></pre><p>That’s because DU views prioritize <em>speed and batching</em> over isolation.<br>Changes stay in cache until you finalize them with <code>.commit()</code>.</p><hr><h2 id="h-step-6-when-to-use-subviews" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0">Step 6: When to Use Subviews</h2><table style="min-width: 50px"><colgroup><col><col></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>Use Case</p></th><th colspan="1" rowspan="1"><p>Why Subviews Help</p></th></tr><tr><td colspan="1" rowspan="1"><p>Large SSZ structures</p></td><td colspan="1" rowspan="1"><p>Update or access only parts without rehashing the whole thing</p></td></tr><tr><td colspan="1" rowspan="1"><p>Proof generation</p></td><td colspan="1" rowspan="1"><p>Each subview corresponds to a Merkle subtree — easy to prove</p></td></tr><tr><td colspan="1" rowspan="1"><p>State updates</p></td><td colspan="1" rowspan="1"><p>Replace only a section of state efficiently</p></td></tr><tr><td colspan="1" rowspan="1"><p>Data reuse</p></td><td colspan="1" rowspan="1"><p>Copy a subtree (e.g. <code>att1.data = att2.data</code>)</p></td></tr><tr><td colspan="1" rowspan="1"><p>Testing</p></td><td colspan="1" rowspan="1"><p>Inspect or mutate inner structures directly</p></td></tr></tbody></table><hr><h2 id="h-example-recap" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> Example Recap</h2><p>Here’s a quick end-to-end example showing subviews in action:</p><pre data-type="codeBlock" text="import { ssz } from &quot;@lodestar/types&quot;;

// Create a tree-backed view
const att = ssz.phase0.Attestation.defaultView();

// Work with nested data (subviews)
att.data.source.epoch = 5;
att.data.target.epoch = 8;

// Replace a subtree
const newData = ssz.phase0.AttestationData.defaultView();
newData.source.epoch = 10;
att.data = newData;

// Create a proof using subviews
const proof = att.createProof([
  ['data', 'source', 'epoch'],
]);

console.log(att.hashTreeRoot().toString());
"><code><span class="hljs-keyword">import</span> { <span class="hljs-title">ssz</span> } <span class="hljs-title"><span class="hljs-keyword">from</span></span> <span class="hljs-string">"@lodestar/types"</span>;

<span class="hljs-comment">// Create a tree-backed view</span>
const att <span class="hljs-operator">=</span> ssz.phase0.Attestation.defaultView();

<span class="hljs-comment">// Work with nested data (subviews)</span>
att.data.source.epoch <span class="hljs-operator">=</span> <span class="hljs-number">5</span>;
att.data.target.epoch <span class="hljs-operator">=</span> <span class="hljs-number">8</span>;

<span class="hljs-comment">// Replace a subtree</span>
const newData <span class="hljs-operator">=</span> ssz.phase0.AttestationData.defaultView();
newData.source.epoch <span class="hljs-operator">=</span> <span class="hljs-number">10</span>;
att.data <span class="hljs-operator">=</span> newData;

<span class="hljs-comment">// Create a proof using subviews</span>
const proof <span class="hljs-operator">=</span> att.createProof([
  [<span class="hljs-string">'data'</span>, <span class="hljs-string">'source'</span>, <span class="hljs-string">'epoch'</span>],
]);

console.log(att.hashTreeRoot().toString());
</code></pre><hr><h2 id="h-in-summary" class="text-3xl font-header !mt-8 !mb-4 first:!mt-0 first:!mb-0"> In Summary</h2><table style="min-width: 50px"><colgroup><col><col></colgroup><tbody><tr><th colspan="1" rowspan="1"><p>Concept</p></th><th colspan="1" rowspan="1"><p>Meaning</p></th></tr><tr><td colspan="1" rowspan="1"><p><strong>View</strong></p></td><td colspan="1" rowspan="1"><p>Lodestar’s representation of SSZ data in memory (tree-backed).</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Subview</strong></p></td><td colspan="1" rowspan="1"><p>A nested view (a field that is itself an SSZ type).</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Why it matters</strong></p></td><td colspan="1" rowspan="1"><p>Enables efficient updates, subtree reuse, and proofs.</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>TreeView vs TreeViewDU</strong></p></td><td colspan="1" rowspan="1"><p>Independent vs linked subviews (immediate vs delayed updates).</p></td></tr><tr><td colspan="1" rowspan="1"><p><strong>Practical uses</strong></p></td><td colspan="1" rowspan="1"><p>Efficient state management, proof generation, data reuse.</p></td></tr></tbody></table><hr><h3 id="h-key-takeaway" class="text-2xl font-header !mt-6 !mb-4 first:!mt-0 first:!mb-0">Key Takeaway</h3><blockquote><p>A <strong>Subview</strong> is just a “view within a view” — a nested SSZ structure you can access and manipulate independently.<br>It’s the bridge between Lodestar’s Merkle trees and the object-oriented way TypeScript developers write code.</p></blockquote><hr><p>Thank you for taking your time to read through this article and if you have any question feel free to reach out. More resources on SSZ here.</p><div data-type="youtube" videoid="p8g6gfzQnD0">
      <div class="youtube-player" data-id="p8g6gfzQnD0" style="background-image: url('https://i.ytimg.com/vi/p8g6gfzQnD0/hqdefault.jpg'); background-size: cover; background-position: center">
        <a href="https://www.youtube.com/watch?v=p8g6gfzQnD0">
          <img src="https://paragraph.com/editor/youtube/play.png" class="play">
        </a>
      </div></div><p>An old video but still important/relevant. </p>]]></content:encoded>
            <author>devsaisa@newsletter.paragraph.com (Lady.In.Stem)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/81f88cfbd502144b4ad5fd10cfedff08b02bcdb66574122bce55a0cd31d44656.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[Understanding Solidity Function Structure: A Guide for Beginners]]></title>
            <link>https://paragraph.com/@devsaisa/understanding-solidity-function-structure-a-guide-for-beginners</link>
            <guid>y5LFvMxQc3oq9hk8SChG</guid>
            <pubDate>Fri, 03 Jan 2025 22:05:54 GMT</pubDate>
            <description><![CDATA[As a new developer to solidity sometimes it can be confusing looking at the syntax of some codes. Today, we will be handling functions. I used to wonder, why does the structure of some functions appear to take parameters twice or include parameters in different position. I did a lil digging and here's what I found. Solidity, the programming language for writing smart contracts on Ethereum and other blockchain platforms, has a unique syntax that can be confusing for beginners. One area is the ...]]></description>
            <content:encoded><![CDATA[<p>As a new developer to solidity sometimes it can be confusing looking at the syntax of some codes. Today, we will be handling functions.</p><p> I used to wonder, why does the structure of some functions appear to take parameters twice or include parameters in different position. I did a lil digging and here's what I found.  </p><p>Solidity, the programming language for writing smart contracts on Ethereum and other blockchain platforms, has a unique syntax that can be confusing for beginners. One area is the structure of functions, especially when parameters seem to appear twice or are placed in different positions. This article will break down the structure of Solidity functions and explain why this happens in simple terms. </p><div class="relative header-and-anchor"><h2 id="h-the-structure-of-a-basic-solidity-function">The structure of a basic solidity function.</h2></div><pre data-type="codeBlock" text="function functionName(parameterType parameterName) visibility modifier returns (returnType) {

    // Function body

}"><code><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">functionName</span>(<span class="hljs-params">parameterType parameterName</span>) <span class="hljs-title">visibility</span> <span class="hljs-title"><span class="hljs-keyword">modifier</span></span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params">returnType</span>) </span>{

    <span class="hljs-comment">// Function body</span>

}</code></pre><ul><li><p>functionName: The name of the function.</p></li><li><p>Parameters: Declared in parenthesis (parameterType parameterName) immediately after the function keyword.</p></li><li><p>Visibility: Defines who can call the function (e.g., public, private, internal, external).</p></li><li><p>Modifiers: Keywords that alter the behavior of the function (e.g., payable, view, pure, or custom modifiers).</p></li><li><p>Returns: Specifies the type of value(s) the function will return.</p></li></ul><p></p><div class="relative header-and-anchor"><h2 id="h-parameters-appearing-twice">PARAMETERS APPEARING TWICE.</h2></div><p>When this happens it's usually due to the following reasons:</p><div class="relative header-and-anchor"><h4 id="h-1-function-modifiers-with-parameters"><strong>1. Function Modifiers with Parameters</strong></h4></div><p>Modifiers in Solidity are reusable pieces of code that can add functionality to functions. Modifiers can also take arguments, which are separate from the function’s parameters.</p><p></p><pre data-type="codeBlock" text="modifier onlyOwner(address _owner) {
      require(msg.sender == _owner, &quot;Not the owner&quot;);
  _;
}
function updateOwner(address _newOwner) public onlyOwner(msg.sender) {
//function body
} "><code><span class="hljs-function"><span class="hljs-keyword">modifier</span> <span class="hljs-title">onlyOwner</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _owner</span>) </span>{
      <span class="hljs-built_in">require</span>(<span class="hljs-built_in">msg</span>.<span class="hljs-built_in">sender</span> <span class="hljs-operator">=</span><span class="hljs-operator">=</span> _owner, <span class="hljs-string">"Not the owner"</span>);
  <span class="hljs-keyword">_</span>;
}
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateOwner</span>(<span class="hljs-params"><span class="hljs-keyword">address</span> _newOwner</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title">onlyOwner</span>(<span class="hljs-params"><span class="hljs-built_in">msg</span>.sender</span>) </span>{
<span class="hljs-comment">//function body</span>
} </code></pre><ul><li><p></p><ul><li><p>The onlyOwner modifier takes _owner as a parameter.</p></li><li><p>The updateOwner function has its own _newowner  parameter.</p></li></ul></li></ul><p>The parameters of the modifier and the function are independent but may seem repetitive because they serve different purposes.</p><div class="relative header-and-anchor"><h4 id="h-2-function-overriding"><strong>2. Function Overriding</strong></h4></div><p>When Contracts are inheriting other contracts, they can sometimes override functions from the parent contract. When this happens the overriding function should match the parents functions signature including the parameters.</p><blockquote><p>Example</p><pre data-type="codeBlock" text="contract Parent {
     function something(uint x) public virtual return (uint)
            return Y +1;
    }
}
contract Child is Parent {
     function something(uint x) public overide returns (uint) {
           return Y + 2;
}"><code><span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Parent</span> </span>{
     <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">something</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> x</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title"><span class="hljs-keyword">virtual</span></span> <span class="hljs-title"><span class="hljs-keyword">return</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span></span>)
            <span class="hljs-title"><span class="hljs-keyword">return</span></span> <span class="hljs-title">Y</span> +1</span>;
    }
}
<span class="hljs-class"><span class="hljs-keyword">contract</span> <span class="hljs-title">Child</span> <span class="hljs-keyword">is</span> <span class="hljs-title">Parent</span> </span>{
     <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">something</span>(<span class="hljs-params"><span class="hljs-keyword">uint</span> x</span>) <span class="hljs-title"><span class="hljs-keyword">public</span></span> <span class="hljs-title">overide</span> <span class="hljs-title"><span class="hljs-keyword">returns</span></span> (<span class="hljs-params"><span class="hljs-keyword">uint</span></span>) </span>{
           <span class="hljs-keyword">return</span> Y <span class="hljs-operator">+</span> <span class="hljs-number">2</span>;
}</code></pre></blockquote><p>something function in Child matches the parameter (uint x) of the parent function in Parent. this makes sure that the child contract will follow the parent's interface. </p><div class="relative header-and-anchor"><h3 id="h-why-parameters-appear-before-or-after-modifiers">Why Parameters Appear Before or After Modifiers</h3></div><p>In Solidity, the placement of parameters, visibility, and modifiers is part of the language’s syntax. Here’s the order:</p><ul><li><p>Function Parameters: Always declared first, directly after the function keyword.</p></li><li><p>Visibility and Modifiers: Come after the parameters to define who can call the function and its behavior.</p></li><li><p>Return Parameters: Declared after the returns keyword, specifying the type of value(s) the function will return</p></li></ul><div class="relative header-and-anchor"><h3 id="h-3low-level-function-calls">3.<strong>Low-Level Function Calls</strong></h3></div><p>I am yet to fully understand this but this is what I gathered. </p><p>Sometimes you will find low-level functions like call or delegate call. They are basically functions that interact with other contracts and they use encoded parameters that will look different from regular parameters. </p><blockquote><div class="relative header-and-anchor"><h3 id="h-example">Example.</h3></div><pre data-type="codeBlock" text="(bool success, bytes memory data) = address(otherContract).call(
    abi.encodeWithSignature(&quot;doSomething(uint256)&quot;, 123)
);"><code>(<span class="hljs-keyword">bool</span> success, <span class="hljs-keyword">bytes</span> <span class="hljs-keyword">memory</span> data) <span class="hljs-operator">=</span> <span class="hljs-keyword">address</span>(otherContract).<span class="hljs-built_in">call</span>(
    <span class="hljs-built_in">abi</span>.<span class="hljs-built_in">encodeWithSignature</span>(<span class="hljs-string">"doSomething(uint256)"</span>, <span class="hljs-number">123</span>)
);</code></pre></blockquote><p>Parameters for the Something function {i wrote on the previous example} are passed via abi.encodeWithSignature.</p><p>The call function itself has its own parameters and return values.</p><div class="relative header-and-anchor"><h3 id="h-this-is-more-advanced-feature-in-solidity-that-help-with-flexibility-and-interoperability-in-the-near-future-when-i-fully-understand-i-will-elaborate">This is more advanced feature in solidity that help with flexibility and interoperability. In the near future when i fully understand , I will elaborate.</h3></div><div class="relative header-and-anchor"><h2 id="h-finally-some-tips-for-beginners">Finally some tips for beginners.</h2></div><ul><li><p><strong>Start Simple</strong>: Focus on understanding basic function structures before diving into modifiers and low-level calls.</p></li><li><p><strong>Read the Documentation</strong>: Solidity’s official documentation is a great resource for learning the syntax and features. READ DOCUMENTATION!!</p></li><li><p><strong>Practice</strong>: Build small contracts to experiment with different function structures and see how they behave.</p></li><li><p><strong>Ask Questions</strong>: Don’t hesitate to seek help from the Solidity community or forums when you encounter something confusing.</p></li></ul><div class="relative header-and-anchor"><h2 id="h-conclusion">Conclusion</h2></div><p>The structure of Solidity functions is designed to be logical and flexible, even if it seems complex at first. By understanding how parameters, visibility, modifiers, and return types fit together, We can write clear and effective smart contracts. We should keep practicing, and soon this will become second nature!</p><p>KEEP BUILDING.</p><p></p>]]></content:encoded>
            <author>devsaisa@newsletter.paragraph.com (Lady.In.Stem)</author>
            <enclosure url="https://storage.googleapis.com/papyrus_images/a24d7786b0a8552304109110caa8e776.jpg" length="0" type="image/jpg"/>
        </item>
        <item>
            <title><![CDATA[My Journey with Base: From a Green Web3 Enthusiast to Building Miniminds]]></title>
            <link>https://paragraph.com/@devsaisa/my-journey-with-base-from-a-green-web3-enthusiast-to-building-miniminds</link>
            <guid>bFrZP8NrAKNRnWpGBQlj</guid>
            <pubDate>Sat, 14 Dec 2024 11:23:58 GMT</pubDate>
            <description><![CDATA[This year, I was introduced to Base, Coinbase’s Ethereum Layer 2 solution, during the ETH Safari Hackathon in September. At the time, I was as green as it gets in Web3, still finding my footing in this fascinating but complex space. Little did I know that my journey with Base would spark a passion that continues to grow.ETH Safari Hackathon: A Crash Course in Web3The ETH Safari Hackathon was my first real deep dive into Web3 development. I attended numerous workshops, eager to soak up knowled...]]></description>
            <content:encoded><![CDATA[<p>This year, I was introduced to <strong>Base</strong>, Coinbase’s Ethereum Layer 2 solution, during the <strong>ETH Safari Hackathon</strong> in September. At the time, I was as green as it gets in Web3, still finding my footing in this fascinating but complex space. Little did I know that my journey with Base would spark a passion that continues to grow.</p><div class="relative header-and-anchor"><h4 id="h-eth-safari-hackathon-a-crash-course-in-web3">ETH Safari Hackathon: A Crash Course in Web3</h4></div><p>The ETH Safari Hackathon was my first real deep dive into Web3 development. I attended numerous workshops, eager to soak up knowledge. One of these workshops was led by the Base team, featuring Elisha, Dami, and another expert whose name escapes me (apologies!).</p><p>I had set my sights on the zkSync and Graph bounties, so I was laser-focused on learning those tools. However, the Base workshop stood out. The way the mentors taught was nothing short of amazing—clear, engaging, and beginner-friendly. As someone new to Web3, I was astonished at how much I could grasp and implement after just afew session. Their teaching style was a breath of fresh air compared to a previous hackathon workshop I had attended, which was… let’s just say less than stellar.  So that is how I met Base. After the worksho that was it. I went ahead and continued working with the zksync plugin.</p><p>A special shoutout to the zkSync/web3.js  mentor - Santiago Trujillo, who was incredibly supportive and willing to help. Anyone who worked with him would agree! H e laid the foundation for my web3 Knowledge.</p><p>The contrast between these experiences was striking, and it made me appreciate the Eth Safari  team’s efforts even more.(Technical mentors) </p><div class="relative header-and-anchor"><h4 id="h-enter-the-base-buildathon-a-new-challenge">Enter the Base Buildathon: A New Challenge</h4></div><p>Fast forward to the Base Buildathon—an event I was not going to miss{ A chance to build on base and learn more about web3, bet) . Determined to learn more about Web3 and Base, I attended every workshop. And when I say attended, I mean I traveled two hours to the venue and was among the first to arrive every single day. Yes, I’m that proud of myself! <span data-name="slightly_smiling_face" class="emoji" data-type="emoji">🙂</span></p><p>This time, I invited my partner from ETH Safari to join me. We decided to build our solution on Base, and I worked on not one but two applications:</p><ol><li><p><strong>Afida</strong>: A crowdfunding platform.</p></li><li><p><strong>Miniminds</strong>: A decentralized application aimed at kids aged 4 to 17. It incorporates crowdfunding to provide quality education to children in developing countries. (there is more to it)</p></li></ol><div class="relative header-and-anchor"><h4 id="h-what-makes-base-special">What Makes Base Special?</h4></div><p>Before I dive deeper, let’s talk about Base itself. It’s an Ethereum Layer 2 solution designed to make transactions faster and cheaper while maintaining the security of the Ethereum mainnet. Built using Optimistic Rollups, Base offers EVM compatibility, making it easy for developers to port their existing projects. What really sets Base apart, though, is its developer-first approach and community support—qualities I experienced firsthand during the Buildathon.</p><div class="relative header-and-anchor"><h4 id="h-beyond-the-buildathon-the-miniminds-vision">Beyond the Buildathon: The Miniminds Vision</h4></div><p>Unlike hackathons, buildathons emphasize continuity. After the event, my partner and I continued working on <strong>Miniminds</strong>. This application holds a special place in my heart because of its potential to make a real difference. By providing quality education to underprivileged kids, Miniminds aims to create opportunities and foster innovation in developing countries.</p><p>We’re still refining the application, but the dream is to push it to production eventualyy. I’m excited for the day you’ll see Miniminds on your screen, helping kids across the globe access the education they deserve and at the same time earn as they learn. We are also giving teachers a chance to showcase their work , control their work and earn as they teach.</p><p><strong>The base meetup.</strong></p><p>After the buildathon the base meetup happened and I got a chance to meet the base team including the founder . At the same time I met may like minded developers. Seeing an interactive community ready to help it inspired me to continue building on base. Even though we did not win the buildathon, I believe in the future miniminds will make a great difference, changing the life of students, teachers and how we view education in general.</p><div class="relative header-and-anchor"><h4 id="h-reflections-and-looking-ahead">Reflections and Looking Ahead</h4></div><p>Looking back, my journey with Base has been trans-formative. From the ETH Safari Hackathon to the Buildathon, I’ve grown not just as a developer but as a problem-solver and visionary. Base has been more than a platform for me; it’s been a catalyst for creativity and collaboration.</p><p>As we continue to build Miniminds, I invite you to follow along. The journey is far from over, and the best is yet to come. Stay tuned, because the future of Web3 is bright—and we’re building it together.</p><p></p>]]></content:encoded>
            <author>devsaisa@newsletter.paragraph.com (Lady.In.Stem)</author>
            <category>web3</category>
            <category>base</category>
            <category>build</category>
            <enclosure url="https://storage.googleapis.com/papyrus_images/a5dbd73417daa05c226a00171290d8d8.jpg" length="0" type="image/jpg"/>
        </item>
    </channel>
</rss>