Wearable Health Data Monetization
What it does:
Allows users to monetize anonymized health data collected from wearable devices by granting paid, permissioned access to verified data buyers.
Why it matters:
Shifts data ownership from platforms to individuals, enabling fair compensation, consent-based access, and transparent tracking of how personal health data is used.
How it works:
-
Users register wearable data streams as on-chain assets
-
Data is stored off-chain with encrypted references
-
Buyers request access to specific data types and time ranges
-
Users approve access and set pricing and duration
-
Payment is escrowed and released upon access activation
-
All data permissions and payments are auditable on-chain
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title WearableHealthDataMonetization
* @author Nam
* @notice Monetize wearable health data through permissioned access
*/
contract WearableHealthDataMonetization {
// -------------------- STRUCTS --------------------
struct DataStream {
string dataReference; // IPFS / encrypted storage pointer
uint256 price; // ETH price per access
bool active;
}
struct AccessGrant {
bool granted;
uint256 expiry;
}
// -------------------- STORAGE --------------------
// user => streamId => DataStream
mapping(address => mapping(uint256 => DataStream)) public dataStreams;
// user => streamId => buyer => AccessGrant
mapping(address => mapping(uint256 => mapping(address => AccessGrant))) public accessGrants;
// -------------------- EVENTS --------------------
event DataStreamRegistered(address indexed user, uint256 indexed streamId);
event AccessRequested(address indexed buyer, address indexed user, uint256 indexed streamId);
event AccessGranted(
address indexed user,
uint256 indexed streamId,
address indexed buyer,
uint256 expiry
);
event PaymentReleased(address indexed user, uint256 amount);
// -------------------- MODIFIERS --------------------
modifier onlyOwner(address _owner) {
require(msg.sender == _owner, "Not data owner");
_;
}
// -------------------- DATA STREAM MANAGEMENT --------------------
/**
* @notice Register a wearable data stream
*/
function registerDataStream(
uint256 _streamId,
string calldata _dataReference,
uint256 _price
)
external
onlyOwner(msg.sender)
{
require(!dataStreams[msg.sender][_streamId].active, "Stream already exists");
dataStreams[msg.sender][_streamId] = DataStream({
dataReference: _dataReference,
price: _price,
active: true
});
emit DataStreamRegistered(msg.sender, _streamId);
}
// -------------------- ACCESS REQUEST --------------------
/**
* @notice Buyer requests access by paying the data price
*/
function requestAccess(address _user, uint256 _streamId)
external
payable
{
DataStream memory stream = dataStreams[_user][_streamId];
require(stream.active, "Inactive data stream");
require(msg.value == stream.price, "Incorrect payment");
emit AccessRequested(msg.sender, _user, _streamId);
}
/**
* @notice User grants access to buyer
*/
function grantAccess(
uint256 _streamId,
address _buyer,
uint256 _duration
)
external
onlyOwner(msg.sender)
{
require(dataStreams[msg.sender][_streamId].active, "Stream inactive");
require(_duration > 0, "Invalid duration");
accessGrants[msg.sender][_streamId][_buyer] = AccessGrant({
granted: true,
expiry: block.timestamp + _duration
});
payable(msg.sender).transfer(dataStreams[msg.sender][_streamId].price);
emit AccessGranted(
msg.sender,
_streamId,
_buyer,
block.timestamp + _duration
);
emit PaymentReleased(msg.sender, dataStreams[msg.sender][_streamId].price);
}
// -------------------- VIEW --------------------
/**
* @notice Check if buyer has active access
*/
function hasAccess(
address _user,
uint256 _streamId,
address _buyer
)
external
view
returns (bool)
{
AccessGrant memory grant =
accessGrants[_user][_streamId][_buyer];
return grant.granted && block.timestamp <= grant.expiry;
}
/**
* @notice Get data reference if access is valid
*/
function getDataReference(
address _user,
uint256 _streamId
)
external
view
returns (string memory)
{
require(
accessGrants[_user][_streamId][msg.sender].granted &&
block.timestamp <= accessGrants[_user][_streamId][msg.sender].expiry,
"Access denied"
);
return dataStreams[_user][_streamId].dataReference;
}
}