Skip to content

Commit

Permalink
Updating concert.md (#198)
Browse files Browse the repository at this point in the history
  • Loading branch information
MedovTimur authored Oct 28, 2024
1 parent d56ebfb commit f61df37
Showing 1 changed file with 82 additions and 84 deletions.
166 changes: 82 additions & 84 deletions docs/examples/NFTs/concert.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
sidebar_label: Concert (FT to NFT transition)
sidebar_position: 14
sidebar_label: Concert
sidebar_position: 4
---

# Concert Program (FT to NFT transition)
Expand All @@ -13,130 +13,128 @@ In this example, a single deployed program can hold one concert at a time. First

The idea is simple - all the internal token interactions are handled using the VMT program, which address must be provided upon initializing a concert program.

The article explains the programming interface, data structure, basic functions and explains their purpose. It can be used as is or modified to suit any custom scenarios. Anyone can easily create their own application and run it on the Vara Network. The source code is available on [GitHub](https://github.com/gear-foundation/dapps/tree/f80c9ca301912fbfbfb2e0a4d3c8f7aa2506d522/contracts/concert).
The article explains the programming interface, data structure, basic functions and explains their purpose. It can be used as is or modified to suit any custom scenarios. Anyone can easily create their own application and run it on the Vara Network. The source code is available on [GitHub](https://github.com/gear-foundation/dapps/tree/master/contracts/concert).

## Interface
## Implementation details

### Events

```rust title="concert/io/src/lib.rs"
pub enum ConcertEvent {
```rust title="concert/app/src/lib.rs"
pub enum Event {
Creation {
creator: ActorId,
concert_id: u128,
number_of_tickets: u128,
concert_id: U256,
number_of_tickets: U256,
date: u128,
},
Hold {
concert_id: u128,
concert_id: U256,
},
Purchase {
concert_id: u128,
amount: u128,
concert_id: U256,
amount: U256,
},
}
```
### Functions
#### Create a concert
```rust title="concert/src/lib.rs"
/// Create a concert.
/// `number_of_tickets` - is the amount of FT minted later.
/// `date` - is the date of the concert holding.
fn create_concert(
pub fn create(
&mut self,
creator: ActorId,
name: String,
description: String,
creator: ActorId,
number_of_tickets: u128,
number_of_tickets: U256,
date: u128,
token_id: u128,
) -> Result<ConcertEvent, ConcertError> {
// ...
token_id: U256,
)
```
- `name` - is the name of an upcoming concert.
- `creator` - is a description of the concert.
- `creator` - is the creator of the concert (the creator will have more functionality).
- `number_of_tickets` - is the amount of FT minted later.
- `date` - is the date of the concert holding.
- `token_id` - id token for multitoken transfer.
- `creator` - is the creator of the concert
- `name` - is the name of an upcoming concert
- `description` - is a description of the concert
- `number_of_tickets` - is the amount of FT minted later
- `date` - is the date of the concert holding
- `token_id` - id token for multitoken transfer

#### Buy tickets
```rust title="concert/src/lib.rs"
async fn buy_tickets(
&mut self,
amount: u128,
mtd: Vec<Option<TokenMetadata>>,
) -> Result<ConcertEvent, ConcertError> {
// ...
pub async fn buy_tickets(&mut self, amount: U256, mtd: Vec<Option<TokenMetadata>>)
```
- `amount` - is the number of tickets one is trying to purchase.
- `mtd` - is the tickets metadata (e.g. seat/row). This argument length should equal the `amount` value.

#### Hold a concert
```rust title="concert/src/lib.rs"
async fn hold_concert(&mut self) -> Result<ConcertEvent, ConcertError> {
// ...
pub async fn hold_concert(&mut self)
```
>Hold a concert, turning of the FT (aka tickets) into NFTs; the hold a concert functionality is only available to the creator

### Init Config
To successfully initialize a concert program, one should provide an ActorID of a GMT-1155 program to hold all the token manipulations. The sender of this message becomes the owner of the program.

```rust title="concert/io/src/lib.rs"
pub struct InitConcert {
pub owner_id: ActorId,
pub mtk_contract: ActorId,
}
```

### `Action` Structure
```rust title="concert/io/src/lib.rs"
pub enum ConcertAction {
Create {
creator: ActorId,
name: String,
description: String,
number_of_tickets: u128,
date: u128,
token_id: u128,
},
Hold,
BuyTickets {
amount: u128,
metadata: Vec<Option<TokenMetadata>>,
},
}
```

### Program metadata and state
Metadata interface description:
To successfully initialize a concert program, one should provide an ActorID of the [Vara Miltiple Token Standard (VMT)](/docs/examples/Standards/vmt.md) program to hold all the token manipulations.

```rust title="concert/io/src/lib.rs"
pub struct ContractMetadata;

impl Metadata for ContractMetadata {
type Init = In<InitConcert>;
type Handle = InOut<ConcertAction, Result<ConcertEvent, ConcertError>>;
type Reply = ();
type Others = ();
type Signal = ();
type State = Out<State>;
```rust title="concert/src/lib.rs"
pub fn init(owner_id: ActorId, vmt_contract: ActorId) -> Self {
let storage = Storage {
owner_id,
contract_id: vmt_contract,
..Default::default()
};
unsafe { STORAGE = Some(storage) };
Self(())
}
```
To display the full program state information, the `state()` function is used:

```rust title="concert/src/lib.rs"
#[no_mangle]
extern fn state() {
let contract = unsafe { CONTRACT.take().expect("Unexpected error in taking state") };
msg::reply::<State>(contract.into(), 0)
.expect("Failed to encode or reply with `State` from `state()`");
}
### Contract Interface

The concert program includes the following interface:

```rust
type TokenMetadata = struct {
title: opt str,
description: opt str,
media: opt str,
reference: opt str,
};

type State = struct {
owner_id: actor_id,
contract_id: actor_id,
name: str,
description: str,
ticket_ft_id: u256,
creator: actor_id,
number_of_tickets: u256,
tickets_left: u256,
date: u128,
buyers: vec actor_id,
id_counter: u256,
concert_id: u256,
running: bool,
metadata: vec struct { actor_id, vec struct { u256, opt TokenMetadata } },
token_id: u256,
};

constructor {
New : (owner_id: actor_id, vmt_contract: actor_id);
};

service Concert {
BuyTickets : (amount: u256, mtd: vec opt TokenMetadata) -> null;
Create : (creator: actor_id, name: str, description: str, number_of_tickets: u256, date: u128, token_id: u256) -> null;
HoldConcert : () -> null;
query GetStorage : () -> State;

events {
Creation: struct { creator: actor_id, concert_id: u256, number_of_tickets: u256, date: u128 };
Hold: struct { concert_id: u256 };
Purchase: struct { concert_id: u256, amount: u256 };
}
};
```

## Conclusion
A source code of the program example is available on GitHub: [`concert/src`](https://github.com/gear-foundation/dapps/tree/f80c9ca301912fbfbfb2e0a4d3c8f7aa2506d522/contracts/concert/src).
A source code of the program example is available on GitHub: [`concert/src`](https://github.com/gear-foundation/dapps/tree/master/contracts/concert/src).

See also an example of the program testing implementation based on [gtest](https://github.com/gear-foundation/dapps/tree/f80c9ca301912fbfbfb2e0a4d3c8f7aa2506d522/contracts/concert/tests).
See also an example of the program testing implementation based on [gtest](https://github.com/gear-foundation/dapps/tree/master/contracts/concert/tests).

For more details about testing programs on Vara, refer to this article: [Program Testing](/docs/build/testing).

0 comments on commit f61df37

Please sign in to comment.