dType Functions Extension
Simple Summary
In the context of dType, the Decentralized Type System described in EIP-1900, we are proposing to add support for registering functions (with a preference for pure
and view
) in the dType Registry.
Abstract
This proposal is part of a series of EIPs focused on expanding the concept of a Decentralized Type System, as explained in EIP-1900. The current EIP specifies the data definitions and interfaces needed to support registering individual smart contract functions, as entries in the dType Registry.
Motivation
In order to evolve the EVM into a Singleton Operating System, we need a way to register, find and address contract functions that we want to run in an automated way. This implies having access to all the data needed to run the function inside the EVM.
Aside from the above motivation, there are also near future benefits for this proposal. Having a globally available, non-custodial functions registry, will democratize the development of tools, such as those targeting: blockchain data analysis (e.g. block explorers), smart contract IDEs, security analysis of smart contracts.
Registering new smart contract functions can be done through the same consensus mechanism as EIP-1900 mentions, in order to avoid burdening the chain state with redundant or improper records.
Specification
This specification targets pure
and view
functions.
For each function, we can store:
name
- typestring
unique function name, as defined in EIP-1900; requiredtypes
- the type data and label of each input, as defined in EIP-1900; requiredoutputs
- the type data and label of each output; requiredcontractAddress
- typeaddress
- smart contract where the function resides, as defined in EIP-1900; optional for interfacessource
- typebytes32
- reference to an external file containing the function source code, as defined in EIP-1900; optional
Therefore, this proposal adds outputs
to the EIP-1900 type registration definition.
An example of a function registration object for the dType registry is:
{
"name": "setStaked",
"types": [
{"name": "TypeA", "label": "typeA", "relation":0, "dimensions":[]}
],
"typeChoice": 4,
"contractAddress": <address of the deployed smart contract where the function is defined>,
"source": <bytes32 hash for referencing source files>,
"outputs": [
{"name": "TypeB", "label": "typeB", "relation":0, "dimensions":[]}
]
}
The above object will be passed to <dType registry>.insert({...})
An additional setOutputs
function is proposed for the dType registry:
function setOutputs(
bytes32 identifier,
dTypes[] memory outputs
)
public
identifier
- typebytes32
, the type’s identifier, as defined in EIP-1900outputs
- typedTypes
, as defined in EIP-1900
Implementation Suggestions
In the dType registry implementation, outputs
can be stored in a mapping
:
mapping(bytes32 => dTypes[]) public outputs;
Rationale
The suggestion to treat each pure
or view
function as a separate entity instead of having a contract-based approach allows us to:
- have a global context of readily available functions
- scale designs through functional programming patterns rather than contract-encapsulated logic (which can be successfully used to scale development efforts independently)
- bidirectionally connect functions with the types they use, making automation easier
- cherry-pick functions from already deployed contracts if the other contract functions do not pass community consensus
- have scope-restricted improvements - instead of redeploying entire contracts, we can just redeploy the new function versions that we want to be added to the registry
- enable fine-grained auditing of individual functions, for the common good
- enable testing directly on a production chain, without state side-effects
The proposal to store the minimum ABI information on-chain, for each function, allows us to:
- enable on-chain automation (e.g. function chaining and composition)
- be backward compatible in case the function signature format changes (e.g. from
bytes4
tobytes32
): multiple signature calculation functions can be registered with dType. Examples:
function getSignatureBytes4(bytes32 identifier)
view
public
returns (bytes4 signature)
function getSignatureBytes32(bytes32 identifier)
view
public
returns (bytes32 signature)
identifier
- the type’s identifier, as defined in EIP-1900signature
- the function’s signature
Concerns about this design might be:
- redundancy of storing
contractAddress
for each function that is part of the same contract
We think that state/storage cost will be compensated through DRYness across the chain, due to reusing types and functions that have already been registered and are now easy to find. Other state/storage cost calculations will be added once the specification and implementation are closer to be finalized.
Note that the input and output types are based on types that have already been registered. This lowers the amount of ABI information needed to be stored for each function and enables developers to aggregate and find functions that use the same types for their I/O. This can be a powerful tool for interoperability and smart contract composition.
Backwards Compatibility
This proposal does not affect extant Ethereum standards or implementations. Registering functions for existing contract deployments should be fully supported.
Test Cases
Will be added.
Implementation
In-work implementation examples can be found at https://github.com/pipeos-one/dType. This proposal will be updated with an appropriate implementation when consensus is reached on the specifications.
Copyright
Copyright and related rights waived via CC0.