Skip to main content

Dataset Ownership

Ownership Model

On Helix, dataset ownership is a fundamental property that determines control rights over a dataset. Each dataset has a single owner represented by their address:

type Dataset struct {
Owner string // Owner address
...
}

The owner has exclusive rights to:

  • Update dataset metadata
  • Approve or reject contributions
  • Transfer ownership to another address

Initial Ownership

When a dataset is created, the transaction sender automatically becomes the owner like in the ETH Ecosystem with onlyOwner:

dataset := types.Dataset{
Owner: msg.Owner, // msg.Owner is the transaction sender's address
...
}

Ownership Verification

Ownership is verified in key ops to enforce access control:

// Ensure only the dataset owner can update
if msg.Owner != dataset.Owner {
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "incorrect owner")
}

Transferring Ownership

Helix supports ownership transfer through a dedicated transaction type:

CLI Command

nuklaid tx dataset update-dataset-owner <denom> <new-owner> --from=bob

Implementation

func (k msgServer) UpdateDatasetOwner(goCtx context.Context, msg *types.MsgUpdateDatasetOwner) (*types.MsgUpdateDatasetOwnerResponse, error) {
ctx := sdk.UnwrapSDKContext(goCtx)

// Check if the dataset exists
existingDataset, isFound := k.GetDataset(ctx, msg.Denom)
if !isFound {
return nil, errorsmod.Wrap(sdkerrors.ErrKeyNotFound, "dataset with this denom does not exist")
}

// Ensure the sender is the current owner
if msg.Owner != existingDataset.Owner {
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "only the dataset owner can transfer ownership")
}

// Update only the owner field while keeping all other fields unchanged
updatedDataset := types.Dataset{
Owner: msg.NewOwner, // Update ownership
Denom: existingDataset.Denom,
Name: existingDataset.Name,
// Other fields preserved...
}

// Store the updated dataset
k.SetDataset(ctx, updatedDataset)

return &types.MsgUpdateDatasetOwnerResponse{}, nil
}

This transaction preserves all dataset attributes while changing only the owner field.

Ownership Implications

Community Datasets

For community datasets (IsCommunityDataset: true), ownership still matters for:

  1. Final approval of contributions
  2. Dataset metadata updates
  3. Changing community status
// Check if the caller is the owner or if it's a community dataset
if msg.Owner != dataset.Owner {
if !dataset.IsCommunityDataset {
return nil, errorsmod.Wrap(sdkerrors.ErrUnauthorized, "only the owner can contribute to this dataset")
}
}

Private Datasets

For private datasets (IsCommunityDataset: false), ownership is even more restrictive:

  • Only the owner can initiate contributions
  • Only the owner can approve contributions
  • Only the owner can update metadata

Querying Dataset Ownership

To check dataset ownership:

nuklaid query dataset show-dataset <denom>

The response includes the owner address:

{
"dataset": {
"owner": "nuklai13fy0hfyy5h9zxmkukfx48j0m84kyl7qpcljh5h",
"denom": "nuklaidataset07d1b507e614c562ef726c4b051"
...
}
}

Ownership vs. Contribution Ownership

It's important to distinguish between dataset ownership and contribution ownership:

  • Dataset ownership: Controls the dataset as a whole
  • Contribution ownership: Controls individual contributions (Covered this in detail on the Contributing to Datasets page)