PathrockNetwork Gno Explorer
HomeBlocksTransactionsTokensRealmsPackagesValidatorsAnalytics

PathrockNetwork Gno Explorer — an independent explorer for Gno.land Mainnet (gnoland-1), operated by PathrockNetwork. Not an official Gno.land service.

gnowebarchive RPC

gno.land/p/nt/ownable/v0

Package
Open in gnoweb ↗

Overview

Kind
Pure package
Name
v0
Namespace
nt / ownable
Files
6 (README)(gnomod.toml)
Exported functions
n/a — not supported for pure packages by the node (vm/qfuncs)
Module
gno.land/p/nt/ownable/v0
gno
0.9

Files (6)

  • README.mdmarkdown
  • gnomod.tomltoml
  • doc.gnogno
  • errors.gnogno
  • ownable.gnogno
  • ownable_test.gnogno
README.mdPreviewRaw
> **v0 - Unaudited**
> This is an initial version of this package that has not yet been formally audited.
> A fully audited version will be published as a subsequent release.
> Use in production at your own risk.

# `ownable` - Ownership pattern for realms

Provides an `Ownable` object that gates privileged operations behind a single owner address. Embed it in a realm (or any struct) to restrict actions like configuration changes, withdrawals, or upgrades.

## Usage

```go
package myrealm

import (
    "chain/runtime"

    "gno.land/p/nt/ownable/v0"
)

// The owner address is chosen explicitly at construction. A common
// choice is the deployer, captured in init after confirming it is a
// real user call.
var owner *ownable.Ownable

func init() {
    caller := runtime.PreviousRealm()
    if !caller.IsUserCall() {
        panic("must be deployed by a user")
    }
    owner = ownable.NewWithAddress(caller.Address())
}

// SetFee is gated: only the current owner may call it.
func SetFee(cur realm, newFee int64) {
    if !cur.IsCurrent() {
        panic("spoofed realm")
    }
    owner.AssertOwnedBy(cur.Previous().Address())
    fee = newFee
}

// Hand the realm over. TransferOwnership itself verifies the caller is owner.
func TransferOwner(cur realm, to address) error {
    return owner.TransferOwnership(0, cur, to)
}
```

There is no auth-mode flag. The single `NewWithAddress` constructor replaced the
old `New` / `NewWithOrigin` / `NewWithAddressByPrevious` sugar: the realm now picks
the owner address explicitly rather than baking a runtime walk into the struct.

## API

```go
type Ownable struct{ /* unexported */ }

const OwnershipTransferEvent = "OwnershipTransfer"

var (
    ErrUnauthorized   = errors.New("ownable: caller is not owner")
    ErrInvalidAddress = errors.New("ownable: new owner address is invalid")
)

// NewWithAddress is the only constructor: the realm picks the owner
// address explicitly (e.g. cur.Previous().Address() after checking
// cur.Previous().IsUserCall() in init).
func NewWithAddress(addr address) *Ownable

// Queries (caller supplies the address to check).
func (o *Ownable) Owner() address             // "" if o is nil or ownership was dropped
func (o *Ownable) OwnedBy(addr address) bool  // true if addr is the current owner
func (o *Ownable) AssertOwnedBy(addr address) // panics with ErrUnauthorized if addr is not the owner

// Authority mutation (thread the caller's own cur; pass 0 as the first arg).
func (o *Ownable) TransferOwnership(_ int, rlm realm, newOwner address) error
func (o *Ownable) DropOwnership(_ int, rlm realm) error // sets owner to "" — irreversible
```

## Notes

- Authority-mutating methods assert `rlm.IsCurrent()` and identify the caller as `rlm.Previous().Address()`, which must equal the current owner. The principal is therefore unforgeable: an attacker cannot supply an arbitrary caller address. Pass `0` as the placeholder first arg and your own `cur` as `rlm`.
- Read helpers (`OwnedBy`, `AssertOwnedBy`) take a bare address; the caller extracts it, guarding with `cur.IsCurrent()` before reading `cur.Previous().Address()`.
- `TransferOwnership` rejects an invalid `newOwner` with `ErrInvalidAddress`. Both mutators emit `OwnershipTransferEvent` with `from` and `to` fields.
- `DropOwnership` is permanent: `owner` becomes `""`, so every owner-gated action becomes unreachable.

Functions

not supported for pure packages by the node (vm/qfuncs)

Signatures reconstructed verbatim from vm/qfuncs — interface params keep their inline definitions.