Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tamagotchi_nft #5

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 20 additions & 13 deletions contracts/03-tamagotchi-nft/io/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ pub struct Tamagotchi {
pub slept: u64,
pub slept_block: u64,
// TODO: 1️⃣ Add new fields
pub approved_account: Option<ActorId>,
}

#[derive(Encode, Decode, TypeInfo)]
Expand All @@ -27,11 +28,14 @@ pub struct Tamagotchi {
pub enum TmgAction {
// TODO: 0️⃣ Copy actions from previous lesson and push changes to the master branch
Name,
Age,
Feed,
Entertain,
Sleep,
Age,
Feed,
Entertain,
Sleep,
// TODO: 2️⃣ Add new actions
Transfer(ActorId),
Approve(ActorId),
RevokeApproval,
}

#[derive(Encode, Decode, TypeInfo)]
Expand All @@ -40,11 +44,14 @@ pub enum TmgAction {
pub enum TmgEvent {
// TODO: 0️⃣ Copy events from previous lesson and push changes to the master branch
Name(String),
Age(u64),
Fed,
Entertained,
Slept,
Age(u64),
Fed,
Entertained,
Slept,
// TODO: 3️⃣ Add new events
Transferred(ActorId),
Approved(ActorId),
ApprovalRevoked,
}

pub struct ProgramMetadata;
Expand All @@ -60,9 +67,9 @@ impl Metadata for ProgramMetadata {
}

pub const HUNGER_PER_BLOCK: u64 = 1;
pub const BOREDOM_PER_BLOCK: u64 = 2;
pub const ENERGY_PER_BLOCK: u64 = 2;
pub const BOREDOM_PER_BLOCK: u64 = 2;
pub const ENERGY_PER_BLOCK: u64 = 2;

pub const FILL_PER_FEED: u64 = 1000;
pub const FILL_PER_ENTERTAINMENT: u64 = 1000;
pub const FILL_PER_SLEEP: u64 = 1000;
pub const FILL_PER_FEED: u64 = 1000;
pub const FILL_PER_ENTERTAINMENT: u64 = 1000;
pub const FILL_PER_SLEEP: u64 = 1000;
67 changes: 49 additions & 18 deletions contracts/03-tamagotchi-nft/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,18 @@ pub struct Tamagotchi {
pub entertained_block: u64,
pub slept: u64,
pub slept_block: u64,
pub approved_account: Option<ActorId>,
}
impl Tamagotchi {
fn current_fed(&mut self) -> u64 {
let a: u64 =
self.fed - (HUNGER_PER_BLOCK as u64) * ((exec::block_height() as u64) - self.fed_block);
a
self.fed - (HUNGER_PER_BLOCK as u64) * ((exec::block_height() as u64) - self.fed_block)
}
fn current_entertained(&mut self) -> u64 {
let b: u64 = self.entertained
- (BOREDOM_PER_BLOCK as u64) * ((exec::block_height() as u64) - self.entertained_block);
b
self.entertained
- (BOREDOM_PER_BLOCK as u64) * ((exec::block_height() as u64) - self.entertained_block)
}
fn current_slept(&mut self) -> u64 {
let c: u64 = self.slept
- (ENERGY_PER_BLOCK as u64) * ((exec::block_height() as u64) - self.slept_block);
c
self.slept - (ENERGY_PER_BLOCK as u64) * ((exec::block_height() as u64) - self.slept_block)
}
}
static mut TAMAGOTCHI: Option<Tamagotchi> = None;
Expand All @@ -55,6 +51,7 @@ extern fn init() {
entertained_block: entertainedblock,
slept: 2000,
slept_block: sleptblock,
approved_account: None,
};
unsafe {
TAMAGOTCHI = Some(tmg);
Expand All @@ -66,17 +63,23 @@ extern fn handle() {
// TODO: 0️⃣ Copy the `handle` function from the previous lesson and push changes to the master branch
let action: TmgAction = msg::load().expect("unable to load action");
let tmg = unsafe { TAMAGOTCHI.get_or_insert(Default::default()) };
if msg::source() == tmg.owner {
match action {
TmgAction::Name => {
match action {
TmgAction::Name => {
if msg::source() == tmg.owner {
msg::reply(TmgEvent::Name(tmg.name.clone()), 0)
.expect("Error in a reply'tamagotchi::name'");
}
TmgAction::Age => {
panic!("You are not the owner of this tamagotchi");
}
TmgAction::Age => {
if msg::source() == tmg.owner {
let age = exec::block_timestamp() - tmg.date_of_birth;
msg::reply(TmgEvent::Age(age), 0).expect("Error in a reply'tamagotchi::age'");
}
TmgAction::Feed => {
panic!("You are not the owner of this tamagotchi");
}
TmgAction::Feed => {
if msg::source() == tmg.owner {
if tmg.current_fed() <= 9000 {
let fed = tmg.fed + FILL_PER_FEED;
msg::reply(TmgEvent::Fed, 0).expect("Error in a reply'tamagotchi::fed'");
Expand All @@ -93,7 +96,10 @@ extern fn handle() {
msg::reply(TmgEvent::Fed, 1).expect("Error in a reply'tamagotchi::fed'");
}
}
TmgAction::Entertain => {
panic!("You are not the owner of this tamagotchi");
}
TmgAction::Entertain => {
if msg::source() == tmg.owner {
if tmg.current_entertained() <= 9000 {
let entertained = tmg.entertained + FILL_PER_ENTERTAINMENT;
msg::reply(TmgEvent::Entertained, 0)
Expand All @@ -112,7 +118,10 @@ extern fn handle() {
.expect("Error in a reply'tamagotchi::entertained'");
}
}
TmgAction::Sleep => {
panic!("You are not the owner of this tamagotchi");
}
TmgAction::Sleep => {
if msg::source() == tmg.owner {
if tmg.current_slept() <= 9000 {
let slept = tmg.slept + FILL_PER_SLEEP;
msg::reply(TmgEvent::Slept, 0).expect("Error in a reply'tamagotchi::slept'");
Expand All @@ -129,9 +138,31 @@ extern fn handle() {
msg::reply(TmgEvent::Slept, 1).expect("Error in a reply'tamagotchi::slept'");
}
}
panic!("You are not the owner of this tamagotchi");
}
TmgAction::Transfer(account) => {
let source = msg::source();
if source == tmg.owner {
tmg.owner = account;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One should reset the approved_account after transferring the ownership.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image

tmg.approved_account = None;
msg::reply(TmgEvent::Transferred(account), 0)
.expect("Error in a reply'tamagotchi::transferred'");
} else if source == tmg.approved_account.unwrap_or_default() {
tmg.owner = account;
msg::reply(TmgEvent::Transferred(account), 0)
.expect("Error in a reply'tamagotchi::transfered'");
}
}
TmgAction::Approve(account) => {
tmg.approved_account = Some(account);
msg::reply(TmgEvent::Approved(account), 0)
.expect("Error in a reply'tamagotchi::approved'");
}
TmgAction::RevokeApproval => {
tmg.approved_account = None;
msg::reply(TmgEvent::ApprovalRevoked, 0)
.expect("Error in a reply'tamagotchi::approval_revoked'");
}
} else {
panic!("You are not the owner of this tamagotchi");
}
}
#[no_mangle]
Expand Down
68 changes: 15 additions & 53 deletions contracts/03-tamagotchi-nft/tests/owning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,69 +4,31 @@ use tamagotchi_nft_io::*;
// TODO: 0️⃣ Copy tests from the previous lesson and push changes to the master branch

#[test]
fn smoke_test() {
fn owning_test() {
let sys = System::new();
sys.init_logger();
let program = Program::current(&sys);
let result = program.send(2, String::from("Goodmoring"));
assert!(!result.main_failed());
let result = program.send(2, TmgAction::Name);
let _result = program.send(2, String::from("Goodmoring"));
let result = program.send(2, TmgAction::Transfer(3.into()));
let log = Log::builder()
.dest(2)
.payload(TmgEvent::Name(String::from("Goodmoring")));
.payload(TmgEvent::Transferred(3.into()));
assert!(result.contains(&log));
let _result = program.send(2, TmgAction::Age);
// let log = Log::builder().dest(2).payload(TmgEvent::Age(sys.block_timestamp()));
// assert!(result.contains(&log));

//How to test the age?
}

#[test]
fn negative_smoke_test() {
let sys = System::new();
sys.init_logger();
let program = Program::current(&sys);
let payload = vec![1, 2, 3];
let _result = program.send(2, payload);
// assert!(result.main_failed());
// Why the assert is panic?

// let result = program.send(1, TmgAction::Name);
// let log = Log::builder().dest(2).payload(TmgEvent::Name("Goodmoring".to_string()));
// assert!(!result.contains(&log));
// let result = program.send(1, TmgAction::Age);
// let log = Log::builder().dest(2).payload(TmgEvent::Age(sys.block_timestamp()));
// assert!(!result.contains(&log));
}

#[test]
fn interaction_test() {
let sys = System::new();
sys.init_logger();
let program = Program::current(&sys);
let result = program.send(2, String::from("Goodmoring"));
assert!(!result.main_failed());
let result = program.send(2, TmgAction::Feed);
let log = Log::builder().dest(2).payload(TmgEvent::Fed);
assert!(result.contains(&log));
let result = program.send(2, TmgAction::Entertain);
let log = Log::builder().dest(2).payload(TmgEvent::Entertained);
assert!(result.contains(&log));
let result = program.send(2, TmgAction::Sleep);
let log = Log::builder().dest(2).payload(TmgEvent::Slept);
let result = program.send(3, TmgAction::Approve(4.into()));
let log = Log::builder().dest(3).payload(TmgEvent::Approved(4.into()));
assert!(result.contains(&log));

let _result = program.send(1, TmgAction::Sleep);
//how to test the panic result?
//negetive test
}
let result = program.send(4, TmgAction::Transfer(5.into()));
let log = Log::builder()
.dest(4)
.payload(TmgEvent::Transferred(5.into()));
assert!(result.contains(&log));

#[test]
fn owning_test() {
let sys = System::new();
sys.init_logger();
let _program = Program::current(&sys);
let result = program.send(5, TmgAction::RevokeApproval);
let log = Log::builder().dest(5).payload(TmgEvent::ApprovalRevoked);
assert!(result.contains(&log));

//why the test is panic?
// TODO: 6️⃣ Test new functionality
}
Loading