<?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: SotaTek | AI &amp; Blockchain Innovation Partner</title>
    <description>The latest articles on DEV Community by SotaTek | AI &amp; Blockchain Innovation Partner (@devsotatek).</description>
    <link>https://dev.to/devsotatek</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4117244%2F6229ec86-28dd-4441-b858-39daab536542.jpg</url>
      <title>DEV Community: SotaTek | AI &amp; Blockchain Innovation Partner</title>
      <link>https://dev.to/devsotatek</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/devsotatek"/>
    <language>en</language>
    <item>
      <title>What Actually Happens When You Mint an NFT?</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Mon, 28 Sep 2026 07:51:12 +0000</pubDate>
      <link>https://dev.to/devsotatek/what-actually-happens-when-you-mint-an-nft-28k5</link>
      <guid>https://dev.to/devsotatek/what-actually-happens-when-you-mint-an-nft-28k5</guid>
      <description>&lt;p&gt;“Mint an NFT” sounds like a single operation.&lt;/p&gt;

&lt;p&gt;From a user's perspective, it often looks like this:&lt;/p&gt;

&lt;p&gt;Connect Wallet&lt;br&gt;
      ↓&lt;br&gt;
Click Mint&lt;br&gt;
      ↓&lt;br&gt;
Confirm Transaction&lt;br&gt;
      ↓&lt;br&gt;
NFT Appears in Wallet&lt;/p&gt;

&lt;p&gt;Underneath that button, several systems have to agree on the same state.&lt;/p&gt;

&lt;p&gt;The image is not necessarily stored on the blockchain. The metadata may live on IPFS or another storage layer. The smart contract owns the token ID and ownership state. The wallet signs the transaction. An indexer eventually makes the new asset visible to the application.&lt;/p&gt;

&lt;p&gt;A simplified architecture looks like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                NFT Application
                      │
                      ▼
                 Mint UI
                      │
                      ▼
                   Wallet
                      │
                signed tx
                      ▼
              Smart Contract
                /          \
               /            \
              ▼              ▼
         Token State     Metadata URI
              │              │
              ▼              ▼
         Blockchain     IPFS / Storage
              │
              ▼
            Events
              │
              ▼
           Indexer
              │
              ▼
        Marketplace / UI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The interesting part is that the NFT itself is only one piece of the system.&lt;/p&gt;

&lt;p&gt;Start With What the NFT Actually Represents&lt;/p&gt;

&lt;p&gt;Before writing a contract, you need to define the asset.&lt;/p&gt;

&lt;p&gt;An NFT could represent:&lt;/p&gt;

&lt;p&gt;A unique collectible&lt;br&gt;
A game character&lt;br&gt;
A ticket&lt;br&gt;
A membership credential&lt;br&gt;
A digital certificate&lt;br&gt;
A real-world asset&lt;br&gt;
A composable digital asset&lt;/p&gt;

&lt;p&gt;That decision affects the contract design, metadata structure, token standard, and transfer model.&lt;/p&gt;

&lt;p&gt;For example, a collection of unique digital artworks has a different structure from a game inventory containing thousands of identical consumable items.&lt;/p&gt;

&lt;p&gt;This is why token standard selection should happen before implementation.&lt;/p&gt;

&lt;p&gt;ERC-721 vs ERC-1155&lt;/p&gt;

&lt;p&gt;For a simple one-of-a-kind asset, ERC-721 is usually the easier mental model.&lt;/p&gt;

&lt;p&gt;Each token has its own ID:&lt;/p&gt;

&lt;p&gt;Collection&lt;br&gt;
│&lt;br&gt;
├── Token #1&lt;br&gt;
├── Token #2&lt;br&gt;
├── Token #3&lt;br&gt;
└── Token #4&lt;/p&gt;

&lt;p&gt;ERC-1155 takes a different approach.&lt;/p&gt;

&lt;p&gt;A single contract can represent multiple token types and quantities:&lt;/p&gt;

&lt;p&gt;Contract&lt;br&gt;
│&lt;br&gt;
├── Item #1001 → 5,000 copies&lt;br&gt;
├── Item #1002 → 2,000 copies&lt;br&gt;
└── Item #1003 → 1 copy&lt;/p&gt;

&lt;p&gt;This makes ERC-1155 useful for applications such as gaming, where an inventory may contain both unique assets and high-volume items.&lt;/p&gt;

&lt;p&gt;The choice is therefore not about which standard is “better”.&lt;/p&gt;

&lt;p&gt;It depends on the asset model.&lt;/p&gt;

&lt;p&gt;A useful rule is:&lt;/p&gt;

&lt;p&gt;Unique asset&lt;br&gt;
    ↓&lt;br&gt;
ERC-721&lt;/p&gt;

&lt;p&gt;Multiple / batch-oriented assets&lt;br&gt;
    ↓&lt;br&gt;
ERC-1155&lt;/p&gt;

&lt;p&gt;NFTs that own other assets&lt;br&gt;
    ↓&lt;br&gt;
Composable design such as ERC-998&lt;/p&gt;

&lt;p&gt;The source article also identifies ERC-721, ERC-1155, ERC-998 and TRC-721 as common options, with the choice depending on asset structure, blockchain and marketplace compatibility.&lt;/p&gt;

&lt;p&gt;The Image Is Not the NFT&lt;/p&gt;

&lt;p&gt;This is one of the most common misconceptions.&lt;/p&gt;

&lt;p&gt;Suppose an NFT displays:&lt;/p&gt;

&lt;p&gt;Golden Sword&lt;br&gt;
Attack: 95&lt;br&gt;
Rarity: Legendary&lt;br&gt;
Image: sword.png&lt;/p&gt;

&lt;p&gt;Those properties are generally represented through metadata.&lt;/p&gt;

&lt;p&gt;A simplified metadata document could look like:&lt;/p&gt;

&lt;p&gt;{&lt;br&gt;
  "name": "Golden Sword",&lt;br&gt;
  "description": "Legendary in-game weapon",&lt;br&gt;
  "image": "ipfs://...",&lt;br&gt;
  "attributes": [&lt;br&gt;
    {&lt;br&gt;
      "trait_type": "Rarity",&lt;br&gt;
      "value": "Legendary"&lt;br&gt;
    },&lt;br&gt;
    {&lt;br&gt;
      "trait_type": "Attack",&lt;br&gt;
      "value": 95&lt;br&gt;
    }&lt;br&gt;
  ]&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;The smart contract does not necessarily store this entire JSON object.&lt;/p&gt;

&lt;p&gt;Instead, the token commonly exposes a metadata URI:&lt;/p&gt;

&lt;p&gt;NFT #1842&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
tokenURI(1842)&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
ipfs://metadata...&lt;/p&gt;

&lt;p&gt;This keeps large assets and metadata outside the blockchain while allowing the token to reference them.&lt;/p&gt;

&lt;p&gt;The source architecture similarly separates metadata from the token itself, with metadata commonly stored off-chain using systems such as IPFS or Arweave and referenced from the token.&lt;/p&gt;

&lt;p&gt;Why Put Metadata Off-Chain?&lt;/p&gt;

&lt;p&gt;Storing an image directly on-chain is possible, but it can be expensive and impractical for many collections.&lt;/p&gt;

&lt;p&gt;A common architecture is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                Blockchain
                    │
                    │ tokenURI
                    ▼
              Metadata URI
                    │
                    ▼
            Decentralized Storage
                    │
          ┌─────────┴─────────┐
          ▼                   ▼
       Metadata             Image
          │                   │
          └─────────┬─────────┘
                    ▼
               NFT Interface
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The important distinction is:&lt;/p&gt;

&lt;p&gt;The blockchain proves token ownership.&lt;/p&gt;

&lt;p&gt;It does not automatically guarantee that every external asset referenced by the token will remain available forever.&lt;/p&gt;

&lt;p&gt;That is why storage architecture is part of NFT engineering, not just a frontend concern.&lt;/p&gt;

&lt;p&gt;The Smart Contract Defines Ownership&lt;/p&gt;

&lt;p&gt;A minimal ERC-721 contract might look like:&lt;/p&gt;

&lt;p&gt;contract GameAsset is ERC721 {&lt;br&gt;
    uint256 private nextTokenId;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function mint(address to)
    external
    returns (uint256)
{
    uint256 tokenId = nextTokenId++;
    _safeMint(to, tokenId);

    return tokenId;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;The important operation here is not the image or metadata.&lt;/p&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;p&gt;_mint(to, tokenId)&lt;/p&gt;

&lt;p&gt;The blockchain now records that:&lt;/p&gt;

&lt;p&gt;Token #1842&lt;br&gt;
        ↓&lt;br&gt;
Owner = 0xA91...&lt;/p&gt;

&lt;p&gt;That ownership state can then be independently verified.&lt;/p&gt;

&lt;p&gt;A marketplace does not need to trust your database to determine who owns the NFT.&lt;/p&gt;

&lt;p&gt;It can query the contract or indexed blockchain data.&lt;/p&gt;

&lt;p&gt;What Actually Happens During Minting?&lt;/p&gt;

&lt;p&gt;Let's follow a mint transaction.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The application prepares the transaction&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The frontend knows:&lt;/p&gt;

&lt;p&gt;Contract address&lt;br&gt;
Token ID / mint parameters&lt;br&gt;
Recipient&lt;br&gt;
Metadata configuration&lt;/p&gt;

&lt;p&gt;It prepares a contract call.&lt;/p&gt;

&lt;p&gt;mint(recipient)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The wallet signs it&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The user confirms the transaction through their wallet.&lt;/p&gt;

&lt;p&gt;The wallet signs the transaction with the user's private key.&lt;/p&gt;

&lt;p&gt;The application does not receive the private key.&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Wallet&lt;br&gt;
 │&lt;br&gt;
 │ signed transaction&lt;br&gt;
 ▼&lt;br&gt;
Blockchain Network&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The transaction reaches the smart contract&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The blockchain executes the contract.&lt;/p&gt;

&lt;p&gt;The contract checks whatever rules have been implemented:&lt;/p&gt;

&lt;p&gt;Can this caller mint?&lt;br&gt;
        │&lt;br&gt;
        ├── No → revert&lt;br&gt;
        │&lt;br&gt;
        └── Yes&lt;br&gt;
             ↓&lt;br&gt;
        Create token&lt;br&gt;
             ↓&lt;br&gt;
        Assign owner&lt;br&gt;
             ↓&lt;br&gt;
        Emit event&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Ownership is written to blockchain state&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After successful execution:&lt;/p&gt;

&lt;p&gt;Token #1842&lt;br&gt;
    │&lt;br&gt;
    ├── Owner → 0xA91...&lt;br&gt;
    └── Metadata → ipfs://...&lt;/p&gt;

&lt;p&gt;The transaction receipt and event logs provide evidence of the state transition.&lt;/p&gt;

&lt;p&gt;Minting Is Also a Security Boundary&lt;/p&gt;

&lt;p&gt;The simple contract above has a major problem:&lt;/p&gt;

&lt;p&gt;Who is allowed to call mint()?&lt;/p&gt;

&lt;p&gt;If anyone can call it, anyone can create unlimited tokens.&lt;/p&gt;

&lt;p&gt;Production contracts therefore need access control.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;function mint(address to)&lt;br&gt;
    external&lt;br&gt;
    onlyRole(MINTER_ROLE)&lt;br&gt;
{&lt;br&gt;
    ...&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Other controls may include:&lt;/p&gt;

&lt;p&gt;Maximum supply&lt;br&gt;
Per-wallet limits&lt;br&gt;
Pausing&lt;br&gt;
Signature-based mint authorization&lt;br&gt;
Payment validation&lt;br&gt;
Allow lists&lt;br&gt;
Mint phases&lt;br&gt;
Upgrade permissions&lt;/p&gt;

&lt;p&gt;This is why smart contract development is one of the security-sensitive stages of NFT development. The source article specifically identifies smart contract security, access control, and transaction integrity as major risks.&lt;/p&gt;

&lt;p&gt;The Event Is Just as Important as the State&lt;/p&gt;

&lt;p&gt;Suppose the contract emits:&lt;/p&gt;

&lt;p&gt;event NFTMinted(&lt;br&gt;
    address indexed owner,&lt;br&gt;
    uint256 indexed tokenId&lt;br&gt;
);&lt;/p&gt;

&lt;p&gt;The event can then be consumed by off-chain infrastructure:&lt;/p&gt;

&lt;p&gt;Smart Contract&lt;br&gt;
      │&lt;br&gt;
      │ NFTMinted&lt;br&gt;
      ▼&lt;br&gt;
Blockchain Node&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Event Listener&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Indexer&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Application Database&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Marketplace / UI&lt;/p&gt;

&lt;p&gt;This is how the application can discover that a new NFT has been minted without constantly scanning every transaction manually.&lt;/p&gt;

&lt;p&gt;The blockchain remains the source of truth.&lt;/p&gt;

&lt;p&gt;The indexer becomes the query layer.&lt;/p&gt;

&lt;p&gt;That distinction matters.&lt;/p&gt;

&lt;p&gt;Why an Indexer Is Necessary&lt;/p&gt;

&lt;p&gt;Imagine a marketplace displaying:&lt;/p&gt;

&lt;p&gt;Latest NFTs&lt;br&gt;
Trending Collections&lt;br&gt;
Owner History&lt;br&gt;
Sales History&lt;br&gt;
Floor Price&lt;br&gt;
Trading Volume&lt;/p&gt;

&lt;p&gt;Querying raw blockchain state for every page load quickly becomes impractical.&lt;/p&gt;

&lt;p&gt;An indexer can transform blockchain events into application-friendly data:&lt;/p&gt;

&lt;p&gt;Blockchain Events&lt;br&gt;
       │&lt;br&gt;
       ▼&lt;br&gt;
    Indexer&lt;br&gt;
       │&lt;br&gt;
       ├── NFT ownership&lt;br&gt;
       ├── Transfers&lt;br&gt;
       ├── Sales&lt;br&gt;
       ├── Collections&lt;br&gt;
       └── Metadata&lt;br&gt;
              │&lt;br&gt;
              ▼&lt;br&gt;
          Database&lt;br&gt;
              │&lt;br&gt;
              ▼&lt;br&gt;
          Frontend&lt;/p&gt;

&lt;p&gt;But indexing introduces its own engineering problems.&lt;/p&gt;

&lt;p&gt;You need to handle:&lt;/p&gt;

&lt;p&gt;Duplicate events&lt;br&gt;
RPC failures&lt;br&gt;
Delayed confirmations&lt;br&gt;
Chain reorganizations&lt;br&gt;
Reprocessing&lt;br&gt;
Idempotency&lt;br&gt;
Metadata synchronization&lt;/p&gt;

&lt;p&gt;So the NFT does not become “visible everywhere” immediately after the user clicks Mint.&lt;/p&gt;

&lt;p&gt;There is a state transition between transaction submitted and application synchronized.&lt;/p&gt;

&lt;p&gt;The Marketplace Does Not Own the NFT&lt;/p&gt;

&lt;p&gt;A marketplace typically facilitates trading.&lt;/p&gt;

&lt;p&gt;The underlying NFT remains governed by its smart contract.&lt;/p&gt;

&lt;p&gt;A simplified secondary sale looks like:&lt;/p&gt;

&lt;p&gt;Seller&lt;br&gt;
  │&lt;br&gt;
  │ list NFT&lt;br&gt;
  ▼&lt;br&gt;
Marketplace&lt;br&gt;
  │&lt;br&gt;
  │ buyer purchases&lt;br&gt;
  ▼&lt;br&gt;
Smart Contract&lt;br&gt;
  │&lt;br&gt;
  ├── transfer NFT&lt;br&gt;
  ├── transfer payment&lt;br&gt;
  └── emit events&lt;br&gt;
          │&lt;br&gt;
          ▼&lt;br&gt;
       Indexer&lt;br&gt;
          │&lt;br&gt;
          ▼&lt;br&gt;
    Updated marketplace&lt;/p&gt;

&lt;p&gt;This is an important architectural boundary.&lt;/p&gt;

&lt;p&gt;The marketplace database should not become the authority for ownership.&lt;/p&gt;

&lt;p&gt;The contract should enforce the actual asset transfer.&lt;/p&gt;

&lt;p&gt;Royalties Are a Contract Design Problem&lt;/p&gt;

&lt;p&gt;NFT projects often want creators to receive a percentage from secondary sales.&lt;/p&gt;

&lt;p&gt;That sounds straightforward:&lt;/p&gt;

&lt;p&gt;Sale = $1,000&lt;br&gt;
Royalty = 5%&lt;br&gt;
Creator = $50&lt;br&gt;
Seller = $950&lt;/p&gt;

&lt;p&gt;But royalty behavior is not uniformly enforced across every marketplace and trading environment.&lt;/p&gt;

&lt;p&gt;This means royalty requirements need to be considered at both levels:&lt;/p&gt;

&lt;p&gt;Smart Contract&lt;br&gt;
      +&lt;br&gt;
Marketplace Integration&lt;/p&gt;

&lt;p&gt;A technically correct royalty implementation does not guarantee identical behavior across every external marketplace.&lt;/p&gt;

&lt;p&gt;This is one reason marketplace compatibility should be considered early rather than after the contract is deployed.&lt;/p&gt;

&lt;p&gt;Immutable vs Upgradeable Contracts&lt;/p&gt;

&lt;p&gt;Another architectural decision is whether the contract should be immutable or upgradeable.&lt;/p&gt;

&lt;p&gt;An immutable contract provides a strong guarantee:&lt;/p&gt;

&lt;p&gt;Deployed&lt;br&gt;
   ↓&lt;br&gt;
Logic stays fixed&lt;/p&gt;

&lt;p&gt;An upgradeable architecture introduces:&lt;/p&gt;

&lt;p&gt;Proxy&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Implementation&lt;br&gt;
  │&lt;br&gt;
  ├── V1&lt;br&gt;
  ├── V2&lt;br&gt;
  └── V3&lt;/p&gt;

&lt;p&gt;Upgradeability can be useful when requirements are expected to evolve.&lt;/p&gt;

&lt;p&gt;But it also introduces additional trust and security assumptions.&lt;/p&gt;

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

&lt;p&gt;Who controls upgrades?&lt;br&gt;
Can the administrator change ownership logic?&lt;br&gt;
Can metadata behavior change?&lt;br&gt;
Is the upgrade mechanism secured?&lt;br&gt;
What happens if the upgrade key is compromised?&lt;/p&gt;

&lt;p&gt;There is no universal answer.&lt;/p&gt;

&lt;p&gt;The important thing is to make the trust model explicit before deployment.&lt;/p&gt;

&lt;p&gt;Gas Is an Architecture Constraint&lt;/p&gt;

&lt;p&gt;Every on-chain operation has a cost.&lt;/p&gt;

&lt;p&gt;The cost can be affected by:&lt;/p&gt;

&lt;p&gt;Blockchain network&lt;br&gt;
Contract complexity&lt;br&gt;
Storage operations&lt;br&gt;
Minting model&lt;br&gt;
Batch size&lt;br&gt;
Current network demand&lt;/p&gt;

&lt;p&gt;For large collections, this can influence whether you use:&lt;/p&gt;

&lt;p&gt;One transaction per NFT&lt;/p&gt;

&lt;p&gt;or a batch-oriented approach.&lt;/p&gt;

&lt;p&gt;ERC-1155 can be particularly useful when many token types or quantities need to be managed efficiently.&lt;/p&gt;

&lt;p&gt;This is why blockchain selection should happen before implementation rather than being treated as an infrastructure detail at the end.&lt;/p&gt;

&lt;p&gt;The Architecture I Would Start With&lt;/p&gt;

&lt;p&gt;For a typical NFT platform, I would separate responsibilities like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                     User
                      │
                      ▼
                Web / Mobile App
                      │
          ┌───────────┴───────────┐
          ▼                       ▼
       Wallet                  Backend
                                  │
                   ┌──────────────┼──────────────┐
                   ▼              ▼              ▼
               Metadata        Indexer       Marketplace
               Service           │
                   │             │
                   ▼             ▼
            IPFS / Storage   Application DB
                                  │
                                  │
                              Blockchain
                                  │
                       ┌──────────┴──────────┐
                       ▼                     ▼
                NFT Contract            Token Contract
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The responsibilities stay clear:&lt;/p&gt;

&lt;p&gt;Wallet       → authorization&lt;br&gt;
Frontend     → user interaction&lt;br&gt;
Backend      → application logic&lt;br&gt;
Smart contract → ownership + on-chain rules&lt;br&gt;
Storage      → metadata + assets&lt;br&gt;
Indexer      → blockchain read model&lt;br&gt;
Marketplace  → trading experience&lt;br&gt;
Blockchain   → settlement + ownership truth&lt;/p&gt;

&lt;p&gt;This separation also makes it easier to replace individual components without redesigning the entire system.&lt;/p&gt;

&lt;p&gt;The Hard Part Isn't Minting&lt;/p&gt;

&lt;p&gt;Writing a basic NFT contract is not particularly difficult.&lt;/p&gt;

&lt;p&gt;Writing a basic NFT contract is not particularly difficult.&lt;/p&gt;

&lt;p&gt;The difficult questions appear around the contract:&lt;/p&gt;

&lt;p&gt;What exactly does the token represent?&lt;br&gt;
Where does the metadata live?&lt;br&gt;
Who can mint?&lt;br&gt;
Can the contract be upgraded?&lt;br&gt;
How is ownership indexed?&lt;br&gt;
How are royalties handled?&lt;br&gt;
What happens when the RPC provider fails?&lt;br&gt;
How does the application reconcile pending transactions?&lt;br&gt;
Which marketplaces support the required behavior?&lt;br&gt;
What happens if metadata becomes unavailable?&lt;/p&gt;

&lt;p&gt;In our blockchain work at SotaTek, these are often the questions that require more architectural consideration than the minting logic itself. The contract may only take a few functions to implement, but making the entire system reliable means thinking through storage, indexing, wallet flows, marketplace compatibility, and the boundary between on-chain and off-chain state.&lt;/p&gt;

&lt;p&gt;These are architecture questions, not Solidity syntax questions.&lt;/p&gt;

&lt;p&gt;That is why a production NFT implementation needs to consider smart contracts, metadata, storage, wallets, indexing, marketplaces, security, and blockchain infrastructure as one system.&lt;/p&gt;

&lt;p&gt;Final Takeaway&lt;/p&gt;

&lt;p&gt;An NFT is not an image stored on a blockchain.&lt;/p&gt;

&lt;p&gt;It is better understood as a combination of:&lt;/p&gt;

&lt;p&gt;Token Standard&lt;br&gt;
      +&lt;br&gt;
Smart Contract&lt;br&gt;
      +&lt;br&gt;
Ownership State&lt;br&gt;
      +&lt;br&gt;
Metadata&lt;br&gt;
      +&lt;br&gt;
Off-chain Storage&lt;br&gt;
      +&lt;br&gt;
Wallet&lt;br&gt;
      +&lt;br&gt;
Blockchain&lt;br&gt;
      +&lt;br&gt;
Indexing&lt;/p&gt;

&lt;p&gt;The blockchain provides verifiable ownership and transaction history.&lt;/p&gt;

&lt;p&gt;The smart contract defines the rules.&lt;/p&gt;

&lt;p&gt;The metadata describes the asset.&lt;/p&gt;

&lt;p&gt;The wallet authorizes transactions.&lt;/p&gt;

&lt;p&gt;The indexer makes blockchain state usable by applications.&lt;/p&gt;

&lt;p&gt;And the marketplace connects that infrastructure to users.&lt;/p&gt;

&lt;p&gt;Once you understand these boundaries, NFT development becomes less about “minting a token” and more about designing a system where on-chain truth and off-chain application state remain consistent.&lt;/p&gt;

&lt;p&gt;For a broader overview of NFT token standards, development stages, use cases, and the cost factors involved in taking an NFT project from contract deployment to marketplace integration, this &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/blockchain/nft-token-development-services/" rel="noopener noreferrer"&gt;NFT token development guide&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; provides additional context.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>nft</category>
      <category>smartcontract</category>
    </item>
    <item>
      <title>What Actually Happens When You Swap Tokens on a DEX?</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Fri, 25 Sep 2026 09:10:29 +0000</pubDate>
      <link>https://dev.to/devsotatek/what-actually-happens-when-you-swap-tokens-on-a-dex-1dk</link>
      <guid>https://dev.to/devsotatek/what-actually-happens-when-you-swap-tokens-on-a-dex-1dk</guid>
      <description>&lt;p&gt;A DEX can look deceptively simple from the frontend.&lt;/p&gt;

&lt;p&gt;Select two tokens, enter an amount, click Swap, approve the transaction, and wait.&lt;/p&gt;

&lt;p&gt;Underneath that button, however, several systems are working together:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Wallet&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
DEX Frontend&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Router / Smart Contract&lt;br&gt;
  │&lt;br&gt;
  ├── Liquidity Pool&lt;br&gt;
  ├── Token Contracts&lt;br&gt;
  └── Pricing Logic&lt;br&gt;
          │&lt;br&gt;
          ▼&lt;br&gt;
      Blockchain&lt;br&gt;
          │&lt;br&gt;
          ▼&lt;br&gt;
       Event Logs&lt;br&gt;
          │&lt;br&gt;
          ▼&lt;br&gt;
       Indexer&lt;/p&gt;

&lt;p&gt;Understanding this flow is useful because a DEX is not simply a UI connected to a smart contract.&lt;/p&gt;

&lt;p&gt;It is a distributed trading system where pricing, liquidity, execution, settlement, and indexing all have different responsibilities.&lt;/p&gt;

&lt;p&gt;Start With the Liquidity Pool&lt;/p&gt;

&lt;p&gt;Consider a simple ETH/USDC pool.&lt;/p&gt;

&lt;p&gt;The pool contains:&lt;/p&gt;

&lt;p&gt;ETH  → 10&lt;br&gt;
USDC → 30,000&lt;/p&gt;

&lt;p&gt;A trader wants to swap ETH for USDC.&lt;/p&gt;

&lt;p&gt;In an AMM-based DEX, the trade does not need to find another trader willing to take the opposite side.&lt;/p&gt;

&lt;p&gt;The trader interacts with the liquidity pool itself.&lt;/p&gt;

&lt;p&gt;Liquidity providers supply the assets, and the AMM determines the exchange rate according to its pricing function.&lt;/p&gt;

&lt;p&gt;A simplified constant-product model is:&lt;/p&gt;

&lt;p&gt;x × y = k&lt;/p&gt;

&lt;p&gt;Where:&lt;/p&gt;

&lt;p&gt;x = reserve of token A&lt;br&gt;
y = reserve of token B&lt;br&gt;
k = invariant&lt;/p&gt;

&lt;p&gt;Before the trade:&lt;/p&gt;

&lt;p&gt;10 ETH × 30,000 USDC&lt;br&gt;
= 300,000&lt;/p&gt;

&lt;p&gt;Suppose the trader sends 1 ETH into the pool.&lt;/p&gt;

&lt;p&gt;The new ETH reserve becomes:&lt;/p&gt;

&lt;p&gt;x' = 11 ETH&lt;/p&gt;

&lt;p&gt;The AMM needs to maintain the invariant:&lt;/p&gt;

&lt;p&gt;11 × y' = 300,000&lt;/p&gt;

&lt;p&gt;Therefore:&lt;/p&gt;

&lt;p&gt;y' ≈ 27,272.73 USDC&lt;/p&gt;

&lt;p&gt;The difference between the old and new reserves represents the amount of USDC that can be removed from the pool, before fees and other implementation details are applied.&lt;/p&gt;

&lt;p&gt;This is the basic idea behind an AMM.&lt;/p&gt;

&lt;p&gt;The important part is that the pool itself becomes the counterparty.&lt;/p&gt;

&lt;p&gt;Price and Execution Price Are Not the Same&lt;/p&gt;

&lt;p&gt;This is where things become more interesting.&lt;/p&gt;

&lt;p&gt;The displayed price might look like:&lt;/p&gt;

&lt;p&gt;1 ETH = 3,000 USDC&lt;/p&gt;

&lt;p&gt;But that does not mean a trader can necessarily swap a large amount of ETH at exactly 3,000 USDC.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;Because the trade changes the pool reserves.&lt;/p&gt;

&lt;p&gt;A larger trade moves the pool further along its pricing curve.&lt;/p&gt;

&lt;p&gt;This creates price impact.&lt;/p&gt;

&lt;p&gt;There is also a difference between:&lt;/p&gt;

&lt;p&gt;Market price&lt;br&gt;
Quoted execution price&lt;br&gt;
Price impact&lt;br&gt;
Slippage tolerance&lt;/p&gt;

&lt;p&gt;A production DEX needs to expose these clearly before the user signs the transaction.&lt;/p&gt;

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

&lt;p&gt;Input:              1.0 ETH&lt;br&gt;
Expected output:    2,970 USDC&lt;br&gt;
Price impact:       0.8%&lt;br&gt;
Minimum received:   2,940 USDC&lt;br&gt;
Network fee:        0.002 ETH&lt;/p&gt;

&lt;p&gt;These numbers are not just UI decoration.&lt;/p&gt;

&lt;p&gt;They are part of the transaction safety model.&lt;/p&gt;

&lt;p&gt;The Frontend Does Not Execute the Swap&lt;/p&gt;

&lt;p&gt;The frontend calculates or retrieves a quote.&lt;/p&gt;

&lt;p&gt;It does not ultimately control the token transfer.&lt;/p&gt;

&lt;p&gt;The actual state transition happens through smart contracts.&lt;/p&gt;

&lt;p&gt;A simplified flow is:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 │&lt;br&gt;
 │ "Swap 1 ETH for USDC"&lt;br&gt;
 ▼&lt;br&gt;
Frontend&lt;br&gt;
 │&lt;br&gt;
 │ request quote&lt;br&gt;
 ▼&lt;br&gt;
Router&lt;br&gt;
 │&lt;br&gt;
 │ calculate route&lt;br&gt;
 ▼&lt;br&gt;
Smart Contract&lt;br&gt;
 │&lt;br&gt;
 │ execute swap&lt;br&gt;
 ▼&lt;br&gt;
Liquidity Pool&lt;br&gt;
 │&lt;br&gt;
 │ update reserves&lt;br&gt;
 ▼&lt;br&gt;
Blockchain State&lt;/p&gt;

&lt;p&gt;The wallet signs the transaction.&lt;/p&gt;

&lt;p&gt;The blockchain executes it.&lt;/p&gt;

&lt;p&gt;The smart contract determines whether the requested operation is valid.&lt;/p&gt;

&lt;p&gt;This distinction is important because the frontend should be treated as an untrusted interface.&lt;/p&gt;

&lt;p&gt;Anyone can call the contract directly.&lt;/p&gt;

&lt;p&gt;The contract itself must enforce the rules.&lt;/p&gt;

&lt;p&gt;Token Approvals Add Another Transaction&lt;/p&gt;

&lt;p&gt;For ERC-20 tokens, users typically need to authorize a contract to spend their tokens.&lt;/p&gt;

&lt;p&gt;This creates an additional step:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
approve()&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Token Contract&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
DEX Router&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
swap()&lt;/p&gt;

&lt;p&gt;So the first interaction with a token may require two transactions:&lt;/p&gt;

&lt;p&gt;approve&lt;br&gt;
swap&lt;/p&gt;

&lt;p&gt;A production frontend needs to make this state understandable.&lt;/p&gt;

&lt;p&gt;Otherwise users may see:&lt;/p&gt;

&lt;p&gt;“Transaction successful”&lt;/p&gt;

&lt;p&gt;and still wonder why the swap has not happened.&lt;/p&gt;

&lt;p&gt;The frontend should distinguish between:&lt;/p&gt;

&lt;p&gt;Approval confirmed&lt;br&gt;
Swap pending&lt;br&gt;
Swap confirmed&lt;br&gt;
Swap failed&lt;/p&gt;

&lt;p&gt;This is a small UX detail with a large operational impact.&lt;/p&gt;

&lt;p&gt;The Router Is Where Things Get Interesting&lt;/p&gt;

&lt;p&gt;A simple DEX might execute:&lt;/p&gt;

&lt;p&gt;ETH → USDC&lt;/p&gt;

&lt;p&gt;But users may not always get the best execution through a single pool.&lt;/p&gt;

&lt;p&gt;A router can split or chain trades:&lt;/p&gt;

&lt;p&gt;ETH&lt;br&gt;
 │&lt;br&gt;
 ├── Pool A&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
USDC&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Pool B&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
DAI&lt;/p&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;p&gt;ETH&lt;br&gt;
 │&lt;br&gt;
 ├── 60% → Pool A&lt;br&gt;
 │&lt;br&gt;
 └── 40% → Pool B&lt;br&gt;
              │&lt;br&gt;
              ▼&lt;br&gt;
             USDC&lt;/p&gt;

&lt;p&gt;The router's job is to determine how the requested trade should be executed according to the available liquidity and routing logic.&lt;/p&gt;

&lt;p&gt;This creates a trade-off.&lt;/p&gt;

&lt;p&gt;More sophisticated routing can improve execution, but it also increases:&lt;/p&gt;

&lt;p&gt;Gas consumption&lt;br&gt;
Contract complexity&lt;br&gt;
Failure modes&lt;br&gt;
Simulation requirements&lt;br&gt;
Security surface&lt;/p&gt;

&lt;p&gt;The cheapest route computationally is not necessarily the route with the best execution price.&lt;/p&gt;

&lt;p&gt;What Happens When the User Clicks "Swap"?&lt;/p&gt;

&lt;p&gt;Let's follow the transaction.&lt;/p&gt;

&lt;p&gt;Step 1: The frontend creates a transaction&lt;/p&gt;

&lt;p&gt;The application prepares something conceptually similar to:&lt;/p&gt;

&lt;p&gt;to:&lt;br&gt;
  DEX Router&lt;/p&gt;

&lt;p&gt;method:&lt;br&gt;
  swapExactTokensForTokens()&lt;/p&gt;

&lt;p&gt;parameters:&lt;br&gt;
  amountIn&lt;br&gt;
  amountOutMin&lt;br&gt;
  path&lt;br&gt;
  recipient&lt;br&gt;
  deadline&lt;br&gt;
Step 2: The wallet asks for authorization&lt;/p&gt;

&lt;p&gt;The user reviews the transaction and signs it.&lt;/p&gt;

&lt;p&gt;The wallet produces a cryptographic signature proving that the account authorized the transaction.&lt;/p&gt;

&lt;p&gt;Step 3: The transaction reaches the network&lt;/p&gt;

&lt;p&gt;The transaction is broadcast to the blockchain network.&lt;/p&gt;

&lt;p&gt;At this point it is not necessarily finalized.&lt;/p&gt;

&lt;p&gt;It may be:&lt;/p&gt;

&lt;p&gt;Pending&lt;br&gt;
   ↓&lt;br&gt;
Included in block&lt;br&gt;
   ↓&lt;br&gt;
Executed&lt;br&gt;
   ↓&lt;br&gt;
Confirmed / finalized&lt;/p&gt;

&lt;p&gt;The frontend therefore needs to handle asynchronous transaction state rather than assuming that submission equals completion.&lt;/p&gt;

&lt;p&gt;Step 4: The smart contract executes&lt;/p&gt;

&lt;p&gt;The router calls the required contracts.&lt;/p&gt;

&lt;p&gt;The transaction may involve:&lt;/p&gt;

&lt;p&gt;Router&lt;br&gt;
  ↓&lt;br&gt;
Token A&lt;br&gt;
  ↓&lt;br&gt;
Pool&lt;br&gt;
  ↓&lt;br&gt;
Token B&lt;/p&gt;

&lt;p&gt;Each contract call changes blockchain state.&lt;/p&gt;

&lt;p&gt;If any required condition fails, the transaction reverts.&lt;/p&gt;

&lt;p&gt;What Happens Inside the Pool?&lt;/p&gt;

&lt;p&gt;The pool receives the input token.&lt;/p&gt;

&lt;p&gt;Then the contract calculates how much output can be released while respecting its pricing rules.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;Before:&lt;/p&gt;

&lt;p&gt;Token A reserve = 10&lt;br&gt;
Token B reserve = 30,000&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ↓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Trader sends Token A&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ↓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;AMM calculation&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ↓
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;After:&lt;/p&gt;

&lt;p&gt;Token A reserve = 11&lt;br&gt;
Token B reserve = ~27,272&lt;/p&gt;

&lt;p&gt;The exact calculation depends on the AMM implementation.&lt;/p&gt;

&lt;p&gt;Real protocols may also account for:&lt;/p&gt;

&lt;p&gt;Trading fees&lt;br&gt;
Concentrated liquidity&lt;br&gt;
Multiple price ranges&lt;br&gt;
Dynamic fees&lt;br&gt;
Different invariant designs&lt;/p&gt;

&lt;p&gt;So the simple x × y = k model is useful for understanding the concept, but it is not a complete representation of every modern AMM.&lt;/p&gt;

&lt;p&gt;Where Do Liquidity Providers Fit?&lt;/p&gt;

&lt;p&gt;The pool needs liquidity.&lt;/p&gt;

&lt;p&gt;Liquidity providers deposit assets into the protocol and receive a claim representing their share of the pool.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;Liquidity Provider&lt;br&gt;
       │&lt;br&gt;
       ├── Token A&lt;br&gt;
       └── Token B&lt;br&gt;
             │&lt;br&gt;
             ▼&lt;br&gt;
       Liquidity Pool&lt;br&gt;
             │&lt;br&gt;
             ▼&lt;br&gt;
          Traders&lt;/p&gt;

&lt;p&gt;In return, LPs can receive a portion of trading fees according to the protocol's rules.&lt;/p&gt;

&lt;p&gt;But providing liquidity is not risk-free.&lt;/p&gt;

&lt;p&gt;LPs can be exposed to:&lt;/p&gt;

&lt;p&gt;Impermanent loss&lt;br&gt;
Smart contract risk&lt;br&gt;
Asset volatility&lt;br&gt;
Oracle risk&lt;br&gt;
Protocol-specific risks&lt;/p&gt;

&lt;p&gt;From an engineering perspective, liquidity is therefore not simply a feature.&lt;/p&gt;

&lt;p&gt;It is part of the protocol's economic design.&lt;/p&gt;

&lt;p&gt;The Blockchain Is the Source of Settlement Truth&lt;/p&gt;

&lt;p&gt;After the transaction executes, the blockchain contains the resulting state.&lt;/p&gt;

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

&lt;p&gt;Trader&lt;br&gt;
  ↓&lt;br&gt;
-1 ETH&lt;br&gt;
+2,970 USDC&lt;/p&gt;

&lt;p&gt;Pool&lt;br&gt;
  ↓&lt;br&gt;
+1 ETH&lt;br&gt;
-2,970 USDC&lt;/p&gt;

&lt;p&gt;The DEX frontend should not invent this state.&lt;/p&gt;

&lt;p&gt;It should derive it from blockchain data.&lt;/p&gt;

&lt;p&gt;That creates an important architecture:&lt;/p&gt;

&lt;p&gt;Blockchain&lt;br&gt;
    │&lt;br&gt;
    ├── Transactions&lt;br&gt;
    ├── Events&lt;br&gt;
    └── Contract State&lt;br&gt;
            │&lt;br&gt;
            ▼&lt;br&gt;
         Indexer&lt;br&gt;
            │&lt;br&gt;
            ▼&lt;br&gt;
       Application DB&lt;br&gt;
            │&lt;br&gt;
            ▼&lt;br&gt;
       DEX Frontend&lt;br&gt;
Why You Need an Indexer&lt;/p&gt;

&lt;p&gt;Reading raw blockchain data directly from the frontend becomes expensive and inconvenient as the application grows.&lt;/p&gt;

&lt;p&gt;Consider a trading page that needs:&lt;/p&gt;

&lt;p&gt;Historical trades&lt;br&gt;
Token prices&lt;br&gt;
Volume&lt;br&gt;
Liquidity&lt;br&gt;
User positions&lt;br&gt;
Transaction history&lt;br&gt;
Pool activity&lt;/p&gt;

&lt;p&gt;You could query the blockchain repeatedly.&lt;/p&gt;

&lt;p&gt;But that is not an efficient application architecture.&lt;/p&gt;

&lt;p&gt;An indexer processes blockchain events and transforms them into application-friendly data.&lt;/p&gt;

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

&lt;p&gt;Swap Event&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Event Listener&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Indexer&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Database&lt;br&gt;
    │&lt;br&gt;
    ├── price history&lt;br&gt;
    ├── volume&lt;br&gt;
    ├── transactions&lt;br&gt;
    └── pool analytics&lt;/p&gt;

&lt;p&gt;The blockchain remains the source of truth.&lt;/p&gt;

&lt;p&gt;The indexed database becomes the query layer.&lt;/p&gt;

&lt;p&gt;That distinction is important.&lt;/p&gt;

&lt;p&gt;Events Are Part of the Integration Contract&lt;/p&gt;

&lt;p&gt;Smart contracts can emit events such as:&lt;/p&gt;

&lt;p&gt;event Swap(&lt;br&gt;
    address indexed sender,&lt;br&gt;
    uint256 amountIn,&lt;br&gt;
    uint256 amountOut&lt;br&gt;
);&lt;/p&gt;

&lt;p&gt;The event allows off-chain systems to observe state transitions without repeatedly reconstructing every operation from scratch.&lt;/p&gt;

&lt;p&gt;But event processing needs to be designed carefully.&lt;/p&gt;

&lt;p&gt;An indexer should account for:&lt;/p&gt;

&lt;p&gt;Duplicate processing&lt;br&gt;
Missed events&lt;br&gt;
RPC failures&lt;br&gt;
Chain reorganizations&lt;br&gt;
Reprocessing&lt;br&gt;
Idempotency&lt;/p&gt;

&lt;p&gt;For example, processing the same Swap event twice should not create two trades in the database.&lt;/p&gt;

&lt;p&gt;This is a distributed-systems problem hiding inside a DeFi application.&lt;/p&gt;

&lt;p&gt;Slippage Is a Safety Mechanism&lt;/p&gt;

&lt;p&gt;Suppose the frontend quotes:&lt;/p&gt;

&lt;p&gt;1 ETH → 3,000 USDC&lt;/p&gt;

&lt;p&gt;But market conditions change before the transaction is executed.&lt;/p&gt;

&lt;p&gt;The user might receive:&lt;/p&gt;

&lt;p&gt;1 ETH → 2,700 USDC&lt;/p&gt;

&lt;p&gt;That may be unacceptable.&lt;/p&gt;

&lt;p&gt;The transaction therefore includes a minimum acceptable output:&lt;/p&gt;

&lt;p&gt;amountOutMin = 2,950 USDC&lt;/p&gt;

&lt;p&gt;If the actual output falls below that threshold, the transaction reverts.&lt;/p&gt;

&lt;p&gt;This is why slippage tolerance is more than a UI preference.&lt;/p&gt;

&lt;p&gt;It becomes a parameter enforced by the smart contract.&lt;/p&gt;

&lt;p&gt;The Mempool Creates Another Problem: MEV&lt;/p&gt;

&lt;p&gt;There is a gap between:&lt;/p&gt;

&lt;p&gt;User signs transaction&lt;/p&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;p&gt;Transaction is executed&lt;/p&gt;

&lt;p&gt;During that period, the transaction may be visible to actors that can observe pending transactions.&lt;/p&gt;

&lt;p&gt;This creates opportunities for Maximal Extractable Value (MEV).&lt;/p&gt;

&lt;p&gt;One common example is a sandwich attack:&lt;/p&gt;

&lt;p&gt;User's swap&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
Attacker observes transaction&lt;br&gt;
     │&lt;br&gt;
     ├── Buy before user&lt;br&gt;
     │&lt;br&gt;
     ├── User executes at worse price&lt;br&gt;
     │&lt;br&gt;
     └── Sell after user&lt;/p&gt;

&lt;p&gt;The result can be worse execution for the original trader.&lt;/p&gt;

&lt;p&gt;DEX design therefore needs to consider:&lt;/p&gt;

&lt;p&gt;Slippage limits&lt;br&gt;
Transaction ordering&lt;br&gt;
Private transaction mechanisms&lt;br&gt;
Routing&lt;br&gt;
Liquidity depth&lt;/p&gt;

&lt;p&gt;MEV is not purely a smart-contract bug.&lt;/p&gt;

&lt;p&gt;It is a consequence of how transaction ordering and public blockchains interact.&lt;/p&gt;

&lt;p&gt;Gas Is Part of the Product&lt;/p&gt;

&lt;p&gt;A technically correct swap can still provide a poor user experience if the transaction costs too much.&lt;/p&gt;

&lt;p&gt;Gas usage depends on factors such as:&lt;/p&gt;

&lt;p&gt;Number of contract calls&lt;br&gt;
Storage operations&lt;br&gt;
Routing complexity&lt;br&gt;
Network conditions&lt;br&gt;
Smart contract implementation&lt;/p&gt;

&lt;p&gt;A simple swap may require relatively little computation, while a multi-hop or multi-contract transaction can be considerably more expensive.&lt;/p&gt;

&lt;p&gt;This creates an important optimization question:&lt;/p&gt;

&lt;p&gt;Is the better price worth the additional execution cost?&lt;/p&gt;

&lt;p&gt;A routing algorithm that saves a user 5 USDC but costs an additional 8 USDC in gas is not actually improving execution.&lt;/p&gt;

&lt;p&gt;The system needs to optimize for net user outcome, not just quoted token output.&lt;/p&gt;

&lt;p&gt;Cross-Chain DEXs Add Another Trust Boundary&lt;/p&gt;

&lt;p&gt;Supporting multiple blockchains sounds like a frontend feature.&lt;/p&gt;

&lt;p&gt;It is not.&lt;/p&gt;

&lt;p&gt;A cross-chain DEX may involve:&lt;/p&gt;

&lt;p&gt;Chain A&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Bridge / Messaging Layer&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
Chain B&lt;br&gt;
  │&lt;br&gt;
  ▼&lt;br&gt;
DEX / Liquidity&lt;/p&gt;

&lt;p&gt;Now the system depends on additional components:&lt;/p&gt;

&lt;p&gt;Bridges&lt;br&gt;
Messaging protocols&lt;br&gt;
Relayers&lt;br&gt;
Multiple RPC providers&lt;br&gt;
Multiple smart contract environments&lt;br&gt;
Cross-chain liquidity&lt;/p&gt;

&lt;p&gt;Every new dependency expands the attack surface.&lt;/p&gt;

&lt;p&gt;Supporting ten chains is not simply ten times the configuration.&lt;/p&gt;

&lt;p&gt;The security model becomes significantly more complex.&lt;/p&gt;

&lt;p&gt;The Architecture I Would Start With&lt;/p&gt;

&lt;p&gt;For a production-oriented AMM DEX, a reasonable architecture is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                User
                  │
                  ▼
            Web / Mobile UI
                  │
        ┌─────────┴─────────┐
        ▼                   ▼
     Wallet              API Layer
                            │
                     ┌──────┴──────┐
                     ▼             ▼
                 Indexer       Analytics
                     │
                     ▼
                Application DB

                  Blockchain
                       │
         ┌─────────────┴─────────────┐
         ▼                           ▼
    Router Contract             Token Contracts
         │
         ▼
    Liquidity Pools
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Each layer has a specific responsibility:&lt;/p&gt;

&lt;p&gt;Frontend       → interaction&lt;br&gt;
Wallet         → authorization&lt;br&gt;
Smart contract → execution + settlement&lt;br&gt;
Liquidity pool → available liquidity&lt;br&gt;
Blockchain     → state + finality&lt;br&gt;
Indexer        → queryable blockchain data&lt;br&gt;
Database       → application read model&lt;br&gt;
Analytics      → aggregated insights&lt;/p&gt;

&lt;p&gt;Keeping these boundaries clear makes the system much easier to test, monitor, and evolve.&lt;/p&gt;

&lt;p&gt;The Hard Part Isn't the Swap&lt;/p&gt;

&lt;p&gt;Writing a basic swap contract is not the hardest part of building a DEX.&lt;/p&gt;

&lt;p&gt;The difficult engineering problems appear around it:&lt;/p&gt;

&lt;p&gt;How much liquidity is available?&lt;br&gt;
How do we calculate a safe quote?&lt;br&gt;
What happens when the transaction is delayed?&lt;br&gt;
How do we handle failed transactions?&lt;br&gt;
How do we prevent unauthorized actions?&lt;br&gt;
How do we index millions of events?&lt;br&gt;
How do we protect users against bad execution?&lt;br&gt;
How do we manage MEV?&lt;br&gt;
What happens when an RPC provider fails?&lt;br&gt;
What changes when we add another chain?&lt;/p&gt;

&lt;p&gt;The swap is only one state transition inside a much larger distributed system.&lt;/p&gt;

&lt;p&gt;Final Takeaway&lt;/p&gt;

&lt;p&gt;A DEX is best understood as a combination of:&lt;/p&gt;

&lt;p&gt;Trading Logic&lt;br&gt;
      +&lt;br&gt;
Liquidity&lt;br&gt;
      +&lt;br&gt;
Smart Contracts&lt;br&gt;
      +&lt;br&gt;
Wallets&lt;br&gt;
      +&lt;br&gt;
Blockchain Infrastructure&lt;br&gt;
      +&lt;br&gt;
Indexing&lt;br&gt;
      +&lt;br&gt;
User Protection&lt;/p&gt;

&lt;p&gt;The frontend makes the system look simple.&lt;/p&gt;

&lt;p&gt;Underneath it, the protocol has to coordinate pricing, liquidity, authorization, execution, settlement, and off-chain data.&lt;/p&gt;

&lt;p&gt;That is why DEX development is less about building a “swap page” and more about designing a reliable financial system around blockchain constraints.&lt;/p&gt;

&lt;p&gt;The most important architectural question is not:&lt;/p&gt;

&lt;p&gt;“How do we build a token swap?”&lt;/p&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;p&gt;“Which parts of the trading system need to be trustless, which parts can remain off-chain, and how do we keep the two consistent?”&lt;/p&gt;

&lt;p&gt;That decision shapes almost every other engineering choice.&lt;/p&gt;

&lt;p&gt;For a broader overview of DEX architecture, trading models, development stages, and the infrastructure involved, see &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/blockchain/dex-development/" rel="noopener noreferrer"&gt;SotaTek's DEX Development guide&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>smartcontract</category>
      <category>ethereum</category>
    </item>
    <item>
      <title>Building an Enterprise AI Chatbot: What the Architecture Actually Looks Like</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Thu, 24 Sep 2026 08:35:12 +0000</pubDate>
      <link>https://dev.to/devsotatek/building-an-enterprise-ai-chatbot-what-the-architecture-actually-looks-like-3a14</link>
      <guid>https://dev.to/devsotatek/building-an-enterprise-ai-chatbot-what-the-architecture-actually-looks-like-3a14</guid>
      <description>&lt;p&gt;An enterprise AI chatbot is easy to demo.&lt;/p&gt;

&lt;p&gt;Connect an LLM to a chat interface, add a system prompt, upload a few documents, and you have something that looks impressive in an afternoon.&lt;/p&gt;

&lt;p&gt;Production is different.&lt;/p&gt;

&lt;p&gt;The moment a chatbot needs to access private company data, respect user permissions, retrieve current information, call internal APIs, and operate reliably at scale, it stops being a simple LLM application.&lt;/p&gt;

&lt;p&gt;It becomes a distributed system.&lt;/p&gt;

&lt;p&gt;A practical architecture usually looks something like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                     User
                       │
                       ▼
                Chat Interface
                       │
                       ▼
                API / Gateway
                       │
                       ▼
             AI Orchestration Layer
                /      |       \
               /       |        \
              ▼        ▼         ▼
           RAG      Tools      Policies
            │         │           │
            ▼         ▼           ▼
      Knowledge DB  CRM/ERP   Access Control
            │         │
            └────┬────┘
                 ▼
                LLM
                 │
                 ▼
          Response / Action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The LLM is only one component.&lt;/p&gt;

&lt;p&gt;The LLM Should Not Be Your Application Backend&lt;/p&gt;

&lt;p&gt;A common first architecture looks like this:&lt;/p&gt;

&lt;p&gt;User → LLM → Response&lt;/p&gt;

&lt;p&gt;That works for general questions.&lt;/p&gt;

&lt;p&gt;It breaks down as soon as the user asks:&lt;/p&gt;

&lt;p&gt;“What is the status of my latest support ticket?”&lt;/p&gt;

&lt;p&gt;The model does not inherently know the answer.&lt;/p&gt;

&lt;p&gt;The application needs to:&lt;/p&gt;

&lt;p&gt;Authenticate the user.&lt;br&gt;
Determine what data the user is allowed to access.&lt;br&gt;
Retrieve the relevant ticket.&lt;br&gt;
Provide that context to the model.&lt;br&gt;
Generate a response.&lt;br&gt;
Return the result without exposing unauthorized data.&lt;/p&gt;

&lt;p&gt;The architecture becomes:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Authentication&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Authorization&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Application Backend&lt;br&gt;
 │&lt;br&gt;
 ├── CRM / Ticketing API&lt;br&gt;
 ├── Knowledge Base&lt;br&gt;
 └── AI Orchestrator&lt;br&gt;
          │&lt;br&gt;
          ▼&lt;br&gt;
         LLM&lt;/p&gt;

&lt;p&gt;This distinction is important:&lt;/p&gt;

&lt;p&gt;The LLM generates language. The application owns the business rules.&lt;/p&gt;

&lt;p&gt;Do not put authorization logic into a prompt and expect the model to enforce it.&lt;/p&gt;

&lt;p&gt;RAG Is a Retrieval System First&lt;/p&gt;

&lt;p&gt;Enterprise chatbots frequently use Retrieval-Augmented Generation (RAG) to answer questions from internal knowledge.&lt;/p&gt;

&lt;p&gt;A simplified pipeline is:&lt;/p&gt;

&lt;p&gt;Documents&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Ingestion&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Chunking&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Embeddings&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Vector Database&lt;/p&gt;

&lt;p&gt;At query time:&lt;/p&gt;

&lt;p&gt;User Query&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Embedding&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Retriever&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Relevant Documents&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Prompt + Context&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
LLM&lt;br&gt;
    │&lt;br&gt;
    ▼&lt;br&gt;
Answer&lt;/p&gt;

&lt;p&gt;The important engineering point is that RAG quality depends heavily on the retrieval layer.&lt;/p&gt;

&lt;p&gt;If the wrong documents are retrieved, a more capable model does not automatically fix the problem.&lt;/p&gt;

&lt;p&gt;That means production RAG needs to consider:&lt;/p&gt;

&lt;p&gt;Chunking strategy&lt;br&gt;
Metadata&lt;br&gt;
Embedding model&lt;br&gt;
Retrieval strategy&lt;br&gt;
Top-K selection&lt;br&gt;
Filtering&lt;br&gt;
Document freshness&lt;br&gt;
Source citations&lt;br&gt;
Access permissions&lt;/p&gt;

&lt;p&gt;A vector database is therefore not just a storage component. It is part of the answer-quality pipeline.&lt;/p&gt;

&lt;p&gt;Authorization Must Happen Before Retrieval&lt;/p&gt;

&lt;p&gt;This is one of the easiest mistakes to make in an enterprise RAG system.&lt;/p&gt;

&lt;p&gt;Imagine a company has documents belonging to:&lt;/p&gt;

&lt;p&gt;Finance&lt;br&gt;
HR&lt;br&gt;
Engineering&lt;br&gt;
Sales&lt;/p&gt;

&lt;p&gt;A user from Sales asks:&lt;/p&gt;

&lt;p&gt;“Show me the latest compensation policy.”&lt;/p&gt;

&lt;p&gt;If the retriever searches the entire vector database first and applies permissions afterward, sensitive HR content may already have entered the model context.&lt;/p&gt;

&lt;p&gt;The safer flow is:&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Identity&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Permissions&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Filtered Retrieval&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
Authorized Documents&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
LLM&lt;/p&gt;

&lt;p&gt;Access control should be part of retrieval itself.&lt;/p&gt;

&lt;p&gt;For multi-tenant systems, this becomes even more important:&lt;/p&gt;

&lt;p&gt;tenant_id = customer_123&lt;br&gt;
user_role = manager&lt;br&gt;
department = sales&lt;/p&gt;

&lt;p&gt;These attributes should influence what the retrieval layer is allowed to return.&lt;/p&gt;

&lt;p&gt;The model should never be responsible for deciding whether a user is authorized to see a document.&lt;/p&gt;

&lt;p&gt;When RAG Is Not Enough&lt;/p&gt;

&lt;p&gt;RAG works well when the chatbot needs to answer questions from relatively stable knowledge.&lt;/p&gt;

&lt;p&gt;But consider:&lt;/p&gt;

&lt;p&gt;“Create a support ticket for this issue.”&lt;/p&gt;

&lt;p&gt;Retrieving documentation does not solve that problem.&lt;/p&gt;

&lt;p&gt;The system needs to perform an action.&lt;/p&gt;

&lt;p&gt;This is where tool calling or agentic workflows become useful.&lt;/p&gt;

&lt;p&gt;User&lt;br&gt;
 │&lt;br&gt;
 ▼&lt;br&gt;
LLM&lt;br&gt;
 │&lt;br&gt;
 ├── Search knowledge&lt;br&gt;
 ├── Get customer&lt;br&gt;
 ├── Create ticket&lt;br&gt;
 └── Check ticket status&lt;/p&gt;

&lt;p&gt;The LLM decides which tool is relevant, but the tools themselves should expose controlled interfaces.&lt;/p&gt;

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

&lt;p&gt;create_ticket(&lt;br&gt;
    customer_id,&lt;br&gt;
    category,&lt;br&gt;
    description&lt;br&gt;
)&lt;/p&gt;

&lt;p&gt;The model should not receive unrestricted database access.&lt;/p&gt;

&lt;p&gt;Give it narrowly scoped capabilities.&lt;/p&gt;

&lt;p&gt;This creates a useful principle:&lt;/p&gt;

&lt;p&gt;Give the model tools, not infrastructure access.&lt;/p&gt;

&lt;p&gt;Chatbot vs Agent&lt;/p&gt;

&lt;p&gt;There is a meaningful architectural difference between answering and acting.&lt;/p&gt;

&lt;p&gt;A traditional enterprise chatbot:&lt;/p&gt;

&lt;p&gt;Question&lt;br&gt;
   ↓&lt;br&gt;
Retrieve&lt;br&gt;
   ↓&lt;br&gt;
Generate&lt;br&gt;
   ↓&lt;br&gt;
Answer&lt;/p&gt;

&lt;p&gt;An agentic workflow:&lt;/p&gt;

&lt;p&gt;Goal&lt;br&gt;
 ↓&lt;br&gt;
Plan&lt;br&gt;
 ↓&lt;br&gt;
Tool&lt;br&gt;
 ↓&lt;br&gt;
Observe&lt;br&gt;
 ↓&lt;br&gt;
Tool&lt;br&gt;
 ↓&lt;br&gt;
Observe&lt;br&gt;
 ↓&lt;br&gt;
Final Result&lt;/p&gt;

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

&lt;p&gt;“Find the customer's last three orders, identify the delayed one, and open a support ticket.”&lt;/p&gt;

&lt;p&gt;The system may need to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Query CRM&lt;/li&gt;
&lt;li&gt;Query order service&lt;/li&gt;
&lt;li&gt;Compare delivery status&lt;/li&gt;
&lt;li&gt;Generate ticket content&lt;/li&gt;
&lt;li&gt;Create ticket&lt;/li&gt;
&lt;li&gt;Return confirmation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That is no longer just a chatbot.&lt;/p&gt;

&lt;p&gt;It is an orchestration system with an LLM as one of its decision-making components.&lt;/p&gt;

&lt;p&gt;Keep the Tool Layer Deterministic&lt;/p&gt;

&lt;p&gt;One of the most useful design principles for agentic systems is to keep tool execution deterministic.&lt;/p&gt;

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

&lt;p&gt;LLM&lt;br&gt;
 │&lt;br&gt;
 │ create_ticket(...)&lt;br&gt;
 ▼&lt;br&gt;
Tool Gateway&lt;br&gt;
 │&lt;br&gt;
 ├── Validate parameters&lt;br&gt;
 ├── Check authorization&lt;br&gt;
 ├── Apply business rules&lt;br&gt;
 ├── Execute API call&lt;br&gt;
 └── Return structured result&lt;/p&gt;

&lt;p&gt;Do not let the model directly execute arbitrary SQL or arbitrary HTTP requests.&lt;/p&gt;

&lt;p&gt;Instead, expose explicit capabilities:&lt;/p&gt;

&lt;p&gt;get_customer()&lt;br&gt;
get_order()&lt;br&gt;
search_policy()&lt;br&gt;
create_ticket()&lt;br&gt;
update_ticket()&lt;/p&gt;

&lt;p&gt;This makes the system easier to secure, test, monitor, and audit.&lt;/p&gt;

&lt;p&gt;Enterprise Data Is Usually the Hard Part&lt;/p&gt;

&lt;p&gt;The LLM is often the easiest component to replace.&lt;/p&gt;

&lt;p&gt;Enterprise data is not.&lt;/p&gt;

&lt;p&gt;A real deployment may need to connect:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             AI Application
                   │
   ┌───────────────┼────────────────┐
   ▼               ▼                ▼
  CRM             ERP           Knowledge Base
   │               │                │
   ▼               ▼                ▼
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Customer Data   Transactions      Documents&lt;/p&gt;

&lt;p&gt;These systems often have different:&lt;/p&gt;

&lt;p&gt;APIs&lt;br&gt;
Authentication models&lt;br&gt;
Data formats&lt;br&gt;
Update frequencies&lt;br&gt;
Failure modes&lt;br&gt;
Rate limits&lt;/p&gt;

&lt;p&gt;The AI layer therefore needs an integration boundary rather than a collection of ad-hoc API calls buried inside prompts.&lt;/p&gt;

&lt;p&gt;Observability Is Part of the Architecture&lt;/p&gt;

&lt;p&gt;A production chatbot should not only log:&lt;/p&gt;

&lt;p&gt;user → response&lt;/p&gt;

&lt;p&gt;You need to understand how the response was produced.&lt;/p&gt;

&lt;p&gt;A useful trace might contain:&lt;/p&gt;

&lt;p&gt;Request ID&lt;br&gt;
User ID&lt;br&gt;
Model&lt;br&gt;
Prompt version&lt;br&gt;
Retrieved documents&lt;br&gt;
Tool calls&lt;br&gt;
Latency&lt;br&gt;
Token usage&lt;br&gt;
Errors&lt;br&gt;
Final response&lt;/p&gt;

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

&lt;p&gt;Request&lt;br&gt;
 │&lt;br&gt;
 ├── Retrieval: 180 ms&lt;br&gt;
 ├── CRM API: 240 ms&lt;br&gt;
 ├── LLM: 1.8 s&lt;br&gt;
 ├── Tokens: 2,431&lt;br&gt;
 └── Total: 2.3 s&lt;/p&gt;

&lt;p&gt;Without this information, debugging a bad answer becomes guesswork.&lt;/p&gt;

&lt;p&gt;Observability also gives you the data needed to optimize cost and latency.&lt;/p&gt;

&lt;p&gt;Evaluation Should Test the System, Not Just the Model&lt;/p&gt;

&lt;p&gt;A model benchmark is not enough to determine whether an enterprise chatbot works.&lt;/p&gt;

&lt;p&gt;You need to evaluate the complete pipeline:&lt;/p&gt;

&lt;p&gt;Question&lt;br&gt;
   ↓&lt;br&gt;
Retrieval&lt;br&gt;
   ↓&lt;br&gt;
Context&lt;br&gt;
   ↓&lt;br&gt;
Model&lt;br&gt;
   ↓&lt;br&gt;
Tool Calls&lt;br&gt;
   ↓&lt;br&gt;
Response&lt;/p&gt;

&lt;p&gt;Useful metrics include:&lt;/p&gt;

&lt;p&gt;Retrieval relevance&lt;br&gt;
Answer correctness&lt;br&gt;
Citation accuracy&lt;br&gt;
Hallucination rate&lt;br&gt;
Tool-call accuracy&lt;br&gt;
Task completion rate&lt;br&gt;
Latency&lt;br&gt;
Cost per request&lt;br&gt;
Human escalation rate&lt;/p&gt;

&lt;p&gt;A model can produce an excellent answer from the wrong document.&lt;/p&gt;

&lt;p&gt;That is still a system failure.&lt;/p&gt;

&lt;p&gt;A Production-Oriented Architecture&lt;/p&gt;

&lt;p&gt;Putting the pieces together:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                     User
                       │
                       ▼
                ┌─────────────┐
                │ API Gateway │
                └──────┬──────┘
                       │
                Authentication
                       │
                       ▼
              ┌─────────────────┐
              │ AI Orchestrator │
              └───────┬─────────┘
                      /|\
                     / | \
                    /  |  \
                   ▼   ▼   ▼
                 RAG Tools Policy
                  │    │     │
                  ▼    ▼     ▼
               Vector CRM   AuthZ
               Store  ERP
                  │    │
                  └────┬┘
                       ▼
                      LLM
                       │
                       ▼
                Validation Layer
                       │
                       ▼
                    Response
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Around the entire system, you also need:&lt;/p&gt;

&lt;p&gt;Observability&lt;br&gt;
Evaluation&lt;br&gt;
Audit Logging&lt;br&gt;
Rate Limiting&lt;br&gt;
Secrets Management&lt;br&gt;
Cost Controls&lt;/p&gt;

&lt;p&gt;These are not optional production extras.&lt;/p&gt;

&lt;p&gt;They are part of the system.&lt;/p&gt;

&lt;p&gt;The Real Architecture Decision&lt;/p&gt;

&lt;p&gt;The interesting question is not:&lt;/p&gt;

&lt;p&gt;“Which LLM should we use?”&lt;/p&gt;

&lt;p&gt;Models change quickly.&lt;/p&gt;

&lt;p&gt;The more durable engineering decisions are:&lt;/p&gt;

&lt;p&gt;Where does enterprise knowledge live?&lt;br&gt;
How is it retrieved?&lt;br&gt;
Where is authorization enforced?&lt;br&gt;
Which actions can the model perform?&lt;br&gt;
How are tool calls validated?&lt;br&gt;
How do we handle failures?&lt;br&gt;
How do we evaluate output quality?&lt;br&gt;
How do we observe the complete request lifecycle?&lt;/p&gt;

&lt;p&gt;Once these boundaries are clear, the underlying model becomes a replaceable component rather than the foundation of the entire architecture.&lt;/p&gt;

&lt;p&gt;Final Takeaway&lt;/p&gt;

&lt;p&gt;An enterprise AI chatbot is not an LLM with a chat UI.&lt;/p&gt;

&lt;p&gt;It is an application architecture that combines:&lt;/p&gt;

&lt;p&gt;LLM&lt;br&gt;
+&lt;br&gt;
RAG&lt;br&gt;
+&lt;br&gt;
Enterprise APIs&lt;br&gt;
+&lt;br&gt;
Access Control&lt;br&gt;
+&lt;br&gt;
Tool Calling&lt;br&gt;
+&lt;br&gt;
Observability&lt;br&gt;
+&lt;br&gt;
Evaluation&lt;/p&gt;

&lt;p&gt;The LLM provides the language interface.&lt;/p&gt;

&lt;p&gt;The surrounding system provides data, permissions, actions, and reliability.&lt;/p&gt;

&lt;p&gt;That is the difference between a chatbot that looks impressive in a demo and one that can actually operate inside an enterprise environment.&lt;/p&gt;

&lt;p&gt;If you're looking at the broader implementation lifecycle, including data preparation, architecture selection, enterprise integration, security, and deployment, this &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/ai-and-machine-learning/enterprise-ai-chatbots/" rel="noopener noreferrer"&gt;enterprise AI chatbot implementation guide&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; provides additional context.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>llm</category>
      <category>softwareengineering</category>
      <category>architecture</category>
    </item>
    <item>
      <title>What Actually Happens When You Put an NFT Into a Game?</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Thu, 24 Sep 2026 08:25:43 +0000</pubDate>
      <link>https://dev.to/devsotatek/what-actually-happens-when-you-put-an-nft-into-a-game-hhb</link>
      <guid>https://dev.to/devsotatek/what-actually-happens-when-you-put-an-nft-into-a-game-hhb</guid>
      <description>&lt;p&gt;Putting an NFT into a game sounds simple:&lt;/p&gt;

&lt;p&gt;Mint an NFT, connect a wallet, and let players trade it.&lt;/p&gt;

&lt;p&gt;That is the easy part.&lt;/p&gt;

&lt;p&gt;The difficult part is deciding what belongs on-chain, what stays off-chain, and how the two systems communicate without turning every gameplay action into a blockchain transaction.&lt;/p&gt;

&lt;p&gt;A production NFT game is not a traditional game with a smart contract attached to it. It is a distributed system with two very different execution environments:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                NFT GAME
                   │
         ┌─────────┴─────────┐
         │                   │
     OFF-CHAIN             ON-CHAIN
         │                   │
    Game Engine         Smart Contracts
    Game Server         NFT Ownership
    Database            Token Balances
    Matchmaking         Asset Transfers
    Gameplay            Marketplace
         │                   │
         └─────────┬─────────┘
                   │
              Wallet / RPC
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Once you look at it this way, many of the architecture decisions become much easier to reason about.&lt;/p&gt;

&lt;p&gt;The Game Should Not Run on the Blockchain&lt;/p&gt;

&lt;p&gt;The first mistake is trying to put gameplay logic on-chain.&lt;/p&gt;

&lt;p&gt;Imagine a multiplayer game where every movement generates a blockchain transaction:&lt;/p&gt;

&lt;p&gt;Player moves&lt;br&gt;
    ↓&lt;br&gt;
Transaction&lt;br&gt;
    ↓&lt;br&gt;
Validator&lt;br&gt;
    ↓&lt;br&gt;
State update&lt;br&gt;
    ↓&lt;br&gt;
Game server&lt;br&gt;
    ↓&lt;br&gt;
Other players&lt;/p&gt;

&lt;p&gt;It would be slow, expensive, and completely unnecessary.&lt;/p&gt;

&lt;p&gt;The blockchain is good at things that need shared, verifiable state.&lt;/p&gt;

&lt;p&gt;A game engine is good at things that need fast, mutable state.&lt;/p&gt;

&lt;p&gt;So the architecture should usually look more like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Game Client
                      │
          ┌───────────┴───────────┐
          │                       │
          ▼                       ▼
    Game Backend              Wallet
          │                       │
          ▼                       ▼
    Game Database            Blockchain
          │                       │
          │                ┌──────┴──────┐
          │                │             │
          │             NFT Contract  Token Contract
          │
          └─────── Asset State ──────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The game server handles gameplay.&lt;/p&gt;

&lt;p&gt;The blockchain handles ownership and other state that needs to be independently verifiable.&lt;/p&gt;

&lt;p&gt;That boundary is probably the most important architectural decision in an NFT game.&lt;/p&gt;

&lt;p&gt;What Actually Goes On-Chain?&lt;/p&gt;

&lt;p&gt;A useful rule is:&lt;/p&gt;

&lt;p&gt;Put the minimum amount of state on-chain that needs blockchain-level ownership, verification, or settlement.&lt;/p&gt;

&lt;p&gt;For an NFT game, that might include:&lt;/p&gt;

&lt;p&gt;Token ownership&lt;br&gt;
NFT ID&lt;br&gt;
Token metadata reference&lt;br&gt;
Supply constraints&lt;br&gt;
Transfer rules&lt;br&gt;
Marketplace transactions&lt;br&gt;
Royalty logic&lt;br&gt;
In-game token balances&lt;/p&gt;

&lt;p&gt;It usually should not include:&lt;/p&gt;

&lt;p&gt;Player coordinates&lt;br&gt;
Animation state&lt;br&gt;
Matchmaking&lt;br&gt;
Real-time combat&lt;br&gt;
Chat&lt;br&gt;
Temporary game state&lt;br&gt;
Every player interaction&lt;/p&gt;

&lt;p&gt;For example, a sword might exist as an NFT:&lt;/p&gt;

&lt;p&gt;NFT #1842&lt;br&gt;
    │&lt;br&gt;
    ├── Owner: 0xA91...&lt;br&gt;
    ├── Token URI&lt;br&gt;
    ├── Rarity&lt;br&gt;
    └── Asset ID&lt;/p&gt;

&lt;p&gt;But the fact that the player currently has that sword equipped belongs in the game layer.&lt;/p&gt;

&lt;p&gt;This gives you two states:&lt;/p&gt;

&lt;p&gt;Blockchain:&lt;br&gt;
"Wallet X owns Sword #1842"&lt;/p&gt;

&lt;p&gt;Game server:&lt;br&gt;
"Player 928 has Sword #1842 equipped"&lt;/p&gt;

&lt;p&gt;The second state can change thousands of times without touching the blockchain.&lt;/p&gt;

&lt;p&gt;The Smart Contract Is the Ownership Layer&lt;/p&gt;

&lt;p&gt;The smart contract should be treated as the authoritative source for blockchain ownership.&lt;/p&gt;

&lt;p&gt;A simplified NFT contract might look like:&lt;/p&gt;

&lt;p&gt;contract GameItem is ERC721 {&lt;br&gt;
    uint256 private nextTokenId;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function mint(address player)
    external
    returns (uint256)
{
    uint256 tokenId = nextTokenId++;
    _safeMint(player, tokenId);
    return tokenId;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;The important part is not the exact implementation.&lt;/p&gt;

&lt;p&gt;It is the responsibility boundary.&lt;/p&gt;

&lt;p&gt;The contract answers:&lt;/p&gt;

&lt;p&gt;Who owns this asset?&lt;br&gt;
Can it be transferred?&lt;br&gt;
Can it be minted?&lt;br&gt;
How many can exist?&lt;br&gt;
What rules apply to the transfer?&lt;/p&gt;

&lt;p&gt;The game server should not maintain a second independent truth about ownership.&lt;/p&gt;

&lt;p&gt;If the database says:&lt;/p&gt;

&lt;p&gt;Player A → Sword #1842&lt;/p&gt;

&lt;p&gt;but the blockchain says:&lt;/p&gt;

&lt;p&gt;Player B → Sword #1842&lt;/p&gt;

&lt;p&gt;the system has a consistency problem.&lt;/p&gt;

&lt;p&gt;For ownership, the blockchain should win.&lt;/p&gt;

&lt;p&gt;What Happens When a Player Buys an NFT?&lt;/p&gt;

&lt;p&gt;This is where the distributed architecture becomes interesting.&lt;/p&gt;

&lt;p&gt;Suppose Player A buys an NFT from Player B.&lt;/p&gt;

&lt;p&gt;A simplified flow is:&lt;/p&gt;

&lt;p&gt;Player A&lt;br&gt;
   │&lt;br&gt;
   │ purchase&lt;br&gt;
   ▼&lt;br&gt;
Marketplace&lt;br&gt;
   │&lt;br&gt;
   │ transaction&lt;br&gt;
   ▼&lt;br&gt;
Blockchain&lt;br&gt;
   │&lt;br&gt;
   ├── transfer NFT&lt;br&gt;
   ├── transfer payment&lt;br&gt;
   └── emit event&lt;br&gt;
           │&lt;br&gt;
           ▼&lt;br&gt;
        Indexer&lt;br&gt;
           │&lt;br&gt;
           ▼&lt;br&gt;
      Game Backend&lt;br&gt;
           │&lt;br&gt;
           ▼&lt;br&gt;
       Game Client&lt;/p&gt;

&lt;p&gt;The blockchain transaction changes ownership.&lt;/p&gt;

&lt;p&gt;The game backend then observes that change and updates its local representation.&lt;/p&gt;

&lt;p&gt;This introduces an important concept:&lt;/p&gt;

&lt;p&gt;Blockchain state and application state are eventually synchronized, not necessarily updated at exactly the same time.&lt;/p&gt;

&lt;p&gt;That means the backend must handle:&lt;/p&gt;

&lt;p&gt;Pending transactions&lt;br&gt;
Failed transactions&lt;br&gt;
Reorganizations&lt;br&gt;
Duplicate events&lt;br&gt;
Delayed confirmations&lt;br&gt;
RPC failures&lt;/p&gt;

&lt;p&gt;A production integration cannot simply assume:&lt;/p&gt;

&lt;p&gt;sendTransaction()&lt;br&gt;
    ↓&lt;br&gt;
success = true&lt;br&gt;
    ↓&lt;br&gt;
updateDatabase()&lt;/p&gt;

&lt;p&gt;The transaction lifecycle is asynchronous.&lt;/p&gt;

&lt;p&gt;Events Are the Bridge&lt;/p&gt;

&lt;p&gt;Smart contract events are useful for synchronizing blockchain activity with the game backend.&lt;/p&gt;

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

&lt;p&gt;event ItemTransferred(&lt;br&gt;
    address indexed from,&lt;br&gt;
    address indexed to,&lt;br&gt;
    uint256 indexed tokenId&lt;br&gt;
);&lt;/p&gt;

&lt;p&gt;The backend can subscribe to blockchain events and update its internal state.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;Smart Contract&lt;br&gt;
      │&lt;br&gt;
      │ ItemTransferred&lt;br&gt;
      ▼&lt;br&gt;
Blockchain Node / RPC&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Event Listener&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Game Database&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Game API&lt;/p&gt;

&lt;p&gt;This is much more scalable than having the game client repeatedly query the blockchain for every piece of state.&lt;/p&gt;

&lt;p&gt;Wallets Are Not Just Login Buttons&lt;/p&gt;

&lt;p&gt;Wallet integration is another place where traditional game architecture changes.&lt;/p&gt;

&lt;p&gt;A wallet provides an address and, more importantly, control over the private key associated with that address.&lt;/p&gt;

&lt;p&gt;The game might therefore use:&lt;/p&gt;

&lt;p&gt;Game Account&lt;br&gt;
     │&lt;br&gt;
     ├── player profile&lt;br&gt;
     ├── progression&lt;br&gt;
     ├── preferences&lt;br&gt;
     └── wallet address&lt;/p&gt;

&lt;p&gt;The wallet address identifies the blockchain account, but it should not automatically become the entire identity system of the game.&lt;/p&gt;

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

&lt;p&gt;Player ID: 92814&lt;br&gt;
Wallet: 0xA91...&lt;/p&gt;

&lt;p&gt;The backend can associate the two after a secure wallet-signature authentication flow.&lt;/p&gt;

&lt;p&gt;This allows the game to maintain normal application functionality while using the wallet for blockchain ownership.&lt;/p&gt;

&lt;p&gt;NFT Metadata Is Another Distributed-System Problem&lt;/p&gt;

&lt;p&gt;The NFT itself may only contain a reference to metadata rather than storing every attribute directly on-chain.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;/p&gt;

&lt;p&gt;NFT&lt;br&gt;
 │&lt;br&gt;
 └── tokenURI&lt;br&gt;
       │&lt;br&gt;
       ▼&lt;br&gt;
    Metadata&lt;br&gt;
       │&lt;br&gt;
       ├── name&lt;br&gt;
       ├── image&lt;br&gt;
       ├── attributes&lt;br&gt;
       └── game asset reference&lt;/p&gt;

&lt;p&gt;That creates another architectural question:&lt;/p&gt;

&lt;p&gt;What happens if the metadata disappears or changes?&lt;/p&gt;

&lt;p&gt;If the game depends on a centralized URL, the NFT may technically exist on-chain while the actual asset becomes unavailable.&lt;/p&gt;

&lt;p&gt;For long-lived assets, the storage strategy therefore matters almost as much as the smart contract itself.&lt;/p&gt;

&lt;p&gt;The blockchain can prove ownership.&lt;/p&gt;

&lt;p&gt;It does not automatically guarantee that every piece of off-chain data associated with that ownership will remain available forever.&lt;/p&gt;

&lt;p&gt;The Game Engine Is Still the Game Engine&lt;/p&gt;

&lt;p&gt;Unity or Unreal Engine remains responsible for what it has always been good at:&lt;/p&gt;

&lt;p&gt;Input&lt;br&gt;
  ↓&lt;br&gt;
Gameplay Logic&lt;br&gt;
  ↓&lt;br&gt;
Rendering&lt;br&gt;
  ↓&lt;br&gt;
Physics&lt;br&gt;
  ↓&lt;br&gt;
Audio&lt;br&gt;
  ↓&lt;br&gt;
Networking&lt;/p&gt;

&lt;p&gt;Blockchain integration becomes another service boundary.&lt;/p&gt;

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

&lt;p&gt;Unity / Unreal&lt;br&gt;
      │&lt;br&gt;
      ▼&lt;br&gt;
Blockchain SDK / Backend API&lt;br&gt;
      │&lt;br&gt;
      ├── Wallet&lt;br&gt;
      ├── NFT data&lt;br&gt;
      ├── Marketplace&lt;br&gt;
      └── Smart contract calls&lt;/p&gt;

&lt;p&gt;This separation is important.&lt;/p&gt;

&lt;p&gt;You do not want blockchain-specific logic spread across hundreds of gameplay components.&lt;/p&gt;

&lt;p&gt;Keep wallet operations, contract interactions, transaction state, and blockchain synchronization behind well-defined interfaces.&lt;/p&gt;

&lt;p&gt;The Real Challenge Is Consistency&lt;/p&gt;

&lt;p&gt;Once you have two state machines, consistency becomes the hard problem.&lt;/p&gt;

&lt;p&gt;Consider this sequence:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Player buys NFT&lt;/li&gt;
&lt;li&gt;Transaction submitted&lt;/li&gt;
&lt;li&gt;Transaction pending&lt;/li&gt;
&lt;li&gt;Game server receives request&lt;/li&gt;
&lt;li&gt;Player closes the game&lt;/li&gt;
&lt;li&gt;Transaction confirms&lt;/li&gt;
&lt;li&gt;Backend misses the event&lt;/li&gt;
&lt;li&gt;Player logs in again&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;What does the game show?&lt;/p&gt;

&lt;p&gt;This is no longer simply a smart-contract problem.&lt;/p&gt;

&lt;p&gt;It is a distributed-systems problem.&lt;/p&gt;

&lt;p&gt;You need mechanisms for:&lt;/p&gt;

&lt;p&gt;Event replay&lt;br&gt;
Idempotent processing&lt;br&gt;
Transaction status tracking&lt;br&gt;
Confirmation handling&lt;br&gt;
Reconciliation&lt;br&gt;
Retry logic&lt;br&gt;
RPC failover&lt;/p&gt;

&lt;p&gt;A useful backend design is:&lt;/p&gt;

&lt;p&gt;Blockchain&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
Event Listener&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
Message Queue&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
Indexer&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
Game Database&lt;br&gt;
     │&lt;br&gt;
     ▼&lt;br&gt;
Game API&lt;/p&gt;

&lt;p&gt;The indexer becomes the bridge between blockchain state and application state.&lt;/p&gt;

&lt;p&gt;Where the Economy Lives&lt;/p&gt;

&lt;p&gt;NFT games often add another layer: fungible tokens.&lt;/p&gt;

&lt;p&gt;You may have:&lt;/p&gt;

&lt;p&gt;NFT&lt;br&gt;
 ├── Characters&lt;br&gt;
 ├── Weapons&lt;br&gt;
 ├── Skins&lt;br&gt;
 └── Land&lt;/p&gt;

&lt;p&gt;Token&lt;br&gt;
 ├── Rewards&lt;br&gt;
 ├── Purchases&lt;br&gt;
 └── Marketplace payments&lt;/p&gt;

&lt;p&gt;This is where tokenomics becomes an engineering concern.&lt;/p&gt;

&lt;p&gt;A reward mechanism that continuously creates tokens without corresponding demand can create an economic problem even if the smart contract is perfectly secure.&lt;/p&gt;

&lt;p&gt;The technical architecture therefore has to support the economic model rather than treating tokenomics as a separate document.&lt;/p&gt;

&lt;p&gt;Security Changes Everything&lt;/p&gt;

&lt;p&gt;Traditional game security focuses heavily on the client and server.&lt;/p&gt;

&lt;p&gt;Blockchain games add another security boundary:&lt;/p&gt;

&lt;p&gt;Client&lt;br&gt;
  ↓&lt;br&gt;
Backend&lt;br&gt;
  ↓&lt;br&gt;
Smart Contract&lt;br&gt;
  ↓&lt;br&gt;
Blockchain&lt;/p&gt;

&lt;p&gt;A vulnerability in a deployed contract can be fundamentally different from a server-side bug.&lt;/p&gt;

&lt;p&gt;You cannot simply deploy a patch and assume the old state disappears.&lt;/p&gt;

&lt;p&gt;Smart contracts handling NFTs, tokens, marketplace transactions, and royalties should therefore be treated as security-critical infrastructure.&lt;/p&gt;

&lt;p&gt;At minimum, review:&lt;/p&gt;

&lt;p&gt;Access control&lt;br&gt;
Mint authorization&lt;br&gt;
Transfer restrictions&lt;br&gt;
Reentrancy&lt;br&gt;
Integer handling&lt;br&gt;
Signature validation&lt;br&gt;
Replay protection&lt;br&gt;
Upgradeability assumptions&lt;br&gt;
Economic attack vectors&lt;/p&gt;

&lt;p&gt;The blockchain layer should be audited independently from the game client.&lt;/p&gt;

&lt;p&gt;The Architecture I Would Start With&lt;/p&gt;

&lt;p&gt;For a typical NFT game, a reasonable starting architecture is:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 ┌───────────────┐
                 │ Game Client   │
                 │ Unity/Unreal  │
                 └───────┬───────┘
                         │
                         ▼
                 ┌───────────────┐
                 │ Game Backend  │
                 └───────┬───────┘
                         │
           ┌─────────────┼─────────────┐
           ▼             ▼             ▼
      Game DB       Blockchain API   Marketplace
                         │
                         ▼
                     RPC Node
                         │
                         ▼
                 ┌───────────────┐
                 │ Smart Contract│
                 ├───────────────┤
                 │ NFT           │
                 │ Token         │
                 │ Marketplace   │
                 └───────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The important thing is not the number of components.&lt;/p&gt;

&lt;p&gt;It is the ownership of responsibilities.&lt;/p&gt;

&lt;p&gt;Game server  → gameplay state&lt;br&gt;
Database     → application state&lt;br&gt;
Blockchain   → verifiable ownership and settlement&lt;br&gt;
Smart contract → enforceable on-chain rules&lt;br&gt;
Wallet       → player-controlled blockchain identity&lt;br&gt;
Indexer      → synchronization&lt;/p&gt;

&lt;p&gt;Once those boundaries are explicit, the system becomes much easier to scale and debug.&lt;/p&gt;

&lt;p&gt;The Main Takeaway&lt;/p&gt;

&lt;p&gt;An NFT game is not a game that happens to use NFTs.&lt;/p&gt;

&lt;p&gt;It is a system where gameplay, blockchain state, wallets, smart contracts, and off-chain infrastructure have to agree on what is true.&lt;/p&gt;

&lt;p&gt;The most important architectural decision is therefore not which blockchain to choose.&lt;/p&gt;

&lt;p&gt;It is deciding:&lt;/p&gt;

&lt;p&gt;What needs to be trustless, and what doesn't?&lt;/p&gt;

&lt;p&gt;Put ownership and settlement where independent verification matters.&lt;/p&gt;

&lt;p&gt;Keep high-frequency gameplay where low latency matters.&lt;/p&gt;

&lt;p&gt;Use the backend and indexer to connect the two worlds.&lt;/p&gt;

&lt;p&gt;That separation keeps the blockchain useful without forcing the entire game to behave like a blockchain.&lt;/p&gt;

&lt;p&gt;And once you understand that boundary, NFT game development starts looking less like “adding Web3 to a game” and more like what it really is:&lt;/p&gt;

&lt;p&gt;designing a distributed system with a game engine on one side and a blockchain on the other.&lt;/p&gt;

&lt;p&gt;If you want to explore the broader NFT game development lifecycle, including asset design, tokenomics, smart contracts, wallet integration, and marketplace architecture, this &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/blockchain/nft-game-development/" rel="noopener noreferrer"&gt;NFT Game Development guide&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; provides the wider context.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>web3</category>
      <category>gamedev</category>
      <category>smartcontract</category>
    </item>
    <item>
      <title>Zero-Knowledge Proofs Without the Magic: What the Prover and Verifier Actually Do</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Mon, 14 Sep 2026 11:18:27 +0000</pubDate>
      <link>https://dev.to/devsotatek/zero-knowledge-proofs-without-the-magic-what-the-prover-and-verifier-actually-do-1533</link>
      <guid>https://dev.to/devsotatek/zero-knowledge-proofs-without-the-magic-what-the-prover-and-verifier-actually-do-1533</guid>
      <description>&lt;h1&gt;
  
  
  Zero-Knowledge Proofs Without the Magic: What the Prover and Verifier Actually Do
&lt;/h1&gt;

&lt;p&gt;Zero-knowledge proofs are often described with a sentence that sounds almost impossible:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Prove that you know something without revealing what you know.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That description is correct, but it hides the part developers actually need to understand.&lt;/p&gt;

&lt;p&gt;A zero-knowledge proof is not encryption. The prover does not simply hide some data and send it to the verifier.&lt;/p&gt;

&lt;p&gt;Instead, the prover constructs a &lt;strong&gt;proof that a computation is valid&lt;/strong&gt;, while revealing only the information that the protocol allows the verifier to see.&lt;/p&gt;

&lt;p&gt;This distinction becomes important when ZK proofs are used in blockchain systems, where computation can be performed privately off-chain and verified cheaply on-chain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start With a Simple Problem
&lt;/h2&gt;

&lt;p&gt;Suppose Alice knows a secret value &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There is a public value derived from it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y = hash(x)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alice wants to prove:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I know a value &lt;code&gt;x&lt;/code&gt; such that &lt;code&gt;hash(x) = y&lt;/code&gt;.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But she does not want to reveal &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A traditional solution would require Alice to reveal the secret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alice
  |
  | x
  v
Verifier
  |
  | hash(x) == y ?
  v
Valid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A zero-knowledge protocol changes the interaction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             secret x
                |
                v
Alice       Prover
                |
                | proof
                v
           Verifier
                |
                v
        "The statement is valid"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The verifier learns that Alice knows a valid &lt;code&gt;x&lt;/code&gt;, but does not learn &lt;code&gt;x&lt;/code&gt; itself.&lt;/p&gt;

&lt;p&gt;The interesting part is how the proof is constructed.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Things You Need to Separate
&lt;/h2&gt;

&lt;p&gt;When working with ZK systems, three concepts are easy to mix together:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. The witness
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;witness&lt;/strong&gt; is the private information known by the prover.&lt;/p&gt;

&lt;p&gt;In our example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;witness = x
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The witness never needs to be exposed to the verifier.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The public inputs
&lt;/h3&gt;

&lt;p&gt;These are values that the verifier is allowed to know.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public input = y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. The statement
&lt;/h3&gt;

&lt;p&gt;The statement defines what must be proven.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hash(x) == y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the prover is effectively proving:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I know x
such that
hash(x) == y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without sending &lt;code&gt;x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That separation between &lt;strong&gt;witness, public inputs, and computation&lt;/strong&gt; is one of the most useful mental models for understanding ZK systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  A ZK Proof Is Really a Proof of Computation
&lt;/h2&gt;

&lt;p&gt;This is where ZK becomes more interesting for blockchain developers.&lt;/p&gt;

&lt;p&gt;Instead of thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I want to hide a value.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I want someone to verify that a computation was executed correctly without giving them all of the computation's private inputs.”&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Private inputs
     |
     v
+-----------+
| Computation|
+-----------+
     |
     v
   Result
     |
     v
   Proof
     |
     v
+-----------+
| Verifier  |
+-----------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The verifier does not need to reproduce the entire computation.&lt;/p&gt;

&lt;p&gt;It only needs to verify the proof.&lt;/p&gt;

&lt;p&gt;This is why ZK proofs are useful for blockchain scaling and privacy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the Blockchain Fits
&lt;/h2&gt;

&lt;p&gt;Blockchains are good at verification, but expensive as general-purpose computation environments.&lt;/p&gt;

&lt;p&gt;Imagine a computation that requires millions of operations.&lt;/p&gt;

&lt;p&gt;Executing all of them directly on-chain can be expensive.&lt;/p&gt;

&lt;p&gt;A ZK-based architecture can move the expensive computation off-chain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Off-chain
              ┌──────────────┐
              │   Prover     │
              │              │
Input ────────&amp;gt;│ Computation  │
              │              │
              │ Generate ZK  │
              │    Proof     │
              └──────┬───────┘
                     │
                     │ proof
                     v
              ┌──────────────┐
              │ Blockchain   │
              │              │
              │   Verifier   │
              └──────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The blockchain does not need to trust the prover.&lt;/p&gt;

&lt;p&gt;It only needs to verify the proof.&lt;/p&gt;

&lt;p&gt;This creates an important engineering trade-off:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Move computation off-chain, but preserve verifiability on-chain.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Is Different From Encryption
&lt;/h2&gt;

&lt;p&gt;A common misunderstanding is that ZK proofs are simply another form of encryption.&lt;/p&gt;

&lt;p&gt;They solve different problems.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;“Only authorized parties should be able to read this data.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Zero-knowledge proof:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“You should be able to verify that this statement is true without learning my private information.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can also combine both techniques in the same system.&lt;/p&gt;

&lt;p&gt;For example, sensitive application data can remain encrypted while a ZK proof demonstrates that the data satisfies a particular condition.&lt;/p&gt;

&lt;h2&gt;
  
  
  From Simple Examples to Real ZK Circuits
&lt;/h2&gt;

&lt;p&gt;Real ZK systems don't usually express the computation as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hash(x) == y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and stop there.&lt;/p&gt;

&lt;p&gt;The computation is represented as a set of constraints.&lt;/p&gt;

&lt;p&gt;Conceptually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x ──&amp;gt; Constraint 1
 │
 ├──&amp;gt; Constraint 2
 │
 └──&amp;gt; Constraint 3
          |
          v
      Valid / Invalid
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The proving system then transforms those constraints into a proof that can be verified without exposing the private witness.&lt;/p&gt;

&lt;p&gt;Depending on the system, this can involve polynomial commitments, elliptic-curve operations, finite fields, and sophisticated proving algorithms.&lt;/p&gt;

&lt;p&gt;You do not need to understand every mathematical detail to build a ZK application.&lt;/p&gt;

&lt;p&gt;But you do need to understand the engineering boundary:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The circuit defines what is provable.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the required business logic cannot be represented correctly in the circuit, the rest of the architecture does not matter.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Cost Is Not Gone. It Has Moved.
&lt;/h2&gt;

&lt;p&gt;This is one of the most important practical considerations.&lt;/p&gt;

&lt;p&gt;ZK systems can reduce the amount of computation that needs to happen on-chain, but generating the proof can itself be computationally expensive.&lt;/p&gt;

&lt;p&gt;A simplified cost model looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                ZK Application
                      |
          +-----------+-----------+
          |                       |
          v                       v
   Proof Generation          Proof Verification
       expensive                 cheaper
      off-chain                  on-chain
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a trade-off between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prover compute&lt;/li&gt;
&lt;li&gt;Proof generation time&lt;/li&gt;
&lt;li&gt;Proof size&lt;/li&gt;
&lt;li&gt;Verification cost&lt;/li&gt;
&lt;li&gt;On-chain gas&lt;/li&gt;
&lt;li&gt;Hardware requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The optimal design depends on the application.&lt;/p&gt;

&lt;p&gt;A system that minimizes gas consumption may require significantly more off-chain computation.&lt;/p&gt;

&lt;p&gt;A system optimized for proof-generation speed may have different hardware or circuit constraints.&lt;/p&gt;

&lt;p&gt;There is no universal “ZK is cheaper” rule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where ZK Proofs Become Useful
&lt;/h2&gt;

&lt;p&gt;The same architecture can support several classes of applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Private identity
&lt;/h3&gt;

&lt;p&gt;A user could prove:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I satisfy eligibility condition X
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without revealing every piece of information used to determine eligibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Private transactions
&lt;/h3&gt;

&lt;p&gt;A system can prove that a transaction satisfies the required rules without exposing all transaction details publicly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scaling
&lt;/h3&gt;

&lt;p&gt;A prover can execute a large amount of computation off-chain and submit a compact proof that the computation was performed correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Verifiable computation
&lt;/h3&gt;

&lt;p&gt;A service can perform computation for a user while providing cryptographic evidence that the result was generated according to a defined computation.&lt;/p&gt;

&lt;p&gt;The common pattern is not simply privacy.&lt;/p&gt;

&lt;p&gt;It is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Compute privately or off-chain → generate proof → verify independently.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Engineering Problems Are Different From Traditional Applications
&lt;/h2&gt;

&lt;p&gt;ZK systems introduce constraints that are easy to underestimate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Circuit complexity
&lt;/h3&gt;

&lt;p&gt;The way you express an algorithm can have a major impact on proving cost.&lt;/p&gt;

&lt;p&gt;An algorithm that is efficient in normal software may be expensive to represent as a ZK circuit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prover performance
&lt;/h3&gt;

&lt;p&gt;Proof generation can require significant CPU, memory, or specialized hardware depending on the proving system and workload.&lt;/p&gt;

&lt;h3&gt;
  
  
  Data availability
&lt;/h3&gt;

&lt;p&gt;In blockchain applications, proving that something is correct is not the same as making the underlying data available.&lt;/p&gt;

&lt;p&gt;You still need to design how relevant data is stored, retrieved, and verified.&lt;/p&gt;

&lt;h3&gt;
  
  
  Smart contract integration
&lt;/h3&gt;

&lt;p&gt;If proofs are verified on-chain, the verifier contract becomes part of the security-critical path.&lt;/p&gt;

&lt;p&gt;Its interface, gas consumption, and failure handling need to be treated like any other production smart contract.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key management
&lt;/h3&gt;

&lt;p&gt;Some proving systems involve trusted setup assumptions or proving/verifying keys.&lt;/p&gt;

&lt;p&gt;The security model of those components needs to be understood before deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Mental Model I Use
&lt;/h2&gt;

&lt;p&gt;When evaluating a ZK architecture, I find it useful to reduce it to four questions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. What is private?
        ↓
2. What must be proven?
        ↓
3. Where is the computation executed?
        ↓
4. Where is the proof verified?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Private:
Customer eligibility data

        ↓

Prove:
Customer satisfies eligibility rules

        ↓

Compute:
Off-chain prover

        ↓

Verify:
Smart contract
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If those four answers are clear, the rest of the architecture becomes much easier to reason about.&lt;/p&gt;

&lt;h2&gt;
  
  
  ZK Is Not a Magic Privacy Layer
&lt;/h2&gt;

&lt;p&gt;Zero-knowledge proofs can provide powerful privacy and verification guarantees, but they do not automatically make an application private or secure.&lt;/p&gt;

&lt;p&gt;The application still needs to handle:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access control&lt;/li&gt;
&lt;li&gt;Key management&lt;/li&gt;
&lt;li&gt;Smart contract security&lt;/li&gt;
&lt;li&gt;Data availability&lt;/li&gt;
&lt;li&gt;Circuit correctness&lt;/li&gt;
&lt;li&gt;Prover infrastructure&lt;/li&gt;
&lt;li&gt;Client-side security&lt;/li&gt;
&lt;li&gt;Protocol assumptions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A perfectly verified proof can still be part of a badly designed system.&lt;/p&gt;

&lt;p&gt;The strongest ZK architectures are therefore not the ones with the most complicated cryptography.&lt;/p&gt;

&lt;p&gt;They are the ones where the &lt;strong&gt;trust boundary is explicit&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Takeaway
&lt;/h2&gt;

&lt;p&gt;The easiest way to understand zero-knowledge proofs is to stop thinking about them as a mechanism for “hiding data.”&lt;/p&gt;

&lt;p&gt;Think of them as a way to establish:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;“This computation was performed correctly, and I can prove it without revealing everything involved in that computation.”&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That model explains why ZK proofs are useful for privacy, blockchain scaling, identity, and verifiable computation.&lt;/p&gt;

&lt;p&gt;And it also explains the engineering trade-off: &lt;strong&gt;you are not eliminating computation—you are moving it to a place where it can be performed privately and then verified efficiently.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For a broader introduction to Zero-Knowledge Proofs, their privacy applications, and practical challenges, see SotaTek's &lt;a href="https://www.sotatek.com/blogs/zero-knowledge-proof-in-blockchain/" rel="noopener noreferrer"&gt;Zero-Knowledge Proof in Blockchain&lt;/a&gt; guide.&lt;/p&gt;

</description>
      <category>blockchain</category>
      <category>cryptocurrency</category>
      <category>web3</category>
      <category>zeroknowledge</category>
    </item>
    <item>
      <title>AI Readiness Assessment for Developers: What to Check Before Building an AI System</title>
      <dc:creator>SotaTek | AI &amp; Blockchain Innovation Partner</dc:creator>
      <pubDate>Wed, 09 Sep 2026 10:52:58 +0000</pubDate>
      <link>https://dev.to/devsotatek/ai-readiness-assessment-for-developers-what-to-check-before-building-an-ai-system-3k79</link>
      <guid>https://dev.to/devsotatek/ai-readiness-assessment-for-developers-what-to-check-before-building-an-ai-system-3k79</guid>
      <description>&lt;p&gt;Having access to an LLM API doesn't mean your application is ready for AI.&lt;/p&gt;

&lt;p&gt;A team can have access to GPT, Claude, Gemini, or an open-source model and still fail to move beyond a proof of concept because of poor data quality, missing integrations, security gaps, unpredictable costs, or an architecture that cannot survive production workloads.&lt;/p&gt;

&lt;p&gt;Before choosing a model, engineering teams should answer a more important question:&lt;/p&gt;

&lt;p&gt;Is the system actually ready to support an AI workload?&lt;/p&gt;

&lt;p&gt;An AI readiness assessment provides a structured way to evaluate that question before committing significant engineering resources.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start With the Use Case, Not the Model&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One of the most common mistakes is starting with model selection:&lt;/p&gt;

&lt;p&gt;“Should we use GPT, Claude, or an open-source LLM?”&lt;/p&gt;

&lt;p&gt;The better question is:&lt;/p&gt;

&lt;p&gt;“What decision or workflow are we trying to improve?”&lt;/p&gt;

&lt;p&gt;A well-defined AI use case should have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A clear input and expected output&lt;/li&gt;
&lt;li&gt;A measurable success criterion&lt;/li&gt;
&lt;li&gt;A defined tolerance for errors&lt;/li&gt;
&lt;li&gt;A known human fallback when necessary&lt;/li&gt;
&lt;li&gt;A reason to use AI instead of deterministic logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example, “use AI for customer support” is too broad.&lt;/p&gt;

&lt;p&gt;A more actionable definition is:&lt;/p&gt;

&lt;p&gt;Generate a response draft using the customer's ticket history and product documentation, then require human approval before sending.&lt;/p&gt;

&lt;p&gt;The second definition gives engineers something they can actually architect, test, and measure.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Evaluate Data Readiness&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For most AI systems, data is a bigger constraint than model availability.&lt;/p&gt;

&lt;p&gt;Before development, check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Availability: Does the required data exist?&lt;/li&gt;
&lt;li&gt;Quality: Is it accurate, consistent, and complete?&lt;/li&gt;
&lt;li&gt;Accessibility: Can the application retrieve it reliably?&lt;/li&gt;
&lt;li&gt;Freshness: How frequently does it change?&lt;/li&gt;
&lt;li&gt;Structure: Is the data usable without extensive transformation?&lt;/li&gt;
&lt;li&gt;Security: Can it legally and safely be exposed to the AI workflow?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For RAG-based systems, for example, simply having thousands of documents is not enough.&lt;/p&gt;

&lt;p&gt;You also need a reliable ingestion pipeline, appropriate chunking, metadata, retrieval strategy, and access control.&lt;/p&gt;

&lt;p&gt;A technically impressive RAG architecture built on unreliable source data will still produce unreliable answers.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check Integration Readiness&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI rarely operates as an isolated component.&lt;/p&gt;

&lt;p&gt;A production AI feature usually needs to interact with existing systems such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CRM or ERP platforms&lt;/li&gt;
&lt;li&gt;Internal APIs&lt;/li&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;Authentication services&lt;/li&gt;
&lt;li&gt;Document storage&lt;/li&gt;
&lt;li&gt;Event queues&lt;/li&gt;
&lt;li&gt;Third-party SaaS platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Evaluate whether these systems provide stable interfaces and sufficient access to the required data.&lt;/p&gt;

&lt;p&gt;Pay particular attention to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API rate limits&lt;/li&gt;
&lt;li&gt;Authentication and authorization&lt;/li&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Failure handling&lt;/li&gt;
&lt;li&gt;Data synchronization&lt;/li&gt;
&lt;li&gt;Legacy system constraints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If critical data is trapped inside an unreliable legacy system, the problem is not your LLM. The integration layer is the actual bottleneck.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Assess Infrastructure and Architecture&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The infrastructure requirements depend heavily on the AI workload.&lt;/p&gt;

&lt;p&gt;A simple API-based LLM feature may only require an application backend, while a more complex system could involve:&lt;/p&gt;

&lt;p&gt;Client&lt;br&gt;
  ↓&lt;br&gt;
Application API&lt;br&gt;
  ↓&lt;br&gt;
AI Orchestrator&lt;br&gt;
  ├── LLM&lt;br&gt;
  ├── Vector Database&lt;br&gt;
  ├── Business APIs&lt;br&gt;
  └── Tool / Function Calls&lt;br&gt;
  ↓&lt;br&gt;
Response + Observability&lt;/p&gt;

&lt;p&gt;Before implementation, determine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where models will run&lt;/li&gt;
&lt;li&gt;Where data will be stored&lt;/li&gt;
&lt;li&gt;Whether GPUs are required&lt;/li&gt;
&lt;li&gt;Expected request volume&lt;/li&gt;
&lt;li&gt;Latency requirements&lt;/li&gt;
&lt;li&gt;Scaling strategy&lt;/li&gt;
&lt;li&gt;Availability requirements&lt;/li&gt;
&lt;li&gt;Provider dependency and fallback options&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Avoid over-engineering the first version.&lt;/p&gt;

&lt;p&gt;A managed LLM API may be the right choice for an early production workload. Self-hosting becomes more attractive when requirements around cost, latency, data residency, model customization, or scale justify the additional operational complexity.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Treat Security as an Architecture Concern&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;AI introduces attack surfaces that traditional applications may not have.&lt;/p&gt;

&lt;p&gt;An AI readiness assessment should consider:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PII and sensitive data handling&lt;/li&gt;
&lt;li&gt;Model and API access control&lt;/li&gt;
&lt;li&gt;Prompt injection&lt;/li&gt;
&lt;li&gt;Data leakage&lt;/li&gt;
&lt;li&gt;Secrets management&lt;/li&gt;
&lt;li&gt;Tenant isolation&lt;/li&gt;
&lt;li&gt;Audit logging&lt;/li&gt;
&lt;li&gt;Output validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Do not assume that an LLM understands your application's authorization model.&lt;/p&gt;

&lt;p&gt;For example, if a user can only access documents belonging to their organization, the retrieval layer must enforce that constraint. It should not rely on the model to “remember” the rule.&lt;/p&gt;

&lt;p&gt;Authorization belongs in the application architecture, not in the prompt.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Define Evaluation Before Development&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A traditional application can often be tested against deterministic expected outputs.&lt;/p&gt;

&lt;p&gt;AI systems are different.&lt;/p&gt;

&lt;p&gt;The same input can produce multiple valid responses, and “looks good in a demo” is not a measurable quality standard.&lt;/p&gt;

&lt;p&gt;Before building, define:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Evaluation datasets&lt;/li&gt;
&lt;li&gt;Accuracy or relevance metrics&lt;/li&gt;
&lt;li&gt;Hallucination criteria&lt;/li&gt;
&lt;li&gt;Safety requirements&lt;/li&gt;
&lt;li&gt;Latency targets&lt;/li&gt;
&lt;li&gt;Acceptable failure rates&lt;/li&gt;
&lt;li&gt;Human evaluation criteria&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A simple evaluation pipeline might look like:&lt;/p&gt;

&lt;p&gt;Input&lt;br&gt;
  ↓&lt;br&gt;
AI System&lt;br&gt;
  ↓&lt;br&gt;
Generated Output&lt;br&gt;
  ↓&lt;br&gt;
Automated Evaluation&lt;br&gt;
  ↓&lt;br&gt;
Human Evaluation (if required)&lt;br&gt;
  ↓&lt;br&gt;
Release / Reject&lt;/p&gt;

&lt;p&gt;This becomes especially important when changing models, prompts, retrieval strategies, or system instructions.&lt;/p&gt;

&lt;p&gt;Without a regression evaluation set, every AI change is partly a production experiment.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Plan for Production Operations&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A successful proof of concept answers:&lt;/p&gt;

&lt;p&gt;“Can we make it work?”&lt;/p&gt;

&lt;p&gt;A production system needs to answer:&lt;/p&gt;

&lt;p&gt;“Can we operate it reliably?”&lt;/p&gt;

&lt;p&gt;At minimum, monitor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Latency&lt;/li&gt;
&lt;li&gt;Error rates&lt;/li&gt;
&lt;li&gt;Token usage&lt;/li&gt;
&lt;li&gt;Cost per request&lt;/li&gt;
&lt;li&gt;Model failures&lt;/li&gt;
&lt;li&gt;Retrieval quality&lt;/li&gt;
&lt;li&gt;Output quality&lt;/li&gt;
&lt;li&gt;User feedback&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Version prompts, system instructions, model configurations, and evaluation datasets just as you would version application code.&lt;/p&gt;

&lt;p&gt;Also design explicit fallback paths.&lt;/p&gt;

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

&lt;p&gt;Primary LLM&lt;br&gt;
    ↓&lt;br&gt;
Failure / Timeout&lt;br&gt;
    ↓&lt;br&gt;
Fallback Model&lt;br&gt;
    ↓&lt;br&gt;
Human Escalation&lt;/p&gt;

&lt;p&gt;The goal is not to eliminate every AI failure. The goal is to contain failures so they do not become system failures.&lt;/p&gt;

&lt;p&gt;A Practical AI Readiness Checklist&lt;/p&gt;

&lt;p&gt;Before starting implementation, engineering teams should be able to answer “yes” to most of these questions:&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbptfsrj0t9x5mhei8sd0.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbptfsrj0t9x5mhei8sd0.png" alt=" " width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If several answers are “no,” building the AI feature immediately may create more technical debt than business value.&lt;/p&gt;

&lt;p&gt;The engineering layer is only part of the equation; this &lt;strong&gt;&lt;em&gt;&lt;a href="https://www.sotatek.com/blogs/ai-and-machine-learning/ai-readiness-assessment/" rel="noopener noreferrer"&gt;AI Readiness Assessment&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt; looks at the organizational, data, and business factors that also determine whether an AI initiative is ready to move forward.&lt;/p&gt;

&lt;p&gt;From Readiness Assessment to Production&lt;/p&gt;

&lt;p&gt;AI readiness is not about achieving a perfect score.&lt;/p&gt;

&lt;p&gt;It is about identifying the constraints that could prevent an AI system from delivering reliable value.&lt;/p&gt;

&lt;p&gt;A practical path is:&lt;/p&gt;

&lt;p&gt;Assess&lt;br&gt;
  ↓&lt;br&gt;
Identify Gaps&lt;br&gt;
  ↓&lt;br&gt;
Prioritize Use Case&lt;br&gt;
  ↓&lt;br&gt;
Design Architecture&lt;br&gt;
  ↓&lt;br&gt;
Build PoC&lt;br&gt;
  ↓&lt;br&gt;
Evaluate&lt;br&gt;
  ↓&lt;br&gt;
Harden&lt;br&gt;
  ↓&lt;br&gt;
Deploy&lt;br&gt;
  ↓&lt;br&gt;
Monitor &amp;amp; Iterate&lt;/p&gt;

&lt;p&gt;The most important decision is often not which AI model to use, but whether the surrounding system is ready to use one effectively.&lt;/p&gt;

&lt;p&gt;Good AI engineering starts before the first API call.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>machinelearning</category>
      <category>software</category>
      <category>llm</category>
    </item>
  </channel>
</rss>
