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

Add ERC: ERC-721 Ownership Shares Extension #266

Merged
merged 42 commits into from
Apr 16, 2024
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
8136d4a
add erc: data access control
Feb 17, 2024
2d60f55
update
bizliaoyuan Feb 17, 2024
975547d
Update erc-7626.md
bizliaoyuan Feb 17, 2024
d23d89e
Update erc-7626.md
chenly Feb 17, 2024
1eac0a2
Update erc-7626.md
chenly Feb 17, 2024
6ce9942
Ownable
bizliaoyuan Feb 18, 2024
0836e71
Update erc-7626.md
chenly Feb 18, 2024
c407c14
change title
Feb 19, 2024
20c7af4
Update ERCS/erc-7626.md
chenly Feb 19, 2024
9c811ea
Update ERCS/erc-7626.md
chenly Feb 19, 2024
22de7f7
rename eip #
Feb 19, 2024
9af4272
rename
Feb 19, 2024
5a3589b
Update erc-7628.md
chenly Feb 20, 2024
1647e89
Update erc-7628.md
chenly Feb 20, 2024
77dfbdf
ERC-721 Balance Extension
bizliaoyuan Feb 23, 2024
8ca460b
update
bizliaoyuan Feb 23, 2024
92cf780
update
bizliaoyuan Feb 23, 2024
db3d4f9
Error: error[preamble-requires-ref-description]: proposals mentioned …
bizliaoyuan Feb 23, 2024
6437253
Error: error[preamble-uint-requires]: preamble header `requires` item…
bizliaoyuan Feb 23, 2024
2020a6d
Update erc-7628.md
bizliaoyuan Feb 23, 2024
c720423
Update erc-7628.md
bizliaoyuan Feb 23, 2024
02281a1
add IERC721
bizliaoyuan Feb 23, 2024
d566d27
Update erc-7628.md
chenly Feb 24, 2024
3b856e4
update
bizliaoyuan Feb 24, 2024
9885664
Merge branch 'erc-7626' of https://github.com/chenly/ERCs into erc-7626
bizliaoyuan Feb 24, 2024
672f523
update Security Considerations
bizliaoyuan Feb 24, 2024
adcf37e
Merge branch 'master' into erc-7626
chenly Feb 24, 2024
5d8c76e
Add Reference Implementation
bizliaoyuan Feb 26, 2024
0134f59
check allowance
bizliaoyuan Feb 26, 2024
5c47ee6
update
bizliaoyuan Feb 26, 2024
48cbcfd
update
bizliaoyuan Feb 26, 2024
18220ef
Update erc-7628.md
chenly Feb 28, 2024
132ed56
Correct some text formatting
Mar 1, 2024
fae628f
change Rationale
bizliaoyuan Mar 2, 2024
50367fa
new version
bizliaoyuan Mar 6, 2024
1c0dafa
change link
bizliaoyuan Mar 6, 2024
63c4333
update
bizliaoyuan Mar 6, 2024
d68a4bb
update
bizliaoyuan Mar 6, 2024
f9f4677
Update erc-7628.md
bizliaoyuan Mar 7, 2024
f93384f
Update erc-7628.md
bizliaoyuan Mar 7, 2024
a3961f4
Update erc-7628.md
bizliaoyuan Mar 7, 2024
a8f5aa5
rm SharesAdded
bizliaoyuan Mar 17, 2024
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
145 changes: 145 additions & 0 deletions ERCS/erc-7626.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
---
eip: 7626
title: Data Access Control
description: A method for authorizing access control of off-chain data.
author: Chen Liaoyuan (@chenly) <[email protected]>
discussions-to: https://ethereum-magicians.org/t/erc-7626-data-access-control/18744
status: Draft
type: Standards Track
category: ERC
created: 2024-02-17
requires: 173
---

## Abstract

This proposal aims to define a blockchain-based data asset access control mechanism, enabling effective management and control of access permissions to data assets. By leveraging blockchain technology and smart contracts, a decentralized and tamper-resistant authorization system can be established, enhancing the security and trustworthiness of data assets.

## Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119 and RFC 8174.

- Owner can manage the list of authorized users for accessing data.
- Authorization can be defined with start and end timestamps.
- Owner can define the URI for off-chain data access, allowing authorized users to download data files.
- Functions are provided to verify whether specified users are authorized to access.
- Owner can define the metadata URI for data, utilizing a JSON file to describe assets.

### Interface
Implementers of this standard **MUST** have all of the following functions:

```solidity
pragma solidity ^0.8.0;

interface IERC7626 {

/* Function to grant access to a user for a specified time period.
* Parameters:
* - user: Address of the user to grant access.
* - start: Start time of the access period.
* - end: End time of the access period.
*/
function grantAccess(address user, uint256 start, uint256 end) external;

/* Function to revoke access of a user.
* Parameters:
* - user: Address of the user whose access is revoked.
*/
function revokeAccess(address user) external;

/* Function to check if a user is authorized based on current time.
* Parameters:
* - user: Address of the user to check authorization for.
* Returns:
* - bool: True if the user is authorized, false otherwise.
*/
function isUserAuthorized(address user) external view returns (bool);

/* Function to set new metadata URI.
* Parameters:
* - newURI: New metadata URI.
*/
function setMetadataURI(string memory newURI) external;

/* Function to set new download URI.
* Parameters:
* - newURI: New download URI.
*/
function setDownloadURI(string memory newURI) external;

/** @dev Returns the metadata URI.
* @return The metadata URI.
*/
function metadataURI() external view returns (string memory);

/** @dev Returns the download URI.
* @return The download URI.
*/
function downloadURI() external view returns (string memory);

/** @dev Emitted when access is granted to a user.
* @param user The address of the user who was granted access.
* @param start The start time of the access period.
* @param end The end time of the access period.
*/
event AccessGranted(address indexed user, uint256 start, uint256 end);

/** @dev Emitted when access is revoked from a user.
* @param user The address of the user whose access was revoked.
*/
event AccessRevoked(address indexed user);
}
```
### Metadata URI JSON Schema

This is an example of "Metadata JSON Schema for `metadataURI()`" referenced above.

```json
{
"name": "Example Asset",
"description": "This is an example asset used for demonstration purposes.",
"created_at": "2024-02-17T12:00:00Z",
"owner": "John Doe",
"license": "CC BY-SA 4.0",
"download_uri": "https://example.com/download",
"document_uri": "https://example.com/document",
"files": [
{
"filename": "example_file1.txt",
"hash": "0xabcdef1234567890"
},
{
"filename": "example_file2.jpg",
"hash": "0x1234567890abcdef"
}
]
}
```

## Rationale

In many scenarios, effective management of data asset access is crucial to ensure that only authorized users can access data. Current solutions often rely on centralized permission management systems, which are susceptible to single points of failure and security risks. By adopting blockchain technology and smart contracts, a decentralized and immutable authorization mechanism can be established, addressing these limitations and enhancing data asset security.

## Backwards Compatibility

This standard is compatible with current [EIP-173](./eip-173.md) standards.

## Reference Implementation

See [`ERC7626.sol`](../assets/eip-7626/contracts/ERC7626.sol) for Contract Implementation.

See [`server.js`](../assets/eip-7626/server.js) for `downloadURI` Implementation.

## Security Considerations

1. Implementing access control functions within smart contracts ensures that authorization logic is resistant to tampering, preventing unauthorized access to data assets. However, it's crucial to thoroughly test for vulnerabilities like reentrancy attacks to prevent exploitation.

2. Time-based access restrictions help mitigate the risk of unauthorized access over time. However, precautions must be taken to address potential issues such as time manipulation attacks, ensuring that access remains restricted as intended.

3. Validating off-chain data access URIs with wallet signatures before querying on-chain authorization status enhances security by preventing unauthorized queries. Robust signature verification mechanisms are essential to prevent forgery or tampering.

4. Transparent metadata descriptions provide clarity and accountability for data assets, reducing the risk of misuse or tampering. Ensuring the integrity of metadata is critical to prevent misleading information or unauthorized access.

## Copyright

Copyright and related rights waived via [CC0](../LICENSE.md).
56 changes: 56 additions & 0 deletions assets/erc-7626/contracts/ERC7626.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-License-Identifier: CC0-1.0
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/access/Ownable.sol";

contract ERC7626 is Ownable{

mapping(address => bool) public authorizedUsers; // Mapping of authorized users
mapping(address => uint256) public accessStartTime; // Mapping of user access start time
mapping(address => uint256) public accessEndTime; // Mapping of user access end time
string public metadataURI; // URI for metadata
string public downloadURI; // URI for data download

// Event emitted when access is granted to a user
event AccessGranted(address indexed user, uint256 start, uint256 end);

// Event emitted when access is revoked from a user
event AccessRevoked(address indexed user);

// Constructor to initialize contract with owner and URIs
constructor(address initialOwner, string memory _metadataURI, string memory _downloadURI) Ownable(initialOwner) {
metadataURI = _metadataURI;
downloadURI = _downloadURI;
}

// Function to grant access to a user for a specified time period
function grantAccess(address user, uint256 start, uint256 end) public onlyOwner {
authorizedUsers[user] = true;
accessStartTime[user] = start;
accessEndTime[user] = end;
emit AccessGranted(user, start, end);
}

// Function to revoke access of a user
function revokeAccess(address user) public onlyOwner {
authorizedUsers[user] = false;
accessStartTime[user] = 0;
accessEndTime[user] = 0;
emit AccessRevoked(user);
}

// Function to check if a user is authorized based on current time
function isUserAuthorized(address user) public view returns (bool) {
return authorizedUsers[user] && (block.timestamp >= accessStartTime[user] || accessStartTime[user] == 0) && (block.timestamp <= accessEndTime[user] || accessEndTime[user] == 0);
}

// Function to set new metadata URI, accessible only by the owner
function setMetadataURI(string memory newURI) public onlyOwner {
metadataURI = newURI;
}

// Function to set new download URI, accessible only by the owner
function setDownloadURI(string memory newURI) public onlyOwner {
downloadURI = newURI;
}
}
61 changes: 61 additions & 0 deletions assets/erc-7626/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Importing necessary libraries
const express = require('express');
const Web3 = require('web3');
const ethUtil = require('ethereumjs-util');

// Initializing web3 to connect to the Ethereum node
const web3 = new Web3('YOUR_ETH_NODE_URL');

// Loading the smart contract ABI
const contractABI = require('./ABI.json');

// Instantiating the smart contract object
const contractAddress = 'CONTRACT_ADDRESS';
const contract = new web3.eth.Contract(contractABI, contractAddress);

// Creating an Express app
const app = express();
const port = 3000;

// API endpoint to check authorization and get file download URIs
app.get('/api/access', async (req, res) => {
try {
const userAddress = req.query.address;
const signature = req.query.signature;
const message = 'Authorization check for download access';

// Verifying the signature
const messageHash = web3.utils.sha3(message);
const sigParams = ethUtil.fromRpcSig(signature);
const publicKey = ethUtil.ecrecover(ethUtil.toBuffer(messageHash), sigParams.v, sigParams.r, sigParams.s);
const recoveredAddress = ethUtil.bufferToHex(ethUtil.pubToAddress(publicKey));

if (recoveredAddress.toLowerCase() !== userAddress.toLowerCase()) {
throw new Error('Signature verification failed');
}

// Calling the isUserAuthorized function of the smart contract to check authorization status
const authorized = await contract.methods.isUserAuthorized(userAddress).call();

if (authorized) {
// If user is authorized, return a JSON containing file download URIs
const fileDownloadURIs = {
"files": [
"https://example.com/download/file1",
"https://example.com/download/file2"
]
};
res.json(fileDownloadURIs);
} else {
res.status(401).send("User is not authorized to access the asset.");
}
} catch (error) {
console.error("Error checking authorization:", error);
res.status(500).send("Internal Server Error");
}
});

// Starting the server
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Loading