Goals:
Requires:
Proposed flow for releasing a new version of a codebase:
What would be included in a transaction to the _Metadata repository_ would be:
Since the hash of the payload is embedded on the Ethereum transaction, we don’t care about who owns the IPFS keypair, for example. Maximum security can be enforced at _Dev_, for example making _Dev_ a multisig. That way, you can enforce however much security do you want by writing or using a contract. It also helps abstract the underlying storage system. This could work with any kind of storage, but of course decentralized storage protocols are preferred.
App would be listening for events in multiple repos and fetch new code packages accordingly.
This base protocol would be pretty generic and agnostic. But knowing that, in our case, we will primarily work on with JavaScript and web tech, we could go a step further and implement a full replacement for NPM.
This would be as simple as having a package.json manifest in all packages, where you can declare a package’s dependencies, and then fetching those dependencies. You could either state them with the Ethereum address of the _Metadata repository_ where it lives, or… you could use ENS! We could own something like aragoncodebases.eth and give out developers subdomains for their _Metadata repositories_. Then you could just point to that subdomain as a dependency.
Asks:
Implementation proposal:
RepoAddr@PackageVersion fetches the given version of that packageRepoName@PackageVersion also resolvesWhat do you think @izqui @harshjv?
Good idea, i like the word 'Package' more than 'Repo' for this concept, as modules can be thought of a package of contracts and frontend code.
Did a quick Solidity spike to think a bit about the data structures. Basically a version of a package could have a factory address for deploying an instance of the contract for that particular version and the IPFS hash for the frontend.
The ENS thing is totally doable I'd imagine something like: latest.ownership.[domain].eth or 170.bylaws.[domain].eth
contract Package is Ownable {
struct Version {
uint32 semanticVersion;
address contractApplicationFactory;
bytes32 frontendIPFSHash; // is it bytes32?
}
mapping (uint32 => uint256) public versionIdBySemanticVersion;
uint32 public lastVersion;
Version[] versions;
function addVersion(uint32 _semanticVersion, address _contract, bytes32 _ipfs) onlyOwner {
uint versionId = versions.push(Version(_semanticVersion, _contract, _ipfs)) - 1;
versionIdBySemanticVersion[_semanticVersion] = _semanticVersion;
lastVersion = _semanticVersion;
}
}
That's it! Regarding ENS, makes a lot of sense. I honestly don't have strong feelings of Package vs Repo, seems like a Repo contains different Packages (could be versions or other packages), but on the other hand a single Package contains different versions. So yeah, Package makes sense.
BTW @harshjv look at @izqui's snippet above, maybe it is of inspiration
@izqui Yep, bytes32 for ipfs mutihash.
Since we are dealing with prebuilt packages, can we expect the contract address in some json file? In our case, a module.json having contractAddress field. That will make a generic Package repo. What do you think?
Yes, talked to Luis about that.
Will follow up with an updated proposal next week :)
El vie., 7 jul. 2017 a las 13:07, Harsh Vakharia (notifications@github.com)
escribió:
@izqui https://github.com/izqui Yep, bytes32 for ipfs mutihash.
Since we are dealing with prebuilt packages, can we expect the contract
address in some json file? In our case, a module.json having
contractAddress field.—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/aragon/aragon/issues/19#issuecomment-313653250, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AAbTYJcH9AdUjEehVSjifcHNnX57nvlmks5sLhF9gaJpZM4OG6YP
.
By the way, wouldn't Aragon Packaging Protocol or Aragon Package Protocol make more sense, since we're packaging modules? Also the abbreviation would be APP 😁
@onbjerg the thing is that this is very much abstracted away from modules, it is just an agnostic way to version data
It took me a bit to get it aswell @onbjerg.
The idea is to have a fully abstracted versioning protocol on top of ETH that keeps track of different
versions of blobs of data that can be located elsewhere (IPFS, Swarm, or even the ETH chain). It provides a common interface for updating the versions and a way to look them up (ENS resolver).
Then we can build the Aragon Package Manager, that implements AVP and its blobs of data are Aragon packages that can be stored anywhere.
Oh, that makes sense, thanks for clarifying @luisivan and @izqui! I don't think we can find a better name than we have now, then 🙂
Did a bit of work on the AVP and got it to the point where it is working with the ENS.
URI scheme: patch.minor.major.name.aragonpm.eth (aragonpm.eth is currently in reveal face, and chances are we will win the name)
Version syntax can look like it is in counter-intuitive order, but ENS uris work this way, from right to left from more broad to more specific.
The versioning resolver implements the logic that allows to fetch the latest version just checking name.aragonpm.eth or the latest version of a specific major or minor 2.ownership.aragonpm.eth will return the latest version of the 2.x.y release, same with 1.2.ownership.aragonpm.eth will return the latest 2.1.y release.
Only subsequent versions can be added. For example 2.1.1 can turn to 2.1.2, 2.2.0 or 3.0.0, every other version transition is disallowed (enforced by the smart contract).
There was significant discussion about how to make the content(bytes node) part of the ENS standard. For the first version it wasn't included given lack of clarity. Problem is bytes32 is not enough for some hash types (including sha256, as referenced in the ERC discussion). IPFS hashes can be base58 decoded, and a bytes32 could be stored, but then there wouldn't be nowhere to save the hash version.
My proposal (and what it is currently implemented) is the following function signature for resolvers returning data:
function content(bytes32 node) constant returns (uint16 locationId, bytes contentHash);
locationId identifies where the content can be found (1 = swarm, 2 = ipfs, 3 = storj...)contentHash is an arbitrary length bytes array that describes how the content can be fetched in the location. It is less efficient than storing fixed sized arrays, but this is way more flexible for future storage locations.Current implementation: https://github.com/aragon/aragon-package-manager/blob/master/contracts/VersioningProtocol.sol#L45
(repo is private for now, only for org members, code is too early)
Moved to apm-contracts and AragonOS documentation
Most helpful comment
It took me a bit to get it aswell @onbjerg.
The idea is to have a fully abstracted versioning protocol on top of ETH that keeps track of different
versions of blobs of data that can be located elsewhere (IPFS, Swarm, or even the ETH chain). It provides a common interface for updating the versions and a way to look them up (ENS resolver).
Then we can build the Aragon Package Manager, that implements AVP and its blobs of data are Aragon packages that can be stored anywhere.