Гайд по виконанню шостого завдання в проекті Canton
Крипто-подорожі з Дмитром - канал про ретродропи, тестнети, блокчейни, скрипти, NFT, криптобіржі, коротше, про все цікаве зі світу криптовалюти. Впевнений, тобі буде цікаво та корисно.
Чат каналу - ласкаво прошу, спілкуємось, ділимося новими активностями, допомагаємо один одному.
Отже, сьогодні виконуємо п'яте завдання для проекту Canton, в якого 400 лямів інвесту. Перше, друге, третє і четверте я розписав в своєму ТГ каналі, можете ознайомитись:
Перше
Друге
Посилання на сторінку з завданням:
https://earn.stackup.dev/campaigns/unlocking-canton-with-daml-unifying-traditional-and-crypto-markets-on-chain/quests/capstone-developing-and-prototyping-smart-contract-logic-5889
Результатом виконання завдання має бути скрін, який ви бачите зверху. Погнали?
Це завдання найкраще виконувати на сервері Linux з будь якими характеристиками. Я спочатку пару годин витратив на термінал в Віндовс, але там інші команди, синтаксис відрізняється, тому все ж зній с одного сервера Nexus і все чудово зробив.
Попереджаю, що вам доведеться копіювати багато даних з попередніх кроків і вставляти їх в наступні. Я спочатку це робив вручну, а потім просто кожен результат з терміналу скидав в Перплексіті і казав йому запам'ятати всі потрібні дані. Потім скидав наступне завдання і просив автоматично заповнити моїми даними. Так швидше і простіше.
curl -sSL https://get.daml.com/ | sh -s 3.3.0-snapshot.20250930.0
export PATH="$HOME/.daml/bin:$PATH"
daml new capstone --template quickstart-java
cd capstone
ls
Після LS має з’явитися папка daml, файл daml.yaml, pom.xml і т.д.
daml build
ls .daml/dist
Має написати у відповіді щось про файл quickstart-0.0.1.dar
apt update
apt install -y openjdk-17-jre
daml test
буде довго думати, потім виведе результат тесту.
Запускаємо пісочницю:
daml sandbox --json-api-port 7575
Напише, що пісочниця запущена, залишаєте це вікно активним і відкриваєте новий термінал
cd ~/capstone
head -n 5 openapi.yaml
openapi: 3.0.3
info:
title: JSON Ledger API HTTP endpoints
version: 3.3.0-SNAPSHOT
curl -v -X POST 'http://localhost:7575/v2/packages' \
-H "Content-Type: application/octet-stream" \
--data-binary @.daml/dist/quickstart-0.0.1.dar
Має показати багато тексту, але обов'язково "HTTP/1.1 200 OK"
curl -d '{"partyIdHint":"Alice","identityProviderId":""}' -H "Content-Type: application/json" -X POST localhost:7575/v2/parties
curl -d '{"partyIdHint":"Bob","identityProviderId":""}' -H "Content-Type: application/json" -X POST localhost:7575/v2/parties
curl -d '{"partyIdHint":"USD_Bank","identityProviderId":""}' -H "Content-Type: application/json" -X POST localhost:7575/v2/parties
curl -d '{"partyIdHint":"EUR_Bank","identityProviderId":""}' -H "Content-Type: application/json" -X POST localhost:7575/v2/parties
Має писати таке: {"partyDetails":{"party":"Alice::1220ed3dd5da9ea12bab4a659a3111edf4a7f41e8402d9d754edabf023d5247ea457","isLocal":true,"localMetadata":{"resourceVersion":"0","annotations":{}},"identityProviderId":""}}root@vm704:~/capstone#
І треба зберегти всі 4 ID - Alice::1220ed3dd5da9ea12bab4a659a3111edf4a7f41e8402d9d754edabf023d5247ea457 і всі інші.
По факту вони будуть однаковими, відрізняються тільки початком: Alice::, Bob:: і так далі. В завданні не сказано замоврачуватись з різними ідентифікаторами, тому вони будуть відрізнятись назвою.
Далі вони будуть називатись <ALICE_ID> <BOB_ID> <USD_BANK> <EUR_BANK>
daml ledger list-parties
Мають бути 5 записів - Аліса, Боб, бакси, євро і пісочниця
curl -X GET 'http://localhost:7575/v2/interactive-submission/preferred-package-version?package-name=quickstart&parties=Alice::ТУТ_СВІЙ_ID' | jq .
{
"packagePreference": {
"packageReference": {
"packageId": "2fa7fec894ed2f78a52c03d35cd5bbd283dd2f415fd6bf40530c50a6445bbd7b",
"packageName": "quickstart",
"packageVersion": "0.0.1"
},
"synchronizerId": "mysynchronizer::122108371738aea79c5f458a3a04dfdbe94b363347ea9c9b7b4df7bf9ba7902295ca"
}
}
Потрібно записати свій packageId
Тепер створюємо багато файлів і заповнюємо їх своїми даними. Потім після кожного файлу пишемо команду і записуємо з результату свої дані:
Створюємо перший файл:
cat > issue_eur.json << 'EOF' { "commands": { "commands": [ { "CreateAndExerciseCommand": { "templateId": "СЮДИ_СВІЙ_packageId:Iou:Iou", "createArguments": { "issuer": "EUR_Bank::СЮДИ_СВІЙ_ID", "owner": "EUR_Bank::СЮДИ_СВІЙ_ID", "currency": "EUR", "amount": "100.0", "observers": [] }, "choice": "Iou_Transfer", "choiceArgument": { "newOwner": "Alice::СЮДИ_СВІЙ_ID" } } } ], "userId": "eur-bank-user", "commandId": "issue-eur-to-alice-1", "actAs": [ "EUR_Bank::СЮДИ_СВІЙ_ID" ] } } EOF
curl -X POST 'http://localhost:7575/v2/commands/submit-and-wait-for-transaction' \ -H "Content-Type: application/json" \ -d @issue_eur.json | jq .
Записуєте собі contractId (<ALICE_TRANSFER_CID>) і offset. Перше дуже довге, друге двозначне (43, наприклад).
Створюємо другий файл:
cat > issue_usd.json << 'EOF' { "commands": { "commands": [ { "CreateAndExerciseCommand": { "templateId": "СЮДИ_СВІЙ_packageId:Iou:Iou", "createArguments": { "issuer": "USD_Bank::СЮДИ_СВІЙ_ID", "owner": "USD_Bank::СЮДИ_СВІЙ_ID", "currency": "USD", "amount": "110.0", "observers": [] }, "choice": "Iou_Transfer", "choiceArgument": { "newOwner": "Bob::СЮДИ_СВІЙ_ID" } } } ], "userId": "usd-bank-user", "commandId": "issue-usd-to-bob-1", "actAs": [ "USD_Bank::СЮДИ_СВІЙ_ID" ] } } EOF
curl -X POST 'http://localhost:7575/v2/commands/submit-and-wait-for-transaction' \ -H "Content-Type: application/json" \ -d @issue_usd.json | jq .
Знову копіюємо собі contractId (<BOB_TRANSFER_CID>) і offset
Створюємо третій файл:
cat > alice_trf.json << 'EOF' { "commands": { "commands": [ { "ExerciseCommand": { "templateId": "СЮДИ_СВІЙ_packageId:Iou:IouTransfer", "contractId": "<СЮДИ_ALICE_TRANSFER_CID>", "choice": "IouTransfer_Accept", "choiceArgument": {} } } ], "userId": "alice-user", "commandId": "alice-accept-eur-transfer", "actAs": [ "Alice::СЮДИ_СВІЙ_ID" ] } } EOF
curl -X POST 'http://localhost:7575/v2/commands/submit-and-wait-for-transaction' \ -H "Content-Type: application/json" \ -d @alice_trf.json | jq .
Зберігаєте contractId (<ALICE_ACCEPT_EUR>) з блоку CreatedEvent
Створюємо четвертий файл:
cat > bob_trf.json << 'EOF' { "commands": { "commands": [ { "ExerciseCommand": { "templateId": "СЮДИ_СВІЙ_packageId:Iou:IouTransfer", "contractId": "СЮДИ_BOB_TRANSFER_CID", "choice": "IouTransfer_Accept", "choiceArgument": {} } } ], "userId": "bob-user", "commandId": "bob-accept-usd-transfer", "actAs": [ "Bob::СЮДИ_СВІЙ_ID" ] } } EOF
curl -X POST 'http://localhost:7575/v2/commands/submit-and-wait-for-transaction' \ -H "Content-Type: application/json" \ -d @bob_trf.json | jq .
Зберігаєте contractId (<BOB_ACCEPT_USD>) з блоку CreatedEvent
Створюємо п'ятий файл:
{ "commands": { "commands": [ { "ExerciseCommand": { "templateId": "<PACKAGE_ID>:Iou:Iou", "contractId": "<ALICE_ACCEPT_EUR>", "choice": "Iou_AddObserver", "choiceArgument": { "newObserver": "<BOB_ID>" } } } ], "userId": "alice-user", "commandId": "iou-disclosure-split-1", "actAs": [ "<ALICE_ID>" ] } } EOF
curl -X POST 'http://localhost:7575/v2/commands/submit-and-wait-for-transaction' \ -H "Content-Type: application/json" \ -d @add_observer.json | jq .
Зберігаєте contractId (<NEW_IOU>) з блоку CreatedEvent
Створюємо шостий файл:
{ "commands": { "commands": [ { "CreateCommand": { "templateId": "<PACKAGE_ID>:IouTrade:IouTrade", "createArguments": { "buyer": "<ALICE_ID>", "seller": "<BOB_ID>", "baseIouCid": "<NEW_IOU>", "baseIssuer": "<EUR_BANK>", "baseCurrency": "EUR", "baseAmount": "100.0", "quoteIssuer": "<USD_BANK>", "quoteCurrency": "USD", "quoteAmount": "110.0" } } } ], "userId": "alice-user", "commandId": "trade-proposal-1", "actAs": [ "<ALICE_ID>" ] } } EOF
curl -X POST 'http://localhost:7575/v2/commands/submit-and-wait-for-transaction' \ -H "Content-Type: application/json" \ -d @propose_trade.json | jq .
Зберігаєте contractId (<TRADE_PROPOSAL_CID>) з блоку CreatedEvent
Створюємо сьомий файл:
{ "commands": { "commands": [ { "ExerciseCommand": { "templateId": "<PACKAGE_ID>:IouTrade:IouTrade", "contractId": "<TRADE_PROPOSAL_CID>", "choice": "IouTrade_Accept", "choiceArgument": { "quoteIouCid": "<BOB_ACCEPT_USD>" } } } ], "userId": "bob-user", "commandId": "trade-acceptance-1", "actAs": [ "<BOB_ID>" ] } } EOF
curl -X POST 'http://localhost:7575/v2/commands/submit-and-wait-for-transaction' \ -H "Content-Type: application/json" \ -d @accept_trade.json | jq .
Те, що ви побачите після цієї команди, і є результатом роботи. Має бути щось типу такого, але з вашими даними:
Робите скрін всього екрану, щоб ці дані було видно, називаєте файл C52Q6_ваше_ім’я_в_проекті і скидаєте на перевірку
Якщо хочеш читати всі актуальні новини і гайди, підписуйся на мій канал:
https://t.me/CryptoTravelsWithDmytro
Якщо маєш запитання по відпрацюванні якогось проекту, приєднуйся до чату:
https://t.me/+O07RU8qeDoUwZGFi
Якщо маєш пропозиції по співпраці або будь які запитання особисто до мене, пиши:
Дякую, що був зі мною до кінця статті!!!
Багато тобі щедрих дропів, гарного настрою і кайфового ворку!!!