Skip to content

Commit

Permalink
readme, contract instruction, deploy-config update
Browse files Browse the repository at this point in the history
  • Loading branch information
iskysun96 committed May 28, 2024
1 parent 79d3344 commit 482044c
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 50 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ algokit project bootstrap all
6. 이제 `orakle-nft-marketplace-app-contracts` 터미널을 선택한 뒤 `poetry shell` 커맨드를 실행해 파이썬 virtual environment를 활성화 시켜주세요.
1. 파이썬 virtual environment를 비활성화 시킬때는 `exit` 커맨드를 실행하시면 됩니다.
2. venv를 활성화 한 뒤 `pip list`를 실행해서 `algorand-python` 및 여러 dependencies들이 나오면 성공적으로 가상환경을 활성화 시킨겁니다.

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

Expand All @@ -65,9 +66,16 @@ https://github.com/algorand-fix-the-bug-campaign/challenge-1/assets/52557585/acd
### 1-4문제: 스마트계약 문제 진행 설명
1. `orakle-nft-marketplace-app-contracts` 터미널에서 `poetry shell`를 실행해서 파이썬 가상환경을 켰는지 확인하세요.
2. `orakle-nft-marketplace-app-contracts/smart_contract/nft_marketplace/contract.ts`로 가시면 문제 1-4가 주석으로 작성되어있습니다.
2. `orakle-nft-marketplace-app-contracts/smart_contract/nft_marketplace/contract.py`로 가시면 문제 1-4가 주석으로 작성되어있습니다.
설명을 자세히 읽고 문제들을 해결하세요!
3. 문제를 다 해결한 뒤 터미널에서 `algokit project run build` 커맨드를 실행해 스마트 계약을 컴파일 하시고 `algokit project deploy localnet` 커맨드를 실행해 `smart_contracts/digital_marketplace/deploy-config.ts` 파일을 실행하세요!
```bash
algokit project run build
```

```bash
algokit project deploy localnet
```
실행 후 다음과 같은 콘솔 값이 출력되면 성공적으로 모든 문제를 해결하신겁니다! 👏👏 이제 문제 5-9로 넘어가세요.
<img width="1033" alt="image" src="https://github.com/algorand-devrel/orakle-coding-assignment-2024/assets/52557585/7c6b578d-fd59-42e6-a11d-184ed7552cef">

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

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

Expand All @@ -131,7 +131,6 @@ def buy(
buyer_txn: gtxn.PaymentTransaction,
quantity: UInt64,
) -> None:

"여기에 코드 작성"

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

"문제 4 시작"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import * as algokit from '@algorandfoundation/algokit-utils'
import { NftMarketplaceClient } from '../artifacts/nft_marketplace/client'
import { TransactionSignerAccount } from '@algorandfoundation/algokit-utils/types/account'
import { Config as AlgokitConfig } from '@algorandfoundation/algokit-utils'

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

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

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

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

// NftMarketplaceClient 앱에 판매할 NFT 에셋 송금
await algorand.send.assetTransfer(
{
// 앱이 판매할 준비가 되도록 Bootstrap 메서드를 호출, NftMarketplaceClient 앱에 판매할 NFT 에셋 송금
await algorand
.newGroup()
.addMethodCall({
sender: deployer.addr,
receiver: app.appAddress,
assetId: assetId,
amount: 100n,
},
{ suppressLog: true },
)
appId: BigInt(app.appId),
method: appClient.appClient.getABIMethod('bootstrap')!,
args: [assetId, unitaryPrice, mbrPay],
})
.addAssetTransfer(sendAssetToSell)
.execute()

console.log('2. 앱 부트스트래핑 완료!')
console.log('3. IU 티켓 에셋 앱으로 송금 완료!')

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

const lateBuyerAppClient = new NftMarketplaceClient(
{
resolveBy: 'id',
sender: lateBuyer,
id: app.appId,
},
algod,
)

// 구매자가 에섯에 옵트인하고 buy 메서드를 호출하는 함수
async function buyAsset(
appClient: NftMarketplaceClient,
Expand All @@ -115,48 +111,66 @@ export async function deploy() {
appAddr: string,
unitaryPrice: number,
): Promise<void> {
// NftMarketplaceClient buy 메서드 호출때 구매 비용 지불로 사용할 결제 트랜잭션 생성
const buyNftPay = await algorand.transactions.payment({
sender: buyer.addr,
receiver: appAddr,
amount: algokit.algos((unitaryPrice * buyAmount) / 1_000_000),
})

try {
let assetInfo = await algorand.account.getAssetInformation(buyer, assetId)
console.log(`${buyerName}가 이미 에셋에 옵트인 되어있어요! 현재 보유한 티켓 수: ${assetInfo.balance}개`)
} catch (e) {
console.log(`${buyerName}가 에셋에 옵트인이 안 되어있어요. 옵트인 진행할게요~`)
// 구매자가 NFT에 옵트인
await algorand.send.assetOptIn(
{

// buy메서드 앱 호출 트랜잭션 생성
const buyAppCall = await appClient
.compose()
.buy(
{
buyerTxn: buyNftPay,
quantity: buyAmount,
},
{ sendParams: { fee: algokit.transactionFees(2), suppressLog: true } },
)
.atc()

// 구매자가 NFT에 옵트인, buyNftPay 결제 트랜잭션, NftMarketplaceClient buy 메서드를 어토믹 트랜잭션으로 동시에 호출
await algorand
.newGroup()
.addAssetOptIn({
sender: buyer.addr,
assetId: assetId,
},
{ suppressLog: true },
)
}
})
.addAtc(buyAppCall)
.execute()

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

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

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

await buyAsset(buyerAppClient, 'buyer', buyer, assetId, 1, app.appAddress, unitaryPrice)
await buyAsset(buyerAppClient, 'buyer', buyer, assetId, 2, app.appAddress, unitaryPrice)

// 판매자가 NftMarketplaceClient 앱을 삭제하며 수익금과 잔여 NFT 에셋을 회수
await appClient.delete.withdrawAndDelete(
{},
{ sendParams: { fee: algokit.transactionFees(3), populateAppCallResources: true } },
)

console.log('4. IU 티켓 판매 종료 및 수익금 회수 완료!')
}

0 comments on commit 482044c

Please sign in to comment.