azimuth-and-ecliptic

Operators of an address are allowed to transfer ownership of all points owned by their associated address (ERC721’s approveAll()). A transfer proxy is allowed to transfer ownership of a single point (ERC721’s approve()).

Azimuth

// Azimuth is just the data store. Ecliptic is the logic contract.
// In this way, Azimuth/Ecliptic is 'upgradeable' - you can 
// swap out Ecliptic in order to change the logic, without
// compromising the Azimuth data store

// Events elided

// the actual azimuth Point
struct Point {
	bytes32 encrptionKey; // encyrption pub key
	bytes32 authenticationKey; // auth pub key
	uint32[] spawned; // children
	bool hasSponsor; // sponsor IS supporting
	bool active; // can be "linked" (no belong to prefix)
	bool escapeRequested; // in pending sponsor-change state
	uint32 sponsor; // curernt supporter or last (if hasSponsor false)
	uint32 escapeRequestedTo; // the new req'd sponsor
	unit32 cryptoSuiteVersion; / pubkey suite version
	uint32 keyRevisionNumber; // incremented when pubkey changed
	unit32 continuityNumber; // incremented on network breach
}

// permisions for a point. aka 'rights'
struct Deed {
	address owner; // eth address owning point
	address managementProxy; // 0 or eth address
	address spawnProxy; // 0 or addr who can spawn children
	address votingProxy; // 0 or addr with voting rights
	address transferProxy; // 0 or addr who can transfer this point
}

// state
//

// uint32 is the point. these are "per point"
mapping(uint32 => Point) public points;
mapping(uint32 => Deed) public rights;

// owner => address. has right to transfer _all_ the owner's points
mapping(address => mapping(address => bool)) public operators;

// base domains for contacting galaxies. Deeply centralized!
string[3] public dnsDomains; // [0] is primary, others are fallbacks

//
// end state

// lookups
//

// per point, who they are sponsoring
mapping(uint32 => uint32[]) public sponsoring;

// gives indexes (index + 1) for the above.
mapping(uint32 => mapping(uint32 => uint256)) public sponsoringIndexes;

// per point, the other points it has escape requests from
mapping(uint32 => uint32[]) public escapeRequests;

// indexes for above
mapping(uint32 => mapping(uint32 => uint256)) public escapeRequestsIndexes;

// points owned by this address
mapping(address => uint32[]) public pointsOwnedBy;

// indexes for above (also used for deleting owners)
mapping(address => mapping(uint32 => uint256)) public pointOwnerIndexes;

// the following four also have indexes, elided here.
//
// per address, points they management proxy for
mapping(address => uint32[]) public managerFor;

// per address, points they can spawn with
mapping(address => uint32[]) public spawningFor;

// per address, points they can vote with
mapping(address => uint32[]) public votingFor;

// per address, points they can transfer
mapping(address => uint32[]) public transferringFor;

//
// end lookups

// logic
//
// eliding anything that isn't directly related to Husk, for now

// Deed-reading:

// returns owner of _point
function getOwner(uint32 _point)
	view
	external
	returns (address owned)
	{
		return rights[_point].owner;
	}
 
// true if _point is owned by _address
function isOwner(uint32 _point, address _address)

// similar to above:
function getManagementProxy(uint32 _point)
function isManagementProxy(uint32 _point, address _address)
	returns (bool result)
// similar, but includes owner and management proxy:
function canManage(uint32 _point, address _who)

// returns all points a proxy address can manage
function getManagerFor(address _proxy)
	returns (uint32[] mfor)

// similar to above for transfers:

// point's current transfer proxy
function getTransferProxy(uint32 _point)
	returns (address transferProxy)
function isTransferProxy(uint32 _point, address _address)
	returns (bool result)
// true for owner, transfer proxy or "operator" of point's current owner
function canTransfer(uint32 _point, address _who)
	returns (bool result)
// returns all points proxy can transfer
function getTransferringFor(address _proxy)
	returns (uint32[] tfor)

// true if operator is allowed to txfr ownership of _owner's points
function isOperator(address _owner, address _operator)
	returns (bool result)

// Deed-Writing **important for Husk**

// See ecliptic
// set owner of _point to _owner
function setOwner(uint32 _point, address _owner)
	onlyOwner // of contract, aka Ecliptic

// See ecliptic
// makes _proxy the _point's management proxy
function setManagementProxy(uint32 _point, address _proxy)

// See ecliptic
// makes _proxy the _point's transfer proxy
function setTransferProxy(uint32 _point, address _proxy)

Ecliptic

// The logic contract / owner for Azimuth.
// Azimuth data store doesn't change, but the way you interact
// with it can change by swapping out / upgrading Ecliptic.

//    This contract implements the ERC721 interface for non-fungible tokens,
//    allowing points to be managed using generic clients that support the
//    standard. It also implements ERC165 to allow this to be discovered.

// Events elided


//  get the current owner of point _tokenId
//
function ownerOf(uint256 _tokenId)
	returns (address owner)

// transfer point _tokenID from _from to _to
function safeTransferFrom(address _from, address _to, uint256 _tokenID)

// transfer point _tokenID from _from to _to
// AND CALL CONTRACT -- Husk!
function safeTransferFrom(address _from, address _to, uint256 _tokenID bytes _data)

//  transfer point _tokenId from _from to _to,
//                  WITHOUT notifying recipient contract
//
function transferFrom(address _from, address _to, uint256 _tokenId)


//  transfer _point to _target, clearing all permissions
//                   data and keys if _reset is true
//
//    Requirements:
//    - :msg.sender must be either _point's current owner, authorized
//      to transfer _point, or authorized to transfer the current
//      owner's points (as in ERC721's operator)
//
function transferPoint(uint32 _point, address _target, bool _reset)

// internally calls azimuth.canTransfer(_point, msg.sender))
// that is: current owner or operator for current owner OR txfr proxy

// internally calls azimuth.setOwner(_point, _target)


Questions / Confusions

  • What is a “prefix”?
    • // getPrefix(): compute prefix ("parent") of _point
    • so the “prefix” is the “parent”
    • What is “parent”?
  • need more clarity on “operator”
    • These are apparently part of the ERC721 standard.

Questions for Husk

  • will red horizon be using the “operator of an address” or its transfer proxy?
  • how do I use “callbacks” - idea being to use the safeTranferFrom and include the husk contract to tell husk that a husk-style transfer just happened.
    • but does this “safeTransfer” imply the recipient must accept? that won’t work for Husk.
    • this seems to be part of the ERC721 standard. Look into
Links to this page