-
Notifications
You must be signed in to change notification settings - Fork 1
/
Music Royalty System
91 lines (80 loc) · 3.03 KB
/
Music Royalty System
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
use solana_program::{
account_info::{next_account_info, AccountInfo},
entrypoint,
entrypoint::ProgramResult,
msg,
program_error::ProgramError,
program_pack::{IsInitialized, Pack, Sealed},
pubkey::Pubkey,
sysvar::{clock::Clock, rent::Rent, Sysvar},
};
use std::mem::size_of;
entrypoint!(process_instruction);
#[derive(Debug)]
pub struct MusicRoyaltyToken {
pub is_initialized: bool,
pub artist_name: String,
pub song_title: String,
pub balance: u64,
pub last_played: u64,
}
impl Sealed for MusicRoyaltyToken {}
impl IsInitialized for MusicRoyaltyToken {
fn is_initialized(&self) -> bool {
self.is_initialized
}
}
impl Pack for MusicRoyaltyToken {
const LEN: usize = size_of::<Self>();
fn pack_into_slice(&self, output: &mut [u8]) {
let output = &mut output[..Self::LEN];
output[0] = self.is_initialized as u8;
output[1..=32].copy_from_slice(self.artist_name.as_bytes());
output[33..=64].copy_from_slice(self.song_title.as_bytes());
output[65..=72].copy_from_slice(&self.balance.to_le_bytes());
output[73..=80].copy_from_slice(&self.last_played.to_le_bytes());
}
fn unpack_from_slice(input: &[u8]) -> Result<Self, ProgramError> {
let input = &input[..Self::LEN];
Ok(Self {
is_initialized: input[0] != 0,
artist_name: String::from_utf8(input[1..=32].to_vec())
.map_err(|_| ProgramError::InvalidInstructionData)?,
song_title: String::from_utf8(input[33..=64].to_vec())
.map_err(|_| ProgramError::InvalidInstructionData)?,
balance: u64::from_le_bytes(
input[65..=72]
.try_into()
.map_err(|_| ProgramError::InvalidInstructionData)?,
),
last_played: u64::from_le_bytes(
input[73..=80]
.try_into()
.map_err(|_| ProgramError::InvalidInstructionData)?,
),
})
}
}
fn create_music_royalty_token_account(
program_id: &Pubkey,
accounts: &[AccountInfo],
artist_name: String,
song_title: String,
balance: u64,
) -> ProgramResult {
let account_info_iter = &mut accounts.iter();
let music_royalty_token_account = next_account_info(account_info_iter)?;
let rent_info = next_account_info(account_info_iter)?;
let system_info = next_account_info(account_info_iter)?;
let payer_info = next_account_info(account_info_iter)?;
// Ensure the program is the owner of the account
if music_royalty_token_account.owner != program_id {
return Err(ProgramError::IncorrectProgramId);
}
// Check that the account is not already initialized
if MusicRoyaltyToken::is_initialized(music_royalty_token_account.data.borrow().as_ref()) {
return Err(ProgramError::AccountAlreadyInitialized);
}
// Calculate the required account rent
let rent = &Rent::from_account_info(rent_info)?;
let required_lamports = rent.minimum_balance(MusicRoyaltyToken::LEN);