> ## 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, language, 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 fileName = fname ?? sourceUrl.split('/').pop();
  return <div className="my-5">
      {code === null ? <div>Loading...</div> : <CodeBlock language={language} filename={fileName} lines>
          {code}
        </CodeBlock>}
      {withSourceLink && <div className="flex justify-end" style={{
    marginTop: "-1rem"
  }}>
          <a href={sourceUrl} target="_blank" rel="noreferrer noopener" className="text-[0.6875rem] font-medium text-[#656d76] no-underline hover:text-[#1f2328] dark:text-[#8b949e] dark:hover:text-[#e6edf3]">
            See code on GitHub
          </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**
  The final part of this tutorial shows how to perform cross-contract calls [in batches and in parallel](#advanced-cross-contract-calls).
</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 written in Rust and has the following structure:

```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
```

***

## 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="🦀 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="8" />
  </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.

<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" />

***

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

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
cd contract-simple-rs
cargo test
```

<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 `tests/`.

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

### 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-simple-rs`), build and deploy it:

```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

```

### 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 combine promises to execute several actions sequentially or call several contracts in parallel. The advanced examples live in the same [cross-contract-calls repository](https://github.com/near-examples/cross-contract-calls), under `contract-advanced-rs`.

### Batch actions

You can combine several actions for the same contract into a batch. The actions execute sequentially, and if one fails, they are all reverted.

<Github fname="batch_actions.rs" language="rust" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-rs/src/batch_actions.rs" start="8" end="20" />

The callback receives the value returned by the final action in the chain:

<Github fname="batch_actions.rs" language="rust" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-rs/src/batch_actions.rs" start="22" end="35" />

### Call multiple contracts in parallel

A contract can call several contracts in parallel. If one call fails, the other calls are **not** reverted.

<Github fname="multiple_contracts.rs" language="rust" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-rs/src/multiple_contracts.rs" start="16" end="55" />

The callback receives one result for each promise and must handle successes and failures independently:

<Github fname="multiple_contracts.rs" language="rust" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-rs/src/multiple_contracts.rs" start="57" end="90" />

If every call returns the same type, you can iterate over the promise results directly:

<Github fname="similar_contracts.rs" language="rust" url="https://github.com/near-examples/cross-contract-calls/blob/main/contract-advanced-rs/src/similar_contracts.rs" start="8" end="57" />

### Test and deploy the advanced contract

Run its unit and Sandbox tests locally:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
cd contract-advanced-rs
cargo test
```

Build, deploy, and initialize the contract with the accounts it will call:

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

Call the examples with enough prepaid gas for their child calls and callbacks:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
near contract call-function as-transaction <account-id> batch_actions json-args '{}' prepaid-gas '300.0 Tgas' attached-deposit '0 NEAR' sign-as <account-id> network-config testnet sign-with-keychain send

near contract call-function as-transaction <account-id> multiple_contracts json-args '{}' prepaid-gas '300.0 Tgas' attached-deposit '0 NEAR' sign-as <account-id> network-config testnet sign-with-keychain send

near contract call-function as-transaction <account-id> similar_contracts json-args '{}' prepaid-gas '300.0 Tgas' attached-deposit '0 NEAR' sign-as <account-id> network-config testnet sign-with-keychain send
```

<Info>
  If a call reports `Exceeded the prepaid gas`, review the gas attached to the child calls and callbacks before increasing the gas on the initiating transaction.
</Info>

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