Гайд по виконанню шостого завдання в проекті 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/partiescurl -d '{"partyIdHint":"Bob","identityProviderId":""}' -H "Content-Type: application/json" -X POST localhost:7575/v2/partiescurl -d '{"partyIdHint":"USD_Bank","identityProviderId":""}' -H "Content-Type: application/json" -X POST localhost:7575/v2/partiescurl -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"
]
}
}
EOFcurl -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"
]
}
}
EOFcurl -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"
]
}
}
EOFcurl -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"
]
}
}
EOFcurl -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>"
]
}
}
EOFcurl -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>"
]
}
}
EOFcurl -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>"
]
}
}
EOFcurl -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
Якщо маєш пропозиції по співпраці або будь які запитання особисто до мене, пиши:
Дякую, що був зі мною до кінця статті!!!
Багато тобі щедрих дропів, гарного настрою і кайфового ворку!!!