---
title: Writing to Network
description:
  Learn how to interact with the Solana network by sending transactions and
  instructions. Follow step-by-step examples to transfer SOL tokens and create
  new tokens using the System Program and Token Extensions Program.
---

In the previous section, we learned how to read data from the Solana network.
Now let's explore how to write data to it. Writing to the Solana network
involves sending transactions that contain one or more instructions.

These instructions are processed by programs (smart contracts) that contain the
business logic for each respective instruction. When you submit a transaction,
the Solana runtime executes each instruction in sequence and atomically (meaning
either all instructions succeed or the entire transaction fails).

In this section, we'll walk through two basic examples:

1. Transferring SOL between accounts
2. Creating a new token

These examples demonstrate how to build and send transactions to invoke Solana
programs. For more details, refer to the
[Transactions and Instructions](/docs/core/transactions) and
[Fees on Solana](/docs/core/fees) pages.

## Transfer SOL

Let's start with a simple example of transferring SOL between accounts. To
transfer SOL from our Playground wallet, we need to invoke the System Program's
[transfer](https://github.com/anza-xyz/agave/blob/v2.1.11/programs/system/src/system_processor.rs#L183-L213)
instruction.

A key concept of Solana's account model is that only the program that owns an
account can deduct an account's lamport (SOL) balance. This means if you want to
transfer SOL from a wallet account, you must invoke the System Program since it
is the program specified in the
[owner](https://github.com/anza-xyz/agave/blob/v2.1.11/sdk/account/src/lib.rs#L55)
field of the account.

<Steps>
<Step>

### Open Example

Click this [link](https://beta.solpg.io/6671d85ecffcf4b13384d19e) to open the
example in Solana Playground. You'll see the following code:

```ts title="client.ts"
import {
  LAMPORTS_PER_SOL,
  SystemProgram,
  Transaction,
  sendAndConfirmTransaction,
  Keypair,
} from "@solana/web3.js";

const sender = pg.wallet.keypair;
const receiver = new Keypair();

const transferInstruction = SystemProgram.transfer({
  fromPubkey: sender.publicKey,
  toPubkey: receiver.publicKey,
  lamports: 0.01 * LAMPORTS_PER_SOL,
});

const transaction = new Transaction().add(transferInstruction);

const transactionSignature = await sendAndConfirmTransaction(
  pg.connection,
  transaction,
  [sender],
);

console.log(
  "Transaction Signature:",
  `https://solana.fm/tx/${transactionSignature}?cluster=devnet-solana`,
);
```

<Accordions>
<Accordion title="Explanation">

This example does the following:

- Set your Playground wallet as the `sender`

  ```ts
  const sender = pg.wallet.keypair;
  ```

- Creates a new keypair as the `receiver`

  ```ts
  const receiver = new Keypair();
  ```

- Constructs a transfer instruction to transfer 0.01 SOL

  ```ts
  const transferInstruction = SystemProgram.transfer({
    fromPubkey: sender.publicKey,
    toPubkey: receiver.publicKey,
    lamports: 0.01 * LAMPORTS_PER_SOL,
  });
  ```

- Builds a transaction including the transfer instruction

  ```ts
  const transaction = new Transaction().add(transferInstruction);
  ```

- Sends and confirms the transaction

  ```ts
  const transactionSignature = await sendAndConfirmTransaction(
    pg.connection,
    transaction,
    [sender],
  );
  ```

- Prints out a link to the SolanaFM explorer in the Playground terminal to view
  the transaction details

  ```ts
  console.log(
    "Transaction Signature:",
    `https://solana.fm/tx/${transactionSignature}?cluster=devnet-solana`,
  );
  ```

</Accordion>
</Accordions>

</Step>
<Step>

### Run Example

Run the code using the `run` command.

```shell title="Terminal"
run
```

<Callout type="info">

Ensure your Playground wallet has devnet SOL. Get devnet SOL from the
[Solana Faucet](https://faucet.solana.com/).

</Callout>

Click on the output link to view the transaction details on the SolanaFM
explorer.

<Accordions>
<Accordion title="Output">

```shell title="Terminal"
Running client...
  client.ts:
    Transaction Signature: https://solana.fm/tx/he9dBwrEPhrfrx2BaX4cUmUbY22DEyqZ837zrGrFRnYEBmKhCb5SvoaUeRKSeLFXiGxC8hFY5eDbHqSJ7NYYo42?cluster=devnet-solana
```

</Accordion>
</Accordions>

![Transfer SOL](/assets/docs/intro/quickstart/transfer-sol.png)

Congratulations! You've just sent your first transaction on Solana! Let's break
down what happened:

- First, we created an instruction specifying what we wanted to do
- Then, we added that instruction to a transaction
- Finally, we sent the transaction to be processed by the Solana network

This is the basic pattern for building transactions to interact with the
programs on the Solana.

</Step>
</Steps>

## Create a Token

Next, let's create a new token using the Token Extensions Program. This requires
two invoking instructions:

1. Create a new account using the System Program
2. Initialize the account's data as a Mint using the Token Extensions Program

<Steps>
<Step>

### Open Example

Click this [link](https://beta.solpg.io/6671da4dcffcf4b13384d19f) to open the
example in Solana Playground. You'll see the following code:

```ts title="client.ts"
import {
  Connection,
  Keypair,
  SystemProgram,
  Transaction,
  clusterApiUrl,
  sendAndConfirmTransaction,
} from "@solana/web3.js";
import {
  MINT_SIZE,
  TOKEN_2022_PROGRAM_ID,
  createInitializeMint2Instruction,
  getMinimumBalanceForRentExemptMint,
} from "@solana/spl-token";

const wallet = pg.wallet;
const connection = new Connection(clusterApiUrl("devnet"), "confirmed");

// Generate keypair to use as address of mint account
const mint = new Keypair();

// Calculate minimum lamports for space required by mint account
const rentLamports = await getMinimumBalanceForRentExemptMint(connection);

// Instruction to create new account with space for new mint account
const createAccountInstruction = SystemProgram.createAccount({
  fromPubkey: wallet.publicKey,
  newAccountPubkey: mint.publicKey,
  space: MINT_SIZE,
  lamports: rentLamports,
  programId: TOKEN_2022_PROGRAM_ID,
});

// Instruction to initialize mint account
const initializeMintInstruction = createInitializeMint2Instruction(
  mint.publicKey,
  2, // decimals
  wallet.publicKey, // mint authority
  wallet.publicKey, // freeze authority
  TOKEN_2022_PROGRAM_ID,
);

// Build transaction with instructions to create new account and initialize mint account
const transaction = new Transaction().add(
  createAccountInstruction,
  initializeMintInstruction,
);

const transactionSignature = await sendAndConfirmTransaction(
  connection,
  transaction,
  [
    wallet.keypair, // payer
    mint, // mint address keypair
  ],
);

console.log(
  "\nTransaction Signature:",
  `https://solana.fm/tx/${transactionSignature}?cluster=devnet-solana`,
);

console.log(
  "\nMint Account:",
  `https://solana.fm/address/${mint.publicKey}?cluster=devnet-solana`,
);
```

<Accordions>
<Accordion title="Explanation">

This example does the following:

- Gets your Playground wallet and creates a connection to the Solana devnet

  ```ts
  const wallet = pg.wallet;
  const connection = new Connection(clusterApiUrl("devnet"), "confirmed");
  ```

- Generates a new keypair to use as the address of the Mint account

  ```ts
  const mint = new Keypair();
  ```

- Calculates the minimum lamports needed for a Mint account

  ```ts
  const rentLamports = await getMinimumBalanceForRentExemptMint(connection);
  ```

- Construct a System Program instruction to create a new account. The
  instruction:

  1. Transfers lamports from the wallet to fund the new account
  2. Allocates the required space for storing mint data
  3. Assigns ownership of the account to the Token Extensions program
     (`TOKEN_2022_PROGRAM_ID`)

  ```ts
  const createAccountInstruction = SystemProgram.createAccount({
    fromPubkey: wallet.publicKey,
    newAccountPubkey: mint.publicKey,
    space: MINT_SIZE,
    lamports: rentLamports,
    programId: TOKEN_2022_PROGRAM_ID,
  });
  ```

- Construct a Token Extensions Program instruction to initialize the Mint
  account data

  ```ts
  const initializeMintInstruction = createInitializeMint2Instruction(
    mint.publicKey,
    2,
    wallet.publicKey,
    wallet.publicKey,
    TOKEN_2022_PROGRAM_ID,
  );
  ```

- Adds both instructions to a single transaction

  ```ts
  const transaction = new Transaction().add(
    createAccountInstruction,
    initializeMintInstruction,
  );
  ```

- Sends and confirms the transaction with two required signers:

  1. The wallet keypair to pay for account creation and transaction fee
  2. The mint keypair because we're creating a new account using its public key
     as the address of the account

  ```ts
  const transactionSignature = await sendAndConfirmTransaction(
    connection,
    transaction,
    [wallet.keypair, mint],
  );
  ```

- Prints out links to view the transaction and mint account details on SolanaFM

  ```ts
  console.log(
    "\nTransaction Signature:",
    `https://solana.fm/tx/${transactionSignature}?cluster=devnet-solana`,
  );

  console.log(
    "\nMint Account:",
    `https://solana.fm/address/${mint.publicKey}?cluster=devnet-solana`,
  );
  ```

</Accordion>
</Accordions>

</Step>
<Step>

### Run Example

Run the code using the `run` command.

```shell title="Terminal"
run
```

<Callout type="info">

Ensure your Playground wallet has devnet SOL. Get devnet SOL from the
[Solana Faucet](https://faucet.solana.com/).

</Callout>

You'll see two links printed to the Playground terminal:

- One for the transaction details
- One for the newly created mint account

Click the links to inspect the transaction details and the newly created mint
account on SolanaFM.

<Accordions>
<Accordion title="Output">

```shell title="Terminal"
Running client...
  client.ts:

Transaction Signature: https://solana.fm/tx/3BEjFxqyGwHXWSrEBnc7vTSaXUGDJFY1Zr6L9iwLrjH8KBZdJSucoMrFUEJgWrWVRYzrFvbjX8TmxKUV88oKr86g?cluster=devnet-solana

Mint Account: https://solana.fm/address/CoZ3Nz488rmATDhy1hPk5fvwSZaipCngvf8rYBYVc4jN?cluster=devnet-solana
```

</Accordion>
</Accordions>

![Create Token](/assets/docs/intro/quickstart/create-token.png)

![Mint Account](/assets/docs/intro/quickstart/mint-account.png)

In this example, we demonstrated how to combine multiple instructions into a
single transaction. The transaction contains two key instructions:

1. Creating a new account using the System Program
2. Initializing that account as a token mint using the Token Extensions Program

This pattern of combining multiple instructions from different programs into one
transaction is common when building more complex Solana transactions. It allows
you to sequentially and atomically execute multiple instructions, ensuring they
either all succeed or all fail together.

</Step>
</Steps>
