<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Toshiya Matsumoto</title>
    <description>The latest articles on DEV Community by Toshiya Matsumoto (@toshiya_matsumoto_ac94abe).</description>
    <link>https://dev.to/toshiya_matsumoto_ac94abe</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2142214%2F2a679b0a-f620-48f3-95fc-41fdc6e40158.jpeg</url>
      <title>DEV Community: Toshiya Matsumoto</title>
      <link>https://dev.to/toshiya_matsumoto_ac94abe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/toshiya_matsumoto_ac94abe"/>
    <language>en</language>
    <item>
      <title>🔐 Practical Guide to ZKP: Learn Real Usecase of ZKP with Plonky2</title>
      <dc:creator>Toshiya Matsumoto</dc:creator>
      <pubDate>Tue, 31 Mar 2026 02:48:05 +0000</pubDate>
      <link>https://dev.to/toshiya_matsumoto_ac94abe/practical-guide-to-zkp-learn-real-usecase-of-zkp-with-plonky2-408l</link>
      <guid>https://dev.to/toshiya_matsumoto_ac94abe/practical-guide-to-zkp-learn-real-usecase-of-zkp-with-plonky2-408l</guid>
      <description>&lt;p&gt;&lt;em&gt;It's for those who have heard of ZKP but never known the real usecase.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Before We Start
&lt;/h2&gt;

&lt;p&gt;Zero-Knowledge Proof (ZKP) is a technology that proves the truth of a statement without revealing the underlying information. A common example is proving you know a password without showing it.&lt;/p&gt;

&lt;p&gt;This article will use the Rust's fast recursive SNARK framework &lt;a href="https://github.com/0xPolygonZero/plonky2" rel="noopener noreferrer"&gt;Plonky2&lt;/a&gt; to build 3 ZKP circuits step by step. By the end of this article, you will understand the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;How ZKP Circuits Work&lt;/strong&gt; — Constraints, Witness, Public Inputs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hash Chain Proof&lt;/strong&gt; — Proving the order of data processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;State Transition Proof&lt;/strong&gt; — Proving the update of Merkle tree&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🧩 Core Model: Circuit, Prover, Verifier
&lt;/h2&gt;

&lt;p&gt;Let's understand the core 3 models of ZKP:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Entity&lt;/th&gt;
&lt;th&gt;What&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Circuit&lt;/strong&gt; 📐&lt;/td&gt;
&lt;td&gt;Define mathematical constraints&lt;/td&gt;
&lt;td&gt;Template of Exam Questions — Define how the answer looks like&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Prover&lt;/strong&gt; 🧑‍💻&lt;/td&gt;
&lt;td&gt;Generate proof with secret inputs&lt;/td&gt;
&lt;td&gt;Student who solves the exam&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;strong&gt;Verifier&lt;/strong&gt; ✅&lt;/td&gt;
&lt;td&gt;Verify validity of proof with public inputs&lt;/td&gt;
&lt;td&gt;Grader who checks the answer without seeing the solution&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Core Concept: &lt;strong&gt;The circuit only defines the rules — it doesn't solve them.&lt;/strong&gt; The prover supplies the secret answer. The verifier checks that the rules were followed without ever seeing that answer.&lt;/p&gt;




&lt;h2&gt;
  
  
  🌍 Real World Flow of ZKP: Who Proves, Who Verifies
&lt;/h2&gt;

&lt;p&gt;Let's see how ZKP is used in the real world:&lt;/p&gt;

&lt;h3&gt;
  
  
  Flow Chart: Outline of Proof and Verification
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────────────────────────────────────────────────────┐
│ 1. Build Circuit (Developer does it once)                            │
│                                                                      │
│ Define constraints with CircuitBuilder → build() → CircuitData       │
│                                                                      │
│ Output:                                                              │
│   ・CircuitData (circuit definition)                                 │
│   ・VerifierCircuitData (verifier key) → made public                 │
└────────────────────────────────┬─────────────────────────────────────┘
                                 │
                  ┌──────────────┴──────────────┐
                  ▼                             ▼
┌───────────────────────────┐   ┌───────────────────────────┐
│ 2. Prove                  │   │ 4. Verify                 │
│                           │   │                           │
│ = The party who holds     │   │ Verifier = Only sees      │
│   the data                │   │ the result                │
│                           │   │                           │
│ ・Has secret inputs       │   │ ・Receives only the proof │
│ ・Sets secrets in         │   │ ・Sees only public inputs │
│   PartialWitness          │   │ ・Knows nothing about     │
│ ・data.prove(pw)          │   │   secret inputs           │
│   generates proof         │   │ ・data.verify(proof)      │
│                           │   │   → Ok / Error            │
└─────────────┬─────────────┘   └─────────────┬─────────────┘
              │                               │
              │  3. Send proof                │
              │  proof + public_inputs        │
              └──────────────►────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Concrete Example: Private Database Update
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌───────────────────┐                    ┌───────────────────┐
│ Prover            │                    │ Verifier          │
│ (Data owner)      │                    │ (Auditor/Contract)│
└────────┬──────────┘                    └────────┬──────────┘
         │                                        │
         │ 1. Update the data                     │
         │    (e.g. change a balance)              │
         │    * This is secret                     │
         │                                        │
         │ 2. Generate ZK proof                   │
         │    prove(secret inputs)                │
         │    → obtain proof                      │
         │                                        │
         │ 3. Send proof ───────────────────────► │
         │    (contains no secret information)     │
         │                                        │
         │                                        │ 4. verify(proof)
         │                                        │    Public inputs only:
         │                                        │    ・old_root → new_root
         │                                        │    ・No idea what changed
         │                                        │    → Ok ✓
         │                                        │
         │                                        │ 5. Update state
         │                                        │    (record new_root)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  👀 Point: What Is Public Or Not
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Information&lt;/th&gt;
&lt;th&gt;Prover knows&lt;/th&gt;
&lt;th&gt;Verifier sees&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;What changed (value, position)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merkle path (sibling nodes)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Old state root (old_root)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;New state root (new_root)&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Proof&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The verifier only confirms that the state root transition is correct. &lt;strong&gt;It never learns what was updated.&lt;/strong&gt; 🤫&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚙️ Setup: Plonky2 Basic Structure
&lt;/h2&gt;

&lt;p&gt;All Plonky2 circuits starts from same 3 type definitions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;plonky2&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;field&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;goldilocks_field&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GoldilocksField&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;plonky2&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;plonk&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PoseidonGoldilocksConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;                    &lt;span class="c1"&gt;// Extension degree (always 2 in Plonky2)&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GoldilocksField&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;              &lt;span class="c1"&gt;// Finite field for arithmetic&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PoseidonGoldilocksConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;     &lt;span class="c1"&gt;// Hash config (Poseidon over Goldilocks)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And all circuits follows the pattern of the same 3 steps&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Build:   CircuitBuilder → Define constraints → builder.build() → CircuitData
2. Prove:   PartialWitness → Set secret inputs → data.prove(pw) → Proof
3. Verify:  data.verify(proof) → Ok(()) or Error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's make it run! 🚀&lt;/p&gt;




&lt;h2&gt;
  
  
  👋 Example 1: "Hello World" Circuit
&lt;/h2&gt;

&lt;p&gt;This first circuit proves &lt;strong&gt;"I know two numbers that add up to a specific sum"&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Sum is public (Verifier can see it). Two numbers are secret (Verifier can't see them).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;plonky2&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
    &lt;span class="nn"&gt;field&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;goldilocks_field&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;GoldilocksField&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;types&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nn"&gt;iop&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="nn"&gt;target&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;witness&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;PartialWitness&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WitnessWrite&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
    &lt;span class="nn"&gt;plonk&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;
        &lt;span class="nn"&gt;circuit_builder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;CircuitBuilder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nn"&gt;circuit_data&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;CircuitConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CircuitData&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="nn"&gt;config&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PoseidonGoldilocksConfig&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nn"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ProofWithPublicInputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;F&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GoldilocksField&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;PoseidonGoldilocksConfig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;SimpleCircuit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CircuitData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// Secret input slot&lt;/span&gt;
    &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;      &lt;span class="c1"&gt;// Secret input slot&lt;/span&gt;
    &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// Made public&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;SimpleCircuit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CircuitConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;standard_recursion_config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CircuitBuilder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Create slots for secret inputs (called "Targets" in Plonky2)&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.add_virtual_target&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.add_virtual_target&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Define constraint: sum = a + b&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Make sum visible to the verifier&lt;/span&gt;
        &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.register_public_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Compile the circuit&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="py"&gt;.build&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ProofWithPublicInputs&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;pw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PartialWitness&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="nf"&gt;.set_target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;F&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_canonical_u64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="nf"&gt;.set_target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;F&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_canonical_u64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="nf"&gt;.prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ProofWithPublicInputs&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;anyhow&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="nf"&gt;.verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Usage：&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;circuit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;SimpleCircuit&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Prover: "I know two numbers that add up to 8"&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;proof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;circuit&lt;/span&gt;&lt;span class="nf"&gt;.prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Verifier: "Is this proof valid?" (can't see 3 and 5 — only sees 8)&lt;/span&gt;
&lt;span class="nd"&gt;assert_eq!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="py"&gt;.public_inputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="nn"&gt;F&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_canonical_u64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;circuit&lt;/span&gt;&lt;span class="nf"&gt;.verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.is_ok&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔍 What Happened?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Build Phase                    Prove Phase                   Verify Phase
┌────────────────┐           ┌────────────────┐          ┌──────────────┐
│ builder.add    │           │ pw.set_target  │          │ data.verify  │
│ (a, b)         │           │ (a=3, b=5)     │          │ (proof)      │
│                │           │                │          │              │
│ Define         │    →      │ Set secret     │    →     │ Verify proof │
│ constraint:    │           │ inputs         │          │              │
│ "sum = a + b"  │           │ → generate     │          │ Visible:     │
│                │           │   proof        │          │  sum=8 only  │
│ * No compute   │           │                │          │              │
│  Rules only    │           │ a=3, b=5 are   │          │ Hidden:      │
│                │           │ NOT in proof   │          │  a=3, b=5    │
└────────────────┘           └────────────────┘          └──────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Build Phase&lt;/strong&gt;: &lt;code&gt;builder.add(a, b)&lt;/code&gt; does &lt;strong&gt;not&lt;/strong&gt; compute &lt;code&gt;a + b&lt;/code&gt;. It creates a &lt;em&gt;constraint&lt;/em&gt; that says "sum must equal a + b". The circuit is a template of rules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prove Phase&lt;/strong&gt;: When the prover sets &lt;code&gt;a=3, b=5&lt;/code&gt;, Plonky2 generates a cryptographic proof that these values satisfy the constraints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify Phase&lt;/strong&gt;: The verifier checks the proof. It sees &lt;code&gt;sum=8&lt;/code&gt; in the public inputs, but has no way of knowing &lt;code&gt;a=3&lt;/code&gt; or &lt;code&gt;b=5&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key point&lt;/strong&gt;: A &lt;code&gt;Target&lt;/code&gt; in Plonky2 is not a variable — it's a "wire" in the circuit. &lt;code&gt;builder.add(a, b)&lt;/code&gt; computes nothing. It just connects two inputs to an addition gate.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🔗 Example 2: Hashchain — Proving Ordered Processing
&lt;/h2&gt;

&lt;p&gt;Alright let's create something more practical now. &lt;br&gt;
It proves that the final hash is calculated from the underlying items in the right processing order.&lt;/p&gt;
&lt;h3&gt;
  
  
  Concept
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;state_0 = hash(0)
state_1 = hash(state_0 || item_0)
state_2 = hash(state_1 || item_1)
state_3 = hash(state_2 || item_2)    ← Final hash (public)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Each step feeds the previous hash into the next.&lt;br&gt;
If any item in the chain is modified, the final hash changes.&lt;br&gt;
The prover proves the chain was computed correctly; the verifier only checks the final hash.&lt;/p&gt;
&lt;h3&gt;
  
  
  Proof and Verification Flow
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  Prover                                   Verifier
  ──────                                   ────────

  Holds secret items:
  items = [item_0, item_1, item_2]
         ↓
  Set secret inputs in circuit:
  pw.set_target(items[0], item_0)
  pw.set_target(items[1], item_1)
  pw.set_target(items[2], item_2)
         ↓
  Generate proof:
  proof = data.prove(pw)
         ↓
  Send proof ──────────────────────────►  Receive proof
  (items are NOT included in proof)        ↓
                                       Extract final hash from
                                       proof.public_inputs
                                         ↓
                                       data.verify(proof) → Ok ✓
                                         ↓
                                       "Does the final hash match
                                        the expected value?"
                                       ← This is business logic (outside the circuit)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="k"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;utils&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;poseidon_hash_out&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;PoseidonHashOutTarget&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;HashChainCircuit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CircuitData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;HashChainCircuit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chain_length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CircuitConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;standard_recursion_config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CircuitBuilder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Create a target (slot) for each item in the chain&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Vec&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;chain_length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="nf"&gt;.map&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.add_virtual_target&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="nf"&gt;.collect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// Start from hash(0)&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;zero&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.zero&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PoseidonHashOutTarget&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;hash_inputs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;zero&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

        &lt;span class="c1"&gt;// Chain: for each item, state = hash(state || item)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;inputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nd"&gt;vec!&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;&lt;span class="nf"&gt;.concat&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PoseidonHashOutTarget&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;hash_inputs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Only expose the final hash — items stay secret&lt;/span&gt;
        &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.register_public_inputs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="py"&gt;.build&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ProofWithPublicInputs&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;pw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PartialWitness&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.items&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="nf"&gt;.iter&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="nf"&gt;.set_target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;F&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_canonical_u32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="nf"&gt;.prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Usage：&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Build a circuit for a chain of length 3&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;circuit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;HashChainCircuit&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Prove: "I processed items [1, 2, 3] in this exact order"&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;proof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;circuit&lt;/span&gt;&lt;span class="nf"&gt;.prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Verify: proof is valid and the final hash is in proof.public_inputs&lt;/span&gt;
&lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;circuit&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="nf"&gt;.verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.is_ok&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  💡 Why is this useful?
&lt;/h3&gt;

&lt;p&gt;Imagine a database with 10,000 records. &lt;br&gt;
The prover generates a single proof for the entire hash chain. The verifier can confirm that all records were processed correctly by checking just that one proof — no need to recalculate anything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Usecase Example：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📋 &lt;strong&gt;Watch Log&lt;/strong&gt;: Proof that logs are not manipulated&lt;/li&gt;
&lt;li&gt;📦 &lt;strong&gt;Batch Process&lt;/strong&gt;: Proof that bulk transactions are processed in the right order&lt;/li&gt;
&lt;li&gt;🔄 &lt;strong&gt;Data Pipeline&lt;/strong&gt;: Proof that the ETL process is processed correctly. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Circuit is nothing but a calculator — &lt;code&gt;hash(hash(hash(0, item0), item1), item2) = final_hash&lt;/code&gt;.&lt;br&gt;
The &lt;em&gt;verifier&lt;/em&gt; judges whether the final hash matches the expected value.&lt;br&gt;
This separation of concerns — mathematical rules inside the circuit, business logic outside — is the fundamental pattern of ZKP design.&lt;/p&gt;


&lt;h2&gt;
  
  
  🌳 Example 3: State Transition — Proves Merkle Tree Update
&lt;/h2&gt;

&lt;p&gt;Many systems store data in a Merkle tree.&lt;br&gt;
&lt;strong&gt;State Transition Proof&lt;/strong&gt; proves "I updated a leaf of the tree and the value of the root has changed from &lt;code&gt;old_root&lt;/code&gt; to &lt;code&gt;new_root&lt;/code&gt;"&lt;/p&gt;

&lt;p&gt;The verifier only sees the two root values.&lt;br&gt;
Which leaf was changed, and what the old or new value was, is never revealed.&lt;/p&gt;
&lt;h3&gt;
  
  
  Merkle Tree Update Root
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    Merkle Tree (height=2, 4 leaves)

            Before Update                       After Update
          old_root                            new_root
           /    \                              /    \
         h01     h23                         h01     h23
        /   \   /   \                       /   \   /   \
      [10] [20] [30] [40]               [10] [99] [30] [40]
             ↑                                  ↑
          index=1                            index=1
          old_value=20                       new_value=99


  What the Prover knows          What the Verifier sees
  ────────────────────          ──────────────────────
  ・index = 1                   ・old_root
  ・old_value = 20              ・new_root
  ・new_value = 99              ・proof (cryptographic)
  ・Merkle path (sibling nodes)
  ・old_root, new_root
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;StateTransitionCircuit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CircuitData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;old_leaf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;new_leaf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;merkle_proof&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;MerkleProofTarget&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;old_root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PoseidonHashOutTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;new_root&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;PoseidonHashOutTarget&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;StateTransitionCircuit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;usize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CircuitConfig&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;standard_recursion_config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CircuitBuilder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;old_leaf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.add_virtual_target&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;new_leaf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.add_virtual_target&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.add_virtual_target&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;merkle_proof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;MerkleProofTarget&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;old_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PoseidonHashOutTarget&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;new_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PoseidonHashOutTarget&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Constraint 1: old_leaf at this index produces old_root&lt;/span&gt;
        &lt;span class="n"&gt;merkle_proof&lt;/span&gt;&lt;span class="py"&gt;.verify&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;old_leaf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;old_root&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Constraint 2: compute root from new_leaf with same index and siblings → computed_new_root&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;computed_new_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
            &lt;span class="n"&gt;merkle_proof&lt;/span&gt;&lt;span class="py"&gt;.get_root&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;new_leaf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Constraint 3: computed root must match the provided new_root&lt;/span&gt;
        &lt;span class="n"&gt;computed_new_root&lt;/span&gt;&lt;span class="nf"&gt;.connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_root&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Public inputs: only the two roots&lt;/span&gt;
        &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.register_public_inputs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;old_root&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.register_public_inputs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;new_root&lt;/span&gt;&lt;span class="nf"&gt;.to_vec&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="py"&gt;.build&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;old_leaf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_leaf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;merkle_proof&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;old_root&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_root&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;The prover sets the witness (secret inputs):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;MerkleTree&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;leaf_index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;old_value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;new_value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;ProofWithPublicInputs&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Get old state&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;proof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="nf"&gt;.prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;leaf_index&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;old_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="nf"&gt;.get_root&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Update the tree&lt;/span&gt;
    &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="nf"&gt;.update_leaf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;leaf_index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_value&lt;/span&gt;&lt;span class="nf"&gt;.hash&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;new_root&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="nf"&gt;.get_root&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Set all secret witnesses&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;pw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PartialWitness&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="nf"&gt;.set_target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.old_leaf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;F&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_canonical_u32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;old_value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="nf"&gt;.set_target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.new_leaf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;F&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_canonical_u32&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="nf"&gt;.set_target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nn"&gt;F&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_canonical_u64&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;leaf_index&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.merkle_proof&lt;/span&gt;&lt;span class="nf"&gt;.set_witness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.old_root&lt;/span&gt;&lt;span class="nf"&gt;.set_witness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;old_root&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.new_root&lt;/span&gt;&lt;span class="nf"&gt;.set_witness&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_root&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="nf"&gt;.prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create a Merkle tree with 4 leaves&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;MerkleTree&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u32&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// height=2 → 4 leaves&lt;/span&gt;
&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="nf"&gt;.update_leaf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10u32&lt;/span&gt;&lt;span class="nf"&gt;.hash&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="nf"&gt;.update_leaf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20u32&lt;/span&gt;&lt;span class="nf"&gt;.hash&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="nf"&gt;.update_leaf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30u32&lt;/span&gt;&lt;span class="nf"&gt;.hash&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="nf"&gt;.update_leaf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;40u32&lt;/span&gt;&lt;span class="nf"&gt;.hash&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;circuit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;StateTransitionCircuit&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Prove: "I changed leaf 1 from 20 to 99"&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;proof&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;circuit&lt;/span&gt;&lt;span class="nf"&gt;.prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Verify: the root transition is correct&lt;/span&gt;
&lt;span class="n"&gt;circuit&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="nf"&gt;.verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;proof&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"should verify"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🤥 Can you deceive?
&lt;/h3&gt;

&lt;p&gt;When a prover tries to cheat — e.g. claiming the old value was 999 when it was actually 20 — the Merkle path won't match the old_root, and proof generation itself fails.&lt;br&gt;
It's impossible to generate a valid proof for a false statement. 🛡️&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Panics — you can't prove a lie&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;std&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;catch_unwind&lt;/span&gt;&lt;span class="p"&gt;(||&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;circuit&lt;/span&gt;&lt;span class="nf"&gt;.prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;tree&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;999&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// 999 ≠ actual value&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nd"&gt;assert!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="nf"&gt;.is_err&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧱 Overall Picture: How To Combine the Patterns
&lt;/h2&gt;

&lt;p&gt;The three patterns above are useful on their own, but they become truly powerful when combined.&lt;/p&gt;

&lt;h3&gt;
  
  
  Combining the Patterns
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌────────────────────────────────────────────────────────────────┐
│                                                                │
│  Prover (the party who holds the data)                         │
│  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━                         │
│                                                                │
│  Step 1: Prove individual operations                           │
│  ┌──────────────────────────────────────────────────────┐      │
│  │                                                      │      │
│  │  ┌────────────────┐  ┌────────────────┐              │      │
│  │  │ Operation A    │  │ Operation B    │  ...         │      │
│  │  │                │  │                │              │      │
│  │  │ State          │  │ State          │              │      │
│  │  │ Transition     │  │ Transition     │              │      │
│  │  │ (Merkle tree)  │  │ (Merkle tree)  │              │      │
│  │  └───────┬────────┘  └───────┬────────┘              │      │
│  │          │ proof_a           │ proof_b                │      │
│  └──────────┼───────────────────┼───────────────────────┘      │
│             │                   │                               │
│             ▼                   ▼                               │
│  Step 2: Chain the proofs together (hash chain)                │
│  ┌──────────────────────────────────────────────────────┐      │
│  │                                                      │      │
│  │  hash(hash(hash(0, proof_a), proof_b), ...)          │      │
│  │    = final_hash                                      │      │
│  │                                                      │      │
│  └─────────────────────────┬────────────────────────────┘      │
│                             │                                  │
│                     Final proof                                │
│                                                                │
└─────────────────────────────┬──────────────────────────────────┘
                              │
                              │  Send proof
                              ▼
┌────────────────────────────────────────────────────────────────┐
│                                                                │
│  Verifier (auditor / smart contract / server)                  │
│  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━                   │
│                                                                │
│  verify(proof) → Ok ✓                                         │
│                                                                │
│  Visible:  old_root, new_root                                  │
│  Hidden:   individual operations, data values, account details │
│                                                                │
│  * Verifying just one proof cryptographically guarantees       │
│    the correctness of ALL operations                           │
│                                                                │
└────────────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Role of Each Pattern
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;What it proves&lt;/th&gt;
&lt;th&gt;Example use cases&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hash Chain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A sequence of data was processed in the correct order&lt;/td&gt;
&lt;td&gt;Audit logs, batch processing, data pipelines&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;State Transition&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;A Merkle tree update was performed correctly&lt;/td&gt;
&lt;td&gt;Database updates, balance changes, config changes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;By combining them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prove each individual update with a state transition proof&lt;/li&gt;
&lt;li&gt;Chain those proofs together with a hash chain&lt;/li&gt;
&lt;li&gt;The verifier checks just one final proof to confirm the correctness of everything&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ Practical Tips
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. 🏎️ Always Build in Release Mode
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;cargo &lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="nt"&gt;--release&lt;/span&gt; test_name
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Debug mode is orders of magnitude slower. A proof that takes 2 seconds in release can take minutes in debug. 🐢→🐇&lt;/p&gt;

&lt;h3&gt;
  
  
  2. 🔁 The Circuit Pattern Is Always the Same
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;MyCircuit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;CircuitData&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// Compiled circuit&lt;/span&gt;
    &lt;span class="c1"&gt;// ... targets (wire slots)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;MyCircuit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;            &lt;span class="c1"&gt;// Build phase: define constraints&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;CircuitBuilder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;F&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;D&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// ... add constraints ...&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="py"&gt;.build&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;        &lt;span class="c1"&gt;// Prove phase: set witness&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;pw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;PartialWitness&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// ... set values on targets ...&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="py"&gt;.data&lt;/span&gt;&lt;span class="nf"&gt;.prove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pw&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. 🔓🔒 Public vs. Secret Is Decided at Build Time
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This value stays secret (only the prover knows it)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.add_virtual_target&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// This value becomes public (verifier can see it)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.register_public_input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Now it's public&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. ⚠️ Constraints Are Assertions, Not Computations
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="c1"&gt;// This does NOT compute a + b at build time&lt;/span&gt;
&lt;span class="c1"&gt;// It creates a gate with the constraint: sum = a + b&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sum&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="nf"&gt;.add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// At prove time, if the witness values don't satisfy&lt;/span&gt;
&lt;span class="c1"&gt;// the constraint, proof generation fails&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🎬 Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Zero-knowledge proofs aren't magic. They're constraint systems wrapped in clever cryptography. The circuit defines the rules, the prover fills in the secret inputs, and the verifier checks the proof without ever seeing those inputs.&lt;/p&gt;

&lt;p&gt;With Plonky2:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔗 &lt;strong&gt;Hash Chain&lt;/strong&gt; — prove that data was processed in the correct order&lt;/li&gt;
&lt;li&gt;🌳 &lt;strong&gt;State Transition&lt;/strong&gt; — prove a database update without revealing what changed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code patterns are consistent and composable. Once you understand &lt;code&gt;CircuitBuilder → PartialWitness → prove → verify&lt;/code&gt;, you can stack simple circuits to build arbitrarily complex proof systems. 🧱✨&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The code in this article uses the &lt;a href="https://github.com/0xPolygonZero/plonky2" rel="noopener noreferrer"&gt;Plonky2&lt;/a&gt; framework — a fast recursive SNARK system built on Poseidon hashing over the Goldilocks field.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>zkp</category>
      <category>cryptocurrency</category>
      <category>webdev</category>
    </item>
    <item>
      <title>React Best Practices in Cursor</title>
      <dc:creator>Toshiya Matsumoto</dc:creator>
      <pubDate>Sun, 01 Feb 2026 08:29:48 +0000</pubDate>
      <link>https://dev.to/toshiya_matsumoto_ac94abe/react-best-practices-in-cursor-79e</link>
      <guid>https://dev.to/toshiya_matsumoto_ac94abe/react-best-practices-in-cursor-79e</guid>
      <description>&lt;h1&gt;
  
  
  Goal
&lt;/h1&gt;

&lt;p&gt;Use React Best Practices quickly out of the box in Cursor.&lt;br&gt;
While it's been written in many blogs for Claude Code but not for Cursor. &lt;br&gt;
Let's make it work!&lt;/p&gt;
&lt;h1&gt;
  
  
  What is React Best Practices?
&lt;/h1&gt;

&lt;p&gt;10+ years of React and Next.js optimization knowledge collection provided by Vercel. &lt;br&gt;
&lt;a href="https://vercel.com/blog/introducing-react-best-practices" rel="noopener noreferrer"&gt;https://vercel.com/blog/introducing-react-best-practices&lt;/a&gt;&lt;br&gt;
Setting them in the skills or rules in the AI agents, it allows the agents to work by referencing to the documents during processing. &lt;/p&gt;
&lt;h1&gt;
  
  
  Procedure
&lt;/h1&gt;

&lt;ol&gt;
&lt;li&gt;Run the following command to install agent-skills under a specific project.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx add-skill vercel-labs/agent-skills
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Select Cursor and follow the instructions. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpbnyukgag67ljekiavd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpbnyukgag67ljekiavd.png" alt=" " width="800" height="679"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It installs the files automatically under&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.cursor/skills/react-best-practices/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;however, &lt;strong&gt;Cursor is not able to detect them just out of the box&lt;/strong&gt; because the format in md files is different from what Cursor expects.&lt;/p&gt;

&lt;p&gt;If you go to &lt;br&gt;
&lt;code&gt;Cursor -&amp;gt; Settings... -&amp;gt; Cursor Settings -&amp;gt; Rules,Skills,Subagents&lt;/code&gt;&lt;br&gt;
you should be seeing No Skills are set over there. &lt;/p&gt;

&lt;p&gt;In order for Cursor to read it, you need to convert it with &lt;code&gt;/migrate-to-skills&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Here is a prompt I used. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j0gc63otfvpdv46e5gf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8j0gc63otfvpdv46e5gf.png" alt=" " width="800" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Conversion command is officially provided by Cursor. &lt;br&gt;
See: &lt;a href="https://cursor.com/docs/context/skills#migrating-rules-and-commands-to-skills" rel="noopener noreferrer"&gt;https://cursor.com/docs/context/skills#migrating-rules-and-commands-to-skills&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Type /migrate-to-skills in Agent chat&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Takeaway
&lt;/h1&gt;

&lt;p&gt;You need to run &lt;code&gt;/migrate-to-skills&lt;/code&gt; for Cursor to read React Best Practices in Cursor.&lt;/p&gt;

</description>
      <category>cursor</category>
      <category>ai</category>
      <category>react</category>
      <category>vercel</category>
    </item>
    <item>
      <title>🚀 Type Safety Across Layers: From Messy DBs to Clean Apps</title>
      <dc:creator>Toshiya Matsumoto</dc:creator>
      <pubDate>Mon, 01 Sep 2025 12:54:28 +0000</pubDate>
      <link>https://dev.to/toshiya_matsumoto_ac94abe/type-safety-across-layers-from-messy-dbs-to-clean-apps-4o23</link>
      <guid>https://dev.to/toshiya_matsumoto_ac94abe/type-safety-across-layers-from-messy-dbs-to-clean-apps-4o23</guid>
      <description>&lt;p&gt;Every developer knows this pain: your database says “nullable is fine,” but your app screams “absolutely not.”&lt;/p&gt;

&lt;p&gt;👉 Example: An event table with a date column. The DB allows &lt;code&gt;null&lt;/code&gt; (because some events don’t have confirmed dates yet).&lt;br&gt;
But in your React UI? Showing an event with date: &lt;code&gt;null&lt;/code&gt; is not only useless — it’s a bug waiting to happen.&lt;/p&gt;

&lt;p&gt;This mismatch creates an annoying gap between your DB schema and your application layer. Ignore it, and you’ll end up patching with type casts that look fine… until runtime crashes say otherwise.&lt;/p&gt;
&lt;h2&gt;
  
  
  ⚠️ The Wrong Way: Casting Your Troubles Away
&lt;/h2&gt;

&lt;p&gt;We’ve all done this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let x: unknown = 'hello';
console.log((x as string).length);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sure, TypeScript stops complaining. But you’ve effectively turned off its seatbelt.&lt;br&gt;
Type assertions bypass safety checks, leaving you with runtime landmines — the exact opposite of why you chose TypeScript in the first place.&lt;/p&gt;
&lt;h2&gt;
  
  
  ✅ The Right Way: Type Guards
&lt;/h2&gt;

&lt;p&gt;Enter &lt;strong&gt;Type Guards&lt;/strong&gt; — TypeScript’s built-in way to narrow types safely.&lt;/p&gt;

&lt;p&gt;Your DB or API DTO might look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// event.dto.ts
type EventDto = {
  name: string;
  date: Date | null;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But your app layer needs stricter guarantees:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// event.ts
type Event = {
  name: string;
  date: Date;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s how you bridge that gap:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function hasDate(event: EventDto): event is Event {
  return event.date !== null;
}

export function filterValidEvents(events: EventDto[]): Event[] {
  return events.filter(hasDate); &amp;lt;== here you go.
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, your UI only ever sees events with valid dates. TypeScript enforces the rule, no assertions required.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎁 Why This Pattern Wins
&lt;/h2&gt;

&lt;p&gt;Type Safety: no unsafe casts, no silent failures.&lt;/p&gt;

&lt;p&gt;Separation of Concerns: DBs stay flexible; apps stay strict.&lt;/p&gt;

&lt;p&gt;Scalable: extendable to any nullable fields or DTOs.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧩 Takeaway
&lt;/h2&gt;

&lt;p&gt;Nullable data is inevitable when dealing with databases or APIs.&lt;br&gt;
But instead of brute-forcing types, let Type Guards do the heavy lifting.&lt;/p&gt;

&lt;p&gt;They let you:&lt;/p&gt;

&lt;p&gt;Accept messy, real-world data from your DB.&lt;/p&gt;

&lt;p&gt;Hand your app layer clean, reliable objects.&lt;/p&gt;

&lt;p&gt;Keep TypeScript as your safety net, not your afterthought.&lt;/p&gt;

&lt;p&gt;👉 Next time you hit the null wall, don’t cast — guard.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🎙️ Building Your Own Live Audio Waveform in React Native</title>
      <dc:creator>Toshiya Matsumoto</dc:creator>
      <pubDate>Sun, 31 Aug 2025 09:46:11 +0000</pubDate>
      <link>https://dev.to/toshiya_matsumoto_ac94abe/building-your-own-live-audio-waveform-in-react-native-4e49</link>
      <guid>https://dev.to/toshiya_matsumoto_ac94abe/building-your-own-live-audio-waveform-in-react-native-4e49</guid>
      <description>&lt;h2&gt;
  
  
  🚀 Motivation
&lt;/h2&gt;

&lt;p&gt;There aren’t many (if any!) well-known libraries out there for live audio recording data visualization with a waveform in React Native. So… why not just build one yourself? 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  🎬 Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F938yepunba048103nlr8.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F938yepunba048103nlr8.gif" alt="Animated GIF showing a loading spinner with bouncing dots" width="720" height="1535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pretty neat, right? Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Assumptions
&lt;/h2&gt;

&lt;p&gt;Here’s the setup I used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`react-native`: 0.79.5
`expo`: 53.0.17
`expo-av`: 15.1.7
`react-native-svg`: 15.12.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Run it with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx expo run:ios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🎤 1. Recording Process
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1-1: Enable Metering
&lt;/h3&gt;

&lt;p&gt;The magic trick 🪄 is setting &lt;code&gt;isMeteringEnabled: true&lt;/code&gt; in &lt;code&gt;recording.prepareToRecordAsync()&lt;/code&gt; from &lt;code&gt;expo-av&lt;/code&gt;. This unlocks audio-level metering data (like dB values).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Audio, InterruptionModeIOS } from 'expo-av';

const { granted, status } = await Audio.requestPermissionsAsync();
await Audio.setAudioModeAsync({
  allowsRecordingIOS: true,
  playsInSilentModeIOS: true,
  staysActiveInBackground: true,
  interruptionModeIOS: InterruptionModeIOS.DuckOthers,
});

// Adjust as you like 🎛️
const recordingOptions = {
  android: {
    extension: '.m4a',
    outputFormat: Audio.AndroidOutputFormat.MPEG_4,
    audioEncoder: Audio.AndroidAudioEncoder.AAC,
    sampleRate: 44100,
    numberOfChannels: 2,
    bitRate: 128000,
  },
  ios: {
    extension: '.m4a',
    outputFormat: Audio.IOSOutputFormat.MPEG4AAC,
    audioQuality: Audio.IOSAudioQuality.HIGH,
    sampleRate: 44100,
    numberOfChannels: 2,
    bitRate: 128000,
    linearPCMBitDepth: 16,
    linearPCMIsBigEndian: false,
    linearPCMIsFloat: false,
  },
  web: {
    mimeType: 'audio/webm;codecs=opus',
    bitsPerSecond: 128000,
  },
};

const recording = new Audio.Recording();
await recording.prepareToRecordAsync({
  ...recordingOptions,
  isMeteringEnabled: true, // 🎯 enables audio-level metering
});
await recording.startAsync();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1-2: Poll the Recording State
&lt;/h3&gt;

&lt;p&gt;Now let’s grab that juicy data 📊. Use the recording object and poll its status every 100ms.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// poll metering data every 100ms
const interval = setInterval(async () =&amp;gt; {
  if (recording) {
    const status = await recording.getStatusAsync();
    if (status.isRecording &amp;amp;&amp;amp; typeof status.metering === 'number') {
      setLevels((prev) =&amp;gt; {
        const newLevels = [...prev, status.metering];
        // keep last 100 samples 🪣
        return newLevels.slice(-100);
      });
    }
  }
}, 100);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example of &lt;code&gt;status&lt;/code&gt;:&lt;br&gt;
&lt;code&gt;{"canRecord": true, "durationMillis": 602, "isRecording": true, "mediaServicesDidReset": false, "metering": -48.3475341796875}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The metering value is what you care about 🎧.&lt;/p&gt;

&lt;p&gt;👉 Decibel scale basics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0 dB   → loudest possible (max recording level) 🔊  
-160 dB → silence 🤫
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I only keep the latest 100 values (slice(-100)) because… who wants a million bars on screen? 🙃&lt;/p&gt;

&lt;p&gt;Time to visualize! 🎨&lt;/p&gt;

&lt;p&gt;Okay let's visualise it.&lt;/p&gt;

&lt;h2&gt;
  
  
  📊 2. Waveform Visualization with SVG
&lt;/h2&gt;

&lt;p&gt;You don’t need to be a math wizard 🧙 to draw waveforms. Just rectangles on a grid!&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works:
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;1&lt;/code&gt;. Draw a rectangle for each audio sample 📦.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Height = based on audio volume.&lt;/li&gt;
&lt;li&gt;Width = fixed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;2&lt;/code&gt;. Place it at the correct (x, y) coordinate.&lt;/p&gt;

&lt;p&gt;Visual guide (yes, it’s really this simple 👇):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1qcstpvuxeq1u4q8skwt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1qcstpvuxeq1u4q8skwt.png" alt="Waveform formula illustration on SVG" width="711" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Converting dB → amplitude&lt;/strong&gt;&lt;br&gt;
Formula:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Math.pow(10, db / 20); // standard dB → amplitude
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For easier handling, add +40 before conversion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Original level: -60dB（almost silence）
Math.pow(10, (-60 + 40) / 20) = Math.pow(10, -1) = 0.1

// Original level: -20dB（small sound volume）
Math.pow(10, (-20 + 40) / 20) = Math.pow(10, 1) = 10

// Original level: 0dB（maximum sound volume）
Math.pow(10, (0 + 40) / 20) = Math.pow(10, 2) = 100
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then scale it with &lt;code&gt;normalizedLevel * height * 0.05&lt;/code&gt;.&lt;br&gt;
(That &lt;code&gt;0.05&lt;/code&gt; is just a tweak factor — adjust to taste! 🎚️)&lt;/p&gt;

&lt;p&gt;And yes, we’ll use &lt;code&gt;Rect&lt;/code&gt; from &lt;code&gt;react-native-svg&lt;/code&gt; to draw the bars.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Codes&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Convert levels to SVG bars
  const width = 358;
  const height = 280;
  const barWidth = 3;
  const barSpacing = 1;
  const maxBarsCount = Math.floor(width / (barWidth + barSpacing));
  const halfHeight = height / 2;

  // Create vertical bars for each level
  const bars = levels.slice(-maxBarsCount).map((level, index) =&amp;gt; {
    const normalizedLevel = Math.max(0, Math.pow(10, (level + 40) / 20));
    const barHeight = Math.max(1, normalizedLevel * height * 0.05);

    // Calculate position so bar extends equally above and below center
    const halfBarHeight = barHeight / 2;

    const startX = 0;
    const x = startX + index * (barWidth + barSpacing);
    const y = halfHeight - halfBarHeight;

    return (
      &amp;lt;Rect
        key={index}
        x={x}
        y={y}
        width={barWidth}
        height={barHeight}
        fill="#8E8E93"
        rx={1}
      /&amp;gt;
    );
  });

  return (
    &amp;lt;View className="bg-white p-2 flex-1"&amp;gt;
      &amp;lt;Svg height={height} width={width}&amp;gt;
        {bars}
      &amp;lt;/Svg&amp;gt;
    &amp;lt;/View&amp;gt;
  );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;(&lt;code&gt;levels.slice(-maxBarsCount)&lt;/code&gt;, &lt;code&gt;maxBarsCount&lt;/code&gt; removes the stale bars that overflows in the screen)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✅ Summary
&lt;/h2&gt;

&lt;p&gt;With just &lt;code&gt;expo-av&lt;/code&gt; + a little SVG magic 🪄, you can visualize live audio waveforms in React Native — no external libraries needed, no hassle.&lt;/p&gt;

&lt;p&gt;Next time you record 🎤, make it look cool too.&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>mobile</category>
      <category>ios</category>
      <category>webdev</category>
    </item>
    <item>
      <title>🧼 Type-Safe Filtering in TypeScript: Handling Nullable Fields from Your Database</title>
      <dc:creator>Toshiya Matsumoto</dc:creator>
      <pubDate>Fri, 30 May 2025 14:09:34 +0000</pubDate>
      <link>https://dev.to/toshiya_matsumoto_ac94abe/type-safe-filtering-in-typescript-handling-nullable-fields-from-your-database-22lo</link>
      <guid>https://dev.to/toshiya_matsumoto_ac94abe/type-safe-filtering-in-typescript-handling-nullable-fields-from-your-database-22lo</guid>
      <description>&lt;h2&gt;
  
  
  🌟 The Challenge: Bridging Type Safety Between DB and App Layers
&lt;/h2&gt;

&lt;p&gt;In many real-world applications, the database schema often permits &lt;code&gt;null&lt;/code&gt; values — for good reason. For instance, a &lt;code&gt;date&lt;/code&gt; field in an event table might be intentionally left blank if the event date hasn’t been finalized yet.&lt;/p&gt;

&lt;p&gt;However, your application layer — especially the part that renders UI — usually prefers clean, reliable data. If a date is &lt;code&gt;null&lt;/code&gt;, you probably don’t want to show that event in the UI at all.&lt;/p&gt;

&lt;p&gt;This creates a gap between what your &lt;strong&gt;database allows&lt;/strong&gt; and what your &lt;strong&gt;application expects&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You might be tempted to solve this quickly with a forced type cast like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;unknown&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hello&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;But&lt;/span&gt; &lt;span class="nx"&gt;relying&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;assertions&lt;/span&gt; &lt;span class="nx"&gt;skips&lt;/span&gt; &lt;span class="nx"&gt;safety&lt;/span&gt; &lt;span class="nx"&gt;checks&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;lead&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;runtime&lt;/span&gt; &lt;span class="nx"&gt;bugs&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="nx"&gt;exactly&lt;/span&gt; &lt;span class="nx"&gt;what&lt;/span&gt; &lt;span class="nx"&gt;TypeScript&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;meant&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;help&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;avoid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🎯 The Solution: Using Type Guards
&lt;/h2&gt;

&lt;p&gt;Instead of casting, a safer and cleaner solution is to use &lt;strong&gt;Type Guards&lt;/strong&gt; — a TypeScript feature that allows you to narrow types in a type-safe way.&lt;/p&gt;

&lt;p&gt;Let’s say your application pulls in event data like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// event.dto.ts - from database or external API&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;EventDto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But your UI layer expects all events to have a valid &lt;code&gt;date&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// event.ts - for use within the app&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To filter out incomplete events, define a custom type guard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hasDate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EventDto&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can filter safely and TypeScript will infer the correct type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;filterValidEvents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;EventDto&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;events&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your UI layer will only receive events that have confirmed dates — and TypeScript will enforce this guarantee for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Benefits
&lt;/h2&gt;

&lt;p&gt;Type safety without unnecessary assertions.&lt;/p&gt;

&lt;p&gt;Separation of concerns: the DB layer can remain flexible, while the app layer stays strict.&lt;/p&gt;

&lt;p&gt;Scalability: you can extend this pattern to other nullable fields and DTOs.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧠 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Dealing with partial or nullable data from external sources is inevitable. But with TypeScript’s type guards, you don’t have to compromise safety or clarity. &lt;br&gt;
Embrace the gap between layers — and bridge it elegantly.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>webdev</category>
      <category>programming</category>
      <category>backend</category>
    </item>
    <item>
      <title>🚀 Seamless Data Magic: From Notion to Database with MCP Server &amp; AI Agents</title>
      <dc:creator>Toshiya Matsumoto</dc:creator>
      <pubDate>Sat, 17 May 2025 02:04:14 +0000</pubDate>
      <link>https://dev.to/toshiya_matsumoto_ac94abe/seamless-data-magic-from-notion-to-database-with-mcp-server-ai-agents-3kp7</link>
      <guid>https://dev.to/toshiya_matsumoto_ac94abe/seamless-data-magic-from-notion-to-database-with-mcp-server-ai-agents-3kp7</guid>
      <description>&lt;h2&gt;
  
  
  🎯 The Goal
&lt;/h2&gt;

&lt;p&gt;Build a seamless bridge between non-engineering contributors managing data in Notion and engineers who need that data formatted for database insertion. &lt;/p&gt;

&lt;h2&gt;
  
  
  🌟 The Challenge
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Values like "Japan" or "Tokyo" don't match the foreign keys in different tables.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🛠 Tech Stack Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Notion&lt;/strong&gt;: Used as the collaborative data entry platform for non-engineers.&lt;br&gt;
&lt;strong&gt;MCP Server&lt;/strong&gt;: Bridges Notion and external tools, enabling structured data retrieval via API.&lt;br&gt;
&lt;strong&gt;Cursor Agent&lt;/strong&gt;: An AI-powered agent that automates data transformation, semantic inference, and prompt execution.&lt;br&gt;
&lt;strong&gt;TypeScript&lt;/strong&gt;: Ensures type safety and robust data handling throughout the automation scripts.&lt;/p&gt;
&lt;h2&gt;
  
  
  🌟 The Solution
&lt;/h2&gt;

&lt;p&gt;🚀 &lt;strong&gt;Let's ask Cursor Agent to infer the semantic data to be the foreign keys in one prompt!&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  🔗 Step 1: Integrate Notion MCP Server to Retrieve Structured Event Data
&lt;/h3&gt;

&lt;p&gt;Non-engineers created and updated event entries directly in Notion—no devs required.&lt;/p&gt;

&lt;p&gt;To extract and structure that data:&lt;br&gt;
✅ I used the Notion MCP Server via Cursor Agent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// .cursor/mcp.json
{
  "mcpServers": {
    "notionApi": {
      "command": "npx",
      "args": [
        "-y",
        "@notionhq/notion-mcp-server"
      ],
      "env": {
        "OPENAPI_MCP_HEADERS": "{\"Authorization\": \"Bearer {YOUR_NOTION_API_KEY}\", \"Notion-Version\": \"2022-06-28\" }"
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows you to retrieve structured data from Notion in AI Agent's context.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠 Step 2: Let Cursor Agent to Infer Semantic Foreign Keys
&lt;/h3&gt;

&lt;p&gt;Ask AI Agent to fetch the master data from the API with curl command in prior, and to infer the semantic foreign keys in each row.&lt;/p&gt;

&lt;p&gt;The data in Notion&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// countries table
-----------------
| id | name     |
-----------------
| 1  | Japan    |
| 2  | USA      |
| 3  | Germany  |
-----------------
// events table
-----------------------------------------------
| id | name         | location   | country_id |
-----------------------------------------------
| 1  | Tech Expo    | Tokyo, JPN | null       |
| 2  | Art Summit   | LA, USA    | null       |
| 3  | Music Fest   | Berlin, DE | null       |
-----------------------------------------------

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Asking the Agent to infer the &lt;code&gt;country_id&lt;/code&gt; in each row from the semantic &lt;code&gt;location&lt;/code&gt; names to match the foreign keys from data you already fetched via API.&lt;/p&gt;

&lt;p&gt;Ultimately the data should look like this in the Agent's context 👏&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-----------------------------------------------
| id | name         | location   | country_id |
-----------------------------------------------
| 1  | Tech Expo    | Tokyo, JPN | 1          |
| 2  | Art Summit   | LA, USA    | 2          |
| 3  | Music Fest   | Berlin, DE | 3          |
-----------------------------------------------
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🧠 Step 3: Ask Agent to convert the data to the payload for the events table
&lt;/h3&gt;

&lt;p&gt;Finally Ask the Agent to convert the data to the payload for the events table following the schema defined in the &lt;code&gt;schema.json&lt;/code&gt; file you put.&lt;/p&gt;

&lt;p&gt;Voila, you can now get the payload ready to be inserted into the events table!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ./output/events.json
{
  "name": "Tech Expo",
  "location": "Tokyo, JPN",
  "country_id": 1
},
{
  "name": "Art Summit",
  "location": "LA, USA",
  "country_id": 2
},
{
  "name": "Music Fest", 
  "location": "Berlin, DE",
  "country_id": 3
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Prompt I used
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// /prompt/create-events.md
### Prompt Instructions

## For Events

- Retrieve the rows in the Events DB, sorted by ascending startDateTime in Notion via notionGeodeworkApi in MCP settings.
- Generate the payload for the events table according to the schema defined in @schema.ts.
- Use the following API to fetch country data:

  API Endpoint: {NEXT_PUBLIC_SUPABASE_URL}/rest/v1/countries
  API Key: {NEXT_PUBLIC_SUPABASE_ANON_KEY}

  Sample curl:
  curl -H "apikey: &amp;lt;API_KEY&amp;gt;" "&amp;lt;API_ENDPOINT&amp;gt;"

- Replace the `country_id` in each row with the foreign key from the country table.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I stored the prompt in the &lt;code&gt;prompt/create-events.md&lt;/code&gt; file so that everybody can use and reproduce the process easily.&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Conclusion
&lt;/h2&gt;

&lt;p&gt;Successfully extracted the structured data from Notion and converted it to the payload for the events table with the help of AI Agent.&lt;/p&gt;

&lt;p&gt;I actually integragted the process to insert the data with &lt;code&gt;drizzle-kit&lt;/code&gt; and &lt;code&gt;supabase&lt;/code&gt; all in one go, but I'll write about it in another blog post!&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>cursor</category>
      <category>notion</category>
      <category>sql</category>
    </item>
    <item>
      <title>Github Actions with Vercel in 2024</title>
      <dc:creator>Toshiya Matsumoto</dc:creator>
      <pubDate>Mon, 13 Jan 2025 14:07:05 +0000</pubDate>
      <link>https://dev.to/toshiya_matsumoto_ac94abe/github-actions-with-vercel-in-2024-3222</link>
      <guid>https://dev.to/toshiya_matsumoto_ac94abe/github-actions-with-vercel-in-2024-3222</guid>
      <description>&lt;p&gt;When you already have the app working on Vercel but you want to integrate Github Actions on top of it. Here's the right place to check.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vercel
&lt;/h3&gt;

&lt;p&gt;You need the following data from Vercel dashboard. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ORG_ID&lt;/code&gt;
Go to the &lt;strong&gt;top page&lt;/strong&gt; &amp;gt; Settings &amp;gt; Team ID.
Note that it's not under individual project page. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The URL you visit is like this&lt;code&gt;https://vercel.com/{your_account_name}s-projects/~/settings&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;PROJECT_ID&lt;/code&gt;&lt;br&gt;
Go to &lt;strong&gt;project page&lt;/strong&gt; &amp;gt; Settings &amp;gt; Team ID &amp;gt; Project ID&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;VERCEL_TOKEN&lt;/code&gt;&lt;br&gt;
Go to &lt;strong&gt;project page&lt;/strong&gt; &amp;gt; Settings &amp;gt; Environment Variables&lt;br&gt;
Enter VERCEL_TOKEN as a key and the arbitrary value.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Github
&lt;/h3&gt;

&lt;p&gt;Go to the Github project page &amp;gt; Settings &amp;gt; Secrets and variables &amp;gt; Actions &amp;gt; Repository secrets &amp;gt; New repository secret&lt;/p&gt;

&lt;p&gt;and set the ones you copied from the Vercel above and others that are needed respectively such as dotenv values depending on your implementation. &lt;/p&gt;

&lt;h3&gt;
  
  
  Code
&lt;/h3&gt;

&lt;p&gt;Create .github/workflows/workflow.yml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: Github Auto Deploy

on:
  push:
    branches:
      - main

env:
  VERCEL_ORG_ID: ${{ secrets.ORG_ID }}
  VERCEL_PROJECT_ID: ${{ secrets.PROJECT_ID }}

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Setup Bun Runtime
        uses: oven-sh/setup-bun@v1
        with:
          bun-version: latest

      - name: Install Dependencies
        run: bun install

      - name: Run Unit Tests
        run: bun unit:test

      - name: Install Playwright Browsers
        run: bunx playwright install --with-deps

      - name: Run E2E Tests
        run: bunx playwright test
        env:
          CI: true
          NODE_ENV: test
          CTF_MGMT_API_ACCESS_TOKEN: ${{ secrets.CTF_MGMT_API_ACCESS_TOKEN }}
          CTF_SPACE_ID: ${{ secrets.CTF_SPACE_ID }}
          CTF_CDA_ACCESS_TOKEN: ${{ secrets.CTF_CDA_ACCESS_TOKEN }}

      - name: Install Vercel CLI
        run: bun install -g vercel@latest

      - name: Pull Vercel Environment Information
        run: vercel pull --yes --environment=production --token=${{ secrets.VERCEL_TOKEN }}

      - name: Build Project Artifacts
        run: vercel build --prod --token=${{ secrets.VERCEL_TOKEN }}

      - name: Deploy Project Artifacts to Vercel
        run: vercel deploy --prebuilt --prod --token=${{ secrets.VERCEL_TOKEN }}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>githubactions</category>
      <category>vercel</category>
      <category>bunjs</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Page can't be indexed in Google Search Console</title>
      <dc:creator>Toshiya Matsumoto</dc:creator>
      <pubDate>Thu, 09 Jan 2025 14:59:03 +0000</pubDate>
      <link>https://dev.to/toshiya_matsumoto_ac94abe/page-cant-be-indexed-in-google-search-console-ghm</link>
      <guid>https://dev.to/toshiya_matsumoto_ac94abe/page-cant-be-indexed-in-google-search-console-ghm</guid>
      <description>&lt;h2&gt;
  
  
  Problem
&lt;/h2&gt;

&lt;p&gt;My personal website pages built with NextJs v14.x.x hosted by Vercel were not indexed at all for ages somewhere down the line ... very shocking...&lt;/p&gt;

&lt;h2&gt;
  
  
  Details in Google Search Console
&lt;/h2&gt;

&lt;p&gt;When you visit Sitemap page, it says &lt;code&gt;Couldn't fetch&lt;/code&gt;.&lt;br&gt;
When I visited URL Inspection page, it says &lt;code&gt;Site-wide availability issues&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Investigating Process
&lt;/h2&gt;

&lt;p&gt;However I could see the content &lt;code&gt;https:mypage/sitemap.xml&lt;/code&gt; on browser.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl -I https:mypage/sitemap.xml&lt;/code&gt; shows 200 response status properly.&lt;/p&gt;

&lt;p&gt;Then I checked more details in &lt;code&gt;Site-wide availability issues&lt;/code&gt; on    &lt;a href="https://support.google.com/webmasters/answer/9012289#will_i_be_indexed&amp;amp;zippy=%2Csite-wide-availability-issues" rel="noopener noreferrer"&gt;https://support.google.com/webmasters/answer/9012289#will_i_be_indexed&amp;amp;zippy=%2Csite-wide-availability-issues&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and then found this one:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Robots.txt unreachable: Google won't crawl a website if the robots.txt file is present but not reachable. You can check your robots.txt availability in the Crawl Stats report.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then I realised that&lt;code&gt;https:mypage/robots.txt&lt;/code&gt; returns 500 status despite the fact that I didn't prepare the robots.txt in my NextJS directory. &lt;/p&gt;

&lt;p&gt;Running production mode in NextJS hides the error details while dev mode shows you the details. &lt;/p&gt;

&lt;p&gt;Voila, my poor error handling returns &lt;code&gt;500&lt;/code&gt; status even though /robots.txt does not exist which in turn confused Google Indexer  and put it the label of &lt;code&gt;Not Indexable Page&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The case is closed. &lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>vercel</category>
      <category>seo</category>
      <category>google</category>
    </item>
    <item>
      <title>Crypto/Web3 Scammers in LinkedIn 😈</title>
      <dc:creator>Toshiya Matsumoto</dc:creator>
      <pubDate>Sun, 17 Nov 2024 08:25:36 +0000</pubDate>
      <link>https://dev.to/toshiya_matsumoto_ac94abe/cryptoweb3-scammers-in-linkedin-51f5</link>
      <guid>https://dev.to/toshiya_matsumoto_ac94abe/cryptoweb3-scammers-in-linkedin-51f5</guid>
      <description>&lt;p&gt;I received quite a few headhunting DM in the LinkedIn from 😈&lt;strong&gt;scammers&lt;/strong&gt;😈 recently.&lt;/p&gt;

&lt;p&gt;I've played around with them for a bit to see what they are like.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who?
&lt;/h2&gt;

&lt;p&gt;They are hacked accounts. Their professions I've met are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Food Consultant&lt;/li&gt;
&lt;li&gt;Manager at Hotel and Restaurant&lt;/li&gt;
&lt;li&gt;Hotel Bartender&lt;/li&gt;
&lt;li&gt;CIO in an IT corporation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What They Offer
&lt;/h2&gt;

&lt;p&gt;They offer an opportunity for Engineer role in web3.0/crypto space like the followings: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Exciting opportunity to develop a Web3 food token website.&lt;/li&gt;
&lt;li&gt;DEX project, but currently lacking the necessary hands to develop it successfully.&lt;/li&gt;
&lt;li&gt;Platform for trading cryptocurrencies referred to as a Dex&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also they have &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Github project&lt;/li&gt;
&lt;li&gt;Job Description (using Google Document)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How They Trap You
&lt;/h2&gt;

&lt;p&gt;They commonly shared the Github projects with half way done or as an assignment to measure your engineering skills, or whatever reasons they are, and attempted to make you download them. &lt;/p&gt;

&lt;p&gt;I've seen somewhere in the LinkedIn thread but it seems those projects have a virus library and designed to skim your important data when you run it in your local.&lt;/p&gt;

&lt;h2&gt;
  
  
  How To Detect It 🤡
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Check their professions in their LinkedIn page. None of them had any association with IT startup or crypto. Since the accounts are hacked and impersonated, they are real person and even have good reputations but have a deep breath first, and try to logically connect the dots.&lt;/li&gt;
&lt;li&gt;They responds to you quite fast in 24 hours regardless of where they live.&lt;/li&gt;
&lt;li&gt;Contributors in the Github account are beginners despite the fact that their main page is very decorative with prototype projects. &lt;/li&gt;
&lt;li&gt;Unprofessional traces somewhere. For example this person's name does not start with the capital letter, although their written text looks professional overall probably due to with AI tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Thoughts
&lt;/h2&gt;

&lt;p&gt;As you can see, making up combining Food Consultant and "food token", with the jargon such as react, node, web3 and solidity, they are not just a random scammers with lack of IT knowledge.&lt;/p&gt;

&lt;p&gt;I guess they use AI tools to generate the most seemingly adequate questions from your CV/Resume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lastly
&lt;/h2&gt;

&lt;p&gt;It seems reasonable to reach the conclusion that they are fraud on the spot but if you are desperate or really looking for an opportunity for your dream, it is fair enough for you to believe it.&lt;/p&gt;

&lt;p&gt;I wish this article helps.&lt;/p&gt;

</description>
      <category>hiring</category>
      <category>web3</category>
      <category>security</category>
      <category>cryptocurrency</category>
    </item>
    <item>
      <title>In React useMemo And useState From Design Philosophy Perspective.</title>
      <dc:creator>Toshiya Matsumoto</dc:creator>
      <pubDate>Thu, 14 Nov 2024 14:58:15 +0000</pubDate>
      <link>https://dev.to/toshiya_matsumoto_ac94abe/in-react-usememo-and-usestate-from-design-philosophy-perspective-2c</link>
      <guid>https://dev.to/toshiya_matsumoto_ac94abe/in-react-usememo-and-usestate-from-design-philosophy-perspective-2c</guid>
      <description>&lt;h2&gt;
  
  
  What is useState in React?
&lt;/h2&gt;

&lt;p&gt;As stated in the official documentation, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;useState is a React Hook that lets you add a state variable to your component.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To fully understand the differences from useMemo, however, it’s helpful to first consider React's design philosophy ⛩️&lt;/p&gt;

&lt;h2&gt;
  
  
  React's design philosophy: Declarative UI
&lt;/h2&gt;

&lt;p&gt;React’s declarative UI principle ensures re-renders and reconstructs the UI on each user interaction to ensure idempotency, which makes building applications simpler and more predictable than with imperative UI principles. &lt;/p&gt;

&lt;p&gt;While React’s Virtual DOM optimises updates by changing only the parts that differ, useState is central to managing these changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tradeoff
&lt;/h2&gt;

&lt;p&gt;However, frequent re-renders can be costly when the codebase involves intensive computations or heavy rendering. &lt;br&gt;
To address this, useMemo becomes essential. According to the official documentation, &lt;/p&gt;
&lt;h2&gt;
  
  
  What is useMemo in React?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;useMemo is a React Hook that lets you cache the result of a calculation between re-renders.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This feature is valuable when dealing with computationally expensive tasks, as useMemo can bypass re-computation by retrieving data from the cache.&lt;/p&gt;
&lt;h2&gt;
  
  
  useMemo or useState
&lt;/h2&gt;

&lt;p&gt;That said, there’s ongoing debate on the optimal use of useMemo, as it involves evaluating dependencies and using memory, which can add overhead. The official guidance notes, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In general, unless you’re creating or looping over thousands of objects, it’s probably not expensive." &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;More on this topic is available here: &lt;a href="https://react.dev/reference/react/useMemo#how-to-tell-if-a-calculation-is-expensive" rel="noopener noreferrer"&gt;https://react.dev/reference/react/useMemo#how-to-tell-if-a-calculation-is-expensive&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;They are kind enough to share how to measure the time spent on the function execution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.time('filter array');
const visibleTodos = filterTodos(todos, tab);
console.timeEnd('filter array');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Pitfall (Digressing Slightly)
&lt;/h2&gt;

&lt;p&gt;Lastly, an important consideration: useMemo compares dependencies with &lt;code&gt;Object.is()&lt;/code&gt;, meaning changes within the same object reference will not trigger re-evaluation. &lt;/p&gt;

&lt;p&gt;This is a key pitfall to keep in mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Take Aways
&lt;/h2&gt;

&lt;p&gt;React employs the design philosophy &lt;strong&gt;Declarative UI&lt;/strong&gt; which takes it granted that some functions are called more than necessary at the expense of simple code experience. &lt;br&gt;
In order to reduce the overhead useMemo is here for you.&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Method Chain: filter().map() is inefficient?</title>
      <dc:creator>Toshiya Matsumoto</dc:creator>
      <pubDate>Mon, 04 Nov 2024 14:04:38 +0000</pubDate>
      <link>https://dev.to/toshiya_matsumoto_ac94abe/method-chain-filtermap-is-inefficient-2gna</link>
      <guid>https://dev.to/toshiya_matsumoto_ac94abe/method-chain-filtermap-is-inefficient-2gna</guid>
      <description>&lt;h2&gt;
  
  
  Method Chaining
&lt;/h2&gt;

&lt;p&gt;You may have seen the code using &lt;code&gt;Array.prototype.filter()&lt;/code&gt; and &lt;code&gt;Array.prototype.map()&lt;/code&gt; to edit and remove the value in Array data in Javascript&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[1,2,3]
.map((mapped) =&amp;gt; mapped + 1)
.filter((filtered) =&amp;gt; filtered &amp;gt; 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Question
&lt;/h2&gt;

&lt;p&gt;I was always wondering if such a &lt;strong&gt;method chaining&lt;/strong&gt; iterates the value in array at each iteration or v8 engine perhaps optimises the operation by performing data aggregation under the hood. &lt;/p&gt;

&lt;p&gt;So I conducted a small research.&lt;/p&gt;

&lt;h2&gt;
  
  
  How?
&lt;/h2&gt;

&lt;p&gt;Using &lt;code&gt;console.time&lt;/code&gt; and &lt;code&gt;console.timeEnd&lt;/code&gt; and measured the average execution time in 10 times with and without Method Chain.&lt;br&gt;
I used Chrome browser for the investigation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.time('Filter Execution Time')
// YOUR CODE
console.timeEnd('Filter Execution Time')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Result: Method Chaining does not aggregate the operation.
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;-&lt;/th&gt;
&lt;th&gt;Method Chain(A)&lt;/th&gt;
&lt;th&gt;No Method Chain(B)&lt;/th&gt;
&lt;th&gt;Aggregate Logic(C)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Iterate 10000000 values&lt;/td&gt;
&lt;td&gt;4656 ms&lt;/td&gt;
&lt;td&gt;4733 ms&lt;/td&gt;
&lt;td&gt;169 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Iterate 100000 values&lt;/td&gt;
&lt;td&gt;27 ms&lt;/td&gt;
&lt;td&gt;24 ms&lt;/td&gt;
&lt;td&gt;4 ms&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As you can see, the result with/without Method Chain did not reveal much difference, while aggregating logic hit the way faster results. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code-A. Use Method Chaining with map() and filter()&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.time('Filter Execution Time')
const result = new Array()
.fill(1).map((e) =&amp;gt; e + 1)
.filter((e) =&amp;gt; e !== 1)
console.timeEnd('Filter Execution Time')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code-B. Separate map() and filter() (No Method Chaining)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.time('Filter Execution Time')
const mapResult = new Array().fill(1).map((e) =&amp;gt; e + 1)
const result = mapResult.filter((e) =&amp;gt; e !== 1)
console.timeEnd('Filter Execution Time')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Code-C. Aggregate logic&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;console.time('Filter Execution Time')
const result = []
new Array().fill(1).forEach((e) =&amp;gt;  {
    if (e !== 1) result.push(e)
})
console.timeEnd('Filter Execution Time')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  But Method Chain is handy isn't it?
&lt;/h3&gt;

&lt;p&gt;For those who think so, I made the chart at every number of iteration from 100 up to 100,000 under the the Code Pattern A, B, and C by counting the average time by milliseconds in 10 times, likewise as the above.&lt;/p&gt;

&lt;h3&gt;
  
  
  Findings
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;There are not much difference when the number of iteration is not large such as 100 - 1,000 anyway.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It is going to matter when the number of iteration grows exponentially such as 1,000,000.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8q0vcp9m6vkw2mlwy8ey.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8q0vcp9m6vkw2mlwy8ey.png" alt="The number of iteration and Execute duration with Method Chain" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Method Chaining&lt;/strong&gt; does not aggregate the operation while the difference of the results widens as the number of iteration grows exponentially. &lt;/p&gt;

&lt;p&gt;Hence I think it's fair to say that when the number of iteration is small, it's ok to use method chain to gain the advantage of its handiness, on the other hand, if you deal with a large number of data, you should consider the algorithm carefully without the method chain. &lt;/p&gt;

&lt;p&gt;Thanks for reading! &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>coding</category>
    </item>
    <item>
      <title>Handling Object Values in React useState()</title>
      <dc:creator>Toshiya Matsumoto</dc:creator>
      <pubDate>Mon, 14 Oct 2024 07:22:16 +0000</pubDate>
      <link>https://dev.to/toshiya_matsumoto_ac94abe/handling-object-values-in-react-usestate-2cha</link>
      <guid>https://dev.to/toshiya_matsumoto_ac94abe/handling-object-values-in-react-usestate-2cha</guid>
      <description>&lt;h2&gt;
  
  
  What is useState in React?
&lt;/h2&gt;

&lt;p&gt;useState is a React hook that allows functional components to manage and update local state.&lt;/p&gt;

&lt;p&gt;But you have to make sure to update the state through &lt;code&gt;useState()&lt;/code&gt;, not directly mutate the &lt;code&gt;state&lt;/code&gt; itself. &lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Example of &lt;code&gt;useState&lt;/code&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [count, setCount] = useState(0);

setCount(count++)
console.log(count) // 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Problem with &lt;code&gt;object&lt;/code&gt; state in &lt;code&gt;useState&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Javascript has two places where it can store the data: &lt;code&gt;stack&lt;/code&gt; and &lt;code&gt;heap&lt;/code&gt;, and it relates to the story of &lt;code&gt;primitive values&lt;/code&gt; and &lt;code&gt;references&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;primitive values&lt;/code&gt; and &lt;code&gt;references&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;stack&lt;/code&gt; is used in Javascript to store static data such as &lt;code&gt;primitive values&lt;/code&gt; (strings, numbers, booleans, undefined, and null) in which the size of the data is fixed, while&lt;br&gt;
&lt;code&gt;heap&lt;/code&gt; is used to store the dynamic data such as &lt;code&gt;references&lt;/code&gt; (objects and functions).&lt;/p&gt;

&lt;p&gt;The values of &lt;code&gt;primitive values&lt;/code&gt; are simply stored in the &lt;code&gt;stack&lt;/code&gt; that's it, while the content of &lt;code&gt;references&lt;/code&gt; itself is stored in &lt;code&gt;heap&lt;/code&gt; referenced from the &lt;code&gt;stack&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This creates a situation where a newly assigned value that references the existing object is interpreted as identical.&lt;/p&gt;

&lt;p&gt;Lets's look at an incorrect example👺:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [state, setState] = useState([1,2]);

const temp = state
temp.push(3)
useState(temp)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because &lt;code&gt;temp&lt;/code&gt; and &lt;code&gt;state&lt;/code&gt; both reference the same values in the heap, they are effectively identical. This violates the rule of useState, which requires a new object or value to trigger a re-render. 😇&lt;/p&gt;

&lt;h2&gt;
  
  
  How to solve it?
&lt;/h2&gt;

&lt;p&gt;⛩️⛩️⛩️⛩️⛩️⛩️⛩️⛩️⛩️⛩️⛩️⛩️⛩️&lt;/p&gt;

&lt;h2&gt;
  
  
  Spread Syntax
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;[...[]]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;helps you create a separate copy of the value in &lt;code&gt;heap&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const a = [1,2]
const b = a
console.log(Object.is(a,b)) // true

const c = [...a]
console.log(Object.is(a,c)) // false
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;voila 😀&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [state, setState] = useState([1,2])
const temp = [...state].push(3)
setData(temp);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the value &lt;code&gt;temp&lt;/code&gt; is different from the original object, ensuring that it no longer shares the same reference as state.&lt;/p&gt;

&lt;h3&gt;
  
  
  Another pitfall &lt;code&gt;in-place&lt;/code&gt; function
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;in-place&lt;/code&gt; functions such as &lt;code&gt;sort()&lt;/code&gt; modifies the data in place, without creating a separate copy of the data structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;a = [1,3]
a.sort((b,c) =&amp;gt; c-b)
console.log(a) // =&amp;gt; [3,1]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the values in &lt;code&gt;a&lt;/code&gt; has changed.&lt;/p&gt;

&lt;p&gt;Again here is an incorrect example👺:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [state, setState] = useState([])

const sortOrder = () =&amp;gt; {
    state.sort((a, b) =&amp;gt; a-b)
    setState(state);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;state is mutated against the rule. 😇&lt;/p&gt;

&lt;p&gt;So here is the solution with spread syntax.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [state setState] = useState([])

const sortOrder = () =&amp;gt; {
   const newState = [...data].sort((a, b) =&amp;gt; a-b)
    setState(newState);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but wait, before reaching to the conclusion with &lt;code&gt;spread syntax&lt;/code&gt;, remember to look up the documentation to to catch up the latest updates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check a document
&lt;/h3&gt;

&lt;p&gt;There is a chance that the functions is updated.&lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;toSorted()&lt;/code&gt; is newly introduced in 2023 that returns a copying version of the input data 🌅&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [state, newState] = useState([])

const sortOrder = () =&amp;gt; {
   const newState = state.toSorted((a, b) =&amp;gt; a-b)
   newState(newState);
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AI is not good at catching up the latest information so this traditional methodology is still worth it!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Let's use spread syntax &lt;code&gt;[...[]]&lt;/code&gt;&lt;br&gt;
but remember to consult the documentation as well.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://felixgerschau.com/javascript-memory-management/" rel="noopener noreferrer"&gt;https://felixgerschau.com/javascript-memory-management/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://react.dev/reference/react/useState" rel="noopener noreferrer"&gt;https://react.dev/reference/react/useState&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>beginners</category>
      <category>react</category>
    </item>
  </channel>
</rss>
