Skip to content

Commit 482044c

Browse files
committed
readme, contract instruction, deploy-config update
1 parent 79d3344 commit 482044c

File tree

3 files changed

+75
-50
lines changed

3 files changed

+75
-50
lines changed

README.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ algokit project bootstrap all
4646
4747
6. 이제 `orakle-nft-marketplace-app-contracts` 터미널을 선택한 뒤 `poetry shell` 커맨드를 실행해 파이썬 virtual environment를 활성화 시켜주세요.
4848
1. 파이썬 virtual environment를 비활성화 시킬때는 `exit` 커맨드를 실행하시면 됩니다.
49+
2. venv를 활성화 한 뒤 `pip list`를 실행해서 `algorand-python` 및 여러 dependencies들이 나오면 성공적으로 가상환경을 활성화 시킨겁니다.
4950

5051
🎉 이제 모든 준비가 되었습니다! Good luck coding! 💻
5152

@@ -65,9 +66,16 @@ https://github.com/algorand-fix-the-bug-campaign/challenge-1/assets/52557585/acd
6566
6667
### 1-4문제: 스마트계약 문제 진행 설명
6768
1. `orakle-nft-marketplace-app-contracts` 터미널에서 `poetry shell`를 실행해서 파이썬 가상환경을 켰는지 확인하세요.
68-
2. `orakle-nft-marketplace-app-contracts/smart_contract/nft_marketplace/contract.ts`로 가시면 문제 1-4가 주석으로 작성되어있습니다.
69+
2. `orakle-nft-marketplace-app-contracts/smart_contract/nft_marketplace/contract.py`로 가시면 문제 1-4가 주석으로 작성되어있습니다.
6970
설명을 자세히 읽고 문제들을 해결하세요!
7071
3. 문제를 다 해결한 뒤 터미널에서 `algokit project run build` 커맨드를 실행해 스마트 계약을 컴파일 하시고 `algokit project deploy localnet` 커맨드를 실행해 `smart_contracts/digital_marketplace/deploy-config.ts` 파일을 실행하세요!
72+
```bash
73+
algokit project run build
74+
```
75+
76+
```bash
77+
algokit project deploy localnet
78+
```
7179
실행 후 다음과 같은 콘솔 값이 출력되면 성공적으로 모든 문제를 해결하신겁니다! 👏👏 이제 문제 5-9로 넘어가세요.
7280
<img width="1033" alt="image" src="https://github.com/algorand-devrel/orakle-coding-assignment-2024/assets/52557585/7c6b578d-fd59-42e6-a11d-184ed7552cef">
7381

projects/orakle-nft-marketplace-app-contracts/smart_contracts/nft_marketplace/contract.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@ def __init__(self) -> None:
6565
- 메서드 호출자 (Txn.sender)가 앱의 생성자(Global.creator_address)인지 체크하세요.
6666
- bootstrapped 글ㄹ로벌 상태가 False인지 체크하세요.
6767
- mbr_pay 트랜잭션을 받는 계정이 앱 계정인지 체크하세요.
68-
- mbr_pay의 알고 송금량이 앱 계정의 미니멈 밸런스(0.1 알고)와 판매할 ASA에 옵트인하기
68+
- mbr_pay의 알고 송금량(amount)이 앱 계정의 미니멈 밸런스(0.1 알고)와 판매할 ASA에 옵트인하기
6969
위한 미니멈 밸런스(0.1 알고)의 합과 같은지 체크해야합니다.
70-
-> 팁: Global이라는 AVM opcode를 통해 여러 정보를 열람할 수 있습니다. 자세한 사항은 아래 힌트 1을 참고해주세요.
70+
-> 팁: Global이라는 AVM opcode를 통해 min_balance, asset_opt_in_min_balance와 같은 여러 정보를 열람할 수 있습니다. 자세한 사항은 아래 힌트 1을 참고해주세요.
7171
7272
# 2단계: bootstrap 메서드는 아래 기능들을 수행합니다.
7373
1. asset_id 글로벌 상태를 인수로 들어온 판매할 ASA 아이디로 업데이트합니다.
@@ -82,7 +82,7 @@ def __init__(self) -> None:
8282
힌트 1 - Global Opcode: https://algorandfoundation.github.io/puya/api-algopy.html#algopy.Global
8383
힌트 2 - How to Inner Transaction: https://algorandfoundation.github.io/puya/lg-transactions.html#inner-transactions
8484
힌트 3 - Asset Transfer Inner Txn: https://algorandfoundation.github.io/puya/api-algopy.itxn.html#algopy.itxn.AssetTransfer
85-
힌트 4 itxn asset transfer 코드 예시: https://github.com/algorandfoundation/puya/blob/2acea25a96c0acd818e9410007d473b2a82e754d/examples/amm/contract.py#L357
85+
힌트 4 - itxn asset transfer 코드 예시: https://github.com/algorandfoundation/puya/blob/2acea25a96c0acd818e9410007d473b2a82e754d/examples/amm/contract.py#L357
8686
"""
8787

8888
"문제 2 시작"
@@ -104,7 +104,7 @@ def bootstrap(
104104
105105
함수 인수 설명:
106106
- buyer_txn: 앱 계정으로 어토믹 그룹에 묶여 동시다발적으로 보내지는 payment 트랜잭션입니다. 에섯 구매를 위해 구매자가 Algo를 보내는 Payment transaction입니다.
107-
- quantity: 구매할 에셋(ASA)의 수량을 나타내는 UInt64 타입의 인수입니다.
107+
- quantity: 에셋(ASA)을 몇개 구매할건지 나타내는 UInt64 타입의 인수입니다.
108108
109109
# 1단계: assert로 buy 호출 조건을 체크하세요.
110110
- bootstrapped 글로벌 상태가 True인지 체크하세요. False라면 부트스트랩이 안된 상태입니다.
@@ -121,7 +121,7 @@ def bootstrap(
121121
122122
힌트 1 - Inner Transaction: https://algorandfoundation.github.io/puya/lg-transactions.html#inner-transactions
123123
힌트 2 - Asset Transfer Inner Txn: https://algorandfoundation.github.io/puya/api-algopy.itxn.html#algopy.itxn.AssetTransfer
124-
힌트 3 itxn asset transfer 코드 예시: https://github.com/algorandfoundation/puya/blob/2acea25a96c0acd818e9410007d473b2a82e754d/examples/amm/contract.py#L357
124+
힌트 3 - itxn asset transfer 코드 예시: https://github.com/algorandfoundation/puya/blob/2acea25a96c0acd818e9410007d473b2a82e754d/examples/amm/contract.py#L357
125125
"""
126126
"문제 3 시작"
127127

@@ -131,7 +131,6 @@ def buy(
131131
buyer_txn: gtxn.PaymentTransaction,
132132
quantity: UInt64,
133133
) -> None:
134-
135134
"여기에 코드 작성"
136135

137136
"문제 3 끝"
@@ -172,6 +171,10 @@ def buy(
172171
- close_remainder_to: 알고 전액이 송금될 주소
173172
174173
이때 두 트랜잭션 다 앱 계정이 보내는 트랜잭션이기 때문에 Inner Transaction을 사용하세요!
174+
175+
힌트 1 - Inner Transaction: https://algorandfoundation.github.io/puya/lg-transactions.html#inner-transactions
176+
힌트 2 - itxn asset transfer 코드 예시: https://github.com/algorandfoundation/puya/blob/2acea25a96c0acd818e9410007d473b2a82e754d/examples/amm/contract.py#L357
177+
175178
"""
176179

177180
"문제 4 시작"

projects/orakle-nft-marketplace-app-contracts/smart_contracts/nft_marketplace/deploy-config.ts

+57-43
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import * as algokit from '@algorandfoundation/algokit-utils'
22
import { NftMarketplaceClient } from '../artifacts/nft_marketplace/client'
33
import { TransactionSignerAccount } from '@algorandfoundation/algokit-utils/types/account'
4+
import { Config as AlgokitConfig } from '@algorandfoundation/algokit-utils'
45

56
// Below is a showcase of various deployment options you can use in TypeScript Client
67
export async function deploy() {
78
console.log('=== Deploying NftMarketplaceClient ===')
9+
AlgokitConfig.configure({ populateAppCallResources: true })
810

911
// 여러 클라이언트 생성
1012
const algod = algokit.getAlgoClient()
@@ -15,8 +17,7 @@ export async function deploy() {
1517
// 랜덤 계정 생성 후 자금 지급
1618
const deployer = await algorand.account.random()
1719
const buyer = await algorand.account.random()
18-
const lateBuyer = await algorand.account.random()
19-
const accounts = [deployer, buyer, lateBuyer]
20+
const accounts = [deployer, buyer]
2021

2122
const dispenser = await algorand.account.dispenser()
2223
for (let i = 0; i < accounts.length; i++) {
@@ -65,25 +66,29 @@ export async function deploy() {
6566
sender: deployer.addr,
6667
receiver: app.appAddress,
6768
amount: algokit.algos(0.2),
69+
extraFee: algokit.algos(0.001),
6870
})
6971

70-
// 앱이 판매할 준비가 되도록 Bootstrap 메서드를 호출
71-
await appClient.bootstrap(
72-
{ asset: assetId, unitaryPrice: unitaryPrice, mbrPay: mbrPay },
73-
{ sendParams: { fee: algokit.transactionFees(2), populateAppCallResources: true, suppressLog: true } },
74-
)
75-
console.log('2. 앱 부트스트래핑 완료!')
72+
const sendAssetToSell = {
73+
sender: deployer.addr,
74+
receiver: app.appAddress,
75+
assetId: assetId,
76+
amount: 100n,
77+
}
7678

77-
// NftMarketplaceClient 앱에 판매할 NFT 에셋 송금
78-
await algorand.send.assetTransfer(
79-
{
79+
// 앱이 판매할 준비가 되도록 Bootstrap 메서드를 호출, NftMarketplaceClient 앱에 판매할 NFT 에셋 송금
80+
await algorand
81+
.newGroup()
82+
.addMethodCall({
8083
sender: deployer.addr,
81-
receiver: app.appAddress,
82-
assetId: assetId,
83-
amount: 100n,
84-
},
85-
{ suppressLog: true },
86-
)
84+
appId: BigInt(app.appId),
85+
method: appClient.appClient.getABIMethod('bootstrap')!,
86+
args: [assetId, unitaryPrice, mbrPay],
87+
})
88+
.addAssetTransfer(sendAssetToSell)
89+
.execute()
90+
91+
console.log('2. 앱 부트스트래핑 완료!')
8792
console.log('3. IU 티켓 에셋 앱으로 송금 완료!')
8893

8994
// 구매자 앱 클라이언트 생성. 이 앱 클라이언트는 구매자 계정과 연동됨.
@@ -96,15 +101,6 @@ export async function deploy() {
96101
algod,
97102
)
98103

99-
const lateBuyerAppClient = new NftMarketplaceClient(
100-
{
101-
resolveBy: 'id',
102-
sender: lateBuyer,
103-
id: app.appId,
104-
},
105-
algod,
106-
)
107-
108104
// 구매자가 에섯에 옵트인하고 buy 메서드를 호출하는 함수
109105
async function buyAsset(
110106
appClient: NftMarketplaceClient,
@@ -115,48 +111,66 @@ export async function deploy() {
115111
appAddr: string,
116112
unitaryPrice: number,
117113
): Promise<void> {
114+
// NftMarketplaceClient buy 메서드 호출때 구매 비용 지불로 사용할 결제 트랜잭션 생성
115+
const buyNftPay = await algorand.transactions.payment({
116+
sender: buyer.addr,
117+
receiver: appAddr,
118+
amount: algokit.algos((unitaryPrice * buyAmount) / 1_000_000),
119+
})
120+
118121
try {
119122
let assetInfo = await algorand.account.getAssetInformation(buyer, assetId)
120123
console.log(`${buyerName}가 이미 에셋에 옵트인 되어있어요! 현재 보유한 티켓 수: ${assetInfo.balance}개`)
121124
} catch (e) {
122125
console.log(`${buyerName}가 에셋에 옵트인이 안 되어있어요. 옵트인 진행할게요~`)
123-
// 구매자가 NFT에 옵트인
124-
await algorand.send.assetOptIn(
125-
{
126+
127+
// buy메서드 앱 호출 트랜잭션 생성
128+
const buyAppCall = await appClient
129+
.compose()
130+
.buy(
131+
{
132+
buyerTxn: buyNftPay,
133+
quantity: buyAmount,
134+
},
135+
{ sendParams: { fee: algokit.transactionFees(2), suppressLog: true } },
136+
)
137+
.atc()
138+
139+
// 구매자가 NFT에 옵트인, buyNftPay 결제 트랜잭션, NftMarketplaceClient buy 메서드를 어토믹 트랜잭션으로 동시에 호출
140+
await algorand
141+
.newGroup()
142+
.addAssetOptIn({
126143
sender: buyer.addr,
127144
assetId: assetId,
128-
},
129-
{ suppressLog: true },
130-
)
131-
}
145+
})
146+
.addAtc(buyAppCall)
147+
.execute()
132148

133-
// NftMarketplaceClient buy 메서드 호출때 구매 비용 지불로 사용할 결제 트랜잭션 생성
134-
const buyNftPay = await algorand.transactions.payment({
135-
sender: buyer.addr,
136-
receiver: appAddr,
137-
amount: algokit.algos((unitaryPrice * buyAmount) / 1_000_000),
138-
})
149+
const assetInfo = await algorand.account.getAssetInformation(buyer, assetId)
150+
console.log(`${buyerName}가 티켓 ${buyAmount}장을 구매하여 ${assetInfo.balance}개의 티켓을 보유하고 있어요!`)
151+
return
152+
}
139153

140-
// 위 결제 트랜잭션과 NftMarketplaceClient buy 메서드를 어토믹 트랜잭션으로 동시에 호출
154+
// 계정이 이미 구매할 에셋(아이유 콘서트 티켓)에 옵트인 되어 있을 시 buy 메서드만 호출
141155
await appClient.buy(
142156
{
143157
buyerTxn: buyNftPay,
144158
quantity: buyAmount,
145159
},
146-
{ sendParams: { fee: algokit.transactionFees(2), populateAppCallResources: true, suppressLog: true } },
160+
{ sendParams: { fee: algokit.transactionFees(2), suppressLog: true } },
147161
)
148162

149163
const assetInfo = await algorand.account.getAssetInformation(buyer, assetId)
150-
console.log(`${buyerName}가 티켓 1장을 추가 구매하여 ${assetInfo.balance}개의 티켓을 보유하고 있어요!`)
164+
console.log(`${buyerName}가 티켓 ${buyAmount}장을 구매하여 ${assetInfo.balance}개의 티켓을 보유하고 있어요!`)
151165
}
152166

153167
await buyAsset(buyerAppClient, 'buyer', buyer, assetId, 1, app.appAddress, unitaryPrice)
168+
await buyAsset(buyerAppClient, 'buyer', buyer, assetId, 2, app.appAddress, unitaryPrice)
154169

155170
// 판매자가 NftMarketplaceClient 앱을 삭제하며 수익금과 잔여 NFT 에셋을 회수
156171
await appClient.delete.withdrawAndDelete(
157172
{},
158173
{ sendParams: { fee: algokit.transactionFees(3), populateAppCallResources: true } },
159174
)
160-
161175
console.log('4. IU 티켓 판매 종료 및 수익금 회수 완료!')
162176
}

0 commit comments

Comments
 (0)