Ecliptic.eth↗ holds the business logic for the ledger kept by Azimuth.eth
. It may be modified by galaxy vote. This determines things such as what the various proxies are capable of, how keys are changed, or verifying that a request is valid.
Ecliptic.eth
uses external contracts such as Azimuth.eth and Polls↗ for data storage so that it can easily be replaced in case the logic needs to be changed without affecting the data. These data contracts are owned by Ecliptic.eth
, and this ownership is passed to the new Ecliptic contract whenever it is replaced. Thus it is advised for clients to not store Ecliptic's contract address directly, but instead ask the Azimuth.eth
contract for its owner
attribute to ensure that transactions are sent to the latest Ecliptic contract. Alternatively, the ENS↗ name Ecliptic.eth
will always resolve to the latest Ecliptic.
You can read about Urbit's first upgrade↗ to Ecliptic, which occurred in the summer of 2021, here↗. The second↗ occurred later in the year and consisted of several small modifications to ready the PKI for the introduction of naive rollups.
Ecliptic.eth
implements the ERC-721↗ interface for non-fungible tokens, as well as the ERC-165↗ standard for interface detection.
There are currently 28 functions which may be called to write to the Ecliptic, and 17 functions to read data from the Ecliptic. Many of these have a corresponding layer 2 action, and/or can be performed using Bridge↗. We note these facts where applicable.
Write functions
Here we briefly describe each function in Ecliptic.eth
which allows one to write data to Ethereum. These can be called using Etherscan↗, but the most common functions may be called from within Bridge.
We only document here the write functions specific to Ecliptic.eth
and not the standard functions that are part of the ERC-721 or ERC-165 interfaces.
Point
s interface
These functions are available to each owner of a Point
, and a subset of them are available to its proxies. All of these actions may be performed from Bridge.
configureKeys
function configureKeys(uint32 _point,bytes32 _encryptionKey,bytes32 _authenticationKey,uint32 _cryptoSuiteVersion,bool _discontinuous)
Configure _point
with network public keys _encryptionKey
, _authenticationKey
, and corresponding _cryptoSuiteVersion
, incrementing the Point
's keyRevisionNumber
if the keys have changed and continuityNumber
number if _discontinuous
is set to true (see Life and Rift).
Corresponds to the layer 2 %configure-keys
action.
spawn
function spawn(uint32 _point, address _target)
Spawn _point
, then either give, or allow _target
to take, ownership of _point
.
If _target
is the :msg.sender
, _target
owns the _point
right away. otherwise, _target
becomes the transfer proxy of _point
.
Requirements:
_point
must not be active_point
must not be a planet with a galaxy prefix_point
's prefix must be linked and under its spawn limit:msg.sender
must be either the owner of_point
's prefix, or an authorized spawn proxy for it
Corresponds to the layer 2 %spawn
action.
transferPoint
function transferPoint(uint32 _point, address _target, bool _reset)
Transfer _point
to _target
, clearing all permissions data and keys if _reset
is true. _reset
set to true makes this transaction a breach↗, and thus this action increments the continuityNumber
of _point
, and usually the keyRevisionNumber
as well (see Life and Rift).
Requirements:
:msg.sender
must be either_point
's current owner, authorized to transfer_point
, or authorized to transfer the current owner's points (i.e. is listed as an ERC-721 operator inoperators
)._target
must not be the zero address.
Corresponds to the layer 2 %transfer-point
action.
escape
function escape(uint32 _point, uint32 _sponsor)
Request escape as _point
to _sponsor
.
If an escape request is already active, this overwrites the existing request.
Requirements:
:msg.sender
must be the owner or manager of_point
,_point
must be able to escape to_sponsor
as per tocanEscapeTo()
Corresponds to the layer 2 %escape
action.
cancelEscape
function cancelEscape(uint32 _point)
Cancel the currently set escape for _point
.
Corresponds to the layer 2 %cancel-escape
action.
adopt
function adopt(uint32 _point)
As the relevant sponsor, accept the _point
.
Requirements:
:msg.sender
must be the owner or management proxy of_point
's requested sponsor
Corresponds to the layer 2 %adopt
action.
reject
function reject(uint32 _point)
As the relevant sponsor, deny the _point
's %adopt
request.
Requirements:
:msg.sender
must be the owner or management proxy of_point
's requested sponsor
Corresponds to the layer 2 %reject
action.
detach
function detach(uint32 _point)
As the _sponsor
, stop sponsoring the _point
.
Requirements:
:msg.sender
must be the owner or management proxy of_point
's current sponsor
Corresponds to the layer 2 %detach
action.
Unlike all other layer 1 actions, layer 1 sponsors may use a layer 1 %detach
on a layer 2 sponsee. See the Layer 2 section for more detail. The detach action available in Bridge is a layer 2 action, so a layer 1 detach must be done manually↗.
Proxy management
These functions are used to manage the various proxies↗. All of these actions may be performed from Bridge.
setManagementProxy
function setManagementProxy(uint32 _point, address _manager)
Configure the management proxy for _point
.
The management proxy may perform "reversible" operations on behalf of the owner. This includes public key configuration and operations relating to sponsorship.
Requirements:
:msg.sender
must be either_point
's current owner or the management proxy.
Corresponds to the layer 2 %set-management-proxy
action.
setSpawnProxy
function setSpawnProxy(uint16 _prefix, address _spawnProxy)
Give _spawnProxy
the right to spawn points with the prefix _prefix
using the spawn
function.
Requirements:
:msg.sender
must be either_point
's current owner or the spawn proxy.
Corresponds to the layer 2 %set-spawn-proxy
action.
setVotingProxy
function setVotingProxy(uint8 _galaxy, address _voter)
Configure the voting proxy for _galaxy
.
The voting proxy is allowed to start polls and cast votes on the point's behalf.
Requirements:
:msg.sender
must be either_point
's current owner or the voting proxy.
There is no corresponding layer 2 action since voting must occur on layer 1.
setTransferProxy
function setTransferProxy(uint32 _point, address _transferProxy)
Give _transferProxy
the right to transfer _point
.
Requirements:
:msg.sender
must be either_point
's current owner, an operator for the current owner, or the transfer proxy.
Corresponds to the layer 2 %set-transfer-proxy
action.
Poll actions
Most of these are functions only available to galaxies. They are related to voting. As voting does not occur on layer 2, there are no corresponding layer 2 actions for poll actions.
Upgrade and document polls last for 30 days, or once a majority is achieved, whichever comes first. If a majority (129) of yes or no votes is achieved, the final vote cast in favor of the winning option also triggers updateUpgradePoll
or updateDocumentPoll
as appropriate. Otherwise, if a quorum of 64 votes is achieved, with a majority voting for yes, and the 30 day voting period has expired, then any Ethereum address may call updateUpgradePoll
or updateDocumentPoll
as appropriate.
startUpgradePoll
function startUpgradePoll(uint8 _galaxy, EclipticBase _proposal)
As _galaxy
, start a poll for the Ecliptic upgrade _proposal
.
Requirements:
:msg.sender
must be the owner or voting proxy of_galaxy
,- the
_proposal
must expect to be upgraded from this specific contract, as indicated by itspreviousEcliptic
attribute.
This action must be performed manually - it is not available in Bridge.
startDocumentPoll
function startDocumentPoll(uint8 _galaxy, bytes32 _proposal)
As _galaxy
, start a poll for the _proposal
. Document polls last for 30 days, or once a majority is achieved, whichever comes first.
The _proposal
argument is the keccak-256 hash of any arbitrary document or string of text.
This action must be performed manually - it is not available in Bridge.
castUpgradeVote
function castUpgradeVote(uint8 _galaxy,EclipticBase _proposal,bool _vote)
As _galaxy
, cast a _vote
on the Ecliptic upgrade _proposal
.
_vote
is true when in favor of the proposal, false otherwise.
This action may be performed from Bridge.
castDocumentVote
function castDocumentVote(uint8 _galaxy, bytes32 _proposal, bool _vote)
As _galaxy
, cast a _vote
on the _proposal
.
_vote
is true when in favor of the proposal, false otherwise.
This action may be performed from Bridge.
updateUpgradePoll
function updateUpgradePoll(EclipticBase _proposal)
Check whether the _proposal
has achieved majority, upgrading to it if it has. Any Ethereum address may call this function.
This action eiher occurs as part of a vote that achieves a majority, or must be performed manually. It is not available in Bridge.
updateDocumentPoll
function updateDocumentPoll(bytes32 _proposal)
Check whether the _proposal
has achieved majority. Any Ethereum address may call this function.
This action eiher occurs as part of a vote that achieves a majority, or must be performed manually. It is not available in Bridge.
Contract owner operations
The following functions may only be performed by the owner of the contract. There are only two such functions, one of which is to spawn galaxies. As all galaxies have already been spawned, it is no longer of any use. Thus only setDnsDomains
is relevant today.
createGalaxy
function createGalaxy(uint8 _galaxy, address _target)
Grant _target
ownership of the _galaxy
and register it for voting. Galaxies are given by a uint8
, and since all 256 galaxies have already been spawned, this function has no valid arguments.
setDnsDomains
function setDnsDomains(string _primary, string _secondary, string _tertiary)
Sets 3 DNS domains by which galaxy IP addresses may be looked up as part of the bootstrap process to get on the network. Currently, all three domains are urbit.org
.
Read functions
Here we briefly describe each function in the Ecliptic which allows one to read data from the contract. These can be called using Etherscan↗.
We only document here the read functions specific to Ecliptic and not the standard functions that are part of the ERC-721 or ERC-165 interfaces.
depositAddress
This returns the deposit address for layer 2, which is 0x1111111111111111111111111111111111111111
. Ships sent to this address are controlled on layer 2 instead of via Ecliptic.
canEscapeTo
function canEscapeTo(uint32 _point, uint32 _sponsor)
Returns a bool
that is true if _point
could try to escape to _sponsor
.
azimuth
Returns the address of the Azimuth.eth contract: 0x223c067f8cf28ae173ee5cafea60ca44c335fecb
.
claims
Returns the address of the Claims↗ contract: 0x1df4ea30e0b1359c9692a161c5f30cd1a6b64ebf
.
polls
Returns the address of the Polls↗ contract: 0x7fecab617c868bb5996d99d95200d2fa708218e4
.
previousEcliptic
Returns the address of the previous Ecliptic address.
getSpawnLimit
function getSpawnLimit(uint32 _point, uint256 _time)
Returns a uint32
that is the total number of children the _point
is allowed to spawn at _time
.
There is no limit for galaxies. Instead, for most galaxies, all stars have already been spawned and placed into one of the lockup contracts: Linear Star Release↗ and Conditional Star Release↗.
Beginning in 2019, stars may spawn at most 1024 planets. This limit doubles every subsequent year until the maximum is reached. However, this limit is not currently implemented on Layer 2.