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

# Basic Auction

> Learn how to build n auction smart contract on NEAR.

export const Github = ({url, start, end, fname, withSourceLink = true}) => {
  const [code, setCode] = useState(null);
  function toRaw(ref) {
    const fullUrl = ref.slice(ref.indexOf('https'));
    const [url] = fullUrl.split('#');
    const [org, repo, , branch, ...pathSeg] = new URL(url).pathname.split('/').slice(1);
    return `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${pathSeg.join('/')}`;
  }
  async function fetchCode(url, fromLine, toLine) {
    let res;
    if (typeof window !== 'undefined') {
      const validUntil = localStorage.getItem(`${url}-until`);
      if (validUntil && Number(validUntil) > Date.now()) {
        res = localStorage.getItem(url);
      }
    }
    if (!res) {
      try {
        res = await (await fetch(url)).text();
        if (typeof window !== 'undefined') {
          localStorage.setItem(url, res);
          localStorage.setItem(`${url}-until`, String(Date.now() + 60000));
        }
      } catch {
        return 'Error fetching code, please try reloading';
      }
    }
    let body = res.split('\n');
    const from = fromLine ? Number(fromLine) - 1 : 0;
    const to = toLine ? Number(toLine) : body.length;
    body = body.slice(from, to);
    const precedingSpace = body.reduce((prev, line) => {
      if (line.length === 0) return prev;
      const spaces = line.match(/^\s+/);
      if (spaces) return Math.min(prev, spaces[0].length);
      return 0;
    }, Infinity);
    return body.map(line => line.slice(precedingSpace === Infinity ? 0 : precedingSpace)).join('\n');
  }
  function buildSourceUrl(url, start, end) {
    const base = url.split('#')[0];
    if (start && end) return `${base}#L${start}-L${end}`;
    if (start) return `${base}#L${start}`;
    return base;
  }
  useEffect(() => {
    const rawUrl = toRaw(url);
    fetchCode(rawUrl, start, end).then(res => setCode(res));
  }, [url, start, end]);
  const sourceUrl = buildSourceUrl(url, start, end);
  const startLine = start ? Number(start) : 1;
  const fileName = fname ?? sourceUrl.split('/').pop();
  return <div className="rounded-[0.625rem] border border-[#d0d7de] dark:border-[#30363d] overflow-hidden my-5 text-[0.8125rem] font-mono shadow-sm dark:shadow-[0_4px_24px_rgba(0,0,0,0.18)]">

      {}
      <div className="flex items-center justify-between py-2 px-[0.875rem] bg-[#f6f8fa] dark:bg-[#161b22] border-b border-[#d0d7de] dark:border-[#30363d]">
        <div className="flex items-center gap-2 text-[#656d76] dark:text-[#8b949e]">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor">
            <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z" />
          </svg>
          <span className="text-xs font-medium text-[#1f2328] dark:text-[#e6edf3]">
            {fileName}
          </span>
        </div>
        {start && end && <span className="text-[0.6875rem] text-[#656d76] dark:text-[#8b949e] bg-[#eaeef2] dark:bg-[#21262d] border border-[#d0d7de] dark:border-[#30363d] rounded-full py-0.5 px-2">
            Lines {start}–{end}
          </span>}
      </div>

      {}
      <div className="overflow-auto max-h-[480px] bg-white dark:bg-[#0d1117] [&_tr]:border-b-0 [&_td]:border-b-0">
        {code === null ? <div className="py-5 px-4 text-xs text-[#656d76] dark:text-[#6e7681]">
            Loading...
          </div> : <table className="w-full border-collapse leading-[1.6]">
            <tbody>
              {code.split('\n').map((line, i) => <tr key={i} className="align-top border-0">
                  <td style={{
    minWidth: '60px'
  }} className="select-none pl-2 pr-3 text-right text-[0.7rem] text-[#8c959f] dark:text-[#3d444d] w-[1%] whitespace-nowrap border-r border-0 border-r-[#d0d7de] dark:border-r-[#21262d]">
                    {startLine + i}
                  </td>
                  <td className="pl-4 pr-6 text-[0.8125rem] text-[#1f2328] dark:text-[#e6edf3] whitespace-pre">
                    {line || ' '}
                  </td>
                </tr>)}
            </tbody>
          </table>}
      </div>

      {}
      {withSourceLink && <div className="flex justify-end py-1.5 px-[0.875rem] bg-[#f6f8fa] dark:bg-[#161b22] border-t border-[#d0d7de] dark:border-[#21262d]">
          <a href={sourceUrl} target="_blank" rel="noreferrer noopener" className="text-[0.6875rem] font-medium text-[#656d76] dark:text-[#8b949e] no-underline flex items-center gap-[0.3rem] hover:text-[#1f2328] dark:hover:text-[#e6edf3] transition-colors">
            View on GitHub
            <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
              <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
              <polyline points="15 3 21 3 21 9" />
              <line x1="10" y1="14" x2="21" y2="3" />
            </svg>
          </a>
        </div>}
    </div>;
};

In this section, we will analyze a simple auction contract, which allows users to place bids, track the highest bidder and claim tokens at the end of the auction. After, we will cover how to test the contract, as well as how to deploy it on `testnet`.

<Info>
  **Documentation**

  During this tutorial, we will be relying on the [Smart Contract Documentation](/smart-contracts/quickstart) and its different sections
</Info>

<Tip>
  **Prerequisites**

  Make sure to read the [Prerequisites](./0-intro) section and install the necessary tools before starting this tutorial
</Tip>

***

## Cloning the contract

To get started we'll clone the [tutorial's repository](https://github.com/near-examples/auctions-tutorial) from GitHub. The repository contains the same smart contracts written in JavaScript (`./contract-ts`) and Rust (`./contract-rs`).

Navigate to the folder of the language you prefer, and then to the `01-basic-auction` folder.

<Tabs>
  <Tab title="🌐 JavaScript">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    git clone git@github.com:near-examples/auctions-tutorial.git

    cd contract-ts/01-basic-auction
    ```
  </Tab>

  <Tab title="🦀 Rust">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    git clone git@github.com:near-examples/auctions-tutorial.git

    cd contract-rs/01-basic-auction
    ```
  </Tab>
</Tabs>

<Info>
  **Frontend**

  The repository also contains a frontend application that interacts with the contract. You can find it in the `frontends` folder. We will cover the frontend in a future section
</Info>

***

## The Contract's State

The contract allows users to place bids using `$NEAR` tokens and keeps track of the highest bidder. Lets start by looking at how we define the contract's state, this is, the data that the contract will store.

<Tabs>
  <Tab title="🌐 JavaScript">
    <Github fname="contract.ts" language="javascript" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-ts/01-basic-auction/src/contract.ts#L4-L14" start="4" end="14" />

    #### Decorator

    The first thing to notice is that the main class of the contract is marked using the `@NearBindgen` decorator, which allows also to further specify that the contract **must be initialized** before being used.

    #### Storage (aka State)

    Another important information revealed by the code is that a contract can store different types of data, in this case:

    * `highest_bid` is an instance of a `Bid` which stores:
      * `bid`: a `BigInt` representing an amount of `$NEAR` tokens in `yoctonear` (`1Ⓝ = 10^24 yⓃ`)
      * `bidder`: an `AccountId` that represents which account placed the bid
    * `auction_end_time` a `BigInt` representing a `unix timestamp` in **nanoseconds**
    * `auctioneer` an `AccountId` that states who can withdraw the funds at the end of the auction
    * `claimed` a `boolean` that tracks if the auctioneer has claimed the funds
  </Tab>

  <Tab title="🦀 Rust">
    <Github fname="lib.rs" language="rust" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-rs/01-basic-auction/src/lib.rs#L5-L19" start="5" end="19" />

    #### Macros

    A first thing to notice is the use of the `#[near(contract_state)]` macro to denote the main structure and derive the `PanicOnDefault` to specify that the contract **must be initialized** before being used.

    We also use the `#[near(serializers = [json, borsh])]` macro to enable both `borsh` and `JSON` (de)serialization of the `Bid` structure. As a rule of thumb: use the `json` serializer for structs that will be used as input / output of functions, and `borsh` for those that will be saved to state.

    #### Storage (aka State)

    Another important information revealed by the code is that the contract can store different types of data.

    * `highest_bid` is an instance of a `Bid` which stores:
      * `bid`: a `NearToken` which simplifies handling `$NEAR` token amounts
      * `bidder`: the `AccountId` that placed the bid
    * `auction_end_time` is a `U64` representing a `unix timestamp` in **nanoseconds**
    * `auctioneer` an `AccountId` that states who can withdraw the funds at the end of the auction
    * `claimed` a `boolean` that tracks if the auctioneer has claimed the funds
  </Tab>
</Tabs>

<Tip>
  **Learn More**

  You can read more about the contract's structure and the type of data it can store in the following documentation pages:

  * [Basic Contract's Anatomy](/smart-contracts/anatomy/anatomy)
  * [Contract's State](/smart-contracts/anatomy/storage)
  * [Data Types](/smart-contracts/anatomy/types)
</Tip>

***

## Initialization Function

Lets now take a look at the initialization function, which we need to call to determine the time at which the auction will end.

<Tabs>
  <Tab title="🌐 JavaScript">
    <Github fname="contract.ts" language="javascript" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-ts/01-basic-auction/src/contract.ts#L16-#L21" start="16" end="21" />

    #### Decorator

    We denote the initialization function using the `@initialize({ privateFunction: true })` decorator. The `privateFunction:true` denotes that the function can only be called by the account on which the contract is deployed.
  </Tab>

  <Tab title="🦀 Rust">
    <Github fname="lib.rs" language="rust" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-rs/01-basic-auction/src/lib.rs#L23-L35" start="23" end="35" />

    #### Macros

    We denote the initialization function using the `#[init]` macro. Notice that the initialization function needs to return an instance of `Self`, i.e. the contract's structure.

    Meanwhile, the `#[private]` denotes that the function can only be called by the account on which the contract is deployed.
  </Tab>
</Tabs>

#### End Time

The end time is represented using a `unix timestamp` in **nano seconds**, and needs to be given as a `String` when calling the initialization function. This is because smart contracts cannot receive numbers larger than `52 bits` and `unix timestamps` are represented in `64 bits`.

#### Initial Bid

Notice that we initialize the contract with a `1 yoctonear` bid, made from the `current account id`. This means that, after the contract is initialized, the first bid will be placed by the contract at 10^-24 NEAR.

#### Claimed

The `claimed` field is initialized as `false`, as the auctioneer has not claimed the funds yet.

#### Auctioneer

The auctioneer is set by the deployer on initialization and is the account that will be able to claim the funds at the end of the auction.

<Tip>
  **Learn More**

  You can read more about the contract's interface in our [contract functions documentation](/smart-contracts/anatomy/functions), and learn about data types on the [data types documentation](/smart-contracts/anatomy/types).
</Tip>

***

## Read-only Functions

The contract implements four functions to give access to its stored data, i.e. the highest bid so far (the amount and by whom), the time at which the auction ends, the auctioneer, and whether the auction has been claimed.

<Tabs>
  <Tab title="🌐 JavaScript">
    <Github fname="contract.ts" language="javascript" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-ts/01-basic-auction/src/contract.ts#L53-L71" start="53" end="71" />

    Functions that do not change the contract's state (i.e. that only read from it) are called `view` functions, and are decorated using the `@view` decorator.
  </Tab>

  <Tab title="🦀 Rust">
    <Github fname="lib.rs" language="rust" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-rs/01-basic-auction/src/lib.rs#L78-L92" start="78" end="92" />

    Functions that do not change the contract's state (i.e. that only read from it) are called `view` functions and take a non-mutable reference to `self` (`&self`).
  </Tab>
</Tabs>

View functions are **free to call**, and do **not require** a NEAR account to sign a transaction in order to call them.

<Tip>
  **Learn More**

  You can read more about the contract's interface in our [contract functions documentation](/smart-contracts/anatomy/functions), and learn about data types on the [data types documentation](/smart-contracts/anatomy/types).
</Tip>

***

## Bidding Function

An auction is not an auction if you can't place a bid! For this, the contract includes a `bid` function, which users will call attaching some `$NEAR` tokens.

The function is quite simple: it verifies if the auction is still active and compares the attached deposit with the current highest bid. If the bid is higher, it updates the `highest_bid` and refunds the previous bidder.

<Tabs>
  <Tab title="🌐 JavaScript">
    <Github fname="contract.ts" language="javascript" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-ts/01-basic-auction/src/contract.ts#L23-L43" start="23" end="43" />
  </Tab>

  <Tab title="🦀 Rust">
    <Github fname="lib.rs" language="rust" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-rs/01-basic-auction/src/lib.rs#L37-L63" start="37" end="63" />
  </Tab>
</Tabs>

#### Payable Functions

The first thing to notice is that the function changes the state, and thus is marked with a `@call` decorator in JS, while taking as input a mutable reference to self (`&mut self`) on Rust. To call this function, a NEAR account needs to sign a transaction and expend GAS.

Second, the function is marked as `payable`, this is because by default **functions do not accept `$NEAR` tokens**! If a user attaches tokens while calling a function that is not marked as `payable`, the transaction will fail.

#### The Environment

Notice that the function can access information about the environment in which it is running, such as who called the function (`predecessor account`), how many tokens they attached as deposit (`attached deposit`), and the approximate `unix timestamp` at which the function is executing (`block timestamp`).

#### Token Transfer

The function finishes by creating a `Promise` to transfer tokens to the previous bidder. This token amount will be deducted immediately and transferred in the next block after the current function has finished executing.

Note that on the first bid, the contract will send 1 yoctonear to itself, this is fine as we can safely assume that the contract will have the lowest denomination of `$NEAR` available to send to itself.

<Accordion title="Handling Funds">
  When a user attaches tokens to a call, the tokens are deposited to the contract's account before the function is executed. However, if the function raises an error during its execution, the tokens are immediately refunded to the user.
</Accordion>

<Tip>
  **Learn More**

  You can read more about the environment variables, payable functions and which actions the contract can perform here:

  * [Environment Variables](/smart-contracts/anatomy/environment)
  * [Payable Functions](/smart-contracts/anatomy/functions)
  * [Transfers and Actions](/smart-contracts/anatomy/actions)
</Tip>

***

## Claim function

You'll notice that the contract has a final function called `claim`, this allows the auctioneer to claim the funds from the contract at the end of the auction. Since, on NEAR, a smart contract account and user account are the same, contracts can still have keys when they are deployed, thus a user could just claim the funds from the contract via a wallet. However, this presents a security issue since by having a key the key holder can take the funds from the contract at any point, maliciously change the contract's state or just delete the contract as a whole. By implementing a `claim` function we can later lock the contract by removing all access keys and have the auctioneer claim the funds via preset conditions via code.

<Tabs>
  <Tab title="🌐 JavaScript">
    <Github fname="contract.ts" language="javascript" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-ts/01-basic-auction/src/contract.ts#L45-L51" start="45" end="51" />
  </Tab>

  <Tab title="🦀 Rust">
    <Github fname="lib.rs" language="rust" url="https://github.com/near-examples/auctions-tutorial/blob/main/contract-rs/01-basic-auction/src/lib.rs#L65-L76" start="65" end="76" />
  </Tab>
</Tabs>

This function is quite simple it does four things:

1. Checks that the auction has ended (the current timestamp is past the auction end time).
2. Checks that the auction has not yet been claimed.
3. Sets the auction as now claimed.
4. And if these conditions hold true it transfers `$NEAR` equal to the highest bid to the auctioneer.

<Tip>
  **Learn More**

  You can read more about locking contracts in this section of the documentation: [locked accounts](/protocol/accounts-contracts/access-keys#locked-accounts)
</Tip>

***

## Conclusion

In this part of the tutorial, we've seen how a smart contract stores data, mutates the stored data, and views the data. In the [next part](./1.2-testing), we will cover how to test the contract, so we can ensure it works as expected before deploying it to `testnet`.
