Skip to content

Commit

Permalink
Geofence, AgeVerified (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
arkavo-com authored Oct 25, 2024
1 parent b2cd419 commit 5fdeba7
Show file tree
Hide file tree
Showing 19 changed files with 6,140 additions and 79 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ Cargo.lock
/cache/
/etc/contracts/substrate-contracts-node
/etc/contracts/ev/
/etc/contracts/simple_abac/.idea/
/etc/contracts/*/.idea/
/apple-app-site-association.json
/dump.rdb
5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "arkavo-rs"
version = "0.9.0"
version = "0.9.1"
edition = "2021"
rust-version = "1.80.0"

Expand Down Expand Up @@ -45,6 +45,9 @@ async-nats = "0.36.0"
serde_json = "1.0.128"
redis = { version = "0.27.2", features = ["tokio-comp"] }
flatbuffers = "24.3.25"
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 }
bs58 = "0.5.1"

[dev-dependencies]
criterion = "0.5.1"
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ brew install nats-server redis flatbuffers

```shell
flatc --binary --rust idl/event.fbs
flatc --binary --rust idl/entity.fbs
flatc --binary --rust idl/metadata.fbs
```

### Installation
Expand Down Expand Up @@ -123,9 +125,9 @@ redis-server

#### Start backend

```shell
cargo run
```
```shell
cargo run
```

The server will start and listen on the configured port.

Expand Down
36 changes: 36 additions & 0 deletions etc/contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,42 @@ cargo contract build --features e2e-tests

### Deploy

#### Content Rating

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

#### Geofence

```text
Code hash 0x63a3ec45fd3ab905924a38227917e278de277c9b80d6865190d18d0d64f560bb
Contract 5H6sLwXKBv3cdm5VVRxrvA8p5cux2Rrni5CQ4GRyYKo4b9B4
```

#### Timestamp

```text
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
```

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

```shell
cargo contract upload --url ws://127.0.0.1:9944 --suri //Alice simple_abac/target/ink/simple_abac.wasm
cargo contract instantiate --url ws://127.0.0.1:9944 --suri //Alice simple_abac/target/ink/simple_abac.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));
}
}
}
29 changes: 29 additions & 0 deletions etc/contracts/geo_fence_contract/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[package]
name = "geo_fence_contract"
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 = []
# do not add
#__ink_dylint_Constructor = []
#__ink_dylint_Storage = []
Loading

0 comments on commit 5fdeba7

Please sign in to comment.