Skip to content
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
93 changes: 73 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,36 @@
# Intellectual Property Protection Smart Contract

This project implements a smart contract for intellectual property (IP) protection using Clarity, the smart contract language for the Stacks blockchain. The contract allows users to register, verify, and transfer ownership of intellectual property.
This project implements a smart contract for intellectual property (IP) protection using Clarity, the smart contract language for the Stacks blockchain. The contract allows users to register, verify, transfer ownership, set expirations, and verify ownership for intellectual property.

## Features

- Register new intellectual property by providing a hash of the work
- Check ownership of registered intellectual property
- Verify the hash of registered intellectual property
- Transfer ownership of registered intellectual property
* Register new intellectual property by providing a hash of the work and an optional expiration date
* Check ownership of registered intellectual property
* Verify the hash of registered intellectual property
* Transfer ownership of registered intellectual property
* Extend the registration period of intellectual property
* Automatic expiration of IP registrations
* Verify the current owner of a specific IP ID (new feature)

## Smart Contract Overview

The main components of the smart contract are:

1. **Data Storage**
- `owner`: Stores the contract owner's principal (address)
- `ip-registrations`: A map that stores IP registrations, indexed by an IP ID
- `ip-counter`: A counter to generate unique IP IDs
* `owner`: Stores the contract owner's principal (address)
* `ip-registrations`: A map that stores IP registrations, indexed by an IP ID
* `registered-hashes`: A map that tracks registered hashes to prevent duplicates
* `ip-counter`: A counter to generate unique IP IDs

2. **Main Functions**
- `register-ip`: Register new IP by providing a hash of the work
- `check-ip-ownership`: Check the ownership of a registered IP
- `verify-ip-hash`: Verify an IP hash against the registered hash
- `transfer-ip`: Transfer ownership of an IP to another address
* `register-ip`: Register new IP by providing a hash of the work and an optional expiration date
* `check-ip-ownership`: Check the ownership of a registered IP
* `verify-ip-hash`: Verify an IP hash against the registered hash
* `transfer-ip`: Transfer ownership of an IP to another address
* `extend-ip-registration`: Extend the registration period of an IP
* `is-hash-registered`: Check if a hash is already registered
* `update-ip-metadata`: Update the hash of an existing IP registration
* `verify-ip-owner`: Verify the current owner of a specific IP ID (new function)

## Usage

Expand All @@ -35,17 +43,19 @@ To use this smart contract, you need to:

To register new intellectual property:

```clarity
(contract-call? .ip-protection-contract register-ip 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef)
```lisp
(contract-call? .ip-protection-contract register-ip
0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
(some u144000))
```

This will return the new IP ID.
This will register the IP with the given hash and set an expiration 144000 blocks in the future. Omit the second argument or use `none` to register without an expiration date.

### Checking IP Ownership

To check the ownership of a registered IP:

```clarity
```lisp
(contract-call? .ip-protection-contract check-ip-ownership u1)
```

Expand All @@ -55,8 +65,9 @@ Replace `u1` with the IP ID you want to check.

To verify the hash of a registered IP:

```clarity
(contract-call? .ip-protection-contract verify-ip-hash u1 0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef)
```lisp
(contract-call? .ip-protection-contract verify-ip-hash u1
0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef)
```

Replace `u1` with the IP ID and provide the hash you want to verify.
Expand All @@ -65,12 +76,44 @@ Replace `u1` with the IP ID and provide the hash you want to verify.

To transfer ownership of an IP:

```clarity
(contract-call? .ip-protection-contract transfer-ip u1 'SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7)
```lisp
(contract-call? .ip-protection-contract transfer-ip u1
'SP2J6ZY48GV1EZ5V2V5RB9MP66SW86PYKKNRV9EJ7)
```

Replace `u1` with the IP ID and provide the principal of the new owner.

### Extending IP Registration

To extend the registration period of an IP:

```lisp
(contract-call? .ip-protection-contract extend-ip-registration u1 u288000)
```

Replace `u1` with the IP ID and provide the new expiration block height.

### Updating IP Metadata

To update the hash of an existing IP registration:

```lisp
(contract-call? .ip-protection-contract update-ip-metadata u1
0x9876543210fedcba9876543210fedcba9876543210fedcba9876543210fedcba)
```

Replace `u1` with the IP ID and provide the new hash.

### Verifying IP Owner

To verify the current owner of a specific IP ID:

```lisp
(contract-call? .ip-protection-contract verify-ip-owner u1)
```

Replace `u1` with the IP ID you want to verify. This function returns the current owner and expiration date (if set) for the specified IP ID.

## Development

To further develop or modify this smart contract:
Expand All @@ -80,6 +123,16 @@ To further develop or modify this smart contract:
3. Test thoroughly using Clarity testing frameworks
4. Deploy the updated contract to the Stacks blockchain

## Safety Features

The contract includes several safety checks:

* Validation of IP hash length and content
* Prevention of duplicate hash registrations
* Expiration date checks to ensure they are set in the future
* Ownership checks for transfers and registration extensions
* Input validation for IP IDs to ensure they are within valid range

## Author

Blessing Eze
184 changes: 177 additions & 7 deletions contracts/shield.clar
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
;; Smart Contract on Intellectual Property Protection

;; Smart Contract on Intellectual Property Protection with Expiration Date, Corrected Safety Checks, IP Update Functionality, Owner Verification, and Optimized Expiration Extension
;; Define error codes
(define-constant ERR-NOT-AUTHORIZED (err u1000))
(define-constant ERR-INVALID-HASH-LENGTH (err u1001))
Expand All @@ -8,14 +7,17 @@
(define-constant ERR-IP-NOT-FOUND (err u1004))
(define-constant ERR-INVALID-IP-ID (err u1005))
(define-constant ERR-IP-ID-OUT-OF-RANGE (err u1006))
(define-constant ERR-IP-EXPIRED (err u1007))
(define-constant ERR-INVALID-EXPIRATION (err u1008))
(define-constant ERR-NO-EXPIRATION-SET (err u1009))

;; Define the contract
(define-data-var owner principal tx-sender)

;; Define a map to store IP registrations
(define-map ip-registrations
{ ip-id: uint }
{ owner: principal, timestamp: uint, hash: (buff 32) }
{ owner: principal, timestamp: uint, hash: (buff 32), expiration: (optional uint) }
)

;; Define a map to track registered hashes
Expand All @@ -28,20 +30,27 @@
(define-data-var ip-counter uint u0)

;; Function to register new IP
(define-public (register-ip (ip-hash (buff 32)))
(define-public (register-ip (ip-hash (buff 32)) (expiration-block (optional uint)))
(let
(
(new-id (+ (var-get ip-counter) u1))
(current-block block-height)
)
;; Perform input validation
(asserts! (is-eq (len ip-hash) u32) ERR-INVALID-HASH-LENGTH)
(asserts! (not (is-eq ip-hash 0x0000000000000000000000000000000000000000000000000000000000000000)) ERR-HASH-ALL-ZEROS)
(asserts! (is-none (map-get? registered-hashes { hash: ip-hash })) ERR-HASH-ALREADY-REGISTERED)
;; Check expiration validity
(asserts! (match expiration-block
expiration (> expiration current-block)
true
)
ERR-INVALID-EXPIRATION)

;; Register the IP
(map-set ip-registrations
{ ip-id: new-id }
{ owner: tx-sender, timestamp: block-height, hash: ip-hash }
{ owner: tx-sender, timestamp: current-block, hash: ip-hash, expiration: expiration-block }
)
;; Track the registered hash
(map-set registered-hashes
Expand All @@ -60,7 +69,19 @@
(ip-data (map-get? ip-registrations { ip-id: ip-id }))
)
(if (is-some ip-data)
(ok (get owner (unwrap-panic ip-data)))
(let
(
(unwrapped-ip-data (unwrap-panic ip-data))
(current-block block-height)
)
(if (and
(is-some (get expiration unwrapped-ip-data))
(>= current-block (unwrap-panic (get expiration unwrapped-ip-data)))
)
ERR-IP-EXPIRED
(ok (get owner unwrapped-ip-data))
)
)
ERR-IP-NOT-FOUND
)
)
Expand All @@ -73,7 +94,19 @@
(ip-data (map-get? ip-registrations { ip-id: ip-id }))
)
(if (is-some ip-data)
(ok (is-eq (get hash (unwrap-panic ip-data)) hash-to-verify))
(let
(
(unwrapped-ip-data (unwrap-panic ip-data))
(current-block block-height)
)
(if (and
(is-some (get expiration unwrapped-ip-data))
(>= current-block (unwrap-panic (get expiration unwrapped-ip-data)))
)
ERR-IP-EXPIRED
(ok (is-eq (get hash unwrapped-ip-data) hash-to-verify))
)
)
ERR-IP-NOT-FOUND
)
)
Expand All @@ -97,8 +130,15 @@
(let
(
(unwrapped-ip-data (unwrap-panic ip-data))
(current-block block-height)
)
(asserts! (is-eq tx-sender (get owner unwrapped-ip-data)) ERR-NOT-AUTHORIZED)
(asserts! (or
(is-none (get expiration unwrapped-ip-data))
(< current-block (unwrap-panic (get expiration unwrapped-ip-data)))
)
ERR-IP-EXPIRED
)
(map-set ip-registrations
{ ip-id: ip-id }
(merge unwrapped-ip-data { owner: new-owner })
Expand All @@ -112,4 +152,134 @@
;; Function to check if a hash is already registered
(define-read-only (is-hash-registered (ip-hash (buff 32)))
(is-some (map-get? registered-hashes { hash: ip-hash }))
)

;; Smart Contract on Intellectual Property Protection with Expiration Date, Corrected Safety Checks, IP Update Functionality, Owner Verification, and Corrected Expiration Extension

;; function to extend IP registration
(define-public (extend-ip-registration (ip-id uint) (new-expiration uint))
(let
(
(current-ip-counter (var-get ip-counter))
(current-block block-height)
)
;; Perform input validation
(asserts! (<= ip-id current-ip-counter) ERR-IP-ID-OUT-OF-RANGE)
(asserts! (> ip-id u0) ERR-INVALID-IP-ID)
(asserts! (> new-expiration current-block) ERR-INVALID-EXPIRATION)

(let
(
(ip-data (map-get? ip-registrations { ip-id: ip-id }))
)
(asserts! (is-some ip-data) ERR-IP-NOT-FOUND)
(let
(
(unwrapped-ip-data (unwrap-panic ip-data))
)
(asserts! (is-eq tx-sender (get owner unwrapped-ip-data)) ERR-NOT-AUTHORIZED)
(match (get expiration unwrapped-ip-data)
current-expiration (if (> new-expiration current-expiration)
(begin
(map-set ip-registrations
{ ip-id: ip-id }
(merge unwrapped-ip-data { expiration: (some new-expiration) })
)
(ok true)
)
ERR-INVALID-EXPIRATION)
(begin
(map-set ip-registrations
{ ip-id: ip-id }
(merge unwrapped-ip-data { expiration: (some new-expiration) })
)
(ok true)
)
)
)
)
)
)

;; Function to update IP metadata (hash)
(define-public (update-ip-metadata (ip-id uint) (new-hash (buff 32)))
(let
(
(current-ip-counter (var-get ip-counter))
)
;; Perform input validation
(asserts! (<= ip-id current-ip-counter) ERR-IP-ID-OUT-OF-RANGE)
(asserts! (> ip-id u0) ERR-INVALID-IP-ID)
(asserts! (is-eq (len new-hash) u32) ERR-INVALID-HASH-LENGTH)
(asserts! (not (is-eq new-hash 0x0000000000000000000000000000000000000000000000000000000000000000)) ERR-HASH-ALL-ZEROS)

(let
(
(ip-data (map-get? ip-registrations { ip-id: ip-id }))
)
(asserts! (is-some ip-data) ERR-IP-NOT-FOUND)
(let
(
(unwrapped-ip-data (unwrap-panic ip-data))
(current-block block-height)
)
;; Check if the caller is the current owner
(asserts! (is-eq tx-sender (get owner unwrapped-ip-data)) ERR-NOT-AUTHORIZED)
;; Check if the IP has not expired
(asserts! (or
(is-none (get expiration unwrapped-ip-data))
(< current-block (unwrap-panic (get expiration unwrapped-ip-data)))
)
ERR-IP-EXPIRED
)
;; Remove the old hash from registered-hashes
(map-delete registered-hashes { hash: (get hash unwrapped-ip-data) })
;; Update the IP registration with the new hash
(map-set ip-registrations
{ ip-id: ip-id }
(merge unwrapped-ip-data { hash: new-hash })
)
;; Add the new hash to registered-hashes
(map-set registered-hashes
{ hash: new-hash }
{ ip-id: ip-id }
)
(ok true)
)
)
)
)

;; Function to verify the current owner of a specific IP ID
(define-read-only (verify-ip-owner (ip-id uint))
(let
(
(current-ip-counter (var-get ip-counter))
)
;; Perform input validation
(asserts! (<= ip-id current-ip-counter) ERR-IP-ID-OUT-OF-RANGE)
(asserts! (> ip-id u0) ERR-INVALID-IP-ID)

(let
(
(ip-data (map-get? ip-registrations { ip-id: ip-id }))
)
(if (is-some ip-data)
(let
(
(unwrapped-ip-data (unwrap-panic ip-data))
(current-block block-height)
)
(if (and
(is-some (get expiration unwrapped-ip-data))
(>= current-block (unwrap-panic (get expiration unwrapped-ip-data)))
)
ERR-IP-EXPIRED
(ok { owner: (get owner unwrapped-ip-data), expiration: (get expiration unwrapped-ip-data) })
)
)
ERR-IP-NOT-FOUND
)
)
)
)