Låt oss diskutera olika sätt att påskynda din produktutveckling.

Visst, då gör vi det
Betyg 4,9/5 på Clutch

MOP

  • Tjänster

  • Produkter

  • Människor

  • Blogg

  • Låt oss bygga

Mer

  • Fallstudier

  • Utmärkelser

  • Kundutlåtanden

  • Lediga tjänster

  • Teknik

Socialt

  • LinkedIn

  • X

  • Instagram

  • Facebook

  • Dribbble

© 2026 Ministry of Programming

  • Integritetspolicy
Tillbaka till bloggen

Kontoabstraktion (ERC-4337)

Dzana Karamustafic
14 oktober 2024Produktdrift och livslängdLäsningstid: 10 minuter
Kontoabstraktion (ERC-4337)

Introduktion av smarta konton och visning av gasfria transaktioner med Paymaster-tjänsten

Kontoabstraktion är konceptet som gör det möjligt för oss att förbättra användarupplevelsen på Web3 när vi interagerar med decentraliserade applikationer (dApps). Vi definierar det som möjligheten att lägga till godtycklig logik i processen att validera en transaktion. Kontoabstraktion i blockkedjesystem gör det möjligt att inneha tillgångar av smarta konton (smarta kontraktsplånböcker), snarare än att hanteras av externt ägda konton (EOAs). ERC-4337-standarden är den tokenstandard för kontoabstraktioner som gör det möjligt för konton på Ethereum att bete sig mer som smarta kontrakt.

EOA:er har begränsade funktioner eftersom regler för användning av EOA-plånböcker är hårdkodade i protokollet och inte kan ändras. Smarta konton, å andra sidan, är lättprogrammerbara, vilket gör det möjligt för utvecklare att lägga till godtycklig logik för att tillhandahålla nya funktioner.

Web3-hinder – Första stegen mot dApps

Den största utmaningen med den nuvarande webb3-användarupplevelsen är de många friktionspunkter som användare stöter på innan de faktiskt kan använda vår decentraliserade applikation (dApp). De måste:

  • Registrering på en plånbok – Registrering kan vara skrämmande på grund av blockkedjeteknikens tekniska natur och de säkerhetsåtgärder som är inblandade. Användare måste förstå olika typer av plånböcker (hårdvaruplånböcker, webbläsartillägg, mobilplånböcker etc.), vikten av privata nycklar och såddfraser samt bästa säkerhetspraxis för att undvika bedrägerier.
  • Skaffa kryptovaluta - Efter att ha skapat en plånbok måste användare skaffa kryptovaluta, vilket vanligtvis kräver att man hittar en pålitlig börs och slutför identitetsverifieringsprocessen (KYC), vilket kan vara avskräckande på grund av integritetsproblem.
  • Överföra pengar till EOA – När användare har köpt kryptovaluta måste de överföra den från börsen till sitt eget externt ägda konto (EOA).
  • Börja betala för bensinavgifter – Att interagera med dApps kräver att man betalar transaktionsavgifter (bensin) som kan fluktuera dramatiskt, vilket är ytterligare ett nytt koncept som våra användare stöter på. Användare är begränsade till att betala bensinavgifter med endast den lokala valutan i det nätverk där vår dApp är distribuerad, vilket kan vara begränsande.
web3 UX-problem som nya dApp-användare stöter på
Bild genererad med ChatGPT

Tänk nu på komplexiteten i dessa steg om vi var tvungna att utföra dem för varje dApp vi använder dagligen.


Kontoabstraktion till undsättning

Account Abstraction (AA) medför två viktiga framsteg: Smart Accounts och UserOps. Vi kommer att förklara ERC-4337-transaktionsflödet med hjälp av smarta konton, med fokus på fyra viktiga komponenter: Användaroperationer, Mempool för användaroperationer, Bundler-tjänst och Paymaster-tjänst.

Blockschema över ett transaktionsflöde med ERC-4337
Bildkälla: ERC-4337

Användaråtgärd 

När en användare interagerar med blockkedjan via sitt smarta konto, inkapslas deras avsedda handlingar i UserOps. En UserOp är inte en traditionell blockkedjetransaktion, utan fungerar snarare som en anpassningsbar transaktion. Följaktligen är det möjligt att programmatiskt ställa in anpassade regler och villkor för dessa transaktioner.

Användaråtgärd Mempool (Alternativ Mempool)

Till skillnad från traditionella transaktioner som går in i den publika mempoolen, dirigeras UserOperations till den alternativa mempoolen – en specialiserad mempool på högre nivå som är specifikt utformad för att hantera UserOps.

Buntlare

Bundler-tjänsten lyssnar på UserOperation mempoolen, bundlar flera UserOps och skickar dem till Entry Point Contract som så småningom hjälper till att hantera UserOps och skapa en enda transaktion att skicka in på blockkedjan.

Kassör

Paymaster-tjänsten möjliggör gasuttag, vilket gör det möjligt för en tredje part (dApp eller plånbok) att betala gasavgifterna för användarens räkning. Dessutom ger den användare möjlighet att betala gasavgifter med ERC-20-tokens.

Baserat på den information som tillhandahållits är det tydligt hur Account Abstraction förbättrar användarupplevelsen på Web3 och hanterar de utmaningar som nya användare står inför. Förbättrad UX möjliggjord av AA omfattar:

  • Batchtransaktioner : Kontoabstraktion möjliggör paketering av flera UserOps till en enda. Genom att göra det minskar paketeringsverktygen effektivt antalet individuella transaktioner, vilket sparar blockkedjans beräkningsresurser och förbättrar den totala effektiviteten. När många transaktioner paketeras till en enda transaktion kan de bearbetas samtidigt, vilket leder till snabbare exekveringstider. Dessutom innebär det att UserOps paketeras och hanteras av en paketeringsverktyg att användare inte behöver hantera och skicka varje operation individuellt själva. Detta förenklar användarupplevelsen.
  • Gasabstraktion: En av de mest fördelaktiga nyckelfunktionerna i ERC-4337 är förmodligen gasabstraktion, vilket minskar komplexiteten i gashanteringen för användarna. Denna metod förenklar interaktioner med blockkedjeteknik eftersom vi befriar användarna från behovet av att hantera eller ens äga nativa blockkedjetokens som ETH.
  • Betala bensin med ERC-20-tokens : Även om sponsring av bensinavgifter förbättrar användarnas tillgänglighet, är det inte alltid ekonomiskt praktiskt. Ett alternativt sätt att upprätthålla en högkvalitativ användarupplevelse är att möjliggöra betalning av bensinavgifter med ERC-20-tokens. Till exempel, istället för att använda ETH:s nativa nätverkstoken för bensinavgifter, använder de USDC.
  • Sömlös Web3-autentisering: Föreställ dig ett scenario där en användare vill interagera med vår dApp men inte har skapat en plånbok. Med hjälp av kontoabstraktion kan vi autentisera en användare med deras befintliga sociala mediekonton: Google eller Facebook. I bakgrunden skapas en EOA automatiskt och tilldelas som ägare till det distribuerade smarta kontot, vilket förenklar användarens inträde i web3-utrymmet.

Account Abstraction är den revolutionerande bryggan som för den sömlösa användarupplevelsen hos Web2 till den blockchain-drivna världen hos Web3.

SDK:er för kontoabstraktion

För att förenkla användningen av smarta konton och bygga dApps har utvecklare tillgång till olika verktyg som integrerar AA i sina projekt. AA API:er och programvaruutvecklingspaket (SDK:er) överbryggar klyftan mellan de komplexiteter som utvecklare stöter på när de implementerar AA-koncept och den smidiga, intuitiva användarupplevelse som förväntas av vanliga användare. De flesta av dessa SDK:er är utformade för att vara "plug & play" – vilket gör att utvecklare snabbt och enkelt kan integrera avancerade AA-funktioner i sina dApps med minimal ansträngning. Av de många tillgängliga SDK:erna är här tre som gör ett bra jobb med att integrera AA i våra projekt:

  • Alkemi: https://www.alchemy.com
  • Biconomy: https://www.biconomy.io
Hemsida för Biconomy
  • ZeroDev: https://zerodev.app

Betalningschef i aktion

Låt oss integrera Biconomys SDK i vårt NextJS-projekt för att visa upp hur man skickar gaslösa transaktioner med deras Paymaster-tjänst.

Starta projektets skapande och välj följande alternativ:

yarn create next-app

✔ What is your project named? … biconomy-gasless-transactions-demo ✔ Would you like to use TypeScript? … Yes ✔ Would you like to use ESLint? … Yes ✔ Would you like to use Tailwind CSS? … Yes ✔ Would you like to use `src/` directory? … No ✔ Would you like to use App Router? (recommended) … Yes ✔ Would you like to customize the default import alias (@/*)? … No

Vi ansluter till en plånbok med hjälp av RegnbågssatsInstallera RainbowKit och dess peer-beroenden, wagmi, viem, och @tanstack/react-query:

yarn add @rainbow-me/rainbowkit wagmi viem@2.x @tanstack/react-query

Välj dina önskade kedjor och konfigurera en wagmi-konfiguration:

import { getDefaultConfig } from "@rainbow-me/rainbowkit";
import { sepolia } from "wagmi/chains";

export const config = getDefaultConfig({
  appName: "biconomy-gasless-transactions-demo",
  projectId: process.env.NEXT_PUBLIC_PROJECT_ID ?? "",
  chains: [sepolia],
  ssr: true,
});

Du kan få ditt projekt-ID från WalletConnect genom att logga in och skapa ett nytt projekt.

Skapa nytt projekt på WalletConnect
Var du hittar ditt projekt-ID på WalletConnect

Nu ska vi skapa en Providers-komponent som vi ska använda i vår layout.js för att koppla in vår applikation med RainbowKitProvider, WagmiProvider, QueryClientProvider och, senare, BiconomyProvider.

"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { WagmiProvider } from "wagmi";
import { RainbowKitProvider, darkTheme } from "@rainbow-me/rainbowkit";
import { config } from "app/wagmiConfig";
import "@rainbow-me/rainbowkit/styles.css";

const queryClient = new QueryClient();

export const Providers = ({ children }: { children: React.ReactNode }) => {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <RainbowKitProvider theme={darkTheme()}>{children}</RainbowKitProvider>
      </QueryClientProvider>
    </WagmiProvider>
  );
};

Genom att använda ConnectButton-komponenten förlitar vi oss på RaibowKit för att hantera våra användares plånboksval, visa plånboksinformation och hantera nätverksväxling.

import { ConnectButton } from "@rainbow-me/rainbowkit";

const Home = () => {
  return <ConnectButton />;
};

export default Home;

Nu ska vi integrera Biconomy i vårt projekt. Nyligen släppte de sitt useAA-paket, specifikt utformat för React-projekt. Detta paket förenklar implementeringen genom att tillhandahålla hooks för transaktionssponsring, sessionshantering och mycket mer. Vi behöver också installera det centrala SDK-paketet, som används internt av useAA för att utföra AA-operationer.

yarn add @biconomy/konto @biconomy/use-aa

Låt oss lägga till BiconomyProvider-komponenten i vår Providers.tsx-fil så att vi kan använda useAA-hooks.

"use client";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { WagmiProvider } from "wagmi";
import { BiconomyProvider } from "@biconomy/use-aa";
import { RainbowKitProvider, darkTheme } from "@rainbow-me/rainbowkit";
import { config } from "app/wagmiConfig";
import { BUNDELER_URL } from "./constants";
import "@rainbow-me/rainbowkit/styles.css";

const queryClient = new QueryClient();

export const Providers = ({ children }: { children: React.ReactNode }) => {
  return (
    <WagmiProvider config={config}>
      <QueryClientProvider client={queryClient}>
        <RainbowKitProvider theme={darkTheme()}>
          <BiconomyProvider
            config={{
              biconomyPaymasterApiKey:
                process.env.NEXT_PUBLIC_BICONOMY_PAYMASTER_API_KEY ?? "",
              bundlerUrl: BUNDELER_URL,
            }}
            queryClient={queryClient}
          >
            {children}
          </BiconomyProvider>
        </RainbowKitProvider>
      </QueryClientProvider>
    </WagmiProvider>
  );
};

Vi kan hämta information om betalningsansvarig och paketleverantör från Biconomys instrumentpanel . Logga in med e-post, Github eller Gitlab och hämta din bundlerUrl .

Hämtar din bundler-URL från Biconomy Dashboard

För att hämta biconomyPaymasterApiKey måste du registrera en ny Paymaster hos valt nätverk, vilket i vårt fall är Sepolias testnätverk. Då kommer du att kunna se din Paymaster-URL och API-nyckeln.

Visar paymaster-URL och API-nyckel på Biconomy Dashboard

Det är möjligt att betala bensinavgifter med ERC-20-tokens direkt. För att skapa ett bensinsponsorskap måste vi ansluta en plånbok och konfigurera en bensintank, där vi sätter in pengar som kommer att användas för att betala våra användares bensinavgifter.

Visar det aktuella värdet för bensintanken som vi konfigurerade via Biconomy Dashboard
För demonstrationsändamål använder jag en av mina tidigare installerade gastankar.

Låt bygga en TransactionForm-komponent som ansvarar för att skicka våra användares transaktioner.

"use client";
import { useAccount } from "wagmi";
import { useSendTransaction, useSmartAccount } from "@biconomy/use-aa";
import { PaymasterMode } from "@biconomy/account";
import { Address, parseEther } from "viem";
import Input from "app/components/Input";
import Button from "app/components/Button";

const TransactionForm = ({ isGasless }: { isGasless: boolean }) => {
  const { address } = useAccount();
  const { mutate, isPending } = useSendTransaction();
  const smartAccount = useSmartAccount();

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    const formData = new FormData(event.target as HTMLFormElement);
    const to = formData.get("address") as Address;
    const value = formData.get("value") as string;
    const etherValue = parseEther(value);

    mutate({
      transactions: {
        to,
        value: etherValue,
      },
      ...(isGasless && {
        options: { paymasterServiceData: { mode: PaymasterMode.SPONSORED } },
      }),
    });
  };

  return (
    <div className="flex flex-col items-center justify-evenly">
      <form
        onSubmit={handleSubmit}
        className="flex flex-col items-end gap-4 justify-center"
      >
        <Input
          label="Smart Account Address"
          name="smartAddress"
          placeholder="Please connect wallet"
          disabled
          value={smartAccount.smartAccountAddress}
        />
        <Input
          label="Address"
          name="address"
          placeholder="0xA0Cf…251e"
          required
          disabled={!address}
        />
        <Input
          label="Value"
          name="value"
          placeholder="0.05"
          required
          disabled={!address}
        />
        {address ? (
          <Button isActive type="submit" className="mt-2" disabled={isPending}>
            {isPending ? "Waiting..." : "Send"}
          </Button>
        ) : (
          <Button className="mt-2" disabled={true}>
            Connect Wallet
          </Button>
        )}
      </form>
    </div>
  );
};

export default TransactionForm;

För närvarande kan vi inte visa den slutliga transaktionshashen för att kontrollera transaktionsinformationen på Etherscan . För att lägga till den här funktionen använder vi useUserOpWait- hooken, som returnerar UserOp-kvittot som innehåller transaktionshashen.

"use client";
import { useAccount } from "wagmi";
import {
  useSendTransaction,
  useSmartAccount,
  useUserOpWait,
} from "@biconomy/use-aa";
import { PaymasterMode } from "@biconomy/account";
import { Address, parseEther } from "viem";
import Link from "next/link";
import Input from "app/components/Input";
import Button from "app/components/Button";
import { formatHash } from "app/helpers";

const TransactionForm = ({ isGasless }: { isGasless: boolean }) => {
  const { address, chain } = useAccount();
  const {
    mutate,
    isPending,
    data: userOpResponse,
    error: errorSendTransaction,
  } = useSendTransaction();
  const smartAccount = useSmartAccount();
  const {
    isLoading: waitIsPending,
    error: waitError,
    data: waitData,
  } = useUserOpWait(userOpResponse);

  const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();

    const formData = new FormData(event.target as HTMLFormElement);
    const to = formData.get("address") as Address;
    const value = formData.get("value") as string;
    const etherValue = parseEther(value);

    mutate({
      transactions: {
        to,
        value: etherValue,
      },
      ...(isGasless && {
        options: { paymasterServiceData: { mode: PaymasterMode.SPONSORED } },
      }),
    });
  };

  return (
    <div className="flex flex-col items-center justify-evenly">
      <form
        onSubmit={handleSubmit}
        className="flex flex-col items-end gap-4 justify-center"
      >
        <Input
          label="Smart Account Address"
          name="smartAddress"
          placeholder="Please connect wallet"
          disabled
          value={smartAccount.smartAccountAddress}
        />
        <Input
          label="Address"
          name="address"
          placeholder="0xA0Cf…251e"
          required
          disabled={!address}
        />
        <Input
          label="Value"
          name="value"
          placeholder="0.05"
          required
          disabled={!address}
        />
        {address ? (
          <Button
            isActive
            type="submit"
            className="mt-2"
            disabled={isPending || waitIsPending}
          >
            {isPending || waitIsPending ? "Waiting..." : "Send"}
          </Button>
        ) : (
          <Button className="mt-2" disabled={true}>
            Connect Wallet
          </Button>
        )}
      </form>
      <div className="w-80 min-h-40">
        {waitData?.receipt?.transactionHash && (
          <div className="flex justify-between">
            Transaction Hash:
            <Link
              href={`${chain?.blockExplorers?.default?.url}/tx/${waitData.receipt.transactionHash}`}
              rel="noopener noreferrer"
              target="_blank"
              className="text-indigo-500"
            >
              {formatHash(waitData.receipt.transactionHash)}
            </Link>
          </div>
        )}
        <div className="flex flex-col gap-2">
          {isPending && <div>Waiting for confirmation...</div>}
          {waitIsPending && (
            <div>Transaction confirmed, waiting to process...</div>
          )}
          {errorSendTransaction && (
            <div className="text-rose-500">{`Error message: ${errorSendTransaction}`}</div>
          )}
          {waitError && (
            <div className="text-rose-500">{`Error message: ${waitError}`}</div>
          )}
        </div>
      </div>
    </div>
  );
};

export default TransactionForm;
Paymaster-analys på Biconomy Dashboard
Du kan se din bensintank i aktion via fliken Analys på Biconomy-instrumentpanelen.

Och där har du det – du har framgångsrikt börjat dra av bensinavgifter från dina användare! Genom att hantera dessa avgifter åt användarna blir din dApp mer tillgänglig och användarvänlig, vilket sannolikt kommer att öka användarengagemang och trafik.

Visa hela kodlösningen: github/web3-transaction-manager

Besök webbappen: vercel/web3-transaction-manager – Observera att för närvarande endast Polygon Amoy-nätverket stöds av den distribuerade appen.