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:
- Final approval of contributions
- Dataset metadata updates
- 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)