LICENLICEN Docs
Developer Guide

Smart Contracts

DataPolicy.sol — the on-chain authority for policy enforcement, escrow management, and royalty settlement.

Smart Contracts

LICEN's on-chain logic lives in a single contract: DataPolicy.sol, deployed on the 0G Galileo Testnet.

Deployed Address

ContractNetworkAddress
DataPolicy0G Galileo Testnet (Chain ID: 16602)0x565ab137D5D18B7Aa32783C7D1a8dc29d83687E7

View on 0G Explorer →


Network Details

ParameterValue
Network Name0G Galileo Testnet
RPC URLhttps://evmrpc-testnet.0g.ai
Chain ID16602
Currency0G (native)
Block Explorerhttps://chainscan-galileo.0g.ai

On-Chain Data Model

The Policy Struct

This struct is the owner's enforceable usage policy. Purpose restrictions are only one field inside a larger control model that also governs pricing, volume, repeat access, and session lifetime.

struct Policy {
    bytes32 datasetRoot;        // Merkle root of encrypted dataset on 0G Storage
    address owner;              // Royalty recipient
    bytes32 manifestHash;       // Hash of off-chain policy manifest (integrity anchor)
    uint256 royaltyPerEpoch;    // Cost per training epoch (in native 0G, wei units)
    uint32  maxEpochsPerRun;    // Max epochs per single training session
    uint32  maxRunsPerRequester;// Lifetime session cap per researcher wallet
    uint64  accessTtlSeconds;   // Session validity window after AccessGranted
    uint64  policyExpiry;       // Unix timestamp — no new requests after this
    bool    active;             // Publisher can pause/unpause
}

The Job Struct

struct Job {
    bytes32 datasetRoot;    // Dataset being trained on
    address requester;      // Researcher who paid
    address provider;       // = backendWallet (the Orchestrator)
    bytes32 purposeId;      // Declared use case (keccak256 of purpose string)
    uint32  requestedEpochs;// Epochs the researcher paid for
    uint256 escrowAmount;   // 0G wei locked
    uint64  requestTime;    // Unix timestamp of request
    JobState state;         // None|Requested|Granted|Running|Completed|Failed|TimedOut|Refunded
    bytes32 termsHash;      // Must match manifestHash at request time
}

Key Functions

Publisher

// Register a dataset and its policy on-chain
function registerDataset(
    bytes32 datasetRoot,
    bytes32 manifestHash,
    uint256 royaltyPerEpoch,
    uint32  maxEpochsPerRun,
    uint32  maxRunsPerRequester,
    uint64  accessTtlSeconds,
    uint64  policyExpiry,
    bytes32[] calldata allowedPurposeIds
) external;

Researcher

// Lock escrow and request access — emits AccessGranted
function requestAccess(
    bytes32 datasetRoot,
    bytes32 purposeId,
    uint32  requestedEpochs,
    bytes32 termsHash
) external payable;
// msg.value must equal royaltyPerEpoch * requestedEpochs

At request time, the contract checks the researcher's requested access against the owner's policy envelope: price, requested epochs, repeat-request caps, access duration, expiry, and allowed purpose IDs.

Orchestrator (backendWallet only)

// Mark job as Running
function startJob(bytes32 jobId) external;

// Settle royalties and mark Completed
function confirmTrainingComplete(
    bytes32 jobId,
    uint32  actualEpochs,
    bytes32 resultHash,
    bytes32 attestationRef
) external;

// Trigger researcher refund
function markJobFailed(bytes32 jobId, string calldata reason) external;

Key Events

event DatasetRegistered(bytes32 indexed datasetRoot, address indexed owner, bytes32 manifestHash);
event AccessGranted(bytes32 indexed jobId, bytes32 indexed datasetRoot, address indexed requester, uint32 epochs);
event JobStarted(bytes32 indexed jobId);
event TrainingCompleted(bytes32 indexed jobId, uint32 actualEpochs, bytes32 resultHash);
event JobFailed(bytes32 indexed jobId, string reason);

Development

Contracts are built with Foundry.

# Run test suite
cd packages/contracts
forge test

# Deploy to 0G Testnet
source .env
forge script script/DeployDataPolicy.s.sol \
  --rpc-url $OG_EVM_RPC_URL \
  --broadcast

On this page