Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

example of range of use cases #8

Closed
nmushegian opened this issue Oct 11, 2016 · 8 comments
Closed

example of range of use cases #8

nmushegian opened this issue Oct 11, 2016 · 8 comments

Comments

@nmushegian
Copy link

From: ethereum/EIPs#82

We want to ensure we can support the whole spectrum of Solidity packages, especially those that allow working with existing systems:

  • Simple static libraries which make no reference to any objects on any chain (ie Math)
  • Packages which describe singleton dapps (they ship address references and type info, but don't intend for people to re-use the solidity code, like actual Solidity libraries (string)).
  • Packages which describe singleton dapps, with extra support code for interacting with the system (eg something that interacts with a registry)
  • Packages which describe dapp "types" which you can deploy, like when an app is too large to build via a factory or requires a complex deployscript (eg a Token system that separates datastore/controller/frontend).

Perhaps another way to think of it is:

  • packages with 0 addresses (just code)
  • 1 address with no state or minimal state (libraries, eth wrapper, a factory that remembers the address type)
  • 1+ addresses with state (1 or more chains)

I think the "contract" vs "library" distinction is almost always a distraction because you can always hard-code addresses into libraries - there is no such category as "1 address with no state"

@tcoulter
Copy link
Contributor

tcoulter commented Oct 11, 2016

👍 I like this list. I'm a bit thrown off by the 1+ addresses description though:

Packages which describe dapp "types" which you can deploy, like when an app is too large to build via a factory or requires a complex deployscript (eg a Token system that separates datastore/controller/frontend).

I'm having trouble groking this, but I do agree that packages should have the ability to have multiple on-chain objects, each with an address.

As a thought experiment, I wonder if there's a 5th case, which might simply be an edge case of the 1+ example above:

  • Multiple addresses of the same type, in a single package.

I'm having trouble coming up with a great example, but this is something I've been asked for in the past. Users want two named, top-level on-chain objects of the same type. If this is something we want to support, we need to come up with a way to have an arbitrary list of deployed address and their types that isn't necessarily one-to-one with the contracts that exist in the package.

@mhhf
Copy link
Collaborator

mhhf commented Oct 11, 2016

I have some worries about the current approach of addresses in the manifest, mostly because I see the need of environments in a package. As others have stated, there might be packages with addresses on different chains and the argument "just publish them to a registry of the other chain" just works if that package is written solely for the "other chain". What about a package which is supposed to work cross chain and has to have information about multiple environments like a ETC-ETH relay?

Currently we solve this problem in Dapple with environments:

Suppose a package is written for two chains A and B and points to a deployed version of a contract C on both.

Chains A and B can be identified by their genesis block hash + the latest observable block hash, which includes the deployed addresses:

"chains": {
  "A": {
    "0x00": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3",
    "0x1f04f1": "0xf3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9"
  },
  "B": {
    "0x00": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3",
    "0x125f22": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
  }
}

and this makes space for environments:

"environments": {
  "A": {
    "C": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"
  },
  "B": {
    "C": "0xd654bdd32fc99471455e86c2e7f7d7b6437e9179"
  }
}

this allows us do deterministically work with multiple environments in one package. Also this would make the manifest, registry agnostic, at least in terms of addresses.

@pipermerriam
Copy link
Member

@mhhf could this be handled at the package manager level rather than at the manifest level? Here is my thinking.

You've used the term environment so I'll stick with that. I'm thinking that environmental awareness would be better handled at the package manage implementation level than included within the manifest itself. My reasoning is as follows.

  1. If I am installing on the mainnet environment then when I pull a manifest for a dependency then any data in that manifest for other chains is superfluous.
  2. Having environment data in the manifest requires consensus for how we reference the various chains. We have to agree on using strings like 'mainnet', 'testnet'. Not a big deal but different frameworks are already using different terminology and this would add some awkwardness to those implementations if it has to internally translate these before publishing packages.
  3. Moving it down to the package manager level simplifies things while still completely allowing each package manager to have cross-chain environmental awareness.

Thoughts on this?

I really like the idea of the manifest not having cross-chain knowledge. This would allow each package manager to handle multi-chain environments however they would like and eliminate the nee

@mhhf
Copy link
Collaborator

mhhf commented Oct 11, 2016

could this be handled at the package manager level rather than at the manifest level

I'm fine with handling this on the package manager level, however I'm not fine with mixing approaches. e.g having "some" addresses in the manifest. In this case we should move all addresses outside of the manifest.

If I am installing on the mainnet environment then when I pull a manifest for a dependency then any data in that manifest for other chains is superfluous.

I see the overhead as minimal but this is a subjective statement. There are objective reasons to follow this approach like not being required to build the registry on a chain in order for using manifests.

Having environment data in the manifest requires consensus for how we reference the various chains.

We don't need to build this consensus, since the chains are identified by their block hashes like shown here:

"chains": {
  "A": {
    "0x00": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3",
    "0x1f04f1": "0xf3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9"
  },
  "B": {
    "0x00": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3",
    "0x125f22": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
  }
}

Every user and framework is then free to name environments arbitrary

@mhhf mhhf mentioned this issue Nov 2, 2016
@pipermerriam
Copy link
Member

@mhhf I've re-read through this and I think this is a solid approach to defining chains and environments. What I'm thinking about now is whether it makes sense for a package manifest to have data about the package on more than one chain. Here is my thinking.

If each manifest instead defines a single chain using the genesis+latest_block_hash approach, then each of the data structures gets flattened out to the following.

{
  "chain": {
    "0x00": "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3",
    "0x1f04f1": "0xf3f4696bbf3b3b07775128eb7a3763279a394e382130f27c21e70233e04946a9"
  },
  contracts: {
    "MyContract": "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b"
  },
}

I've only just begun thinking about this so I'm unsure about whether this idea of having a manifest per chain causes problems elsewhere, but I do like that it simplifies the overall data contained in the manifest.

@tcoulter
Copy link
Contributor

tcoulter commented Nov 2, 2016

My gut instinct is similar to @pipermerriam's approach. As well, the data in @pipermerriam's comment above shouldn't be added by the user, and instead by the packager. To put this in contrast, here's what npm stores for Truffle: https://registry.npmjs.org/truffle/ (you might want the JSON formatter chrome plugin). You'll notice this is way more data than what I've written in my package.json (e.g., node version). Granted, the link I've provided to you is a list of all released versions of Truffle, but choose a single version and compare it to our manifest; you'll see that npm has added a considerable amount of data about the environment. I think we should do the same thing in our case.

@nmushegian
Copy link
Author

@pipermerriam @tcoulter

That sounds like it could work, could you extend the examples to show how you would address two use cases:

  1. making the eth-usd example depend on the owned example

https://github.com/ethpm/epm-spec/tree/master/use-cases/eth-usd-oracle-example/contracts
https://github.com/ethpm/epm-spec/tree/master/use-cases/owned-example

  1. creating a TokenPairFactory package which gave you tokens 2 at a time like get2FromOtherFactory() returns (Token, Token), constructed from a specific address packaged with a package like ConsenSys/Token-Factory

https://github.com/ConsenSys/Token-Factory

@pipermerriam
Copy link
Member

This is now fully documented in the readme.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants