Давайте начнем с трех основных параметров протокола NEAR:
- Proof of Stake
- Шарды
- WASM смарт-контракт
Консенсус блокчейна Proof of Stake достигается за счет количества токенов, а не майнинга. NEAR почти мгновенно достигает завершения транзакции благодаря 1-секундному созданию блока.
Блокчейн сегментирован, что означает, что вызовы между контрактами являются асинхронными (не путать с синхронными, как в Ethereum или Solana). При написании на NEAR кода контракта вам нужно принять во внимание работу с факторной моделью. Требование асинхронности необходимо, чтобы сегменты могли обрабатываться параллельно, что приводит к гораздо большей пропускной способности транзакций. Блокчейны, в которых смарт-контракты не сегментированы, просто достигнут потолка масштабируемости, разгрузка на GPU или ASIC (оставаясь синхронными) может только отсрочить этот потолок, но не приведет к экспоненциальному масштабированию.
NEAR контракты — это код поддерживающий WASM, поэтому вы можете кодировать на любом языке, который может быть скомпилирован в WASM. В настоящее время AssemblyScript и RUST больше всего поддерживаются с соответствующими инструментами.
Построить WebApp на протоколе NEAR (именно это и есть доступ Near) очень просто по сравнению с другими блокчейнами.
Давайте клонируем пример отсюда https://github.com/near-examples/counter
git clone https://github.com/near-examples/counter yarn
Ядро нашего контракта включает в себя хранение в цепочке, ведение журнала управления для сгенерированного чека и экспортированные публичные функции. Функции, которые устанавливают хранилище, должны быть вызваны, иначе их можно будет посмотреть (даже без учетной записи NEAR).
Near поддерживает несколько типов коллекций (которые сами себя описывают) в Near-sdk-as.
Вот основные из них которые вам понадобятся:
- storage.getPrimitive — get/set
- persistentMap — set/get
- persistentUnorderedMap — set/get/query/length
Мы не включаем постоянный вектор, нам следует избегать его использования так как очень легко сжечь огромное количество итерационных векторов газа. Мы стараемся использовать наборы, когда это возможно.
Значения по умолчанию для коллекций persistMap имеют суффикс.
let balance = myPersistentMap.get("myacc.near", u128.Zero)!
logging.log будет печатать вывод журнала в квитанции при вызове функции. Это полезно для управления потоком того, что произошло, особенно когда контракты становятся более сложными. Пример удобочитаемого контракта на чеканку, он имеет сообщение в журнале «alice.near отчеканил 5,0 ZOD из zod.near».
Развернем наш контракт, для этого нам понадобится Near-Cli.
npm install near-cli -g
Для развертывания создадим фиктивную учетную запись testnet. Учетные записи являются контрактами, и вы можете иметь только 1 контракт на учетную запись. Для создания нескольких контрактов вам необходимо использовать дополнительные учетные записи, contract1.me.near, contract2.me.near.
Давайте вызовем функцию getCounter.
yarn build
ACC1=$(near dev-deploy out/main.wasm | sed 's/.*id: (.*), node.*/1/' | head -n 1)
near view --accountId $ACC1 $ACC1 getCounter '{}'
На выходе
View call: dev-1623290109414-64922580028342.getCounter({})
0
Увеличивает счетчик
near call --accountId $ACC1 $ACC1 incrementCounter '{"value": 1}'
Посмотрим на этот вызов в обозревателе блоков.https://explorer.testnet.near.org/accounts/dev-1623290109414-64922580028342
Отлично.
Чтобы просмотреть функцию, мы можем использовать curl, но нам нужно проанализировать некоторые выходные данные командной строки, проще написать скрипт быстрого узла. Нам даже не нужен near аккаунт.
node << EOF
const fetch = require('node-fetch');
async function go() {
const args_base64 = Buffer.from('{}').toString('base64')
const params = {account_id: "zodtv.near", method_name: "mint_status",
request_type: "call_function", finality: "final", "args_base64": args_base64}
const json_args = {jsonrpc: "2.0", id: "1", method: "query", params: params}
const fetch_args = {
method: "POST",
body: JSON.stringify(json_args),
headers: {
"Content-Type": "application/json"
}
}
const response = await fetch("https://rpc.mainnet.near.org", fetch_args);
const {result} = await response.json();
const mint_status = JSON.parse((new TextDecoder()).decode(new Uint8Array(result.result)))
console.log(mint_status)
}
go()
EOF
В следующем коде используется API RPC. https://docs.near.org/docs/api/rpc чтобы запросить состояние контракта zodtv.near
{
"total_minted": "3120000000000000000000000000",
"level": "0",
"near_price": "3000000000000000000000000",
"zod_price": "10000000000000000000000"
}
Near деноминации 24, yocto.
3_000_000_000_000__000_000_000_000
3,0
На этом и завершим. А в следующий раз рассмотрим работу с веб-интерфейсом, а также правильное получение баланса, состояния и много другого.