# Write to a Contract with `writeContractAsync` button

This recipe shows how to implement a button that allows users to interact with a smart contract by executing the `writeContractAsync` function returned by [useScaffoldWriteContract](/hooks/useScaffoldWriteContract). By following this guide, you can create a user interface for writing data to a contract.

<details open>
  <summary>Here is the full code, which we will be implementing in the guide below:</summary>

  ```tsx title="components/Greetings.tsx"
  import { useState } from "react";
  import { parseEther } from "viem";
  import { useScaffoldWriteContract } from "~~/hooks/scaffold-eth";

  export const Greetings = () => {
    const [newGreeting, setNewGreeting] = useState("");

    const { writeContractAsync, isPending } = useScaffoldWriteContract("YourContract");

    const handleSetGreeting = async () => {
      try {
        await writeContractAsync(
          {
            functionName: "setGreeting",
            args: [newGreeting],
            value: parseEther("0.01"),
          },
          {
            onBlockConfirmation: (txnReceipt) => {
              console.log("📦 Transaction blockHash", txnReceipt.blockHash);
            },
          },
        );
      } catch (e) {
        console.error("Error setting greeting", e);
      }
    };

    return (
      <>
        <input
          type="text"
          placeholder="Write your greeting"
          className="input border border-primary"
          onChange={(e) => setNewGreeting(e.target.value)}
        />
        <button
          className="btn btn-primary"
          onClick={handleSetGreeting}
          disabled={isPending}
        >
          {isPending ? <span className="loading loading-spinner loading-sm"></span> : "Send"}
        </button>
      </>
    );
  };
  ```
</details>

## Implementation

### Step 1: Set Up Your Component

Create a new component in the "components" folder. This component will enable users to write data to a smart contract.

```tsx title="components/Greetings.tsx"
export const Greetings = () => {
  return (
    <>
      <input
        type="text"
        placeholder="Write your greeting"
        className="input border border-primary"
      />
      <button className="btn btn-primary">Send</button>
    </>
  );
};
```

### Step 2: Initialize `useScaffoldWriteContract` hook

Initialize the `useScaffoldWriteContract` hook. This hook provides the `writeContractAsync` function for sending transactions, we'll create `handleSetGreeting` function in which we'll call and pass parameters to `writeContractAsync` required to perform contract interaction.

```tsx
import { useState } from "react"; // [!code hl]
import { parseEther } from "viem"; // [!code hl]
import { useScaffoldWriteContract } from "~~/hooks/scaffold-eth"; // [!code hl]

export const Greetings = () => {
  const [newGreeting, setNewGreeting] = useState(""); // [!code hl]

  const { writeContractAsync } = useScaffoldWriteContract("YourContract"); // [!code hl]

  const handleSetGreeting = async () => { // [!code hl]
    try { // [!code hl]
      await writeContractAsync( // [!code hl]
        { // [!code hl]
          functionName: "setGreeting", // [!code hl]
          args: [newGreeting], // [!code hl]
          value: parseEther("0.01"), // [!code hl]
        }, // [!code hl]
        { // [!code hl]
          onBlockConfirmation: (txnReceipt) => { // [!code hl]
            console.log("📦 Transaction blockHash", txnReceipt.blockHash); // [!code hl]
          }, // [!code hl]
        }, // [!code hl]
      ); // [!code hl]
    } catch (e) { // [!code hl]
      console.error("Error setting greeting", e); // [!code hl]
    } // [!code hl]
  }; // [!code hl]

  return (
    <>
      <input
        type="text"
        placeholder="Write your greeting"
        className="input border border-primary"
      />
      <button className="btn btn-primary">Send</button>
    </>
  );
};
```

### Step 3: Add input change logic and send transaction when users click the button

Wire up the input field to update the `newGreeting` state when the user types in a new greeting and call `handleSetGreeting` function when user click on the button.

```tsx
import { useState } from "react";
import { parseEther } from "viem";
import { useScaffoldWriteContract } from "~~/hooks/scaffold-eth";

export const Greetings = () => {
  const [newGreeting, setNewGreeting] = useState("");

  const { writeContractAsync } = useScaffoldWriteContract("YourContract");

  const handleSetGreeting = async () => {
    try {
      await writeContractAsync(
        {
          functionName: "setGreeting",
          args: [newGreeting],
          value: parseEther("0.01"),
        },
        {
          onBlockConfirmation: (txnReceipt) => {
            console.log("📦 Transaction blockHash", txnReceipt.blockHash);
          },
        },
      );
    } catch (e) {
      console.error("Error setting greeting", e);
    }
  };

  return (
    <>
      <input
        type="text"
        placeholder="Write your greeting"
        className="input border border-primary"
        onChange={(e) => setNewGreeting(e.target.value)} // [!code hl]
      />
      <button
        className="btn btn-primary"
        onClick={handleSetGreeting} // [!code hl]
      >
        Send
      </button>
    </>
  );
};
```

### Step 4: Bonus adding loading state

We can use `isPending` returned from `useScaffoldWriteContract` while the transaction is being mined and also disable the button.

```tsx
import { useState } from "react";
import { parseEther } from "viem";
import { useScaffoldWriteContract } from "~~/hooks/scaffold-eth";

export const Greetings = () => {
  const [newGreeting, setNewGreeting] = useState("");
  const { writeContractAsync, isPending } = useScaffoldWriteContract("YourContract"); // [!code hl]

  const handleSetGreeting = async () => {
    try {
      await writeContractAsync(
        {
          functionName: "setGreeting",
          args: [newGreeting],
          value: parseEther("0.01"),
        },
        {
          onBlockConfirmation: (txnReceipt) => {
            console.log("📦 Transaction blockHash", txnReceipt.blockHash);
          },
        },
      );
    } catch (e) {
      console.error("Error setting greeting", e);
    }
  };

  return (
    <>
      <input
        type="text"
        placeholder="Write your greeting"
        className="input border border-primary"
        onChange={(e) => setNewGreeting(e.target.value)}
      />

      <button
        className="btn btn-primary"
        onClick={handleSetGreeting}
        disabled={isPending} // [!code hl]
      >
        {isPending ? <span className="loading loading-spinner loading-sm"></span> : "Send"}{/* // [!code hl] */}
      </button>
    </>
  );
};
```
