> **Can't find what you're looking for?** Use `search_docs` on the docs MCP server at `https://v3.viem.sh/api/mcp` to find what you need.

# Write Contract \[contract.write]

Executes a write (`nonpayable`/`payable`) function on a contract and waits for the transaction
receipt.

A write function modifies blockchain state, requires gas, and broadcasts a transaction.

Use [`Actions.contract.simulate`](/docs/actions/public/contract/simulate) first when you need to
validate the call.

## Usage

Use `writeSync` to execute a contract write and wait for its transaction receipt.

:::code-group
```ts twoslash [example.ts]
import { Abi } from 'viem/utils'
import { client } from './viem.config'

const receipt = await client.contract.writeSync({
  abi: Abi.from(['function mint(uint32 tokenId)']),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
})
// @log: {
// @log:   status: 'success',
// @log:   transactionHash: '0x...',
// @log: }
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
import { Account, Client, http, walletActions } from 'viem'
import { mainnet } from 'viem/chains'

export const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  transport: http(),
}).extend(walletActions())
```
:::

### Asynchronous Usage

Use `write` when the transaction hash is needed immediately and receipt tracking happens
elsewhere.

:::code-group
```ts twoslash [example.ts]
import { Abi } from 'viem/utils'
import { client } from './viem.config'

const hash = await client.contract.write({
  abi: Abi.from(['function mint(uint32 tokenId)']),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
})
// @log: "0x4ca7ee652d57678f26e887c19671f76c1aff..."
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
import { Account, Client, http, walletActions } from 'viem'
import { mainnet } from 'viem/chains'

export const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  transport: http(),
}).extend(walletActions())
```
:::

### Standalone Action

Call `Actions.contract.writeSync` directly by passing the Client as the first argument. Use
`Actions.contract.write` for the asynchronous variant.

:::code-group
```ts twoslash [example.ts]
import { Actions } from 'viem'
import { Abi } from 'viem/utils'
import { client } from './viem.config'

const receipt = await Actions.contract.writeSync(client, {
  abi: Abi.from(['function mint(uint32 tokenId)']),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
})
// @log: {
// @log:   status: 'success',
// @log:   transactionHash: '0x...',
// @log: }
```

```ts twoslash [viem.config.ts] filename="viem.config.ts"
import { Account, Client, http } from 'viem'
import { mainnet } from 'viem/chains'

export const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  transport: http(),
})
```
:::

:::tip
Use [`Actions.contract.simulate`](/docs/actions/public/contract/simulate) to validate the call
before broadcasting.
Pass the returned `request` to [`Actions.contract.writeSync`](#standalone-action).

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint(uint32 tokenId)'])
// ---cut---
const { request } = await Actions.contract.simulate(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
})
const receipt = await Actions.contract.writeSync(client, request)
```
:::

## Recipes

### Call a Payable Function

Pass `account` to select the sender and `value` to send native currency.

```ts twoslash
import { Account, Client, http, walletActions } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const account = Account.fromPrivateKey('0x…')
const client = Client.create({
  chain: mainnet,
  transport: http(),
}).extend(walletActions())

const hash = await client.contract.write({
  abi: Abi.from(['function deposit() payable']),
  account, // [!code focus]
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'deposit',
  value: 1n, // [!code focus]
})
```

### Write a Simulated Request

Simulate first when you need to inspect the decoded result before sending the resolved request.

```ts twoslash
import {
  Account,
  Client,
  http,
  publicActions,
  walletActions,
} from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  transport: http(),
})
  .extend(publicActions())
  .extend(walletActions())

const { request, result } = await client.contract.simulate({
  abi: Abi.from(['function mint(uint32 tokenId) returns (uint32)']),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
})

const hash = await client.contract.write(request) // [!code focus]
```

### Write a Blob Transaction

For a Local Account, provide blobs and a [KZG context](/docs/utilities/kzg/from) to prepare and sign an EIP-4844 transaction.

```ts twoslash
import { Account, Client, http, walletActions } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi, Kzg } from 'viem/utils'

declare const kzg: Kzg.Kzg

const client = Client.create({
  account: Account.fromPrivateKey('0x…'),
  chain: mainnet,
  transport: http(),
}).extend(walletActions())

const hash = await client.contract.write({
  abi: Abi.from(['function mint()']),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  blobs: ['0x1234'], // [!code focus]
  functionName: 'mint',
  kzg, // [!code focus]
  maxFeePerBlobGas: 1_000_000_000n, // [!code focus]
  type: 'eip4844', // [!code focus]
})
```

## Return Value

### Synchronous

`TransactionReceipt`

The transaction receipt.

### Asynchronous

`Hex`

The transaction hash.

## Parameters

Both variants support the parameters below. `writeSync` also supports the sync parameters
documented for [`Actions.transaction.sendSync`](/docs/actions/wallet/transaction/send#parameters).

### abi

* **Type:** `Abi`

The contract's ABI. The `functionName` and `args` are inferred from it.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const hash = await Actions.contract.write(client, {
  abi: Abi.from(['function mint(uint32 tokenId)']), // [!code focus]
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
})
```

### accessList

* **Type:** `AccessList`

The EIP-2930 access list to attach to the transaction.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  accessList: [ // [!code focus]
    { // [!code focus]
      address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus]
      storageKeys: [ // [!code focus]
        '0x0000000000000000000000000000000000000000000000000000000000000001', // [!code focus]
      ], // [!code focus]
    }, // [!code focus]
  ], // [!code focus]
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'mint',
})
```

### account

* **Type:** `Account | Address`
* **Default:** `client.account`

The account to send the transaction from. Falls back to the account configured on the client.

```ts twoslash
import { Account, Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint(uint32 tokenId)'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  account: Account.fromPrivateKey('0x…'), // [!code focus]
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
})
```

### address

* **Type:** `Address`

The address of the contract.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint(uint32 tokenId)'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2', // [!code focus]
  args: [69420],
  functionName: 'mint',
})
```

### args

* **Type:** Inferred from `abi` and `functionName`.

The arguments to pass to the contract function.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const hash = await Actions.contract.write(client, {
  abi: Abi.from(['function mint(uint32 tokenId)']),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420], // [!code focus]
  functionName: 'mint',
})
```

### assertChainId

* **Type:** `boolean`
* **Default:** `true`

Whether to verify that the Client's chain matches the connected network for a JSON-RPC Account.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  account: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e',
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  assertChainId: false, // [!code focus]
  functionName: 'mint',
})
```

### authorizationList

* **Type:** `AuthorizationList`

The signed EIP-7702 authorization list to attach to the transaction.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  authorizationList: [ // [!code focus]
    { // [!code focus]
      address: '0xA0Cf798816D4b9b9866b5330EEa46a18382f251e', // [!code focus]
      chainId: 1, // [!code focus]
      nonce: 0n, // [!code focus]
      r: '0x...', // [!code focus]
      s: '0x...', // [!code focus]
      yParity: 0, // [!code focus]
    }, // [!code focus]
  ], // [!code focus]
  functionName: 'mint',
})
```

### blobs

* **Type:** `readonly Hex[]`

The blobs to attach to the transaction (EIP-4844).

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  blobs: ['0x1234'], // [!code focus]
  functionName: 'mint',
})
```

### blobVersionedHashes

* **Type:** `readonly Hex[]`

The EIP-4844 versioned hashes for the attached blobs.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  blobVersionedHashes: ['0x...'], // [!code focus]
  functionName: 'mint',
})
```

### chain

* **Type:** `Chain | null`
* **Default:** `client.chain`

The target chain. Pass `null` to skip the current-chain assertion.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet, optimism } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint(uint32 tokenId)'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  chain: optimism, // [!code focus]
  functionName: 'mint',
})
```

### dataSuffix

* **Type:** `Hex`
* **Default:** `client.dataSuffix`

The data to append to the encoded function calldata.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  dataSuffix: '0xdeadbeef', // [!code focus]
  functionName: 'mint',
})
```

### functionName

* **Type:** Inferred from `abi`.

The name of the function to call on the contract.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint(uint32 tokenId)'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint', // [!code focus]
})
```

### gas

* **Type:** `bigint | number | Hex`

The gas limit for the transaction.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'mint',
  gas: 100_000n, // [!code focus]
})
```

### gasPrice

* **Type:** `bigint | number | Hex`

The gas price for a legacy or EIP-2930 transaction.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'mint',
  gasPrice: 20_000_000_000n, // [!code focus]
})
```

### kzg

* **Type:** `Kzg`

For a Local Account, the KZG context derives EIP-4844 blob fields during preparation and signing. JSON-RPC Account sends ignore this option.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi, Kzg } from 'viem/utils'

declare const kzg: Kzg.Kzg
const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  blobs: ['0x1234'],
  functionName: 'mint',
  kzg, // [!code focus]
})
```

### maxFeePerBlobGas

* **Type:** `bigint | number | Hex`

The maximum fee per blob gas for an EIP-4844 transaction.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'mint',
  maxFeePerBlobGas: 1_000_000_000n, // [!code focus]
})
```

### maxFeePerGas

* **Type:** `bigint | number | Hex`

The maximum total fee per gas for an EIP-1559 transaction.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'mint',
  maxFeePerGas: 20_000_000_000n, // [!code focus]
})
```

### maxPriorityFeePerGas

* **Type:** `bigint | number | Hex`

The maximum priority fee per gas for an EIP-1559 transaction.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'mint',
  maxPriorityFeePerGas: 1_000_000_000n, // [!code focus]
})
```

### nonce

* **Type:** `bigint | number | Hex`

The nonce to use for the transaction.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'mint',
  nonce: 69, // [!code focus]
})
```

### requestOptions

* **Type:** `{ dedupe?: boolean; signal?: AbortSignal; ... }`

The options to pass to the underlying transport request.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
const controller = new AbortController()
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'mint',
  requestOptions: { signal: controller.signal }, // [!code focus]
})
```

### type

* **Type:** `string`

The transaction type to use.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
const abi = Abi.from(['function mint()'])
// ---cut---
const hash = await Actions.contract.write(client, {
  abi,
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  functionName: 'mint',
  type: 'eip1559', // [!code focus]
})
```

### value

* **Type:** `bigint | number | Hex`

The value (in wei) to send with the transaction. Only available on `payable` functions.

```ts twoslash
import { Actions, Client, http } from 'viem'
import { mainnet } from 'viem/chains'
import { Abi, Value } from 'viem/utils'

const client = Client.create({ chain: mainnet, transport: http() })
// ---cut---
const hash = await Actions.contract.write(client, {
  abi: Abi.from(['function mint(uint32 tokenId) payable']),
  address: '0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2',
  args: [69420],
  functionName: 'mint',
  value: Value.fromEther('0.01'), // [!code focus]
})
```

## Errors

| Error | Description |
| --- | --- |
| `ContractError.ContractFunctionExecutionError` | The contract function could not be executed. Its `cause` is `ContractError.ContractFunctionRevertedError` when the call reverts. |
| `Actions.transaction.Errors.TransactionReceiptRevertedError` | The transaction receipt status was `reverted` and `throwOnReceiptRevert` was enabled. |
