aionnetwork / AIP

Network & Protocol Improvement Proposals for Aion
https://aion.network
16 stars 13 forks source link

AIP #008 - Aion Interface Registry #13

Closed thegostep closed 5 years ago

thegostep commented 5 years ago

Title: Aion Interface Registry Author(s): Sam Pajot-Phipps, Yao Sun, Stephane Gosselin Type: ASC (Aion Standards and Conventions) Status: Rejected Creation Date: April 15th, 2018 Contact Information: sam@aion.network


Summary

A standard for a universal registry smart contract where any address can register which interface it supports and delegate responsibility for its implementation. This standard follows the ERC-820 standard from Ethereum.

Value Proposition

Provide a way to determine if a contract implements an interface of interest before executing a transaction.

Motivation

Contract pseudo-introspection provides a standard way for the manager of a contract to describe the interface it has implemented such that it can be queried by other contracts before executing a transaction.

Delegated implementation allows a manager to define a delegated address which implements an interface on behalf of the main address.

The registry contract also provides a simple way of monitoring the deployment of contracts with an interface of interest.

Non-Goals

Success Metrics

There are two key indicators of success for this standard: 1) Number of interface registered 2) Number of queries for interface registrations

Description

A standard for a universal registry smart contract where any address can register which interface it supports and delegate responsibility for its implementation. This standard follows the ERC-820 standard from Ethereum.

Contract pseudo-introspection provides a standard way for the manager of a contract to describe the interface it has implemented such that it can be queried by other contracts before executing a transaction.

Delegated implementation allows a manager to define a delegated address which implements an interface on behalf of the main address.

The registry contract also provides a simple way of monitoring the deployment of contracts with an interface of interest.

Specification

Definitions

Interface Naming Conventions

Each interface name must be unique. Following the guidelines used in ERC-820, interfaces for approved AIPs must use the following conventions.

MUST be named AIP###XXXXX where ### is the number of the AIP and XXXXX should be the name of the interface in CamelCase. The meaning of this interface SHOULD be defined in the specified AIP.

Examples:

sha3("AIP004Token") sha3("AIP004TokensSender") sha3("AIP004TokensRecipient")

Methods for AIRDelegateInterface

isDelegateFor function

Called to get whether or not this delegate contract implements the interface interfaceHash for the address target.

NOTE: Although the function returns true or false, it is necessary to return sha3("AIR_ACCEPT_MAGIC") to avoid issues with calling fallback functions which return booleans.
NOTE: This interface is only required if the delegate is a different address than the manager.

parameters addr: Address supporting an interface.
interfaceHash: Sha3 hash of the interface name.

function isDelegateFor(address addr, bytes32 interfaceHash) external constant returns(bytes32);

Methods for AionInterfaceRegistry

InterfaceDelegateSet event

Indicate that the address target supports the interface interfaceHash through the delegate address delegate.

If the target implements the interface itself, target and delegate will be equivalent.

This event can be monitored to determine the number of contracts on the network which support a given interface.

parameters
target: Address supporting an interface.
interfaceHash: Sha3 hash of the interface name.
delegate: Address implementing the interface on behalf of target.

event InterfaceDelegateSet(address indexed target, bytes32 indexed interfaceHash, address indexed delegate)

ManagerChanged event

Indicate that the address newManager now controls the interface registration of the address target.

parameters
target: Address supporting an interface.
newManager: Address controlling the registration on behalf of target.

event ManagerChanged(address indexed target, address indexed newManager)

getInterfaceDelegate function

Called to get the address of the delegate implementing the interfaceHash on behalf of the target.

NOTE: MUST return address 0x0 if the target does not support the interface.

parameters target: Address supporting an interface.
interfaceHash: Sha3 hash of the interface name.

function getInterfaceDelegate(address target, bytes32 interfaceHash) external constant returns (address)

getManager function

Called to get the address of the manager which controls the registration of the target.

NOTE: MUST return address target if no manager have been set.

parameters target: Address supporting an interface.

function getManager(address target) public constant returns(address)

interfaceHash function

Called to get the sha3 hash of an interface given its name as a string interfaceName.

parameters interfaceName: String of the interface name.

function interfaceHash(string interfaceName) public constant returns(bytes32)

setInterfaceDelegate function

Called to set the address of the delegate which implements the interface interfaceHash on behalf of the target.

NOTE: MUST remove an interface by calling with delegate set to address 0.
NOTE: MUST call with delegate set as address target if the target contract implements the interface itself (without a delegate).

parameters target: Address supporting an interface.
interfaceName: String of the interface name.
delegate: Address implementing the interface on behalf of target.

function setInterfaceDelegate(address target, bytes32 interfaceHash, address delegate) public

setManager function

Called to set the address of the manager which controls the registration of the target.

parameters target: Address supporting an interface.
manager: Address of the manager for target.

function setManager(address target, address manager) public

Solidity Contract

pragma solidity 0.4.15;

/// @dev The interface a contract MUST implement if it is the delegate of some (other) interface for any address other than itself.
interface AIRDelegateInterface {
    /// @notice Indicates whether the contract implements the interface `interfaceHash` for the address `target` or not.
    /// @param addr Address for which the contract will implement the interface
    /// @param interfaceHash sha3 hash of the name of the interface
    /// @return AIR_ACCEPT_MAGIC only if the contract implements `interfaceHash` for the address `target`.
    function isDelegateFor(address target, bytes32 interfaceHash) external constant returns(bytes32);
}

contract AionInterfaceRegistry {
    /// @notice Magic value which is returned if a contract implements an interface on behalf of some other address.
    bytes32 constant AIR_ACCEPT_MAGIC = sha3("AIR_ACCEPT_MAGIC");

    mapping (address => mapping(bytes32 => address)) interfaces;
    mapping (address => address) managers;

    modifier canManage(address target) {
        require(getManager(target) == msg.sender);
        _;
    }

    /// @notice Indicates a contract is the `delegate` of `interfaceHash` for `target`.
    event InterfaceDelegateSet(address indexed target, bytes32 indexed interfaceHash, address indexed delegate);
    /// @notice Indicates `newManager` is the address of the new manager for `target`.
    event ManagerChanged(address indexed target, address indexed newManager);

    /// @notice Query if an address implements an interface and through which contract.
    /// @param target Address being queried for the delegate of an interface.
    /// @param interfaceHash sha3 hash of the name of the interface as a string.
    /// @return The address of the contract which implements the interface `interfaceHash` for `target`
    /// or `0x0` if `target` did not register a delegate for this interface.
    function getInterfaceDelegate(address target, bytes32 interfaceHash) public constant returns (address) {
        return interfaces[target][interfaceHash];
    }

    /// @notice Get the manager of an address.
    /// @param target Address for which to return the manager.
    /// @return Address of the manager for a given address.
    function getManager(address target) public constant returns(address) {
        // By default the manager of an address is the same address
        if (managers[target] == address(0))
            return target;
        else
            return managers[target];
    }

    /// @notice Compute the sha3 hash of an interface given its name.
    /// @param interfaceName Name of the interface as a string.
    /// @return The sha3 hash of an interface name.
    function interfaceHash(string interfaceName) public constant returns(bytes32) {
        return sha3(interfaceName);
    }

    /// @notice Sets the contract which implements a specific interface for an address.
    /// Only the manager defined for that address can set it.
    /// (Each address is the manager for itself until it sets a new manager.)
    /// @param target Address to define the interface for.
    /// @param interfaceHash sha3 hash of the name of the interface as a string.
    function setInterfaceDelegate(address target, bytes32 interfaceHash, address delegate) public canManage(target) {
        if (delegate != address(0) && delegate != msg.sender)
            require(AIRDelegateInterface(delegate).isDelegateFor(target, interfaceHash) == AIR_ACCEPT_MAGIC);
        interfaces[target][interfaceHash] = delegate;
        InterfaceDelegateSet(target, interfaceHash, delegate);
    }

    /// @notice Sets the `manager` as manager for the `target` address.
    /// The new manager will be able to call `setInterfaceDelegate` for `target`.
    /// @param target Address for which to set the new manager.
    /// @param manager Address of the new manager for `target`. (Pass `0x0` to reset the manager to `target` itself.)
    function setManager(address target, address manager) public canManage(target) {
        managers[target] = manager == target ? address(0) : manager;
        ManagerChanged(target, manager);
    }
}

Logic

This standard is based on ERC-820 from Ethereum. The following modifications have been made in migrating the standard.

Risks & Assumptions

This standard does not guarantee that a given contract will behave as described by the associated interface. Since interface registration is perform on an opt-in basis by the author of the smart contract, users querying the interface registry must assume the author could register a false interface.

Test Cases

N/A

Implementations

N/A

Dependencies

N/A

Copyright

All AIP’s are public domain. Copyright waiver: https://creativecommons.org/publicdomain/zero/1.0/

jennijuju commented 5 years ago

Hi @thegostep, thank you for submitting the proposal. Could you please add a short explanation about what is out-of-scope for this proposal under Non-Goal section?

jennijuju commented 5 years ago

Updated status to "Review".

And accepting final feedback now till Dec 7th.

jennijuju commented 5 years ago

This AIP is rejected.

Reason: This Aion interface registry is for Aion Solidity contracts only. Since Aion is deprecating Solidity from the network, this registry will be no longer needed.