Привет фрэнс! 👋

Добро пожаловать в первую часть серии руководств по использованию плагина StarkNet Hardhat для разработки смарт-контрактов Cairo!

Если вы планируете использовать JavaScript в качестве предпочтительного языка в экосистеме StarkNet, вы обратились по адресу.

В этом уроке мы намеренно будем использовать ссылки на другие ресурсы, потому что на момент написания StarkNet находится в альфа-версии, поэтому ожидайте, что все изменится и сломается… И связанные ресурсы, вероятно, также изменятся, чтобы отразить эволюцию 🧬

Монтаж

Обо всем по порядку, поэтому, пожалуйста, обратитесь к репозиторию проекта за инструкциями по установке и настройке:

  1. Установить сам Hardhat
  2. Включите плагин Hardhat в созданный вами проект hardhat в соответствии с инструкциями.
  3. Создайте новый проект (в нашем случае мы назвали его hardhat-tutorial)
  4. Перейдите к только что созданному проекту
  5. Обязательно запустите npm i @shardlabs/starknet-hardhat-plugin — save-dev

Примечание. После установки каски и запуска npx hardhat настройка проекта должна выглядеть примерно так:

Примечание. После успешной установки убедитесь, что у вас также запущен докер, или, если у вас локально установлен cairo-lang, настройте venv в файле конфигурации каски — примерно так !

Привет, мир

Теперь мы подошли к самой веселой части! 👻

Сначала скопируйте контракт, найденный здесь, и вставьте его в свой проект в папку contracts внутри вашего проекта в каске.

Примечание: вы можете удалить контракт Solidity (.sol), если он был создан с вашим проектом.

Вы можете назвать контракт hello.cairo ! На момент написания контракт выглядел так:

// Declare this file as a StarkNet contract.
%lang starknet
 
from starkware.cairo.common.cairo_builtins import HashBuiltin
 
// Define a storage variable.
@storage_var
func balance() -> (res: felt) {
}
 
// Increases the balance by the given amount.
@external
func increase_balance{
   syscall_ptr: felt*,
   pedersen_ptr: HashBuiltin*,
   range_check_ptr,
}(amount: felt) {
   let (res) = balance.read();
   balance.write(res + amount);
   return ();
}
 
// Returns the current balance.
@view
func get_balance{
   syscall_ptr: felt*,
   pedersen_ptr: HashBuiltin*,
   range_check_ptr,
}() -> (res: felt) {
   let (res) = balance.read();
   return (res=res);
}

Команды

Мы собираемся показать вам, как компилировать, развертывать и взаимодействовать с вашим контрактом с помощью команд Hardhat StarkNet. Но сначала давайте настроим наш файл hardhat.config.ts, найдем его или поместим в корень нашего проекта и следуем инструкциям ниже.

import "@shardlabs/starknet-hardhat-plugin";
 
module.exports = {
   starknet: {
       dockerizedVersion: "0.10.3",
       network: "alpha-goerli"
   },
   networks: {
   }
};

В консоли напишите эту команду:

> npx hardhat starknet-compile contracts/hello.cairo

После успешной компиляции вы должны увидеть эти файлы .json в своем проекте:

Развертывание учетной записи

Теперь мы хотели бы развернуть наш контракт!

Но, в отличие от предыдущих версий StarkNet, для этого мы будем использовать учетную запись, которая уже развернута и профинансирована.

На самом деле это трехэтапный процесс:

  1. Предварительно рассчитайте адрес аккаунта, который мы развернем позже
  2. Пополнить заранее рассчитанный адрес
  3. Выполните фактическое развертывание

Подробнее об этом можно узнать здесь.

Это то, что мы будем делать на следующих нескольких шагах.

  1. Давайте добавим в наш проект новый файл в папке /scripts и назовем его deploy-account.ts.
  2. Чтобы создать учетную запись в тестовой сети, мы можем запустить следующий скрипт в нашем проекте. Скопируйте следующий код в deploy-account.ts.
import { starknet } from "hardhat";
 
async function keypress() {
    process.stdin.setRawMode(true);
    return new Promise<void>((resolve) =>
        process.stdin.once("data", () => {
            process.stdin.setRawMode(false);
            resolve();
        })
    );
}
 
(async () => {
    const account = await starknet.OpenZeppelinAccount.createAccount();
    console.log(
        `Account created at ${account.address} with private key=${account.privateKey} and public key=${account.publicKey}`
    );
    console.log(
        "Please fund the address. Even after you get a confirmation that the funds were transferred, you may want to wait for a couple of minutes."
    );
    console.log("Press any key to continue...");
    await keypress();
    console.log("Deploying...");
    await account.deployAccount({ maxFee: 1e18 });
    console.log("Deployed");
})()
    .then(() => process.exit(0))
    .catch((err) => {
        console.error(err);
        process.exit(1);
    });

3. Запустите в консоли следующую команду:

Запуск скриптов npx в каске/deploy-account.ts

Примечание. убедитесь, что вы сохранили свой адрес, закрытый и открытый ключи, отображаемые в консоли.

4. Пополнение счета

Когда скрипт приостанавливает выполнение, вы должны добавить средства на сгенерированный адрес — команда createAccount() выведет адрес счета, который мы затем будем использовать для пополнения через кран!

Вы должны дать ему несколько минут, чтобы транзакция была принята.

Обратите внимание — учетная запись еще не развернута, поэтому вы не сможете увидеть ее на Starkscan!

5. Развертывание учетной записи.

Как только мы убедимся, что финансирование прошло успешно (проверив, были ли переведены токены), мы можем продолжить — нажмите Enter!.

После развертывания учетной записи будет выведен хэш транзакции учетной записи. Чтобы убедиться, что договор принят в сети, скопируйте адрес и вставьте его в поле поиска Вояджер или Старкскан.

Обратите внимание, что из-за большого сетевого трафика сначала может не быть результата, поэтому лучше подождать несколько минут, прежде чем проверять снова.

Развертывание контракта и взаимодействие

Хорошо. Теперь мы развернули учетную запись, которая будет развертывать наш контракт. Мы можем приступить к развертыванию контракта hello.cairo.

Создайте новый скрипт, назовите его deploy-contract.ts и поместите его в папку /scripts.

Примечание. Обязательно добавьте адрес и закрытый ключ из предыдущих шагов в функцию getOZAccount().

import hardhat from "hardhat";
import { starknet } from "hardhat";
 
async function main() {
    const account = await getOZAccount();
    const contractFactory = await hardhat.starknet.getContractFactory("hello");
    await account.declare(contractFactory, { maxFee: 1e18 });
    const contract = await account.deploy(contractFactory);
    console.log("Deployed to:", contract.address);
 
    const { res: balanceBefore } = await contract.call("get_balance");
    console.log("Balance before invoke: ", balanceBefore);
 
    await account.invoke(contract, "increase_balance", { amount: 10 });
    const { res: balanceAfter } = await contract.call("get_balance");
    console.log("Balance after invoke:", balanceAfter);
}
 
main()
    .then(() => process.exit(0))
    .catch((error) => {
        console.error(error);
        process.exit(1);
    });
 
/**
 * Returns an instance of OZAccount. Expected to be deployed
 */
 export async function getOZAccount() {
    return await starknet.OpenZeppelinAccount.getAccountFromAddress(
        // address from previous step
        "0x5b34912eb729c73edccc8380488177b9fed2868f431dd693d0a715306a5c37e",
        // private key from previous step
        "0x2cb7362c74f2e2ed432779eeacca7f0d"
    );
}

Примечание. Метод getContractFactory() извлекает скомпилированный контракт по имени.

Теперь в консоли запустите:

Окончательный результат в консоли:

Вот и все!

Поздравляем! :)

Больше информации

Также обязательно ознакомьтесь с репозиторием hardhat-example для получения дополнительных примеров функций и использования!

Следующий

Вы могли заметить, что выполнение этого в тестовой сети может быть медленным 😞

Но не волнуйтесь — в следующем уроке мы увидим, как выполнять те же операции, но на локальном экземпляре сети starknet, называемом devnet. Поэтому не забудьте подписаться на наш блог иTwitter.

Удачного кодирования!🚀🚀🚀

‍*Эта статья изначально была опубликована в блоге SpaceShard.