From c9abbcb8288e1f3117d11e77243d27e479332d61 Mon Sep 17 00:00:00 2001 From: "Chris Kim (Hyunggun)" Date: Fri, 31 May 2024 14:25:31 +0900 Subject: [PATCH] instructions update --- README.md | 20 ++++--- .../src/components/Buy.tsx | 10 +++- .../src/components/Sell.tsx | 2 +- .../src/components/Withdraw.tsx | 2 +- .../src/methods.ts | 53 +++++++++++-------- .../src/utils/getCurrentNftmClient.ts | 2 +- 6 files changed, 55 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index a3a19d6..f104b54 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ https://github.com/algorand-fix-the-bug-campaign/challenge-1/assets/52557585/acd ### 로컬 네트워크 실행 1. 도커 데스크탑을 실행한 뒤 터미널에서 `algokit localnet start` 커맨드로 로컬 네트워크를 실행시켜주세요.[더 자세히 알고 싶다면 여기를 클릭해주세요!](https://github.com/algorandfoundation/algokit-cli/blob/main/docs/features/localnet.md#creating--starting-the-localnet). 오늘 모든 코드는 로컬 네트워크에서 실행됩니다. -> 만약 로컬 네트워크 연결이 안되거나 뭔가 문제가 생기면 `algokit localnet reset` 커맨드로 다시 로컬네트워크를 지우고 생성하시면 됩니다. +> 만약 로컬 네트워크 연결이 안되거나 뭔가 문제가 생기면 `algokit localnet reset` 커맨드로 다시 로컬네트워크를 지우고 다시 생성하시면 됩니다. ### 1-4문제: 스마트계약 문제 진행 설명 1. `orakle-nft-marketplace-app-contracts` 터미널에서 `poetry shell`를 실행해서 파이썬 가상환경을 켰는지 확인하세요. @@ -76,19 +76,24 @@ algokit project run build ```bash algokit project deploy localnet ``` + +> 🚧 주목!! `algokit project deploy localnet` 작동 도중 에러가 나서 스마트계약을 고치셨다면 다시 `algokit project run build`를 해서 스마트계약을 재 compile 한 후 deploy 커멘드를 실행해주셔야 합니다! + 실행 후 다음과 같은 콘솔 값이 출력되면 성공적으로 모든 문제를 해결하신겁니다! 👏👏 이제 문제 5-9로 넘어가세요. image ### 5-9문제: 프론트앤드 연동 문제 진행 설명 -1. `orakle-nft-marketplace-app-frontend` 터미널로 가서 `npm run dev`를 실행해 로컬 서버를 실행한 뒤, 브라우저에 페이지를 열고 진행해주세요! -2. `orakle-nft-marketplace-app-contracts` 터미널에서 `algokit project deploy localnet`를 실행하시면 "=== Deploying NftMarketplaceList ===" 밑에 - "Created app ****..." 라는 메시지가 뜹니다. 여기서 나오는 app ID 번호를 복사해서 `src/utils/marketplaceListAppId.ts`에 `marketplaceListAppId` 변수값으로 붙여넣어주세요. +1. `orakle-nft-marketplace-app-contracts` 터미널에서 `algokit project deploy localnet`를 실행하시면 "=== Deploying NftMarketplaceList ===" 밑에 + "Created app ****..." 라는 메시지가 뜹니다. 여기서 나오는 app ID 번호를 복사해서 `src/utils/marketplaceListAppId.ts`에 `marketplaceListAppId` 변수값으로 넣어주세요. Screenshot 2024-05-28 at 9 08 36 PM -4. 문제 5은 `src/utils/getCurrentNftmClient.ts` 파일에 있습니다! 파일에 문제가 적혀있습니다. -5. 문제 6-9는 `src/methods.ts` 파일에 있습니다! 파일에 문제들이 적혀있습니다. + +2. `orakle-nft-marketplace-app-frontend` 터미널로 가서 `npm run dev`를 실행해 로컬 서버를 실행하고, 브라우저에 페이지를 열고 진행해주세요! `npm run dev` 실행시 프론트에서 사용할 앱 클라이언트 파일이 `src/contracts`에 자동 생성되니 꼭 먼저 실행한 한 후 진행해주세요! + +3. 문제 5은 `src/utils/getCurrentNftmClient.ts` 파일에 있습니다! 파일에 문제가 적혀있습니다. +4. 문제 6-9는 `src/methods.ts` 파일에 있습니다! 파일에 문제들이 적혀있습니다. 6. 문제들를 다 해결한 뒤 아래 설명대로 직접 웹사이트에 가서 실행해보세요: -> 🚧 주목!! 아래 단계를 실행 도중 에러가 발생할 시 위에 단계2를 다시 실행해 Nft Marketplace List 스마트계약을 로컬 네트워크에 재배포 한 후 app id 값을 교체한 뒤 진행해주세요! +> 🚧 주목!! 아래 단계를 실행 도중 에러가 발생할 시 위에 단계1를 다시 실행해 Nft Marketplace List 스마트계약을 로컬 네트워크에 재배포 한 후 app id 값을 교체한 뒤 진행해주세요! #### 1. 로컬 지갑 연결 - `Wallet Connection` 버튼을 눌러 로컬 지갑을 연결하세요. @@ -98,6 +103,7 @@ algokit project deploy localnet #### 3. 판매할 NFT 리스팅 - 위에 `sell NFT` 버튼을 누르고 `Select NFT to Sell`에서 2단계에서 만든 테스트 NFT를 선택, 개수는 1개, 가격은 1알고로 설정한 뒤 `publish`를 눌러 nft를 리스팅하세요. 이때 서명 창이 **4번** 나옵니다. 서명창에서 패스워드 기입 없이 `ok` 버튼을 눌러 서명하세요. +- 리스팅 후 과제 제출을 위해 판매 NFT 등록이 보이도록 스크린샷을 찍어주세요! #### 4. NFT 구매 - `Buy now` 버튼을 누르고 Buy Amount를 1개로 설정한 뒤 `Buy NFT!`를 눌러 구매하세요. 서명 창 1번 나옵니다. #### 5. 수익금 회수 및 스마트계약 삭제 diff --git a/projects/orakle-nft-marketplace-app-frontend/src/components/Buy.tsx b/projects/orakle-nft-marketplace-app-frontend/src/components/Buy.tsx index d2c22ab..2ea8973 100644 --- a/projects/orakle-nft-marketplace-app-frontend/src/components/Buy.tsx +++ b/projects/orakle-nft-marketplace-app-frontend/src/components/Buy.tsx @@ -48,7 +48,15 @@ const Buy = ({ openModal, setModalState, currentAppId, unitaryPrice }: BuyInterf const appAddress = algosdk.getApplicationAddress(currentAppId) try { - await methods.buy(algorandClient, nftmClient, activeAddress, currentAppDetails!.assetId, appAddress, BigInt(quantity), unitaryPrice)() + await methods.buyNft( + algorandClient, + nftmClient, + activeAddress, + currentAppDetails!.assetId, + appAddress, + BigInt(quantity), + unitaryPrice, + )() } catch (error) { enqueueSnackbar('Error while buying the NFT', { variant: 'error' }) setLoading(false) diff --git a/projects/orakle-nft-marketplace-app-frontend/src/components/Sell.tsx b/projects/orakle-nft-marketplace-app-frontend/src/components/Sell.tsx index fbab255..206d401 100644 --- a/projects/orakle-nft-marketplace-app-frontend/src/components/Sell.tsx +++ b/projects/orakle-nft-marketplace-app-frontend/src/components/Sell.tsx @@ -42,7 +42,7 @@ const Sell = ({ openModal, setModalState }: SellInterface) => { const nftmClient = await getCurrentNftmClient(algorandClient, 0, activeAddress, signer) try { - await methods.create( + await methods.createAndListNft( algorandClient, nftmClient, listClient, diff --git a/projects/orakle-nft-marketplace-app-frontend/src/components/Withdraw.tsx b/projects/orakle-nft-marketplace-app-frontend/src/components/Withdraw.tsx index b8c19a0..693c556 100644 --- a/projects/orakle-nft-marketplace-app-frontend/src/components/Withdraw.tsx +++ b/projects/orakle-nft-marketplace-app-frontend/src/components/Withdraw.tsx @@ -60,7 +60,7 @@ const Withdraw = ({ openModal, setModalState }: WithdrawInterface) => { } try { - await methods.deleteApp(nftmClient, listClient, Number(myAppId))() + await methods.deleteAppAndWithdraw(nftmClient, listClient, Number(myAppId))() } catch (error) { enqueueSnackbar('Error deleting the app', { variant: 'error' }) setLoading(false) diff --git a/projects/orakle-nft-marketplace-app-frontend/src/methods.ts b/projects/orakle-nft-marketplace-app-frontend/src/methods.ts index d81ca54..58e8275 100644 --- a/projects/orakle-nft-marketplace-app-frontend/src/methods.ts +++ b/projects/orakle-nft-marketplace-app-frontend/src/methods.ts @@ -8,9 +8,9 @@ import { marketplaceListAppId } from './utils/marketplaceListAppId' === 먼저 읽고 진행해주세요!! === methods.ts 파일은 디지털 마켓플레이스 앱을 생성하고 호출하는 여러 메서드들을 정의하는 파일입니다. 이 파일에는 3개의 함수가 정의되어 있습니다. -1. create: src/components/Sell.tsx에서 NFT 판매 리스팅을 할때 사용. -2. buy: src/components/Buy.tsx에서 NFT 구매를 할때 사용. -3. deleteApp: src/components/Withdraw.tsx에서 수익금을 인출 및 스마트계약 삭제할때 사용. +1. createAndListNft: src/components/Sell.tsx에서 NFT 판매 리스팅을 할때 사용. +2. buyNft: src/components/Buy.tsx에서 NFT 구매를 할때 사용. +3. deleteAppAndWithdraw: src/components/Withdraw.tsx에서 수익금을 인출 및 스마트계약 삭제할때 사용. 기억하세요! nftmClient로 nft marketplace 스마트계약을 배포 및 호출할때는 항상 await을 사용해야합니다. @@ -18,7 +18,7 @@ nftmClient로 nft marketplace 스마트계약을 배포 및 호출할때는 항 이 파일에는 문제 6부터 9까지 총 4문제가 있습니다. 아래 설명들을 자세히 읽고 문제를 풀어주세요! */ -export function create( +export function createAndListNft( algorand: algokit.AlgorandClient, nftmClient: NftMarketplaceClient, listClient: NftMarketplaceListClient, @@ -34,7 +34,7 @@ export function create( 문제 6 문제5에서 생성한 nftmClient를 사용하여 앱을 배포하세요. - 사용해야할 인수: + 사용해야할 createAndListNft의 인수: - nftmClient: 문제 5에서 정의한 nft marketplace app client 스마트계약 배포시 `deploy`가 아닌 `create` 메서드를 사용해서 배포하세요. @@ -53,15 +53,17 @@ export function create( 문제 7 앱이 판매할 준비가 되도록 Bootstrap 메서드를 호출하세요. - bootstrap 메서드는 앱이 필요한 미니멈 밸런스를 지급하고 앱이 판매할 NFT 에셋에 옵트인하는 메서드입니다. + bootstrap 메서드는 앱이 필요한 미니멈 밸런스를 앱에게 지급하고 앱이 판매할 NFT 에셋에 옵트인하는 메서드입니다. - 사용해야할 create함수의 인수: + 사용해야할 createAndListNft의 인수: - assetBeingSold: 판매할 NFT 에셋의 ID - unitaryPrice: NFT 하나의 가격 - 부트스트랩 메서드는 호출 시 판매할 NFT에 옵트인하는 inner transaction이 있습니다. + 부트스트랩 메서드 안에는 판매할 NFT에 옵트인하는 inner transaction이 있습니다. 따라서 부트스트랩 메서드 호출자가 inner transaction의 트랜잭션 비용을 대신 내야합니다. - 이 추가 비용은 mbrTxn안에 extraFee를 통해서 설정할 수 있습니다. 이때 extraFee는 AlgoAmount 데이터타입을 받습니다!! (그냥 숫자 넣으면 에러뜸) + 이 추가 비용은 부트스트랩 호출 시 어토믹으로 묶여서 동시체결될 mbrTxn안에 extraFee를 통해서 설정할 수 있습니다. + 이때 extraFee는 AlgoAmount 데이터타입을 받습니다!! (그냥 숫자 넣으면 에러뜸) + 알고랜드의 트랜잭션 비용은 0.001 Algos입니다. 팁! @@ -102,7 +104,7 @@ export function create( } } -export function buy( +export function buyNft( algorand: algokit.AlgorandClient, nftmClient: NftMarketplaceClient, sender: string, @@ -114,15 +116,19 @@ export function buy( return async () => { /* 문제 8 - 구매자가 구매할 NFT에 optin하는 트랜잭션과 buy 메서드를 어토믹 그룹으로 묶어 동시다발적으로 실행하는 코드를 작성하세요. + 아래 3개의 트랜잭션을 어토믹 그룹으로 묶어서 실행하는 코드를 구현하세요. + 1. assetOptInTxn(라인 157): 구매자가 구매할 NFT에 optin하는 트랜잭션 + 2. buyerTxn(라인 144): buy 메서드 호출 시 구매를 위해 Algo를 앱계정으로 송금하는 트랜잭션 + 3. buy 메서드 호출 트랜잭션 - 알고랜드에서는 계정이 특정 ASA에 optin을 해야지만 그 ASA를 받고 보유할 수 있습니다. 따라서 이 파일의 buy 함수는 먼저 - 구매자가 구매할 NFT에 optin을 했는지 체크하고 했다면 바로 스마트계약의 buy 메서드를 호출하고, optin을 안했다면 - 먼저 optin을 하고 buy 메서드를 호출합니다. + 알고랜드에서는 계정이 특정 ASA에 optin을 해야지만 그 ASA를 받고 보유할 수 있습니다. 따라서 이 파일의 buyNft 함수는 먼저 + 구매자가 구매할 NFT에 optin을 했는지 체크합니다. + - optin이 되어 있으면 바로 스마트계약의 buy 메서드를 호출 + - optin을 안했다면 먼저 optin을 하고 buy 메서드를 호출 여러분은 optin을 하고 buy 메서드를 어토믹으로 동시에 호출하는 코드를 작성하셔야 합니다. - 사용해야할 인수: + 사용해야할 buyNft의 인수: - nftmClient: 문제 5에서 정의한 nft marketplace app client - quantity: 구매할 NFT의 수량 @@ -130,10 +136,11 @@ export function buy( - buyerTxn: 구매자가 구매할 NFT에 대한 지불을 하는 트랜잭션입니다. - assetOptInTxn: 구매자가 구매할 NFT에 optin을 하는 트랜잭션입니다. - 여기서 buyerTxn은 buy 메서드의 인수로 들어가기 때문에 자동으로 어토믹 그룹에 포함됩니다. 따라서 assetOptInTxn만 어토믹 그룹에 추가해주시면 됩니다. + 여기서 buyerTxn은 buy 메서드의 인수로 들어가기 때문에 자동으로 어토믹 그룹에 포함됩니다. 따라서 assetOptInTxn만 따로 어토믹 그룹에 추가해주시면 됩니다. 어토믹그룹을 형성하고 execute하는것을 까먹지 마세요! - 힌트1: fluent Atomic Composer로 어토믹 그룹을 형성, 트랜잭션 추가, 제출하는법: https://github.com/algorandfoundation/algokit-client-generator-ts/blob/main/docs/usage.md#using-the-fluent-composer:~:text=Using%20the%20fluent%20composer + 힌트1: fluent Atomic Composer로 어토믹 그룹을 형성, 트랜잭션 추가, 제출하는법: https://github.com/algorandfoundation/algokit-client-generator-ts/blob/main/docs/usage.md#using-the-fluent-composer:~:text=await%20client.compose()%0A%20%20.methodOne(%7B%20arg1%3A%20123%20%7D%2C%20%7B%20boxes%3A%20%5B%27V%27%5D%20%7D)%0A%20%20//%20Non%2DABI%20transactions%20can%20still%20be%20added%20to%20the%20group%0A%20%20.addTransaction(fundingTransaction)%0A%20%20.methodTwo(%7B%20arg1%3A%20%27foo%27%20%7D)%0A%20%20.execute() + 힌트2: 앱 클라이언트로 특정 메서드 호출 방법: https://github.com/algorandfoundation/algokit-client-generator-ts/blob/main/docs/usage.md#no-ops */ const buyerTxn = await algorand.transactions.payment({ @@ -169,7 +176,7 @@ export function buy( } } -export function deleteApp(nftmClient: NftMarketplaceClient, listClient: NftMarketplaceListClient, appId: number) { +export function deleteAppAndWithdraw(nftmClient: NftMarketplaceClient, listClient: NftMarketplaceListClient, appId: number) { return async () => { console.log('deleting app') @@ -178,7 +185,7 @@ export function deleteApp(nftmClient: NftMarketplaceClient, listClient: NftMarke 앱을 삭제하고 수익금과 잔여 NFT를 회수하는 withdrawAndDelete 메서드를 호출하세요. withdrawAndDelete 메서드는 OnComplete Actions가 DeleteApplication으로 설정된 특별한 메서드입니다. - nftmClient에는 delete라는 property가 있습니다. 이 delete property에 withdrawAndDelete 메서드가 있으니 이 메서드를 호출하시면 됩니다. + nftmClient에는 delete라는 property가 있습니다. 이 delete property 안에 withdrawAndDelete 메서드가 있으니 이 메서드를 호출하시면 됩니다. 앱 클라이언트로 withdrawAndDelete 같은 메서드를 호출할때 전달값을 두개 넣을 수 있습니다. 1. ABI Arguments: 스마트계약 메서드 호출시 전달값을 넣는 곳입니다. @@ -189,10 +196,10 @@ export function deleteApp(nftmClient: NftMarketplaceClient, listClient: NftMarke additional parameters: withdrawAndDelete는 2개의 inner txn를 보냅니다. - 1. 수익금 판매자에게 송금 - 2. 잔여 nft 송금 - 따라서 호출시 sendParams 안에 추가 fee 설정을 해야합니다. - - fee: sendParams 객체 안에 fee를 algokit.algos(0.003)fh 설정해야합니다. + 1. 수익금을 판매자에게 송금 + 2. 잔여 nft를 판매자에게 송금 + 따라서 2개의 트랜잭션 비용을 메서드 호출자가 대신 내야함으로 sendParams 안에 추가 fee 설정을 해야합니다. + - fee: sendParams 객체 안에 fee를 algokit.algos(0.003)로 설정하세요. 힌트1: 앱클라이언트로 앱을 delete 하는법 - https://github.com/algorandfoundation/algokit-client-generator-ts/blob/main/docs/usage.md#update-and-delete-calls 힌트2: 앱 클라이언트 메서드 호출때 메서드 전달값 넣는법: https://github.com/algorandfoundation/algokit-client-generator-ts/blob/main/docs/usage.md#abi-arguments diff --git a/projects/orakle-nft-marketplace-app-frontend/src/utils/getCurrentNftmClient.ts b/projects/orakle-nft-marketplace-app-frontend/src/utils/getCurrentNftmClient.ts index 15c4741..5d22ab8 100644 --- a/projects/orakle-nft-marketplace-app-frontend/src/utils/getCurrentNftmClient.ts +++ b/projects/orakle-nft-marketplace-app-frontend/src/utils/getCurrentNftmClient.ts @@ -33,7 +33,7 @@ export function getCurrentNftmClient( 주목!!! - 3번째 줄에서 import { NftMarketplaceClient } from '../contracts/NftMarketplace'로 import한 클래스는 - Nft 마켓플레이스 앱을 빌드할때 자동 생성된 클라이언트 클래스입니다. + Nft 마켓플레이스 앱을 빌드할때 자동 생성된 클라이언트 클래스입니다. 이 파일이 없다면 `npm run dev`를 실행하시면 자동으로 생성됩니다. - 이 문제는 getCurrentNftmClient 함수의 인수로 들어오는 4개의 인수를 모두 사용하셔서 푸셔야 합니다. - id값에는 getCurrentNftmClient의 인수값으로 들어오는 currentAppId를 넣어주세요. - sender값에는 { addr: activeAddress!, signer }를 복붙해주세요. useWallet를 통해 현재 연결된 지갑 주소와 서명자를 포함한 객체를 설정해주는 코드입니다.