# ABI і дані виклику

> Формат виклику контрактів NeuroChain — дані виклику в JSON з function і args, як контракт читає аргументи, ідентичність того, хто викликає, через хост, прикріплена сума, результат, помилки та стандартний інтерфейс NRC-20.

Source: https://docs.nro.world/uk/build/abi

Виклик контракту — це транзакція на адресу `.app`, поле `data` якої містить виклик. Канонічний формат — JSON у UTF-8:

```json
{"function":"transfer","args":{"to":"neuro:bob.human","amount":"250"}}
```

У транзакції `data` містить цей JSON **рядком** (hex-кодування теж приймається). Нода передає байти експорту контракту `call(input_ptr, input_len)`.

## Правила

| Правило | Чому |
|---------|------|
| **Назву методу передавайте в `function`.** | Старі контракти приймали й `method`; у новому коді не треба. |
| **Ідентичність — від хоста.** Викликайте `get_caller()`; ігноруйте поле `caller` у JSON. | У JSON будь-хто може записати будь-який `caller`. Значення хоста — перевірений підписант транзакції (або контракт, що викликає, у міжконтрактному виклику). |
| **Надсилайте компактний JSON.** Без пробілів після `:` і `,` — як дає `JSON.stringify`. | Невеликі `no_std`-контракти шукають аргументи побайтовим пошуком `"key":`; пробіли це ламають. |
| **Суми — десятковими рядками** в цілих токенах: `"amount":"250"`. | Нода їх переводить (див. нижче); рядки не втрачають точності в JavaScript. |
| **Назви аргументів у `args` мають бути унікальними.** | Побайтовий пошук знаходить перше `"key":` будь-де в даних, тож `args` можна передати й на верхньому рівні. |

## Суми переводить нода

Перш ніж виклик дійде до контракту, нода переписує за вас один аргумент:

- **Виклики контрактів:** `args.amount`, заданий десятковим рядком чи числом, вважається сумою в **цілих токенах** і переводиться в найменші одиниці за `decimals` контракту (`"250"` при 6 знаках → `250000000`).
- **Розгортання:** `init_args.total_supply` переводиться так само за `init_args.decimals`, який має бути **числом** JSON (рядок читається як 0 знаків).

Усі інші аргументи доходять до контракту без змін. Людську суму контракт не бачить ніколи.

## Прикріплена сума

`value` транзакції (в uNRO) зараховується на акаунт контракту **після** успішного виклику. Якщо виклик перервався чи вичерпав fuel, сума лишається у відправника. Host-функції, яка повідомила б контракту прикріплену суму, поки немає; якщо вона потрібна, контракт може порівняти `get_balance()` до і після або прийняти суму аргументом і перевірити її.

## Результат і помилки

Контракт повертає байти через `set_return(ptr, len)`. За домовленістю:

```json
{"ok":"<value>"}            // успіх
{"error":"Unknown function"}  // помилка, яку повідомив контракт
```

Контракт, що **перервався** (`unreachable`, вичерпано fuel, доступ за межі пам'яті), робить транзакцію невдалою: зміни сховища відкочено, сума не переміщена, комісія й nonce витрачені. Статус: `failed`.

Прочитати результат без транзакції:

```bash
curl -s -X POST "$GATEWAY/api/v1/contracts/neuro:<10 hex>.app/call" \
  -H 'Content-Type: application/json' \
  -d '{"function":"balance_of","args":{"address":"neuro:<15 hex>.human"},"dry_run":true}'
```

У відповіді — `success`, `return_data`, `gas_used` і події, які виклик створив би. Записуючі виклики через цей ендпоінт (`dry_run: false`) відхиляються, коли нода працює з `CHAIN_ENV=mainnet`; надсилайте транзакцію.

## Конструктор і `initialize`

- Експорт `init`, якщо є, виконується один раз під час розгортання.
- Якщо розгортання містить `init_args`, контракт потім викликається з `{"function":"initialize", …init_args}` — аргументи на верхньому рівні. Див. [Розгортання контрактів](./deploy#_4-what-every-validator-does).

## Стандартні інтерфейси

Інтерфейс — це задокументований набір методів, а не додаткові WASM-експорти: контракт реалізує його, відповідаючи на назви функцій.

### NRC-20 (взаємозамінний токен)

Реалізовано в `neurochain/contracts/nrc20`. Усередині контракту кожна сума — ціле число в найменших одиницях токена; надсилайте `amount` у цілих токенах, нода переведе (див. вище).

| Функція | Аргументи | Примітки |
|---------|-----------|----------|
| `initialize` | `name`, `symbol`, `decimals`, `total_supply` | Один раз; випускає всю пропозицію тому, хто викликав, і робить його `owner` |
| `name`, `symbol`, `decimals`, `total_supply` | — | Читання |
| `balance_of` | `address` | Читання |
| `transfer` | `to`, `amount` | Від того, хто викликав |
| `approve` | `spender`, `amount` | |
| `allowance` | `owner`, `spender` | Читання |
| `transfer_from` | `from`, `to`, `amount` | Витрачає дозвіл, наданий тому, хто викликав |
| `mint` | `to`, `amount` | Лише власник |
| `burn` | `amount` | Від того, хто викликав |
| `owner` | — | Читання |

Приймаються також назви в camelCase (`balanceOf`, `totalSupply`, `transferFrom`). Перекази створюють подію `Transfer`.

Інші інтерфейси в репозиторії: сертифікати в стилі NRC-721 (`ncert`) і DAO-управління (`dao`, `gov_dao`); їхні ABI-файли лежать поруч з кодом (`*.abi.json`).

## Міжконтрактні виклики

Контракт може викликати інший через host-функцію `call_contract`, до **8 рівнів вкладеності** (`MAX_CALL_DEPTH`). Усередині викликаного `get_caller()` повертає адресу контракту, що викликав. Див. [Міжконтрактні виклики](/uk/neurowasm/cross-contract).
