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/r/g1qp5pt8cdq2f6kfdamn3yuxwg6quqnfpyewzz39/upgrade_registry

Realm
Open in gnoweb ↗

Overview

Kind
Realm (renderable)
Name
upgrade_registry
Namespace
g1qp5pt8cdq2f6kfdamn3yuxwg6quqnfpyewzz39
Files
3 (gnomod.toml)
Exported functions
9
Module
gno.land/r/g1qp5pt8cdq2f6kfdamn3yuxwg6quqnfpyewzz39/upgrade_registry
gno
0.9

Files (3)

  • gnomod.tomltoml
  • upgrade_registry.gnogno
  • upgrade_registry_test.gnogno
upgrade_registry_test.gnogno
1package upgrade_registry23import (4	"chain"5	"strconv"6	"strings"7	"testing"89	"gno.land/p/nt/testutils/v0"10	"gno.land/p/nt/uassert/v0"11)1213// In production the registrant is usually a realm; user addresses give14// the same self-registration semantics in tests (Register binds the15// entry to the CALLER's address either way).16var (17	v1       = testutils.TestAddress("contract_v1")18	v2       = testutils.TestAddress("contract_v2")19	v3       = testutils.TestAddress("contract_v3")20	teamEOA  = testutils.TestAddress("team")21	attacker = testutils.TestAddress("attacker")22)2324// resetState resets all package-level state between tests.25func resetState() {26	entries = make(map[address]*ContractEntry)27	entryAddrs = []address{}28	ownerContracts = make(map[address][]address)29}3031// register self-registers addr under name; when owner is non-empty the32// nominee accepts, completing the two-step handover.33func register(cur realm, addr address, name string, owner address) {34	testing.SetRealm(testing.NewUserRealm(addr))35	Register(cross(cur), name, owner)36	if owner != "" && owner != addr {37		testing.SetRealm(testing.NewUserRealm(owner))38		AcceptOwnership(cross(cur), addr)39	}40}4142// ---------- Register (proof of control) ----------4344func TestRegister_BindsToCallerAddress(cur realm, t *testing.T) {45	resetState()46	register(cur, v1, "vault", teamEOA)4748	e := entries[v1]49	uassert.Equal(t, string(v1), string(e.Address))50	uassert.Equal(t, string(teamEOA), string(e.Owner))51	uassert.Equal(t, "vault", e.Name)5253	// the audit's P1: there is no way to register an address you do not54	// control — the entry address is ALWAYS the caller's own. An55	// attacker registering gets an entry for themselves, not the victim.56	testing.SetRealm(testing.NewUserRealm(attacker))57	Register(cross(cur), "fake_vault", "")58	uassert.Equal(t, string(attacker), string(entries[attacker].Address))59	_, hijacked := entries[v2]60	uassert.False(t, hijacked, "no entry may exist for an address that never registered itself")61}6263func TestRegister_OwnerDefaultsToContract(cur realm, t *testing.T) {64	resetState()65	register(cur, v1, "vault", "")6667	uassert.Equal(t, string(v1), string(entries[v1].Owner))68}6970func TestRegister_DuplicateRejected(cur realm, t *testing.T) {71	resetState()72	register(cur, v1, "vault", "")7374	testing.SetRealm(testing.NewUserRealm(v1))75	uassert.AbortsWithMessage(t, cur,76		"contract already registered: "+string(v1),77		func() { Register(cross(cur), "vault_again", "") },78	)79}8081func TestRegister_NameValidation(cur realm, t *testing.T) {82	resetState()83	testing.SetRealm(testing.NewUserRealm(v1))8485	for _, bad := range []string{"", "Vault", "has space", "tick`name", strings.Repeat("a", MaxNameLen+1)} {86		uassert.AbortsContains(t, cur,87			"name must be",88			func() { Register(cross(cur), bad, "") },89		)90	}91}9293func TestRegister_InvalidOwnerRejected(cur realm, t *testing.T) {94	resetState()95	testing.SetRealm(testing.NewUserRealm(v1))9697	uassert.AbortsWithMessage(t, cur,98		"invalid owner address: junk",99		func() { Register(cross(cur), "vault", address("junk")) },100	)101}102103// ---------- Deprecate ----------104105func TestDeprecate_OwnerOnly(cur realm, t *testing.T) {106	resetState()107	register(cur, v1, "vault_v1", teamEOA)108	register(cur, v2, "vault_v2", teamEOA)109110	testing.SetRealm(testing.NewUserRealm(attacker))111	uassert.AbortsWithMessage(t, cur,112		"only the owner can deprecate this contract",113		func() { Deprecate(cross(cur), v1, v2) },114	)115116	testing.SetRealm(testing.NewUserRealm(teamEOA))117	Deprecate(cross(cur), v1, v2)118	uassert.Equal(t, string(v2), string(GetLatest(v1)))119}120121func TestDeprecate_SuccessorMustBeRegistered(cur realm, t *testing.T) {122	resetState()123	register(cur, v1, "vault_v1", teamEOA)124125	// the audit's dangling-successor + front-running route: pointing at126	// an unregistered address is refused outright, and a successor entry127	// can only ever be created by the successor contract itself128	testing.SetRealm(testing.NewUserRealm(teamEOA))129	uassert.AbortsWithMessage(t, cur,130		"successor is not a registered contract: "+string(v2),131		func() { Deprecate(cross(cur), v1, v2) },132	)133}134135func TestDeprecate_SelfAndDoubleRejected(cur realm, t *testing.T) {136	resetState()137	register(cur, v1, "vault_v1", teamEOA)138	register(cur, v2, "vault_v2", teamEOA)139140	testing.SetRealm(testing.NewUserRealm(teamEOA))141	uassert.AbortsWithMessage(t, cur,142		"successor cannot be the contract itself",143		func() { Deprecate(cross(cur), v1, v1) },144	)145	Deprecate(cross(cur), v1, v2)146	uassert.AbortsWithMessage(t, cur,147		"contract is already deprecated",148		func() { Deprecate(cross(cur), v1, v2) },149	)150}151152func TestDeprecate_CircularChainRejected(cur realm, t *testing.T) {153	resetState()154	register(cur, v1, "vault_v1", teamEOA)155	register(cur, v2, "vault_v2", teamEOA)156	register(cur, v3, "vault_v3", teamEOA)157158	testing.SetRealm(testing.NewUserRealm(teamEOA))159	Deprecate(cross(cur), v1, v2)160	Deprecate(cross(cur), v2, v3)161162	// closing the loop from the tail must abort163	uassert.AbortsWithMessage(t, cur,164		"deprecating "+string(v3)+" to "+string(v1)+" would create a circular migration chain",165		func() { Deprecate(cross(cur), v3, v1) },166	)167}168169// ---------- chain queries ----------170171func TestGetLatest_WalksChain(cur realm, t *testing.T) {172	resetState()173	register(cur, v1, "vault_v1", teamEOA)174	register(cur, v2, "vault_v2", teamEOA)175	register(cur, v3, "vault_v3", teamEOA)176177	testing.SetRealm(testing.NewUserRealm(teamEOA))178	Deprecate(cross(cur), v1, v2)179	Deprecate(cross(cur), v2, v3)180181	uassert.Equal(t, string(v3), string(GetLatest(v1)))182	uassert.Equal(t, string(v3), string(GetLatest(v2)))183	uassert.Equal(t, string(v3), string(GetLatest(v3)))184	// unknown addresses come back unchanged185	uassert.Equal(t, string(attacker), string(GetLatest(attacker)))186}187188func TestGetMigrationChain(cur realm, t *testing.T) {189	resetState()190	register(cur, v1, "vault_v1", teamEOA)191	register(cur, v2, "vault_v2", teamEOA)192193	testing.SetRealm(testing.NewUserRealm(teamEOA))194	Deprecate(cross(cur), v1, v2)195196	out := GetMigrationChain(v1)197	uassert.True(t, strings.Contains(out, "vault_v1"), "chain must name v1")198	uassert.True(t, strings.Contains(out, "[deprecated]"), "chain must tag deprecation")199	uassert.True(t, strings.Contains(out, "vault_v2"), "chain must name v2")200	uassert.Equal(t, "not found: "+string(attacker), GetMigrationChain(attacker))201}202203// ---------- TransferOwnership ----------204205func TestTransferOwnership(cur realm, t *testing.T) {206	resetState()207	register(cur, v1, "vault", teamEOA)208	newOwner := testutils.TestAddress("newowner")209210	testing.SetRealm(testing.NewUserRealm(attacker))211	uassert.AbortsWithMessage(t, cur,212		"only the owner can transfer ownership",213		func() { TransferOwnership(cross(cur), v1, attacker) },214	)215216	testing.SetRealm(testing.NewUserRealm(teamEOA))217	uassert.AbortsWithMessage(t, cur,218		"invalid new owner address: junk",219		func() { TransferOwnership(cross(cur), v1, address("junk")) },220	)221	TransferOwnership(cross(cur), v1, newOwner)222	// nomination alone changes nothing (two-step)223	uassert.Equal(t, string(teamEOA), string(entries[v1].Owner))224	uassert.Equal(t, string(v1), GetOwnerContracts(teamEOA))225226	testing.SetRealm(testing.NewUserRealm(newOwner))227	AcceptOwnership(cross(cur), v1)228	uassert.Equal(t, string(newOwner), string(entries[v1].Owner))229	uassert.Equal(t, "none", GetOwnerContracts(teamEOA))230	uassert.Equal(t, string(v1), GetOwnerContracts(newOwner))231}232233// ---------- render ----------234235func TestRender_EmptyState(cur realm, t *testing.T) {236	resetState()237	out := Render("")238	uassert.True(t, strings.HasPrefix(out, "# Upgrade Registry\n\n"), "heading first")239	uassert.True(t, strings.HasSuffix(out, "No contracts registered.\n"),240		"empty state must still say the registry is empty")241	// round-4 audit: the scope disclosure is not conditional on there being242	// entries — an empty page must not read as an endorsement-free zone.243	uassert.True(t, strings.Contains(out, "**Names are not.**"),244		"the name-scope disclosure must appear even in the empty state")245}246247// TestRender_CarriesNameScopeDisclosure is the regression guard for the248// round-4 audit finding that all three review passes raised: the rendered249// page gives a self-asserted NAME the most visual weight while only the250// ADDRESS is actually proven. Names are deliberately never made unique251// (first-come uniqueness on an immutable permissionless registry would let252// an attacker burn every valuable name forever), so disclosing the scope in253// the output is the entire mitigation. It cannot be added after deploy.254//255// Each assertion below names a distinct claim, so deleting or softening any256// one of them fails this test rather than silently degrading the warning.257func TestRender_CarriesNameScopeDisclosure(cur realm, t *testing.T) {258	resetState()259	register(cur, v1, "vault_v1", teamEOA)260261	// The impersonation this disclosure exists for: a second, unrelated262	// address registering the SAME name is permitted and renders equally.263	register(cur, attacker, "vault_v1", "")264265	out := Render("")266	for _, claim := range []string{267		"> [!NOTE]",268		"Addresses are self-registered and therefore verified",269		"**Names are not.**",270		"NOT unique",271		"may impersonate another project",272		"address, never by name.",273	} {274		uassert.True(t, strings.Contains(out, claim),275			"rendered disclosure must carry the claim: "+claim)276	}277278	// Both duplicate-named entries really are present — the disclosure is279	// describing a live condition, not a hypothetical one.280	uassert.Equal(t, 2, strings.Count(out, "**vault_v1**"),281		"duplicate names are permitted and both must render")282}283284func TestRender_Sections(cur realm, t *testing.T) {285	resetState()286	register(cur, v1, "vault_v1", teamEOA)287	register(cur, v2, "vault_v2", teamEOA)288289	testing.SetRealm(testing.NewUserRealm(teamEOA))290	Deprecate(cross(cur), v1, v2)291292	out := Render("")293	uassert.True(t, strings.Contains(out, "## Active"), "active section")294	uassert.True(t, strings.Contains(out, "## Deprecated"), "deprecated section")295	uassert.True(t, strings.Contains(out, "DEPRECATED"), "deprecation flag")296	uassert.True(t, strings.Contains(out, string(v2)), "successor shown")297}298299// ---------- re-audit regressions (2026-09-02) ----------300301func TestOwnerNomination_RequiresConsent(cur realm, t *testing.T) {302	resetState()303304	// re-audit P2: registering with someone else's address as owner must305	// NOT attach them — no pollution of GetOwnerContracts, no GetInfo306	// showing them as owner, until they accept307	victim := teamEOA308	testing.SetRealm(testing.NewUserRealm(attacker))309	Register(cross(cur), "gnoswap_router", victim)310311	uassert.Equal(t, string(attacker), string(entries[attacker].Owner))312	uassert.Equal(t, "none", GetOwnerContracts(victim))313	uassert.True(t, strings.Contains(GetInfo(attacker), string(attacker)),314		"info must show the contract itself as owner pre-acceptance")315316	// only the nominee can accept; a bystander cannot317	testing.SetRealm(testing.NewUserRealm(newOwnerAddr()))318	uassert.AbortsWithMessage(t, cur,319		"caller is not the pending owner of "+string(attacker),320		func() { AcceptOwnership(cross(cur), attacker) },321	)322}323324func newOwnerAddr() address {325	return testutils.TestAddress("bystander")326}327328func TestDeprecate_SuccessorConsentRequired(cur realm, t *testing.T) {329	resetState()330	register(cur, v1, "vault", teamEOA)331332	// re-audit P2: an attacker chains their entry INTO a legit contract,333	// forging predecessor provenance — refused unless the caller owns334	// the successor entry too335	testing.SetRealm(testing.NewUserRealm(attacker))336	Register(cross(cur), "vault_v1_old", "")337	uassert.AbortsWithMessage(t, cur,338		"successor entry is not owned by the caller: "+string(v1),339		func() { Deprecate(cross(cur), attacker, v1) },340	)341}342343func TestMigrationChain_MarksTruncation(cur realm, t *testing.T) {344	resetState()345	// build a chain longer than MaxChainLen entirely under one owner346	prev := address("")347	addrs := make([]address, MaxChainLen+5)348	for i := range addrs {349		addrs[i] = testutils.TestAddress("link_" + strconv.Itoa(i))350		testing.SetRealm(testing.NewUserRealm(addrs[i]))351		Register(cross(cur), "link", teamEOA)352		testing.SetRealm(testing.NewUserRealm(teamEOA))353		AcceptOwnership(cross(cur), addrs[i])354		if prev != "" {355			Deprecate(cross(cur), prev, addrs[i])356		}357		prev = addrs[i]358	}359360	out := GetMigrationChain(addrs[0])361	uassert.True(t, strings.Contains(out, "truncated"),362		"over-length chains must carry an explicit truncation marker")363	// GetLatest still resolves the true endpoint364	uassert.Equal(t, string(addrs[len(addrs)-1]), string(GetLatest(addrs[0])))365}366367func TestTransferNomination_CanBeCleared(cur realm, t *testing.T) {368	resetState()369	register(cur, v1, "vault", teamEOA)370371	testing.SetRealm(testing.NewUserRealm(teamEOA))372	TransferOwnership(cross(cur), v1, attacker)373	TransferOwnership(cross(cur), v1, "")374375	// round-4 audit L2: clearing again is a pure no-op, and the emitted376	// event is now suppressed for it. The return value and the state are377	// unchanged either way, which is all a unit test can observe here --378	// this toolchain's testing stdlib carries no events accessor. That the379	// second clear emits NOTHING is asserted externally by380	// tools/test_upgrade_registry_events.sh, which counts the events381	// `gno test -print-events` prints for this very suite.382	uassert.Equal(t, "pending ownership nomination cleared",383		TransferOwnership(cross(cur), v1, ""))384	uassert.Equal(t, "", string(mustGet(v1).PendingOwner))385386	testing.SetRealm(testing.NewUserRealm(attacker))387	uassert.AbortsWithMessage(t, cur,388		"caller is not the pending owner of "+string(v1),389		func() { AcceptOwnership(cross(cur), v1) },390	)391}392393// ---------- round-3 audit regressions (2026-09-02) ----------394395func TestRenderLatest_ExactBudgetChainIsComplete(cur realm, t *testing.T) {396	resetState()397	// exactly RenderLatestHops deprecated hops + terminal endpoint:398	// the walk must be reported COMPLETE (round-3 off-by-one)399	n := RenderLatestHops + 1400	addrs := make([]address, n)401	for i := range addrs {402		addrs[i] = testutils.TestAddress("hop_" + strconv.Itoa(i))403		testing.SetRealm(testing.NewUserRealm(addrs[i]))404		Register(cross(cur), "hop", teamEOA)405		testing.SetRealm(testing.NewUserRealm(teamEOA))406		AcceptOwnership(cross(cur), addrs[i])407		if i > 0 {408			Deprecate(cross(cur), addrs[i-1], addrs[i])409		}410	}411	latest, complete := renderLatest(addrs[0])412	uassert.True(t, complete, "an exactly-budget chain must be complete")413	uassert.Equal(t, string(addrs[n-1]), string(latest))414}415416// ---------- audit gap closures (2026-09-21, apps-pipeline round) ----------417418func TestStraySendRejectedEverywhere(cur realm, t *testing.T) {419	resetState()420	register(cur, v1, "vault", teamEOA)421422	// audit Y2: the realm holds no banker, so attached coins would423	// strand forever — every crossing function must abort them424	msg := "this realm does not accept coins"425	testing.SetRealm(testing.NewUserRealm(teamEOA))426	testing.SetOriginSend(chain.Coins{{Denom: "ugnot", Amount: 5}})427	uassert.AbortsWithMessage(t, cur, msg, func() { Register(cross(cur), "paid", "") })428	uassert.AbortsWithMessage(t, cur, msg, func() { AcceptOwnership(cross(cur), v1) })429	uassert.AbortsWithMessage(t, cur, msg, func() { TransferOwnership(cross(cur), v1, attacker) })430	uassert.AbortsWithMessage(t, cur, msg, func() { Deprecate(cross(cur), v1, v2) })431	testing.SetOriginSend(nil)432}433434func TestDeprecate_BoundedWalkRefusal(cur realm, t *testing.T) {435	resetState()436	// audit Y5.1: the round-3 bounded-walk panic had zero coverage.437	// Build a chain longer than MaxChainLen, then point a fresh entry438	// at its head — the verification walk must refuse, not walk it.439	prev := address("")440	addrs := make([]address, MaxChainLen+5)441	for i := range addrs {442		addrs[i] = testutils.TestAddress("bw_" + strconv.Itoa(i))443		testing.SetRealm(testing.NewUserRealm(addrs[i]))444		Register(cross(cur), "link", teamEOA)445		testing.SetRealm(testing.NewUserRealm(teamEOA))446		AcceptOwnership(cross(cur), addrs[i])447		if prev != "" {448			Deprecate(cross(cur), prev, addrs[i])449		}450		prev = addrs[i]451	}452	fresh := testutils.TestAddress("bw_fresh")453	testing.SetRealm(testing.NewUserRealm(fresh))454	Register(cross(cur), "fresh", teamEOA)455	testing.SetRealm(testing.NewUserRealm(teamEOA))456	AcceptOwnership(cross(cur), fresh)457	uassert.AbortsWithMessage(t, cur,458		"successor chain too long to verify; cannot deprecate",459		func() { Deprecate(cross(cur), fresh, addrs[0]) },460	)461}462463func TestRenderLatest_LongChainMarked(cur realm, t *testing.T) {464	resetState()465	// audit Y5.2: the incomplete branch and Render's long-chain marker466	// were untested. Budget-boundary node must be NON-terminal here.467	n := RenderLatestHops + 3468	addrs := make([]address, n)469	for i := range addrs {470		addrs[i] = testutils.TestAddress("lc_" + strconv.Itoa(i))471		testing.SetRealm(testing.NewUserRealm(addrs[i]))472		Register(cross(cur), "hop", teamEOA)473		testing.SetRealm(testing.NewUserRealm(teamEOA))474		AcceptOwnership(cross(cur), addrs[i])475		if i > 0 {476			Deprecate(cross(cur), addrs[i-1], addrs[i])477		}478	}479	_, complete := renderLatest(addrs[0])480	uassert.False(t, complete, "an over-budget chain must be reported incomplete")481	uassert.True(t, strings.Contains(Render(""), "(long chain; use GetLatest)"),482		"render must mark over-budget chains instead of mislabeling an endpoint")483}484485func TestRender_Pagination(cur realm, t *testing.T) {486	resetState()487	// audit Y5.3: the MaxRenderEntries window was untested488	for i := 0; i < MaxRenderEntries+5; i++ {489		a := testutils.TestAddress("pg_" + strconv.Itoa(i))490		testing.SetRealm(testing.NewUserRealm(a))491		Register(cross(cur), "entry", "")492	}493	out := Render("")494	uassert.True(t, strings.Contains(out,495		"_Showing the most recent "+strconv.Itoa(MaxRenderEntries)+" entries of "+496			strconv.Itoa(MaxRenderEntries+5)+"."),497		"over-window registries must announce the window AND the true total")498	// round-4 audit: announcing the window is not enough on an immutable499	// realm — the page must also say where the unlisted entries went, since500	// a flood of new entries evicts older ones from this view permanently.501	uassert.True(t, strings.Contains(out, "remain queryable by address via GetInfo"),502		"the eviction notice must point at the accessors that still serve them")503}504505func TestRenomination_OverwritesPrior(cur realm, t *testing.T) {506	resetState()507	register(cur, v1, "vault", teamEOA)508	a := testutils.TestAddress("nominee_a")509	b := testutils.TestAddress("nominee_b")510511	// audit Y5.4: a newer nomination must revoke the older one512	testing.SetRealm(testing.NewUserRealm(teamEOA))513	TransferOwnership(cross(cur), v1, a)514	TransferOwnership(cross(cur), v1, b)515	testing.SetRealm(testing.NewUserRealm(a))516	uassert.AbortsWithMessage(t, cur,517		"caller is not the pending owner of "+string(v1),518		func() { AcceptOwnership(cross(cur), v1) },519	)520	testing.SetRealm(testing.NewUserRealm(b))521	AcceptOwnership(cross(cur), v1)522	uassert.Equal(t, string(b), string(entries[v1].Owner))523}524525func TestSelfNominationAcceptKeepsIndexClean(cur realm, t *testing.T) {526	resetState()527	register(cur, v1, "vault", teamEOA)528529	// audit Y5.5: owner nominating themselves and accepting must not530	// duplicate or lose the ownerContracts index entry531	testing.SetRealm(testing.NewUserRealm(teamEOA))532	TransferOwnership(cross(cur), v1, teamEOA)533	AcceptOwnership(cross(cur), v1)534	uassert.Equal(t, string(teamEOA), string(entries[v1].Owner))535	uassert.Equal(t, string(v1), GetOwnerContracts(teamEOA))536}537538func TestOpsOnUnregisteredAbort(cur realm, t *testing.T) {539	resetState()540	// audit Y5.6: the not-found aborts were never asserted541	ghost := testutils.TestAddress("ghost")542	msg := "contract not found: " + string(ghost)543	testing.SetRealm(testing.NewUserRealm(teamEOA))544	uassert.AbortsWithMessage(t, cur, msg, func() { AcceptOwnership(cross(cur), ghost) })545	uassert.AbortsWithMessage(t, cur, msg, func() { TransferOwnership(cross(cur), ghost, teamEOA) })546	uassert.AbortsWithMessage(t, cur, msg, func() { Deprecate(cross(cur), ghost, v1) })547	// GetInfo shares mustGet with the three crossing paths above; its548	// same-realm panic is not catchable by the revive-based Aborts helpers549}550551func TestRegister_OwnerEqualsSelfNoPending(cur realm, t *testing.T) {552	resetState()553	// audit Y5.7: registering with your own address as owner must leave554	// no pending nomination (the explicit owner==contractAddr branch)555	testing.SetRealm(testing.NewUserRealm(v1))556	Register(cross(cur), "vault", v1)557	uassert.Equal(t, string(v1), string(entries[v1].Owner))558	uassert.Equal(t, "", string(entries[v1].PendingOwner))559}560

Functions

  • AcceptOwnership(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, contractAddr string) string

  • Deprecate(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, contractAddr string, successorAddr string) string

  • GetInfo(contractAddr string) string

  • GetLatest(contractAddr string) string

  • GetMigrationChain(contractAddr string) string

  • GetOwnerContracts(owner string) string

  • Register(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, name string, owner string) string

  • Render(path string) string

  • TransferOwnership(cur interface {.seal func(); Address func() .uverse.address; IsCode func() bool; IsCurrent func() bool; IsEphemeral func() bool; IsUser func() bool; IsUserCall func() bool; IsUserRun func() bool; PkgPath func() string; Previous func() .uverse.realm; String func() string; Sub func(string) .uverse.realm; Subpath func() string}, contractAddr string, newOwner string) string

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

Rendered

RenderedRawgnoweb ↗

vm/qrender output, sanitized (docs/render-security.md) and displayed in an empty-sandbox iframe — scripts, forms and popups cannot run. Links stay inert in-preview; right-click to open.