<?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: amionweb</title>
    <description>The latest articles on DEV Community by amionweb (@amionweb).</description>
    <link>https://dev.to/amionweb</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%2F1452510%2F7c7a3a56-fe0f-4731-a8e9-728dab67a6ea.png</url>
      <title>DEV Community: amionweb</title>
      <link>https://dev.to/amionweb</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amionweb"/>
    <language>en</language>
    <item>
      <title>Your AI Agent Probably Doesn't Need a Vector Database</title>
      <dc:creator>amionweb</dc:creator>
      <pubDate>Sat, 30 May 2026 17:09:59 +0000</pubDate>
      <link>https://dev.to/amionweb/your-ai-agent-probably-doesnt-need-a-vector-database-36mb</link>
      <guid>https://dev.to/amionweb/your-ai-agent-probably-doesnt-need-a-vector-database-36mb</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hermes-agent-2026-05-15"&gt;Hermes Agent Challenge&lt;/a&gt;: Write About Hermes Agent&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Your AI Agent Probably Doesn't Need a Vector Database
&lt;/h1&gt;

&lt;p&gt;There's a reflex in agent-building right now. You decide your agent should "remember things," and within ten minutes you're comparing managed vector-DB tiers, picking an embedding model, and quietly arguing with yourself about chunk size and overlap.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hermes-agent.nousresearch.com/" rel="noopener noreferrer"&gt;Hermes Agent&lt;/a&gt; — one of the more capable open agents you can run yourself — skips all of that for its long-term memory. It remembers past sessions with SQLite and full-text search. No embeddings. No vector index. No cosine-similarity threshold to babysit.&lt;/p&gt;

&lt;p&gt;The first time I noticed this, I assumed it was a placeholder. The thing you rip out before you're &lt;em&gt;serious&lt;/em&gt;. The longer I sat with it, the more it looked like the serious choice, and the reflex looked like the placeholder.&lt;/p&gt;

&lt;p&gt;This post is about why that is, where it breaks down, and what it should change about how you build memory into your own agents. If you've never touched embeddings, don't worry — the next two sections get you up to speed in plain language. If you build RAG for a living, skip to "Where keyword search actually loses."&lt;/p&gt;

&lt;h2&gt;
  
  
  Two different problems hiding under one word
&lt;/h2&gt;

&lt;p&gt;"Memory" gets used for two jobs that have almost nothing in common, and conflating them is where a lot of agent designs go wrong.&lt;/p&gt;

&lt;p&gt;The first job is &lt;strong&gt;recall&lt;/strong&gt;: &lt;em&gt;what happened in our past sessions?&lt;/em&gt; You asked me to set up a deploy script last Tuesday; can I find that conversation and the script we landed on? This is retrieval over a growing pile of transcripts.&lt;/p&gt;

&lt;p&gt;The second job is &lt;strong&gt;user modeling&lt;/strong&gt;: &lt;em&gt;who is this person and how do they like to work?&lt;/em&gt; Not a specific event, but a slowly-built profile — they prefer terse answers, they're on Windows, they hate when I touch their config without asking.&lt;/p&gt;

&lt;p&gt;These want different tools. Recall is a search problem. User modeling is a summarization-and-inference problem. Hermes treats them separately, and that separation is half the reason the design holds together. Recall runs on full-text search. User modeling is handed off to &lt;a href="https://honcho.dev/" rel="noopener noreferrer"&gt;Honcho&lt;/a&gt;, which maintains an evolving, "dialectic" model of you across conversations. Two problems, two mechanisms, no forcing one tool to do both.&lt;/p&gt;

&lt;p&gt;The rest of this post is about the recall half, because that's the part everyone instinctively reaches for a vector database to solve.&lt;/p&gt;

&lt;h2&gt;
  
  
  A 90-second primer: vectors vs. full-text search
&lt;/h2&gt;

&lt;p&gt;If you already know this cold, skip ahead. If not, here's the whole idea.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;vector database&lt;/strong&gt; stores text as embeddings — long lists of numbers a model produces, positioned so that things with &lt;em&gt;similar meaning&lt;/em&gt; sit close together. Ask "how do I get a refund," and it can surface a passage about "returning a purchase" even though they share no words. That semantic reach is the superpower. The cost: you run an embedding model on everything going in and every query coming out, you store and index the vectors, and you accept that retrieval is fuzzy and a little opaque. Why did it return &lt;em&gt;that&lt;/em&gt;? Because the math said it was near. Good luck reading the math.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full-text search&lt;/strong&gt; — what SQLite's FTS5 gives you — is the grown-up version of keyword matching. It indexes the actual words, then ranks results by a relevance formula (BM25: roughly, rarer words that appear more often in a document score higher). Search "refund policy shopify," and you get the sessions where those terms actually show up, ranked best-first. It's fast, it's cheap, and crucially, you can &lt;em&gt;read&lt;/em&gt; exactly why a result matched.&lt;/p&gt;

&lt;p&gt;One reaches for meaning. The other reaches for words. The conventional wisdom says agents need meaning, so they need vectors. Hermes quietly bets that for &lt;em&gt;session recall&lt;/em&gt;, words are enough, and the places where they aren't can be patched more cheaply than a vector stack costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Hermes actually remembers
&lt;/h2&gt;

&lt;p&gt;Three layers, and none of them are exotic. That's the point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Every session goes into SQLite, indexed by FTS5.&lt;/strong&gt; All your CLI and messaging conversations land in one local database file (&lt;code&gt;~/.hermes/state.db&lt;/code&gt;), full-text indexed. When something might be relevant later, the agent searches its own history the way you'd search a codebase: by terms, ranked by relevance, and it gets back the &lt;em&gt;actual messages&lt;/em&gt; — not a lossy paraphrase of them. Conceptually, recall looks closer to this than to a similarity query:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- not the literal Hermes query, but the shape of it&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;session_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;snippet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;messages&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="s1"&gt;'['&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;']'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'…'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;   &lt;span class="n"&gt;messages&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt;  &lt;span class="n"&gt;messages&lt;/span&gt; &lt;span class="k"&gt;MATCH&lt;/span&gt; &lt;span class="s1"&gt;'deploy AND script AND staging'&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt;  &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;          &lt;span class="c1"&gt;-- BM25 relevance, best first&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In practice these come back in around 20ms against the local file. There's no network hop, because there's nowhere to hop to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A separate, bounded layer holds curated notes.&lt;/strong&gt; Next to the raw log, Hermes keeps two small agent-maintained files in &lt;code&gt;~/.hermes/memories/&lt;/code&gt;: a running &lt;code&gt;MEMORY.md&lt;/code&gt; of facts worth keeping (capped around 800 tokens) and a &lt;code&gt;USER.md&lt;/code&gt; profile (around 500). They're injected into the system prompt as a frozen snapshot when a session starts, and the agent edits them deliberately with add, replace, and remove operations. This is the distilled layer — not everything that was ever said, but the handful of things the agent decided were worth writing down in plain language. It's the difference between your shell history and the README you keep by hand. The condensing work happens &lt;em&gt;here&lt;/em&gt;, on what to keep, and stays out of the recall path, so search itself never hands back a guess.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Deep user modeling is delegated.&lt;/strong&gt; For a richer, evolving picture of who you are, Hermes can hand off to &lt;a href="https://honcho.dev/" rel="noopener noreferrer"&gt;Honcho&lt;/a&gt;, which reasons about each conversation after it ends and accumulates insight about your preferences, habits, and goals. It's optional, and it's deliberately a different system from raw recall.&lt;/p&gt;

&lt;p&gt;Here's the whole shape:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   ┌────────────────────────────────────────────────┐
   │  this conversation (working context)            │
   └───────────────┬────────────────────────────────┘
                   │ when relevant, search the past
                   ▼
   ┌────────────────────────────────────────────────┐
   │  SQLite + FTS5  (~/.hermes/state.db)            │
   │  raw sessions · keyword/BM25 · returns messages │
   └────────────────────────────────────────────────┘
        ▲                                   ▲
        │ distilled by hand                 │ separate track
   ┌──────────────────────────┐   ┌──────────────────────────┐
   │ MEMORY.md / USER.md       │   │ Honcho (optional)        │
   │ agent-curated facts       │   │ evolving user model      │
   └──────────────────────────┘   └──────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No embedding service anywhere in the recall path. No vector index to keep warm. A database file you could open and read on a plane.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is a better default than it sounds
&lt;/h2&gt;

&lt;p&gt;I want to be fair to vectors later, so let me be specific about what the boring approach buys you first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It costs almost nothing to run.&lt;/strong&gt; Every embedding-based memory pays a tax on both ends: you embed what you store, and you embed every query. At low volume that's noise. For an always-on agent that's reading and writing memory all day, it adds up, and it adds a network dependency to a path that now works with a local file and zero API calls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can debug it.&lt;/strong&gt; This is the one I underrate every time. When an FTS-backed agent recalls the wrong thing, you can run the query yourself and see precisely why. When a vector-backed agent recalls the wrong thing, you're staring at cosine distances trying to reverse-engineer the embedding model's taste. One of these you fix on a Tuesday afternoon. The other becomes a ticket that says "memory feels off sometimes."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It's portable and inspectable.&lt;/strong&gt; The memory is a file. You can back it up, copy it to another machine, grep it, audit what your agent knows, and delete what it shouldn't. Try explaining to a security reviewer what's inside your vector index. Now hand them a SQLite file they can query.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It doesn't drift under you.&lt;/strong&gt; Swap your embedding model — a new version, a different provider — and strictly, your old vectors live in a different space than your new ones. Teams paper over this, but it's a real, recurring source of "why did retrieval quietly get worse." Keyword indexes don't have model-version baggage. The word "refund" in 2024 is the word "refund" in 2026.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It works offline and on tiny hardware.&lt;/strong&gt; The whole pitch of Hermes is an agent that lives on infrastructure you own, possibly something cheap. Full-text search is right at home there. A vector stack wants more.&lt;/p&gt;

&lt;p&gt;None of these are clever. Added together, for the specific job of "find the relevant past conversation," they're hard to argue with.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where keyword search actually loses
&lt;/h2&gt;

&lt;p&gt;Now the honest part, because "you never need vectors" would be the wrong lesson.&lt;/p&gt;

&lt;p&gt;Full-text search fails exactly where you'd expect: when the words don't match but the meaning does. If three months ago you discussed "rolling back a release" and today you ask about "reverting a deploy," BM25 may shrug. It has no idea those are the same idea. Embeddings would catch it. Other genuine weak spots:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Conceptual or fuzzy queries&lt;/strong&gt; ("that thing we tried when latency spiked") where you can't supply the keywords because you don't remember them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synonym-heavy or jargon-rich domains&lt;/strong&gt;, where the same concept has ten surface forms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cross-lingual recall&lt;/strong&gt;, where the stored text and the query aren't even in the same language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is real, and pretending otherwise would be the kind of advocacy this challenge is already full of. But two things soften it in Hermes's design, and the second one is the interesting part.&lt;/p&gt;

&lt;p&gt;First, the curated &lt;code&gt;MEMORY.md&lt;/code&gt; layer records the facts that matter in clean, canonical language. So your most important memories don't hang on whether you can reproduce the exact words from a six-week-old transcript.&lt;/p&gt;

&lt;p&gt;Second — and this is what a vector-DB reflex misses — the thing doing the searching is an &lt;em&gt;agent&lt;/em&gt;, not a dumb retrieval pipeline. If "reverting a deploy" comes back empty, a capable agent can just try "rollback," then "release," then "revert" on its own. A RAG pipeline fires one query and lives with whatever it gets. An agent can rifle through its own filing cabinet, reformulating until it finds the drawer. That recovers a surprising amount of what naive keyword matching would drop, and it costs nothing but a few extra tokens. It won't fully close the semantic gap. It narrows it without an embedding in sight.&lt;/p&gt;

&lt;p&gt;And when that isn't enough? FTS5 and a vector index aren't enemies. The mature move is hybrid: keyword search for the 90% that's precise and cheap, embeddings layered on for the conceptual long tail. Hermes is literally built this way. Keyword recall ships by default, and you can run a semantic provider — Mem0, Supermemory, Honcho — &lt;em&gt;alongside&lt;/em&gt; it, never replacing the built-in store. The hybrid model isn't a hack you bolt on later. It's the shipped design. Starting with vectors gets the order backwards: you pay for the expensive, fuzzy tool first and add the cheap, precise one afterward, if ever.&lt;/p&gt;

&lt;h2&gt;
  
  
  A decision guide you can actually use
&lt;/h2&gt;

&lt;p&gt;Strip away the framework and here's the call for &lt;em&gt;your&lt;/em&gt; agent's memory:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;If you need…&lt;/th&gt;
&lt;th&gt;Reach for&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"Find the session where we did X"&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Full-text search (FTS5)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Cheap, fast, debuggable, exact&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bounded long-term facts&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Agent-curated notes (MEMORY.md)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Keeps what matters in clean, canonical language&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"Who is this user, how do they work"&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;A user model (e.g. Honcho)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Different problem from recall&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Recall across synonyms/concepts&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Add embeddings (hybrid)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The one place vectors clearly earn it&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Everything, day one&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Start with FTS, measure, then add&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;You'll likely never hit the wall&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The general principle Hermes is quietly demonstrating: &lt;strong&gt;default to the boring, legible tool, and add the expensive, opaque one only when you can point at the specific query it failed.&lt;/strong&gt; That's not a memory rule. That's just engineering. It's easy to forget in a field where every blog post assumes a vector database the way older ones assumed jQuery.&lt;/p&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;The interesting thing about Hermes's memory isn't that it's clever. It's that it's deliberately &lt;em&gt;not&lt;/em&gt; clever, and it works anyway. SQLite, full-text search, a summarization pass, and a separate track for modeling the user. Four ordinary pieces, each doing one job it's genuinely good at.&lt;/p&gt;

&lt;p&gt;I came in expecting to find a corner that had been cut. I left thinking most agent projects cut the corner in the other direction — reaching for vectors out of habit, paying for semantic recall they rarely exercise, and trading away the things that actually matter day to day: cost, portability, and being able to answer "why did it remember that?"&lt;/p&gt;

&lt;p&gt;If you're about to add memory to an agent, try the boring version first. Index the text. Summarize the old stuff. Search by words. Measure where it genuinely fails before you reach for the embeddings. There's a decent chance, like me, you'll be surprised how rarely you need to.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;If you've shipped agent memory both ways, I'd like to hear where full-text search ran out of road for you — that boundary is the actually-interesting question, and nobody seems to write it down.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>hermesagentchallenge</category>
      <category>devchallenge</category>
      <category>agents</category>
      <category>ai</category>
    </item>
    <item>
      <title>I added up everything Google gives developers for free after I/O 2026. It's kind of absurd</title>
      <dc:creator>amionweb</dc:creator>
      <pubDate>Sat, 23 May 2026 16:23:28 +0000</pubDate>
      <link>https://dev.to/amionweb/i-added-up-everything-google-gives-developers-for-free-after-io-2026-its-kind-of-absurd-2ajn</link>
      <guid>https://dev.to/amionweb/i-added-up-everything-google-gives-developers-for-free-after-io-2026-its-kind-of-absurd-2ajn</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-io-writing-2026-05-19"&gt;Google I/O 2026 Writing Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  I added up everything Google gives developers for free after I/O 2026. It's kind of absurd.
&lt;/h1&gt;

&lt;p&gt;Most of the I/O 2026 coverage is about whether AI is coming for our jobs. I went looking for something more practical and, honestly, more fun: &lt;strong&gt;how much can you actually build without paying Google a cent?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I expected "a free trial and then a paywall." What I found, after poking around &lt;a href="https://aistudio.google.com/" rel="noopener noreferrer"&gt;AI Studio&lt;/a&gt; and the docs, is that you can build a genuinely real AI app — multimodal, grounded in live search, even fully offline — for &lt;strong&gt;$0&lt;/strong&gt;. Here's the complete free stack after I/O 2026, what you can build with it, and where the free ceiling actually is.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. AI Studio itself — a free playground for every model
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://aistudio.google.com/" rel="noopener noreferrer"&gt;Google AI Studio&lt;/a&gt; is free to use in your browser. No credit card. You get a playground for the entire model lineup — Gemini 3.5 Flash, the image models, video, speech — plus the run settings that matter: temperature, the &lt;strong&gt;Thinking level&lt;/strong&gt; dial, structured outputs, function calling, and a one-toggle &lt;strong&gt;Grounding with Google Search&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a beginner, this alone is huge: you can test prompts against frontier models, see exactly how each setting changes the output, and click &lt;strong&gt;"Get code"&lt;/strong&gt; to export a working snippet — before writing a single line yourself. It's the cheapest way to learn what these models can do, and it costs nothing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💡 &lt;em&gt;[Screenshot spot: the AI Studio playground with a model selected and the free run-settings panel visible.]&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2. The Gemini API free tier — enough to prototype a real app
&lt;/h2&gt;

&lt;p&gt;The Gemini API has a &lt;strong&gt;free tier&lt;/strong&gt; you can use with an API key from AI Studio. It's rate-limited (limited requests per minute and per day), but for learning, prototyping, and small projects it's genuinely enough to ship something real.&lt;/p&gt;

&lt;p&gt;That means you can wire Gemini 3.5 Flash or 3.1 Flash Lite into a side project — a chatbot, a summarizer, a classifier — and run it for free while you build. You only start paying when you graduate to production volume. For most people learning this stuff, you'll build three projects before you ever hit a bill.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Rate limits change over time — check the current &lt;a href="https://ai.google.dev/gemini-api/docs/rate-limits" rel="noopener noreferrer"&gt;free-tier limits&lt;/a&gt; before you architect around them.)&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. 5,000 free Google Search groundings a month
&lt;/h2&gt;

&lt;p&gt;This is the one that surprised me. AI models have a knowledge cutoff — they don't know recent events. The fix is &lt;strong&gt;grounding&lt;/strong&gt;: letting the model search Google before answering. And Google gives you &lt;strong&gt;5,000 grounded prompts per month for free&lt;/strong&gt; (after that it's about $14 per 1,000).&lt;/p&gt;

&lt;p&gt;5,000 free real-time-grounded answers a month is plenty for a personal project or an early-stage app. Your free chatbot can answer questions about &lt;em&gt;today's&lt;/em&gt; news, not just its training data. Flip one toggle in AI Studio and it just works.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Gemma 4 — not a free tier, actually free &lt;em&gt;forever&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;Here's where "free" stops meaning "free tier" and starts meaning &lt;strong&gt;yours&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemma 4&lt;/strong&gt; is Google's open-weight model family, released under a license that lets you download the weights and run them on your own hardware — no API, no key, no per-token cost, ever. The small versions (the ~2B and ~4B "E-series") run on a laptop, a phone, even a Raspberry Pi. The bigger ones (a 26B mixture-of-experts and a 31B dense model with a 256K context window) run on a decent GPU.&lt;/p&gt;

&lt;p&gt;The implications are wild for a beginner: you can build an AI app where &lt;strong&gt;nothing is metered and nothing leaves your machine.&lt;/strong&gt; Download once from &lt;a href="https://huggingface.co/google" rel="noopener noreferrer"&gt;Hugging Face&lt;/a&gt; or Kaggle, and your inference cost is exactly zero, forever. For anything privacy-sensitive — personal data, offline tools — this is the whole game.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Free image, voice, and more (in the playground)
&lt;/h2&gt;

&lt;p&gt;In AI Studio you can also experiment for free with the parts of the stack people assume cost money on day one:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Image generation&lt;/strong&gt; — try Imagen and the "Nano Banana" image models right in the playground.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Speech&lt;/strong&gt; — text-to-speech voices you can steer with prompts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time voice&lt;/strong&gt; — the Live API for talking to a model out loud.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You won't run these at production scale for free, but for &lt;em&gt;learning what's possible&lt;/em&gt; and building a demo, the playground is an open sandbox.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you can actually build for $0
&lt;/h2&gt;

&lt;p&gt;Stack it all together and a beginner can ship, for free:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;multimodal chatbot&lt;/strong&gt; (text + image input) on the Gemini free tier...&lt;/li&gt;
&lt;li&gt;...that &lt;strong&gt;stays current&lt;/strong&gt; using the 5,000 free monthly Google searches...&lt;/li&gt;
&lt;li&gt;...prototyped and debugged entirely in &lt;strong&gt;AI Studio's free playground&lt;/strong&gt;...&lt;/li&gt;
&lt;li&gt;...or, if privacy matters, rebuilt to run &lt;strong&gt;100% offline and unmetered on Gemma 4.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's not a toy. That's a real, shippable app, built on a $0 budget. A year ago this would have cost real money or required a research lab.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest catch
&lt;/h2&gt;

&lt;p&gt;Free isn't infinite, and pretending otherwise will burn you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free-tier rate limits are real.&lt;/strong&gt; You'll hit requests-per-minute caps fast if you loop API calls — batch your work and design around the limits (I learned this the hard way).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prompts on the free tier may be used to improve Google's models.&lt;/strong&gt; Don't send anything sensitive through the free API. (This is exactly where running Gemma 4 &lt;em&gt;locally&lt;/em&gt; earns its keep.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Preview models can change or vanish.&lt;/strong&gt; Don't hard-code a preview model into something you can't easily update.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Free to prototype" ≠ "free at scale."&lt;/strong&gt; The moment you have real traffic, you'll cross into paid — so know which model tier you're on &lt;em&gt;before&lt;/em&gt; you grow (the price gap between tiers can be 6×).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;The loudest story out of Google I/O 2026 is about AI replacing developers. The quieter, more useful story is that the cost of &lt;em&gt;becoming&lt;/em&gt; one of those developers just dropped to zero. A free playground, a free API tier, 5,000 free grounded searches a month, and a genuinely free, run-it-yourself model family — that's a complete on-ramp, and it costs nothing but your time.&lt;/p&gt;

&lt;p&gt;If you've been waiting for a "good time" to start building with AI, this is it. Open AI Studio, grab a free key, and ship something this weekend. The only thing it'll cost you is the afternoon.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Free-tier details, grounding allowances, and model availability are from Google AI Studio and the &lt;a href="https://ai.google.dev/gemini-api/docs" rel="noopener noreferrer"&gt;Gemini API docs&lt;/a&gt; during the I/O 2026 window; limits change, so verify the current numbers before relying on them. I drafted this post with AI assistance and verified the free-tier specifics against Google's docs and AI Studio myself.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>googleiochallenge</category>
    </item>
    <item>
      <title>Your AI can read. Gemma 4 can see</title>
      <dc:creator>amionweb</dc:creator>
      <pubDate>Sat, 23 May 2026 07:20:24 +0000</pubDate>
      <link>https://dev.to/amionweb/your-ai-can-read-gemma-4-can-see-3264</link>
      <guid>https://dev.to/amionweb/your-ai-can-read-gemma-4-can-see-3264</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-gemma-2026-05-06"&gt;Gemma 4 Challenge: Write About Gemma 4&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Your AI can read. Gemma 4 can see. Here's what that actually changes.
&lt;/h1&gt;

&lt;p&gt;For two years, talking to an AI meant typing. You described things in words, the AI answered in words. If you wanted help with a photo, a handwritten note, or a screenshot, you first had to &lt;em&gt;translate it into a paragraph&lt;/em&gt; — and hope you didn't leave out the part that mattered.&lt;/p&gt;

&lt;p&gt;Gemma 4 is &lt;strong&gt;multimodal&lt;/strong&gt;, which is a clunky word for a simple idea: you can show it a picture instead of describing one. I spent an afternoon doing exactly that, and the gap between "tell the AI" and "show the AI" turned out to be bigger than I expected.&lt;/p&gt;

&lt;p&gt;Here's what multimodal actually means, three things I showed it, and how you can try it yourself in about five minutes — free, no fancy hardware.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Multimodal" in one sentence
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;mode&lt;/strong&gt; is a &lt;em&gt;type&lt;/em&gt; of input: text is one mode, images are another, audio is a third.&lt;/p&gt;

&lt;p&gt;A text-only model is like texting a friend who can only read words. A multimodal model is like video-calling that friend — you can hold something up to the camera and they just &lt;em&gt;see&lt;/em&gt; it.&lt;/p&gt;

&lt;p&gt;Gemma 4 handles text, images, and audio through the same model. You don't bolt on a separate "image reader." The thing that understands your sentence is the same thing that understands your photo. That matters more than it sounds, and the examples make it obvious.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things I showed it
&lt;/h2&gt;

&lt;p&gt;I didn't write clever prompts. I literally uploaded a photo and asked a plain question, the way you'd ask a knowledgeable friend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. A drooping houseplant.&lt;/strong&gt; I uploaded a photo of a sad-looking plant and asked, &lt;em&gt;"What's wrong with this?"&lt;/em&gt; It pointed out the yellowing lower leaves and damp-looking soil and suggested I was overwatering — and to check that the pot actually drained. I never told it the leaves were yellow. It looked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A handwritten grocery list.&lt;/strong&gt; My handwriting is genuinely bad. I snapped a photo and asked it to type the list out. It read all but one item correctly (it guessed "tomatoes" where I'd scrawled something closer to "tamarind" — fair). Typing that list myself would've taken longer than photographing it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. A screenshot of a line chart&lt;/strong&gt; with no title. I asked, &lt;em&gt;"What's the trend here?"&lt;/em&gt; It described the steady climb, called out the dip in the middle, and noted the sharp rise at the end — reading the &lt;em&gt;shape&lt;/em&gt; of the data, not just labels. For someone who finds charts intimidating, that's a quiet superpower.&lt;/p&gt;

&lt;p&gt;None of this was perfect. It got one grocery item wrong, and if I'd asked it to read tiny dense text it would've struggled. But "show instead of describe" changes the &lt;em&gt;kind&lt;/em&gt; of help you can ask for. You stop being the translator.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is a bigger deal than it looks
&lt;/h2&gt;

&lt;p&gt;Three reasons this matters beyond the novelty:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;You skip the translation step.&lt;/strong&gt; Describing an image in words is lossy and slow. A photo carries everything at once — color, layout, handwriting, the thing you didn't think to mention.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It opens AI to people who don't love typing.&lt;/strong&gt; Point a camera at a problem and ask about it. That's a far lower bar than composing the perfect prompt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The small versions run on your own machine.&lt;/strong&gt; Gemma 4 comes in sizes small enough to run on a laptop or even a phone, offline. So "show the AI a photo" doesn't have to mean "upload my private photo to someone's server." It can all happen on your device. For anything personal — documents, medical photos, your kid's homework — that's the difference between &lt;em&gt;useful&lt;/em&gt; and &lt;em&gt;no thanks&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last point is the one I keep coming back to. A model that can &lt;em&gt;see&lt;/em&gt;, running entirely on hardware you own, with no internet connection, would have sounded like science fiction in 2023. It's a free download in 2026.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it yourself in five minutes
&lt;/h2&gt;

&lt;p&gt;You don't need a powerful computer to &lt;em&gt;start&lt;/em&gt;. Two paths, easiest first.&lt;/p&gt;

&lt;h3&gt;
  
  
  Path A — zero install (browser, free)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Google AI Studio&lt;/strong&gt; (&lt;a href="https://aistudio.google.com" rel="noopener noreferrer"&gt;aistudio.google.com&lt;/a&gt;) and sign in with a Google account.&lt;/li&gt;
&lt;li&gt;Start a new prompt and pick a &lt;strong&gt;Gemma 4&lt;/strong&gt; model from the model dropdown.&lt;/li&gt;
&lt;li&gt;Click the image/upload icon, add any photo from your computer — a plant, a receipt, a whiteboard, a chart.&lt;/li&gt;
&lt;li&gt;Type a plain question: &lt;em&gt;"What is this?"&lt;/em&gt; or &lt;em&gt;"Read the text in this image."&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Watch it answer based on what it &lt;em&gt;sees&lt;/em&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's the whole thing. No setup, no card, no code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Path B — run it on your own machine (offline, private)
&lt;/h3&gt;

&lt;p&gt;If you want it running locally with nothing leaving your computer:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;strong&gt;Ollama&lt;/strong&gt; from &lt;a href="https://ollama.com" rel="noopener noreferrer"&gt;ollama.com&lt;/a&gt; (one download, Windows/Mac/Linux).&lt;/li&gt;
&lt;li&gt;Open a terminal and pull the small multimodal model:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ollama run gemma4:e4b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first run downloads the model once (a couple of gigabytes). After that it works with no internet.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the chat prompt, point it at an image file on your computer and ask your question. It reads the picture locally — nothing uploaded.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Start with Path A to feel the magic, switch to Path B when you want privacy.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd explore next
&lt;/h2&gt;

&lt;p&gt;The thing I want to try next is audio: Gemma 4 hears as well as sees, which means you could hand it a voice memo and a photo &lt;em&gt;together&lt;/em&gt; and ask one question about both. We're early in figuring out what that unlocks.&lt;/p&gt;

&lt;p&gt;But the simple version is already enough to change how I use AI day to day. I type less. I show more. And the friend on the other end of the video call finally has eyes.&lt;/p&gt;

&lt;p&gt;If you try it, show it something weird and tell me what it said — that's the fun part.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want to go deeper? The official models are on &lt;a href="https://huggingface.co/google" rel="noopener noreferrer"&gt;Hugging Face&lt;/a&gt; and &lt;a href="https://www.kaggle.com/models/google/gemma-4" rel="noopener noreferrer"&gt;Kaggle&lt;/a&gt;, all free to download.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>gemmachallenge</category>
      <category>gemma</category>
    </item>
    <item>
      <title>RoboFire: Cloud Clash Game Challenge Submission: Alibaba Cloud Web Game</title>
      <dc:creator>amionweb</dc:creator>
      <pubDate>Sun, 27 Apr 2025 10:35:47 +0000</pubDate>
      <link>https://dev.to/amionweb/robofire-cloud-clash-game-challenge-submission-alibaba-cloud-web-game-o0j</link>
      <guid>https://dev.to/amionweb/robofire-cloud-clash-game-challenge-submission-alibaba-cloud-web-game-o0j</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://int.alibabacloud.com/m/1000402443/" rel="noopener noreferrer"&gt;Alibaba Cloud&lt;/a&gt; Challenge: &lt;a href="https://dev.to/challenges/alibaba"&gt;Build a Web Game&lt;/a&gt;.&lt;/em&gt;*&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;An exciting arcade-style game where you control a robot shooting down clouds and collecting coins while avoiding dangerous obstacles!&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Live url:&lt;/strong&gt; &lt;a href="https://robo-fire.vercel.app/" rel="noopener noreferrer"&gt;https://robo-fire.vercel.app/&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/amionweb" rel="noopener noreferrer"&gt;
        amionweb
      &lt;/a&gt; / &lt;a href="https://github.com/amionweb/robo-fire" rel="noopener noreferrer"&gt;
        robo-fire
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;RoboFire: Cloud Clash 🤖☁️&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;An exciting arcade-style game where you control a robot shooting down clouds and collecting coins while avoiding dangerous obstacles!&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎮 Play Now&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://robo-fire.vercel.app/" rel="nofollow noopener noreferrer"&gt;Play RoboFire: Cloud Clash&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;✨ Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;🎯 Intuitive controls with keyboard support&lt;/li&gt;
&lt;li&gt;🌟 Beautiful visual effects and animations&lt;/li&gt;
&lt;li&gt;🎨 Smooth gameplay mechanics&lt;/li&gt;
&lt;li&gt;📈 Progressive difficulty system&lt;/li&gt;
&lt;li&gt;🏆 High score tracking&lt;/li&gt;
&lt;li&gt;🎵 Engaging sound effects&lt;/li&gt;
&lt;li&gt;📱 Responsive design&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🕹️ How to Play&lt;/h2&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Use &lt;strong&gt;Arrow keys&lt;/strong&gt; or &lt;strong&gt;WASD&lt;/strong&gt; to move your robot&lt;/li&gt;
&lt;li&gt;Press &lt;strong&gt;Spacebar&lt;/strong&gt; to shoot at clouds&lt;/li&gt;
&lt;li&gt;Collect falling coins to score points&lt;/li&gt;
&lt;li&gt;Avoid obstacles (lightning bolts and asteroids)&lt;/li&gt;
&lt;li&gt;Reach level 10 to win!&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🚀 Getting Started&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Clone the repository&lt;/span&gt;
git clone https://github.com/amionweb/robo-fire

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Navigate to the project directory&lt;/span&gt;
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; robofire-cloud-clash

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Install dependencies&lt;/span&gt;
npm install

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Start the development server&lt;/span&gt;
npm run dev&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🛠️ Built With&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;HTML5 Canvas&lt;/li&gt;
&lt;li&gt;TailwindCSS&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;🎯 Game Mechanics&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Clouds&lt;/strong&gt;: Shoot them to create collectible coins&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/amionweb/robo-fire" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&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%2Fnob7age1x6e65yqfzdlq.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%2Fnob7age1x6e65yqfzdlq.png" alt=" "&gt;&lt;/a&gt;&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%2Fjkcgskj9lgrval3psmc7.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%2Fjkcgskj9lgrval3psmc7.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ☁️ Alibaba Cloud Services Implementation
&lt;/h2&gt;

&lt;p&gt;For RoboFire: Cloud Clash, I used &lt;strong&gt;Alibaba Cloud Object Storage Service (OSS)&lt;/strong&gt; to &lt;strong&gt;host and serve&lt;/strong&gt; the static game files, and configured a &lt;strong&gt;custom domain&lt;/strong&gt; for a professional, fast-loading experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Services Used:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Object Storage Service (OSS)&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why:&lt;/strong&gt; OSS provides a highly reliable, scalable, and cost-effective way to store static web assets like HTML, CSS, JavaScript, and images.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How Integrated:&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Built the game locally with &lt;code&gt;npm run build&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Uploaded the build folder contents directly to an OSS bucket.&lt;/li&gt;
&lt;li&gt;Configured the bucket for &lt;strong&gt;static website hosting&lt;/strong&gt; (setting the index document to &lt;code&gt;index.html&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Experience:&lt;/strong&gt;
OSS made it extremely easy to deploy updates — I just re-upload the latest build files. The performance was excellent with low latency globally.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Domain Management + Custom Domain Binding&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why:&lt;/strong&gt; Custom domains make the game more shareable and professional.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How Integrated:&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Purchased or linked an existing domain via Alibaba Cloud Domains.&lt;/li&gt;
&lt;li&gt;Mapped the domain to my OSS bucket via a CNAME record.&lt;/li&gt;
&lt;li&gt;Configured HTTPS using Alibaba Cloud SSL certificates for secure access.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Experience:&lt;/strong&gt;
Domain setup was straightforward following Alibaba Cloud's documentation. Enabling HTTPS ensured that game assets loaded securely without browser warnings.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Benefits:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fast content delivery worldwide&lt;/li&gt;
&lt;li&gt;Very low maintenance and update cost&lt;/li&gt;
&lt;li&gt;Scalable without worrying about backend servers&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Challenges:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;The initial learning curve with setting correct bucket permissions (public read) for the static website.&lt;/li&gt;
&lt;li&gt;Slight delay (~10–15 mins) when applying custom domain settings and SSL.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🎯 Game Development Highlights
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Simple Yet Addictive Gameplay:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I designed RoboFire: Cloud Clash to have a fast gameplay loop — move, shoot, collect, avoid — making it highly engaging even with minimal mechanics.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Progressive Difficulty
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;One of the coolest features is the dynamic level system. As players collect coins, the enemy cloud speed increases, making higher levels genuinely challenging without introducing complex new elements.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Clean Responsive Canvas Integration
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Using &lt;strong&gt;HTML5 Canvas&lt;/strong&gt; inside a &lt;strong&gt;React&lt;/strong&gt; environment with &lt;strong&gt;Vite&lt;/strong&gt; made rendering super fast and allowed the game to adapt nicely to different screen sizes (desktop, tablet, mobile).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Retro-Futuristic Visuals
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I’m especially proud of the polished visual design — a clean, modern robot combined with nostalgic arcade-style effects like glowing coins and cloud explosions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Optimized Performance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Despite animations and firing mechanics, the game remains lightweight (~a few MBs), fast-loading, and smooth at 60fps even on lower-end devices.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>alibabachallenge</category>
      <category>devchallenge</category>
      <category>gamedev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>From Components to Creativity: Building a Portfolio with KendoReact</title>
      <dc:creator>amionweb</dc:creator>
      <pubDate>Mon, 24 Mar 2025 06:45:29 +0000</pubDate>
      <link>https://dev.to/amionweb/from-components-to-creativity-building-a-portfolio-with-kendoreact-343n</link>
      <guid>https://dev.to/amionweb/from-components-to-creativity-building-a-portfolio-with-kendoreact-343n</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/kendoreact"&gt;KendoReact Free Components Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What I Built
&lt;/h3&gt;

&lt;p&gt;I built a personal portfolio website using React and KendoReact components. The portfolio showcases my skills, experience, projects, and testimonials from clients. The website is designed to be responsive, with a clean and modern UI that adapts to both light and dark themes. The portfolio includes several sections such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Hero Section&lt;/em&gt;: A visually appealing introduction with a 3D animated background and a call-to-action to download my resume or get in touch.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;About Section&lt;/em&gt;: A brief introduction about myself, my skills, and what I specialize in.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Experience Section&lt;/em&gt;: A timeline of my professional experience, highlighting key roles and responsibilities.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Projects Section&lt;/em&gt;: A showcase of my featured projects, including technologies used and completion status.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Technologies Section&lt;/em&gt;: A detailed breakdown of my technical skills, categorized by frontend, backend, and DevOps.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Testimonials Section&lt;/em&gt;: Client testimonials with ratings, displayed in a grid layout for desktop and a carousel for mobile.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Contact Section&lt;/em&gt;: A form for visitors to get in touch with me, along with my contact information and social media links.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The portfolio is built with a focus on user experience, leveraging animations and transitions to create a smooth and engaging browsing experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://kendo-portfolio-lemon.vercel.app/" rel="noopener noreferrer"&gt;https://kendo-portfolio-lemon.vercel.app/&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fassets.dev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/amionweb" rel="noopener noreferrer"&gt;
        amionweb
      &lt;/a&gt; / &lt;a href="https://github.com/amionweb/kendo-portfolio" rel="noopener noreferrer"&gt;
        kendo-portfolio
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;h3&gt;
  
  
  KendoReact Experience
&lt;/h3&gt;

&lt;p&gt;I leveraged KendoReact's free components extensively throughout the portfolio to create a polished and professional UI. Here are some of the key components I used:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;em&gt;Card Components&lt;/em&gt;: Used in multiple sections (About, Experience, Projects, Testimonials) to display content in a structured and visually appealing way.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;TileLayout&lt;/em&gt;: Used in the About section to display my skills in a grid layout with staggered animations.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Fade Animation&lt;/em&gt;: Applied across various sections to create smooth fade-in animations as the user scrolls through the page.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Button Components&lt;/em&gt;: Used for call-to-action buttons, theme toggling, and navigation.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;ProgressBar&lt;/em&gt;: Used in the Projects and Technologies sections to visually represent skill levels and project completion status.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Chip and ChipList&lt;/em&gt;: Used in the Projects section to display the technologies used in each project.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Avatar&lt;/em&gt;: Used in the Testimonials section to display client images.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Input and Label&lt;/em&gt;: Used in the Contact section for the form fields.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Drawer&lt;/em&gt;: Used in the mobile navigation menu to provide a smooth and responsive user experience.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;AppBar&lt;/em&gt;: Used for the navigation bar, which is fixed at the top and adapts to the scroll position.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By using these KendoReact components, I was able to focus more on the overall design and functionality of the portfolio, rather than spending time building UI components from scratch. The components provided by KendoReact are highly customizable and integrate seamlessly with React, making the development process efficient and enjoyable.&lt;/p&gt;

&lt;h3&gt;
  
  
  AIm to Impress
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Delightfully Designed
&lt;/h3&gt;

</description>
      <category>devchallenge</category>
      <category>kendoreactchallenge</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Kendo React Challenge Submission</title>
      <dc:creator>amionweb</dc:creator>
      <pubDate>Mon, 24 Mar 2025 06:26:56 +0000</pubDate>
      <link>https://dev.to/amionweb/kendo-react-challenge-submission-3l84</link>
      <guid>https://dev.to/amionweb/kendo-react-challenge-submission-3l84</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/kendoreact"&gt;KendoReact Free Components Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Demo
&lt;/h3&gt;

&lt;h2&gt;
  
  
  KendoReact Experience
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AIm to Impress
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Delightfully Designed
&lt;/h3&gt;

</description>
      <category>devchallenge</category>
      <category>kendoreactchallenge</category>
      <category>react</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stellar contract CRUD Tutorial: Smart Contract Challenge</title>
      <dc:creator>amionweb</dc:creator>
      <pubDate>Mon, 19 Aug 2024 06:55:47 +0000</pubDate>
      <link>https://dev.to/amionweb/stellar-contract-crud-tutorial-smart-contract-challenge-1n74</link>
      <guid>https://dev.to/amionweb/stellar-contract-crud-tutorial-smart-contract-challenge-1n74</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/stellar"&gt;Build Better on Stellar: Smart Contract Challenge &lt;/a&gt;: Create a Tutorial&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Tutorial
&lt;/h2&gt;


&lt;div class="ltag__link"&gt;
  &lt;a href="/amionweb" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F1452510%2F7c7a3a56-fe0f-4731-a8e9-728dab67a6ea.png" alt="amionweb"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/amionweb/stellar-contract-crud-tutorial-a-step-by-step-guide-from-zero-to-hero-536a" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Stellar contract CRUD Tutorial A Step-by-Step Guide from Zero to Hero&lt;/h2&gt;
      &lt;h3&gt;amionweb ・ Aug 19 '24&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#stellarchallenge&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


&lt;p&gt;Here’s a structured submission for the "Build Better on Stellar: Smart Contract Challenge":&lt;/p&gt;




&lt;h2&gt;
  
  
  What I Created
&lt;/h2&gt;

&lt;p&gt;For the "Build Better on Stellar: Smart Contract Challenge," I developed a comprehensive smart contract for managing products on the Stellar blockchain. This contract includes CRUD (Create, Read, Update, Delete) operations, allowing users to manage product listings effectively. The functionalities include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create a Product:&lt;/strong&gt; Adds a new product to the system with details like name, description, and price.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Get a Product by ID:&lt;/strong&gt; Retrieves a product's details using its unique ID.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Update a Product:&lt;/strong&gt; Updates the product's details, including its name, description, and price.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete a Product:&lt;/strong&gt; Marks a product as inactive without removing it from storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permanently Delete a Product:&lt;/strong&gt; Completely removes a product from storage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Delete All Products:&lt;/strong&gt; Clears all products from the system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This contract enhances the Stellar developer experience by providing a practical example of managing data through smart contracts. Developers can utilize this contract as a blueprint for their own projects, easily adapting it to different use cases by modifying the product data structure or extending functionalities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Journey
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Research and Content Creation
&lt;/h3&gt;

&lt;p&gt;My journey began with researching the Stellar smart contract capabilities and the Soroban SDK, which is used to build smart contracts on Stellar. I studied existing examples and documentation to understand best practices and the nuances of developing smart contracts in Rust.&lt;/p&gt;

&lt;h3&gt;
  
  
  Motivation
&lt;/h3&gt;

&lt;p&gt;The motivation behind this submission was to create a flexible and practical example of a smart contract that could be immediately useful to other developers. The goal was to provide a straightforward implementation of CRUD operations, which are fundamental for many applications. By using this example, developers can get a head start on building and deploying their own smart contracts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning and Experience
&lt;/h3&gt;

&lt;p&gt;Throughout this process, I gained a deeper understanding of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Smart Contract Development:&lt;/strong&gt; From writing and deploying smart contracts to handling data persistence on the Stellar blockchain.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stellar Ecosystem:&lt;/strong&gt; How to interact with the Stellar network using Soroban SDK and the specific requirements for smart contracts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rust Programming:&lt;/strong&gt; Leveraging Rust for building secure and efficient smart contracts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I am particularly proud of creating a well-documented and functional contract that simplifies the complexities of smart contract development on Stellar. It is designed to be a practical resource for beginners and experienced developers alike.&lt;/p&gt;

&lt;h3&gt;
  
  
  Future Goals
&lt;/h3&gt;

&lt;p&gt;Moving forward, I plan to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Extend Functionality:&lt;/strong&gt; Add features such as user authentication and role-based access control to the contract.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improve Documentation:&lt;/strong&gt; Create more detailed tutorials and examples to help developers integrate and customize smart contracts in their projects.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explore Other Use Cases:&lt;/strong&gt; Develop smart contracts for different applications, such as financial transactions or decentralized voting systems, to broaden the scope of practical implementations on Stellar.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This submission represents a foundational step in the journey of integrating smart contracts into real-world applications on the Stellar blockchain. It is designed to be both educational and practical, providing a valuable tool for developers looking to build on Stellar.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>stellarchallenge</category>
      <category>blockchain</category>
      <category>web3</category>
    </item>
    <item>
      <title>Stellar contract CRUD Tutorial A Step-by-Step Guide from Zero to Hero</title>
      <dc:creator>amionweb</dc:creator>
      <pubDate>Mon, 19 Aug 2024 06:55:24 +0000</pubDate>
      <link>https://dev.to/amionweb/stellar-contract-crud-tutorial-a-step-by-step-guide-from-zero-to-hero-536a</link>
      <guid>https://dev.to/amionweb/stellar-contract-crud-tutorial-a-step-by-step-guide-from-zero-to-hero-536a</guid>
      <description>&lt;p&gt;In this tutorial, we'll guide you through creating a Stellar smart contract from scratch. You'll learn how to implement basic CRUD (Create, Read, Update, Delete) operations for managing products in a decentralized application (dApp). By the end of this tutorial, you'll be able to add, update, delete, view, and get all products using a Stellar smart contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;Before we dive into the code, make sure you have the following:&lt;/p&gt;

&lt;h2&gt;
  
  
  Set Up Environment / Project Installation Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A) Environment Setup:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install Rust, using command:&lt;br&gt;
&lt;code&gt;curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;nstall the Soroban CLI using below mentioned command. For more info visit =&amp;gt; &lt;a href="https://developers.stellar.org/docs/smart-contracts" rel="noopener noreferrer"&gt;Soroban docs&lt;/a&gt;&lt;br&gt;
&lt;code&gt;cargo install --locked soroban-cli&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install &lt;a href="https://nodejs.org/en" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Get the &lt;a href="https://www.freighter.app/" rel="noopener noreferrer"&gt;Freighter Wallet&lt;/a&gt; extension for you browser.&lt;br&gt;
Once enabled, then got to the network section and connect your wallet to the testnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install wasm32-unknown-unknown package using command:&lt;br&gt;
&lt;code&gt;rustup target add wasm32-unknown-unknown&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To configure your CLI to interact with Testnet, run the following command:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;soroban network add \
  --global testnet \
  --rpc-url https://soroban-testnet.stellar.org:443 \
  --network-passphrase "Test SDF Network ; September 2015"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 1: Setting Up the Project
&lt;/h3&gt;

&lt;p&gt;First, create a new Rust project by running the following command in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;stellar contract init product-crud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate to the project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;product-crud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These dependencies allow us to interact with Stellar's Soroban platform.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Defining the Product Struct
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;lib.rs&lt;/code&gt; file, start by defining the &lt;code&gt;Product&lt;/code&gt; struct. This struct will hold the details of each product.&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="nd"&gt;#![no_std]&lt;/span&gt; &lt;span class="c1"&gt;// We don't use the Rust standard library in smart contracts&lt;/span&gt;
&lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;soroban_sdk&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;contracttype&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Struct to represent a product in our dApp&lt;/span&gt;
&lt;span class="nd"&gt;#[contracttype]&lt;/span&gt;
&lt;span class="nd"&gt;#[derive(Clone)]&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;Product&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;id&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="c1"&gt;// Unique ID for the product&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;         &lt;span class="c1"&gt;// Name of the product&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Description of the product&lt;/span&gt;
    &lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="n"&gt;price&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="c1"&gt;// Price of the product&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;Explanation:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;Product&lt;/code&gt; struct is defined with fields such as &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;description&lt;/code&gt;, and &lt;code&gt;price&lt;/code&gt;. This struct will store information about each product.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Setting Up the Contract
&lt;/h3&gt;

&lt;p&gt;Next, define the main contract structure and the CRUD operations. Here's how you can start:&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;soroban_sdk&lt;/span&gt;&lt;span class="p"&gt;::{&lt;/span&gt;&lt;span class="n"&gt;contract&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;contractimpl&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;symbol_short&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// Define a contract type called ProductContract&lt;/span&gt;
&lt;span class="nd"&gt;#[contract]&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;ProductContract&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Enum for referencing product storage&lt;/span&gt;
&lt;span class="nd"&gt;#[contracttype]&lt;/span&gt;
&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Productbook&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;Product&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="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Symbol to track the total count of products&lt;/span&gt;
&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;COUNT_PRODUCT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Symbol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nd"&gt;symbol_short!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"C_PROD"&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;Explanation:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;ProductContract&lt;/code&gt; struct is defined as the main contract.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Productbook&lt;/code&gt; is an enum used to store and retrieve products by their ID.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;COUNT_PRODUCT&lt;/code&gt; is a symbol used to track the number of products stored.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 5: Implementing the Create Operation
&lt;/h3&gt;

&lt;p&gt;Now, let's implement the function to create a new product.&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="nd"&gt;#[contractimpl]&lt;/span&gt;
&lt;span class="k"&gt;impl&lt;/span&gt; &lt;span class="n"&gt;ProductContract&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;create_product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;price&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="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;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;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;count_product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.get&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;COUNT_PRODUCT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or&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="n"&gt;count_product&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&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_product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;count_product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;};&lt;/span&gt;

        &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="nf"&gt;.set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nn"&gt;Productbook&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;new_product&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt;&lt;span class="nf"&gt;.clone&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_product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.set&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;COUNT_PRODUCT&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;count_product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;log&lt;/span&gt;&lt;span class="o"&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="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Product Created with ID: {}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;new_product&lt;/span&gt;&lt;span class="py"&gt;.id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;new_product&lt;/span&gt;&lt;span class="py"&gt;.id&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;Explanation:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;create_product&lt;/code&gt; function increments the &lt;code&gt;count_product&lt;/code&gt; by 1 and creates a new product with the provided details.&lt;/li&gt;
&lt;li&gt;The product is then stored in the contract's storage, and the ID of the newly created product is returned.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 6: Implementing the Read Operation
&lt;/h3&gt;

&lt;p&gt;Let's add a function to retrieve a product by its ID.&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;impl&lt;/span&gt; &lt;span class="n"&gt;ProductContract&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;get_product_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product_id&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;Product&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;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Productbook&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.get&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;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Product&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;id&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="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_str&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;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Not Found"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;String&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from_str&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;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Not Found"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;price&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="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;Explanation:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;get_product_by_id&lt;/code&gt; function retrieves a product from storage by its ID. If the product is not found, it returns a default &lt;code&gt;Product&lt;/code&gt; with "Not Found" values.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 7: Implementing the Update Operation
&lt;/h3&gt;

&lt;p&gt;Now, add a function to update the details of an existing product.&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;impl&lt;/span&gt; &lt;span class="n"&gt;ProductContract&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;update_product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;product_id&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;new_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&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;new_description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&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;new_price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;u64&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="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Productbook&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_id&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;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_product_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;product_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_name&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="py"&gt;.name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_description&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="py"&gt;.description&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nf"&gt;Some&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;new_price&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="py"&gt;.price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.set&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;key&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;product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;log&lt;/span&gt;&lt;span class="o"&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="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Product with ID: {} has been updated."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product_id&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;Explanation:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;update_product&lt;/code&gt; function allows updating the product's name, description, and price. If new values are provided, they replace the existing ones.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 8: Implementing the Delete Operation
&lt;/h3&gt;

&lt;p&gt;Finally, let's implement a function to delete a product by its ID.&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;impl&lt;/span&gt; &lt;span class="n"&gt;ProductContract&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;delete_product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product_id&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="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Productbook&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.has&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;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.remove&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;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="k"&gt;log&lt;/span&gt;&lt;span class="o"&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="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Product with ID: {} has been deleted."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;log&lt;/span&gt;&lt;span class="o"&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="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Product with ID: {} does not exist."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;product_id&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;delete_product&lt;/code&gt; function removes a product from storage by its ID. If the product doesn't exist, a message is logged.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 9: Implementing the Get All Products Operation
&lt;/h3&gt;

&lt;p&gt;Lastly, let's add a function to retrieve all products.&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;impl&lt;/span&gt; &lt;span class="n"&gt;ProductContract&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;get_all_products&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Env&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;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;Product&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="n"&gt;count_product&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;u64&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.storage&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.instance&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.get&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;COUNT_PRODUCT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.unwrap_or&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="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Vec&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="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..=&lt;/span&gt;&lt;span class="n"&gt;count_product&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;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;Self&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get_product_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="nf"&gt;.clone&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;products&lt;/span&gt;&lt;span class="nf"&gt;.push_back&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;product&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;products&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;Explanation:&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;get_all_products&lt;/code&gt; function iterates through all the stored products and returns them as a vector.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 10: Testing and Deploying the Contract
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In order to deploy the smartcontract you will need an account. You can either use the an account from the &lt;code&gt;Freighter Wallet&lt;/code&gt; or can configure an account named &lt;code&gt;alice&lt;/code&gt; in the testnet using the command:&lt;br&gt;
&lt;code&gt;soroban keys generate --global alice --network testnet&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can see the public key of account &lt;code&gt;alice&lt;/code&gt;:&lt;br&gt;
&lt;code&gt;soroban keys address alice&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;=&amp;gt; Go inside the &lt;code&gt;/product-crud&lt;/code&gt; directory and do the below mentioned steps:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build the contract:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;soroban contract build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Alternte command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo build --target wasm32-unknown-unknown --release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Install Optimizer:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo install --locked soroban-cli --features opt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Build an Opmize the contract:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;soroban contract optimize --wasm target/wasm32-unknown-unknown/release/hello_world.wasm 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Steps to the Deploy smart-contract on testnet:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;deploy the smartcontract on the testnet and get deployed address of the smartcontract using the following command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stellar contract deploy --wasm target\wasm32-unknown-unknown\release\hello_world.wasm  --network testnet --source alice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;&lt;em&gt;Deployed address of this smartcontract:&lt;/em&gt;&lt;/strong&gt; &lt;code&gt;contract_address&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;*NOTE: If you get the XDR Error &lt;code&gt;error: xdr processing error: xdr value invalid&lt;/code&gt;, then follow this &lt;a href="https://stellar.org/blog/developers/protocol-21-upgrade-guide" rel="noopener noreferrer"&gt;article&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Invoke functions from the smart-contract:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;#### To invoke any of the function from the smartcontract you can use this command fromat.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;soroban contract invoke \
  --id &amp;lt;DEPLOYED_CONTRACT_ADDRESS&amp;gt; \
  --source &amp;lt;YOUR_ACCOUNT_NAME&amp;gt; \
  --network testnet \
  -- \
  &amp;lt;FUNCTION_NAME&amp;gt; --&amp;lt;FUNCTION_PARAMETER&amp;gt; &amp;lt;ARGUMENT&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are example &lt;code&gt;soroban contract invoke&lt;/code&gt; commands for each of the functions in the &lt;code&gt;ProductContract&lt;/code&gt; smart contract, using dummy data. Replace &lt;code&gt;&amp;lt;DEPLOYED_CONTRACT_ADDRESS&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;YOUR_ACCOUNT_NAME&amp;gt;&lt;/code&gt;, and other placeholders with actual values.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Create a Product
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &amp;lt;DEPLOYED_CONTRACT_ADDRESS&amp;gt; &lt;span class="nt"&gt;--source&lt;/span&gt; &amp;lt;YOUR_ACCOUNT_NAME&amp;gt; &lt;span class="nt"&gt;--network&lt;/span&gt; testnet &lt;span class="nt"&gt;--&lt;/span&gt; create_product &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"Sample Product"&lt;/span&gt; &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"A description of the sample product."&lt;/span&gt; &lt;span class="nt"&gt;--price&lt;/span&gt; 1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Get a Product by ID
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &amp;lt;DEPLOYED_CONTRACT_ADDRESS&amp;gt; &lt;span class="nt"&gt;--source&lt;/span&gt; &amp;lt;YOUR_ACCOUNT_NAME&amp;gt; &lt;span class="nt"&gt;--network&lt;/span&gt; testnet &lt;span class="nt"&gt;--&lt;/span&gt; get_product_by_id &lt;span class="nt"&gt;--product_id&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Update a Product
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &amp;lt;DEPLOYED_CONTRACT_ADDRESS&amp;gt; &lt;span class="nt"&gt;--source&lt;/span&gt; &amp;lt;YOUR_ACCOUNT_NAME&amp;gt; &lt;span class="nt"&gt;--network&lt;/span&gt; testnet &lt;span class="nt"&gt;--&lt;/span&gt; update_product &lt;span class="nt"&gt;--product_id&lt;/span&gt; 1 &lt;span class="nt"&gt;--new_name&lt;/span&gt; &lt;span class="s2"&gt;"Updated Product"&lt;/span&gt; &lt;span class="nt"&gt;--new_description&lt;/span&gt; &lt;span class="s2"&gt;"Updated description of the product."&lt;/span&gt; &lt;span class="nt"&gt;--new_price&lt;/span&gt; 1200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Delete a Product
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &amp;lt;DEPLOYED_CONTRACT_ADDRESS&amp;gt; &lt;span class="nt"&gt;--source&lt;/span&gt; &amp;lt;YOUR_ACCOUNT_NAME&amp;gt; &lt;span class="nt"&gt;--network&lt;/span&gt; testnet &lt;span class="nt"&gt;--&lt;/span&gt; delete_product &lt;span class="nt"&gt;--product_id&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Permanently Delete a Product
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &amp;lt;DEPLOYED_CONTRACT_ADDRESS&amp;gt; &lt;span class="nt"&gt;--source&lt;/span&gt; &amp;lt;YOUR_ACCOUNT_NAME&amp;gt; &lt;span class="nt"&gt;--network&lt;/span&gt; testnet &lt;span class="nt"&gt;--&lt;/span&gt; delete_product_permanently &lt;span class="nt"&gt;--product_id&lt;/span&gt; 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Delete All Products
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;soroban contract invoke &lt;span class="nt"&gt;--id&lt;/span&gt; &amp;lt;DEPLOYED_CONTRACT_ADDRESS&amp;gt; &lt;span class="nt"&gt;--source&lt;/span&gt; &amp;lt;YOUR_ACCOUNT_NAME&amp;gt; &lt;span class="nt"&gt;--network&lt;/span&gt; testnet &lt;span class="nt"&gt;--&lt;/span&gt; delete_all_products
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Explanation of Parameters
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;--id &amp;lt;DEPLOYED_CONTRACT_ADDRESS&amp;gt;&lt;/code&gt;: The address where the smart contract is deployed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--source &amp;lt;YOUR_ACCOUNT_NAME&amp;gt;&lt;/code&gt;: The account name used to invoke the contract.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--network testnet&lt;/code&gt;: The network on which the contract is deployed (e.g., &lt;code&gt;testnet&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;FUNCTION_NAME&amp;gt;&lt;/code&gt;: The function you want to invoke in the smart contract.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;FUNCTION_PARAMETER &amp;lt;ARGUMENT&amp;gt;&lt;/code&gt;: The parameters required by the function.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Replace placeholders with actual values to interact with your deployed contract on the Stellar testnet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Congratulations! You've successfully created a Stellar smart contract that performs CRUD operations for managing products. This guide walked you through setting up a Rust project, defining the contract and product structure, and implementing each CRUD operation step by step. You can now use this knowledge to build more complex dApps on the Stellar network.&lt;/p&gt;

</description>
      <category>stellarchallenge</category>
    </item>
  </channel>
</rss>
