> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nexis.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Create Transactions on the Nexis Native Chain Network

> Make your first transactions on DevNet, using the System and memo programs!

## Summary

All modifications to onchain data happen through **transactions**. Transactions
are mostly a set of instructions that invoke Nexis Native Chain programs. Transactions are
atomic, meaning they either succeed - if all the instructions have been executed
properly - or fail as if the transaction hasn't been run at all.

## Lesson

### Transactions are atomic

Any modification to onchain data happens through transactions sent to programs.

A transaction on Nexis Native Chain is similar to a transaction elsewhere: it is atomic.
**Atomic means the entire transaction runs or fails**.

Think of paying for something online:

* The balance of your account is debited
* The bank transfers the funds to the merchant

Both of these things need to happen for the transaction to be successful. If
either of them fails, none of them should happen, rather than pay the merchant
and not debit your account, or debit the account but not pay the merchant.

Atomic means either the transaction happens - meaning all the individual steps
succeed - or the entire transaction fails.

### Transactions contain instructions

The steps within a transaction on Nexis Native Chain are called **instructions**.

Each instruction contains:

* an array of accounts that will be read from and/or written to. This is what
  makes Nexis Native Chain fast - transactions that affect different accounts are processed
  simultaneously
* the public key of the program to invoke
* data passed to the program being invoked, structured as a byte array

When a transaction is run, one or more Nexis Native Chain programs are invoked with the
instructions included in the transaction.

As you might expect, `@nexis-network/web3.js` provides helper functions for creating
transactions and instructions. You can create a new transaction with the
constructor, `new Transaction()`. Once created, you can add instructions to the
transaction using the `add()` method.

One of those helper functions is `SystemProgram.transfer()`, which makes an
instruction for the `SystemProgram` to transfer some NZT:

```typescript theme={null}
const transaction = new Transaction();

const sendSolInstruction = SystemProgram.transfer({
  fromPubkey: sender,
  toPubkey: recipient,
  lamports: LAMPORTS_PER_SOL * amount,
});

transaction.add(sendSolInstruction);
```

The `SystemProgram.transfer()` function requires:

* a public key corresponding to the sender's account
* a public key corresponding to the recipient's account
* the amount of NZT to send in lamports.

`SystemProgram.transfer()` returns the instruction for sending NZT from the
sender to the recipient.

The program used in this instruction will be the `system` program (at the
address `11111111111111111111111111111111`), the data will be the amount of NZT
to transfer (in Lamports) and the accounts will be based on the sender and
recipient.

The instruction can then be added to the transaction.

Once all the instructions have been added, a transaction needs to be sent to the
cluster and confirmed:

```typescript theme={null}
const signature = sendAndConfirmTransaction(connection, transaction, [
  senderKeypair,
]);
```

The `sendAndConfirmTransaction()` function takes the following parameters:

* a cluster connection
* a transaction
* an array of keypairs that will act as signers on the transaction - in this
  example, we only have one signer: the sender.

### Transactions have fees

Transaction fees are built into the Nexis Native Chain economy as compensation to the
validator network for the CPU and GPU resources required in processing
transactions. Nexis Native Chain transaction fees are deterministic.

The first signer included in the array of signers on a transaction is
responsible for paying the transaction fee. If this signer does not have enough
NZT in their account to cover the transaction fee, the transaction will be
dropped with an error like:

```
> Transaction simulation failed: Attempt to debit an account but found no record of a prior credit.
```

If you get this error, it’s because your keypair is brand new and doesn’t have
any NZT to cover the transaction fees. Let’s fix this by adding the following
lines just after we've set up the connection:

```typescript theme={null}
await airdropIfRequired(
  connection,
  keypair.publicKey,
  1 * LAMPORTS_PER_SOL,
  0.5 * LAMPORTS_PER_SOL,
);
```

This will deposit 1 NZT into your account which you can use for testing. This
won’t work on Mainnet where it would have value. But it's incredibly convenient
for testing locally and on Devnet.

You can also use the Nexis Native Chain CLI command `solana airdrop 1` to get free test NZT
in your account when testing, whether locally or on devnet.

### Nexis Native Chain Explorer

<img src="https://mintlify.s3.us-west-1.amazonaws.com/nexisnetwork/public/assets/courses/unboxed/solana-explorer-devnet.png" alt="Nexis Native Chain Explorer set to Devnet" />

All transactions on the blockchain are publicly viewable on the
[Nexis Native Chain Explorer](http://explorer.nexis.network). For example, you could take the
signature returned by `sendAndConfirmTransaction()` in the example above, search
for that signature in the Nexis Native Chain Explorer, then see:

* when it occurred
* which block it was included in
* the transaction fee
* and more!

<img src="https://mintlify.s3.us-west-1.amazonaws.com/nexisnetwork/public/assets/courses/unboxed/solana-explorer-transaction-overview.png" alt="Nexis Native Chain Explorer with details about a transaction" />

## Lab

We’re going to create a script to send NZT to other students.

### Basic scaffolding

We'll start by using the same packages and `.env` file we made earlier in
[Intro to Cryptography](/content/courses/intro-to-solana/intro-to-cryptography).

Create a file called `transfer.ts`:

```typescript theme={null}
import {
  Connection,
  Transaction,
  SystemProgram,
  sendAndConfirmTransaction,
  PublicKey,
} from "@nexis-network/web3.js";
import "dotenv/config";
import { getKeypairFromEnvironment } from "@nexis-network-developers/helpers";

const suppliedToPubkey = process.argv[2] || null;

if (!suppliedToPubkey) {
  console.log(`Please provide a public key to send to`);
  process.exit(1);
}

const senderKeypair = getKeypairFromEnvironment("SECRET_KEY");

console.log(`suppliedToPubkey: ${suppliedToPubkey}`);

const toPubkey = new PublicKey(suppliedToPubkey);

const connection = new Connection("https://api.devnet.nexis.network", "confirmed");

console.log(
  `✅ Loaded our own keypair, the destination public key, and connected to Nexis Native Chain`,
);
```

Run the script to ensure it connects, loads your keypair, and loads:

```bash theme={null}
npx esrun transfer.ts (destination wallet address)
```

### Create the transaction and run it

Add the following to complete the transaction and send it:

```typescript theme={null}
console.log(
  `✅ Loaded our own keypair, the destination public key, and connected to Nexis Native Chain`,
);

const transaction = new Transaction();

const LAMPORTS_TO_SEND = 5000;

const sendSolInstruction = SystemProgram.transfer({
  fromPubkey: senderKeypair.publicKey,
  toPubkey,
  lamports: LAMPORTS_TO_SEND,
});

transaction.add(sendSolInstruction);

const signature = await sendAndConfirmTransaction(connection, transaction, [
  senderKeypair,
]);

console.log(
  `💸 Finished! Sent ${LAMPORTS_TO_SEND} to the address ${toPubkey}. `,
);
console.log(`Transaction signature is ${signature}!`);
```

### Experiment!

Send NZT to other students in the class.

```bash theme={null}
npx esrun transfer.ts (destination wallet address)
```

## Challenge

Answer the following questions:

* How much NZT did the transfer take? What is this in USD?

* Can you find your transaction on [https://explorer.nexis.network](https://explorer.nexis.network)? Remember we are
  using the `devnet` network.

* How long does the transfer take?

* What do you think "confirmed" means?

<Callout type="success">
  ### Completed the lab?

  Push your code to GitHub and
  [tell us what you thought of this lesson](https://form.typeform.com/to/IPH0UGz7#answers-lesson=dda6b8de-9ed8-4ed2-b1a5-29d7a8a8b415)!
</Callout>
