Skip to content

Commit

Permalink
Add content rating contract
Browse files Browse the repository at this point in the history
Introduce a new content rating contract to validate content based on age levels. This includes enum definitions for RatingLevel, AgeLevel, and Error, and implements validation logic and unit tests.
  • Loading branch information
arkavo-com committed Oct 24, 2024
1 parent 1c251cf commit f9b7ad4
Show file tree
Hide file tree
Showing 3 changed files with 256 additions and 0 deletions.
12 changes: 12 additions & 0 deletions etc/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ cargo contract build --features e2e-tests

### Deploy

#### Content Rating

```text
Code hash 0xcee0206b80f939ec9da4c69a62284e22e0fa05c98e0c7341deeb3a7e835ef261
Contract 5HKLo6CKbt1Z5dU4wZ3MiufeZzjM6JGwKUWUQ6a91fmuA6RB
```

#### Geofence

```text
Expand All @@ -59,6 +66,11 @@ Code hash 0xee2250ba4215f273e571ecdfc2a373ccc96de5f82c19fcdaca889218fac5ac39
Contract 5D35jFeQboveKiaQSxyLKENGqrnjgUc7B4D23QbhJK4Yr7jT
```

```shell
cargo contract upload --url ws://127.0.0.1:9944 --suri //Alice content_rating/target/ink/content_rating.wasm
cargo contract instantiate --url ws://127.0.0.1:9944 --suri //Alice content_rating/target/ink/content_rating.wasm --execute
```

```shell
cargo contract upload --url ws://127.0.0.1:9944 --suri //Alice timestamp_validator/target/ink/timestamp_validator.wasm
cargo contract instantiate --url ws://127.0.0.1:9944 --suri //Alice timestamp_validator/target/ink/timestamp_validator.wasm --execute
Expand Down
26 changes: 26 additions & 0 deletions etc/contracts/content_rating/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "content_rating"
version = "0.1.0"
authors = ["[your_name] <[your_email]>"]
edition = "2021"

[dependencies]
ink = { version = "5.0.0", default-features = false }
scale = { package = "parity-scale-codec", version = "3.6.12", default-features = false, features = ["derive"] }
scale-info = { version = "2.11.3", default-features = false, features = ["derive"], optional = true }

[dev-dependencies]
ink_e2e = { version = "5.0.0" }

[lib]
path = "lib.rs"

[features]
default = ["std"]
std = [
"ink/std",
"scale/std",
"scale-info/std",
]
ink-as-dependency = []
e2e-tests = []
218 changes: 218 additions & 0 deletions etc/contracts/content_rating/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
#![cfg_attr(not(feature = "std"), no_std, no_main)]
#![allow(unexpected_cfgs)]
#[ink::contract]
mod content_rating {
#[derive(Debug, PartialEq, Eq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub enum RatingLevel {
Unused = 0,
None = 1,
Mild = 2,
Moderate = 3,
Severe = 4,
}

#[derive(Debug, PartialEq, Eq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub struct Rating {
violent: RatingLevel,
sexual: RatingLevel,
profane: RatingLevel,
substance: RatingLevel,
hate: RatingLevel,
harm: RatingLevel,
mature: RatingLevel,
bully: RatingLevel,
}

#[derive(Debug, PartialEq, Eq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub enum AgeLevel {
Kids, // Under 13
Teens, // 13 to 17
Adults, // 18 and above
}

#[derive(Debug, PartialEq, Eq, scale::Encode, scale::Decode)]
#[cfg_attr(feature = "std", derive(scale_info::TypeInfo))]
pub enum Error {
ViolentContentTooHigh,
SexualContentNotAllowed,
ProfaneContentNotAllowed,
SubstanceContentNotAllowed,
HateContentNotAllowed,
HarmContentNotAllowed,
MatureContentNotAllowed,
BullyingContentNotAllowed,
}

#[ink(storage)]
pub struct ContentRating {
// Contract storage (empty for this case)
}

impl ContentRating {
#[ink(constructor)]
pub fn new() -> Self {
Self {}
}

#[ink(message)]
pub fn validate_content(&self, age_level: AgeLevel, rating: Rating) -> Result<(), Error> {
match age_level {
AgeLevel::Kids => self.validate_kids_content(&rating),
AgeLevel::Teens => self.validate_teens_content(&rating),
AgeLevel::Adults => Ok(()), // Everything is allowed for adults
}
}

fn validate_kids_content(&self, rating: &Rating) -> Result<(), Error> {
// For kids, only mild violence is allowed, everything else must be none
if !matches!(rating.violent, RatingLevel::None | RatingLevel::Mild) {
return Err(Error::ViolentContentTooHigh);
}
if !matches!(rating.sexual, RatingLevel::None) {
return Err(Error::SexualContentNotAllowed);
}
if !matches!(rating.profane, RatingLevel::None) {
return Err(Error::ProfaneContentNotAllowed);
}
if !matches!(rating.substance, RatingLevel::None) {
return Err(Error::SubstanceContentNotAllowed);
}
if !matches!(rating.hate, RatingLevel::None) {
return Err(Error::HateContentNotAllowed);
}
if !matches!(rating.harm, RatingLevel::None) {
return Err(Error::HarmContentNotAllowed);
}
if !matches!(rating.mature, RatingLevel::None) {
return Err(Error::MatureContentNotAllowed);
}
if !matches!(rating.bully, RatingLevel::None) {
return Err(Error::BullyingContentNotAllowed);
}
Ok(())
}

fn validate_teens_content(&self, rating: &Rating) -> Result<(), Error> {
// For teens, certain content must be none, others can be up to mild
if matches!(rating.violent, RatingLevel::Moderate | RatingLevel::Severe) {
return Err(Error::ViolentContentTooHigh);
}
if matches!(rating.sexual, RatingLevel::Moderate | RatingLevel::Severe) {
return Err(Error::SexualContentNotAllowed);
}
if matches!(rating.profane, RatingLevel::Moderate | RatingLevel::Severe) {
return Err(Error::ProfaneContentNotAllowed);
}
// These must be none for teens
if !matches!(rating.substance, RatingLevel::None) {
return Err(Error::SubstanceContentNotAllowed);
}
if !matches!(rating.hate, RatingLevel::None) {
return Err(Error::HateContentNotAllowed);
}
if !matches!(rating.harm, RatingLevel::None) {
return Err(Error::HarmContentNotAllowed);
}
if matches!(rating.mature, RatingLevel::Moderate | RatingLevel::Severe) {
return Err(Error::MatureContentNotAllowed);
}
if !matches!(rating.bully, RatingLevel::None) {
return Err(Error::BullyingContentNotAllowed);
}
Ok(())
}

#[ink(message)]
pub fn check_content(&self, age_level: AgeLevel, rating: Rating) -> bool {
self.validate_content(age_level, rating).is_ok()
}
}

#[cfg(test)]
mod tests {
use super::*;

#[ink::test]
fn kids_content_validation_works() {
let contract = ContentRating::new();

// Valid kids content
let valid_kids_rating = Rating {
violent: RatingLevel::Mild,
sexual: RatingLevel::None,
profane: RatingLevel::None,
substance: RatingLevel::None,
hate: RatingLevel::None,
harm: RatingLevel::None,
mature: RatingLevel::None,
bully: RatingLevel::None,
};
assert!(contract.check_content(AgeLevel::Kids, valid_kids_rating));

// Invalid kids content (too violent)
let invalid_kids_rating = Rating {
violent: RatingLevel::Moderate,
sexual: RatingLevel::None,
profane: RatingLevel::None,
substance: RatingLevel::None,
hate: RatingLevel::None,
harm: RatingLevel::None,
mature: RatingLevel::None,
bully: RatingLevel::None,
};
assert!(!contract.check_content(AgeLevel::Kids, invalid_kids_rating));
}

#[ink::test]
fn teens_content_validation_works() {
let contract = ContentRating::new();

// Valid teens content
let valid_teens_rating = Rating {
violent: RatingLevel::Mild,
sexual: RatingLevel::Mild,
profane: RatingLevel::Mild,
substance: RatingLevel::None,
hate: RatingLevel::None,
harm: RatingLevel::None,
mature: RatingLevel::Mild,
bully: RatingLevel::None,
};
assert!(contract.check_content(AgeLevel::Teens, valid_teens_rating));

// Invalid teens content (substance use)
let invalid_teens_rating = Rating {
violent: RatingLevel::Mild,
sexual: RatingLevel::Mild,
profane: RatingLevel::Mild,
substance: RatingLevel::Mild,
hate: RatingLevel::None,
harm: RatingLevel::None,
mature: RatingLevel::Mild,
bully: RatingLevel::None,
};
assert!(!contract.check_content(AgeLevel::Teens, invalid_teens_rating));
}

#[ink::test]
fn adult_content_validation_works() {
let contract = ContentRating::new();

// All content levels are valid for adults
let adult_rating = Rating {
violent: RatingLevel::Severe,
sexual: RatingLevel::Severe,
profane: RatingLevel::Severe,
substance: RatingLevel::Severe,
hate: RatingLevel::Severe,
harm: RatingLevel::Severe,
mature: RatingLevel::Severe,
bully: RatingLevel::Severe,
};
assert!(contract.check_content(AgeLevel::Adults, adult_rating));
}
}
}

0 comments on commit f9b7ad4

Please sign in to comment.