> ## 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.

# Updating Contracts

> Learn how to upgrade NEAR smart contracts safely, including programmatic updates, migration strategies, and best practices for contract versioning.

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>;
};

Learn how to update NEAR smart contracts, both through tools like NEAR CLI and programmatically. Understand the implications of state migration when changing contract logic.

NEAR accounts separate their logic (contract's code) from their state (storage),
allowing the code to be changed.

Contract's can be updated in two ways:

1. **Through tools** such as [NEAR CLI](../../tools/cli) or the
   [NEAR API](../../tools/near-api) (if you hold
   the account's
   [full access key](../../protocol/accounts-contracts/access-keys)).
2. **Programmatically**, by implementing a method that
   [takes the new code and deploys it](#programmatic-update).

***

## Updating Through Tools

Simply re-deploy another contract using your preferred tool, for example, using
[NEAR CLI](../../tools/cli):

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
# (optional) If you don't have an account, create one
near create-account <account-id> --useFaucet

# Deploy the contract
near deploy <account-id> <wasm-file>
```

***

## Programmatic Update

A smart contract can also update itself by implementing a method that:

1. Takes the new wasm contract as input
2. Creates a Promise to deploy it on itself

<CodeGroup>
  <Github fname="update.rs" url="https://github.com/near-examples/update-migrate-rust/blob/main/self-updates/base/src/update.rs" start="10" end="31" />

  <Github fname="main.go" url="https://github.com/Emir-Asanov/near-go-examples/blob/example-release-1/self-update/main.go" start="10" end="53" />
</CodeGroup>

#### How to Invoke Such Method?

<Tabs>
  <Tab title="CLI">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Call the update_contract method
    near contract call-function as-transaction <contract-account> update_contract file-args </path/to/wasm.wasm> prepaid-gas '300.0 Tgas' attached-deposit '0 NEAR' sign-as <manager-account> network-config testnet sign-with-keychain send
    ```
  </Tab>

  <Tab title="🌐 JavaScript">
    ```js theme={"theme":{"light":"github-light","dark":"github-dark"}}
    // Load the contract's raw bytes
    const code = fs.readFileSync("./path/to/wasm.wasm");

    // Call the update_contract method
    await wallet.callFunction({
      contractId: guestBook,
      method: "update_contract",
      args: code,
      gas: "300000000000000",
    });
    ```
  </Tab>
</Tabs>

<Tip>
  **DAO Factories**

  This is how DAO factories
  [update their contracts](https://github.com/near-daos/sputnik-dao-contract/blob/main/sputnikdao-factory2/src/factory_manager.rs#L60)
</Tip>

***

## Migrating the State

Since the account's logic (smart contract) is separated from the account's state
(storage), **the account's state persists** when re-deploying a contract.

Because of this, **adding methods** or **modifying existing ones** will yield
**no problems**.

However, deploying a contract that **modifies or removes structures** stored in
the state will raise an error: `Cannot deserialize the contract state`, in which
case you can choose to:

1. Use a different account
2. Rollback to the previous contract code
3. Add a method to migrate the contract's state

<hr className="subsection" />

### The Migration Method

If you have no option but to migrate the state, then you need to implement a
method that:

1. Reads the current state of the contract
2. Applies different functions to transform it into the new state
3. Returns the new state

<Tip>
  **DAO Update**

  This is how DAOs
  [update themselves](https://github.com/near-daos/sputnik-dao-contract/blob/main/sputnikdao2/src/upgrade.rs#L59)
</Tip>

<hr className="subsection" />

### Example: Guest Book Migration

Imagine you have a Guest Book where you store messages, and the users can pay
for such messages to be "premium". You keep track of the messages and payments
using the following state:

<CodeGroup>
  <Github fname="lib.rs" url="https://github.com/near-examples/update-migrate-rust/blob/main/basic-updates/base/src/lib.rs" start="10" end="21" />

  <Github fname="index.js" url="https://github.com/near/near-sdk-js/blob/develop/examples/src/basic-updates/basic-updates-base.js" start="12" end="33" />

  <Github fname="main.go" url="https://github.com/Emir-Asanov/near-go-examples/blob/example-release-1/guest-book/base/main.go" start="12" end="22" />
</CodeGroup>

#### Update Contract

At some point you realize that you could keep track of the `payments` inside of
the `PostedMessage` itself, so you change the contract to:

<CodeGroup>
  <Github fname="lib.rs" url="https://github.com/near-examples/update-migrate-rust/blob/main/basic-updates/update/src/lib.rs" start="12" end="23" />

  <Github fname="index.js" url="https://github.com/near/near-sdk-js/blob/develop/examples/src/basic-updates/basic-updates-update.js" start="21" end="43" />

  <Github fname="main.go" url="https://github.com/Emir-Asanov/near-go-examples/blob/example-release-1/guest-book/v2/main.go" start="14" end="26" />
</CodeGroup>

#### Incompatible States

If you deploy the update into an initialized account the contract will fail to
deserialize the account's state, because:

1. There is an extra `payments` vector saved in the state (from the previous
   contract)
2. The stored `PostedMessages` are missing the `payment` field (as in the
   previous contract)

#### Migrating the State

To fix the problem, you need to implement a method that goes through the old
state, removes the `payments` vector and adds the information to the
`PostedMessages`:

<CodeGroup>
  <Github fname="lib.rs" url="https://github.com/near-examples/update-migrate-rust/blob/main/basic-updates/update/src/migrate.rs" start="3" end="51" />

  <Github fname="index.js" url="https://github.com/near/near-sdk-js/blob/develop/examples/src/basic-updates/basic-updates-update.js" start="5" end="68" />

  <Github fname="main.go" url="https://github.com/Emir-Asanov/near-go-examples/blob/example-release-1/guest-book/v2/main.go" start="34" end="87" />
</CodeGroup>

Notice that in Rust/JS, `migrate` is actually an [initialization method](../anatomy/storage) that **ignores** the existing state (`[#init(ignore_state)]`), thus being able to execute and rewrite the state.

In Go, `Migrate()` is a regular `@contract:mutating` method that reads the old state manually using `env.StateRead()`, transforms it, and writes the new state back — no special init directive is needed.

<Accordion title="Why we should remove old structures from the state?">
  To understand why we should remove old structures from the state let's take a look to how the data is stored.

  For example, if the old version of the contract stores two messages with payments according methods `get_messages` and `get_payments` will return the following results:

  <Accordion title="get_messags result">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    INFO --- Result -------------------------
    |    [
    |      {
    |        "premium": false,
    |        "sender": "test-ac-1719933221123-3.testnet",
    |        "text": "Hello"
    |      },
    |      {
    |        "premium": false,
    |        "sender": "test-ac-1719933221123-3.testnet",
    |        "text": "Hello"
    |      }
    |    ]
    |    ------------------------------------
    ```
  </Accordion>

  <Accordion title="get_payments result">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    INFO --- Result -------------------------
     |    [
     |      "10000000000000000000000",
     |      "10000000000000000000000"
     |    ]
     |    ------------------------------------
    ```
  </Accordion>

  But if we take a look at the storage as text using following command, we will see that each payment is stored under its own key started with `p\` prefix.

  ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
  near contract view-storage <CONTRACT_ID> all as-text network-config testnet now
  ```

  <Accordion title="Storage as text result">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    INFO Contract state (values):
     |      key:   STATE
     |      value: \x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00m\x02\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00p
     |      --------------------------------
     |      key:   m\x00\x00\x00\x00\x00\x00\x00\x00
     |      value: \x00\x1f\x00\x00\x00test-ac-1719933221123-3.testnet\x05\x00\x00\x00Hello
     |      --------------------------------
     |      key:   m\x01\x00\x00\x00\x00\x00\x00\x00
     |      value: \x00\x1f\x00\x00\x00test-ac-1719933221123-3.testnet\x05\x00\x00\x00Hello
     |      --------------------------------
     |      key:   p\x00\x00\x00\x00\x00\x00\x00\x00
     |      value: \x00\x00@\xb2\xba\xc9\xe0\x19\x1e\x02\x00\x00\x00\x00\x00\x00
     |      --------------------------------
     |      key:   p\x01\x00\x00\x00\x00\x00\x00\x00
     |      value: \x00\x00@\xb2\xba\xc9\xe0\x19\x1e\x02\x00\x00\x00\x00\x00\x00
     |      --------------------------------
    ```
  </Accordion>

  That means that while migrating the state to a new version we need not only change the messages structure, but also remove all payments related keys from the state. Otherwise, the old keys will simply stay behind being orphan, still occupying space.

  To remove them in `migrate` method, we call `clear()` method on payments vector in mutable `old_state` struct. This method removes all elements from the collection.
</Accordion>

<Tip>
  You can follow a migration step by step in the
  [official migration example](https://github.com/near-examples/update-migrate-rust/tree/main/basic-updates/base)
  Javascript migration example testfile can be found on here:
  [test-basic-updates.ava.js](https://github.com/near/near-sdk-js/blob/develop/examples/__tests__/test-basic-updates.ava.js),
  run by this command: `pnpm run test:basic-update` in examples directory.
</Tip>
