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

# Cross Contract Call

> Learn how to perform a basic cross-contract call on NEAR to set and retrieve greetings.

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

This example performs the simplest cross-contract call possible: it calls our [Hello NEAR](https://github.com/near-examples/hello-near-examples) example to set and retrieve a greeting.
It is one of the simplest examples on making a cross-contract call, and the perfect gateway to the world of interoperative contracts.

<Info>
  **Advanced Cross-Contract Calls**
  Check the tutorial on how to perform cross-contract calls [in batches and in parallel](./advanced-xcc)
</Info>

***

## Clone the Example

You have two options to start the project:

1. You can use the app through `Github Codespaces`, which will open a web-based interactive environment.
2. Clone the repository locally and use it from your computer.

| Codespaces                                                                                                                                      | Clone locally                                              |
| ----------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/near-examples/cross-contract-calls?quickstart=1) | 🌐 `https://github.com/near-examples/cross-contract-calls` |

***

## Structure of the Example

The smart contract is available in two flavors: Rust and JavaScript

<Tabs>
  <Tab title="🌐 JavaScript">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    ┌── sandbox-ts # sandbox testing
    │    ├── hello-near
    │    │    └── hello-near.wasm
    │    └── main.ava.ts
    ├── src # contract's code
    │    └── contract.ts
    ├── package.json
    ├── README.md
    └── tsconfig.json
    ```
  </Tab>

  <Tab title="🦀 Rust">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    ┌── tests # sandbox testing
    │    ├── hello-near
    │    │    └── hello-near.wasm
    │    └── tests.rs
    ├── src # contract's code
    │    ├── external.rs
    │    └── lib.rs
    ├── Cargo.toml # package manager
    ├── README.md
    └── rust-toolchain.toml
    ```
  </Tab>
</Tabs>

***

## Smart Contract

The contract exposes methods to query the greeting and change it. These methods do nothing but calling `get_greeting` and `set_greeting` in the `hello-near` example.

### Querying for the Greeting

The contract performs a cross-contract call to `hello.near-example.testnet` to get the greeting message, and then handles the response in a **callback function**.

<Tabs>
  <Tab title="🌐 JavaScript">
    <Github fname="contract.ts" language="ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-simple-ts/src/contract.ts#L25-L40" start="25" end="40" />
  </Tab>

  <Tab title="🦀 Rust (low level)">
    <Github fname="lib.rs" language="rust" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-simple-rs/src/low_level.rs#L6-L23" start="6" end="23" />
  </Tab>

  <Tab title="🦀 Rust (high level)">
    <Github fname="external.rs" language="rust" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-simple-rs/src/high_level.rs#L9-L21" start="9" end="21" />

    Which requires you to define the external contract interface:

    <Github fname="external.rs" language="rust" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-simple-rs/src/external_contract.rs" start="4" end="12" />
  </Tab>
</Tabs>

### Callback Function

The callback function processes the result of the cross-contract call. In this case, it simply returns the greeting message obtained from the `hello-near` contract.

Notice that the callback function is marked as **private**, meaning it can only be called by the contract itself.

<Tabs>
  <Tab title="🌐 JavaScript">
    <Github fname="contract.ts" language="ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-simple-ts/src/contract.ts#L42-L52" start="42" end="52" />
  </Tab>

  <Tab title="🦀 Rust">
    <Github fname="lib.rs" language="rust" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-simple-rs/src/low_level.rs#L25-L39" start="25" end="39" />
  </Tab>
</Tabs>

***

## Testing the Contract

The contract readily includes a set of unit and sandbox testing to validate its functionality. To execute the tests, run the following commands:

<Tabs>
  <Tab title="🌐 JavaScript">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    cd contract-simple-ts
    yarn
    yarn test
    ```
  </Tab>

  <Tab title="🦀 Rust">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    cd contract-simple-rs
    cargo test
    ```
  </Tab>
</Tabs>

<Tip>
  The `integration tests` use a sandbox to create NEAR users and simulate interactions with the contract.
</Tip>

In this project in particular, the integration tests first deploy the `hello-near` contract. Then,
they test that the cross-contract call correctly sets and retrieves the message. You will find the integration tests
in `sandbox-ts/` for the JavaScript version and in `tests/` for the Rust version.

<CodeGroup>
  <Github fname="main.ava.ts" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-simple-ts/sandbox-ts/main.ava.ts" start="8" end="52" />

  <Github fname="lib.rs" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-simple-rs/tests/tests.rs" start="4" end="77" />
</CodeGroup>

### Deploying the Contract to the NEAR network

In order to deploy the contract you will need to create a NEAR account.

<Tabs>
  <Tab title="Short">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Create a new account pre-funded by a faucet
    near create-account <accountId> --useFaucet
    ```
  </Tab>

  <Tab title="Full">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Create a new account pre-funded by a faucet
    near account create-account sponsor-by-faucet-service <my-new-dev-account>.testnet autogenerate-new-keypair save-to-keychain network-config testnet create
    ```
  </Tab>
</Tabs>

Go into the directory containing the smart contract (`cd contract-advanced-ts` or `cd contract-advanced-rs`), build and deploy it:

<Tabs>
  <Tab title="🌐 JavaScript">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    npm run build
    near deploy <accountId> ./build/cross_contract.wasm --initFunction new --initArgs '{"hello_account":"hello.near-example.testnet"}'
    ```
  </Tab>

  <Tab title="🦀 Rust">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    cargo near deploy build-non-reproducible-wasm <accountId> with-init-call new json-args '{"hello_account":"hello.near-example.testnet"}' prepaid-gas '100.0 Tgas' attached-deposit '0 NEAR' network-config testnet sign-with-keychain send

    ```
  </Tab>
</Tabs>

### CLI: Interacting with the Contract

To interact with the contract through the console, you can use the following commands:

<Tabs>
  <Tab title="Short">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Get message from the hello-near contract
    # Replace <accountId> with your account ID
    near call <accountId> query_greeting --useAccount <accountId>

    # Set a new message for the hello-near contract
    # Replace <accountId> with your account ID
    near call <accountId> change_greeting '{"new_greeting":"XCC Hi"}' --useAccount <accountId>
    ```
  </Tab>

  <Tab title="Full">
    ```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
    # Get message from the hello-near contract
    # Replace <accountId> with your account ID
    near contract call-function as-transaction <accountId> query_greeting json-args '{}' prepaid-gas '100.0 Tgas' attached-deposit '0 NEAR' sign-as <accountId> network-config testnet sign-with-keychain send

    # Set a new message for the hello-near contract
    # Replace <accountId> with your account ID
    near contract call-function as-transaction <accountId> change_greeting json-args '{"new_greeting":"XCC Hi"}' prepaid-gas '100.0 Tgas' attached-deposit '0 NEAR' sign-as <accountId> network-config testnet sign-with-keychain send
    ```
  </Tab>
</Tabs>

***

## Moving Forward

A nice way to learn is by trying to expand a contract. Modify the cross contract example to use the [guest-book](https://github.com/near-examples/guest-book-examples)
contract!. In this way, you can try to make a cross-contract call that attaches money. Remember to correctly [handle the callback](/smart-contracts/anatomy/crosscontract#callback-function),
and to return the money to the user in case of error.

### Advanced Cross Contract Calls

Your contract can perform multiple cross-contract calls in simultaneous, creating promises that execute in parallel, or as a batch transaction. Check the [advanced cross contract calls
tutorial](./advanced-xcc) to learn more.

<Note>
  **Versioning for this article**

  At the time of this writing, this example works with the following versions:

  * near-cli: `4.0.13`
  * node: `18.19.1`
  * rustc: `1.77.0`
</Note>
