ergoplatform / oracle-core

Core off-chain component of Oracle Pools
Apache License 2.0
62 stars 37 forks source link

[300 SigmaUSD] Provide a proof that contracts are coming from EIP-23 #87

Closed greenhat closed 2 years ago

greenhat commented 2 years ago

The proof should be verifiable by anyone.

I'm thinking of hashes of the contracts that are published in the EIP-23 and verified in our tests. I explained this idea in more detail at https://github.com/ergoplatform/ergo-playgrounds/issues/25. Which should be implemented as a part of this issue.

SethDusek commented 2 years ago

Hmm, what if instead of using plutomonkey to give P2S addresses, we store the eip23 contracts as part of oracle-core source code, and use node to compile them? The node API doesn't have any way to pass constants directly, but it could be done with string substitution I suppose, so Pool contract would be something like:

{
  // This box (pool box)
  //   epoch start height is stored in creation Height (R3)
  //   R4 Current data point (Long)
  //   R5 Current epoch counter (Int)
  // 
  //   tokens(0) pool token (NFT)
  //   tokens(1) reward tokens
  //   When initializing the box, there must be one reward token. When claiming reward, one token must be left unclaimed   

  val otherTokenId = INPUTS(1).tokens(0)._1
  val refreshNFT = fromBase64({refreshNftInput})
  val updateNFT = fromBase64({updateNftInput})

  sigmaProp(otherTokenId == refreshNFT || otherTokenId == updateNFT)
}

After replacing the {} parameters, it could be compiled. This would also make it easier to provide new contracts, since currently it can be a bit tricky for a new user to create a contract, and figure out the indices for constants. The downside I see is that this would require a Node API call, but the contracts could be cached for the same inputs somewhere.

greenhat commented 2 years ago

@SethDusek Interesting! I've never thought of using the node for ErgoScript compilation. Constant substitution is not a problem. We can do it in the compiled tree like we're doing it now. However, I see the following cons:

kettlebell commented 2 years ago

Will work on this.

kettlebell commented 2 years ago

@greenhat, I think we need a place to hold the actual contracts as separate files so that we can link directly to them once https://github.com/ergoplatform/ergo-playgrounds/pull/26 is merged. The ergoplatform/eips repo just has *.md files. Maybe we can create a directory for eip-0023?

greenhat commented 2 years ago

Good idea! Please, do a PR for eip-23 PR. Ideally, we'd want to render contract code from a separate file in the eip md file along with a contract hash and link to scastie to verify this hash.

kettlebell commented 2 years ago

Markdown only allows embedding of external things via raw HTML tags. We can use permalinks to code and Github renders it like follows: https://github.com/kettlebell/rust_hello_world

It looks a bit ugly though, and you can't control the height of the code snippet from what I see. What do you think?

kettlebell commented 2 years ago

But you do get syntax highlighting and line numbers which can be useful when discussing aspects of the contracts with others.

greenhat commented 2 years ago

Although it does not look all that pretty it has a link to the whole file so it should be fine.

kettlebell commented 2 years ago

Sure. The link is also tied to the commit hash, so we'll need to be careful to update the links on each contract modification.

greenhat commented 2 years ago

Sure. The link is also tied to the commit hash, so we'll need to be careful to update the links on each contract modification.

I see the problem with using links with commit hashes. Contract edits during the PR lifecycle will not be shown unless link in the EIP file is updated. I'd rather use link relative to the EIP file.

kettlebell commented 2 years ago

Yeah agreed. Ok, I'll try to get it working with HTML.

kettlebell commented 2 years ago

@SethDusek not sure where your comment went but I like the submodule approach. The verification through scastie should actually be placed in oracle-core, since operators will come here for the binary and instructions. The EIP markdown file stands alone as the authoritative source. Maybe we can modify ergo-playgrounds to load the EIP markdown file, parse out the contracts, then process it all in a single hit?

I tried embedding <object> tags in the markdown file to bring in external text, but it doesn't work. Not surprising, it's a really bad idea security-wise.

greenhat commented 2 years ago

@SethDusek not sure where your comment went but I like the submodule approach. The verification through scastie should actually be placed in oracle-core, since operators will come here for the binary and instructions. The EIP markdown file stands alone as the authoritative source. Maybe we can modify ergo-playgrounds to load the EIP markdown file, parse out the contracts, then process it all in a single hit?

When I made this issue, I focused not solely on verifying oracle contracts but on building a framework/workflow for checking any contracts against EIPs(or published by other means) in any off-chain code. My thinking was to show the contract's hash in the EIP file and then check the same hash somehow in the off-chain code. In our case, it might be a unit test loading the contract from default_parameters.rs and checking its hash against the expected as a hard-coded string. Thus, anyone can check the hash in the EIP file with the hard-coded expected hash in our unit test.

I tried embedding <object> tags in the markdown file to bring in external text, but it doesn't work. Not surprising, it's a really bad idea security-wise.

We can scrap the idea of inlining contract code into EIP md file and go with links. I mean, sooner or later, we'd want to analyze contracts in EIPs with external tools, so we'd have to throw away inlining anyway.

kettlebell commented 2 years ago

Sounds good. I've made the PR: https://github.com/ergoplatform/eips/pull/78, the changed section looks as follows: https://github.com/ergoplatform/eips/blob/fec79b7e72c017d02aa799b3748ae845c02f8874/eip-0023/eip-0023.md#contracts-with-base-64-encoded-hash-of-ergo-tree-bytes.

Also I've taken your idea of the unit test and packaged it as a separate command in the binary. This allows operators to check it without having to compile the binary. (see https://github.com/ergoplatform/oracle-core/pull/105)

Once the PR + eip23 branch is merged, we can add the scastie verification links (need to have a stable URL for the contracts).

greenhat commented 2 years ago

EIP PR looks excellent! I guess it's as far as we can go with scastie. I guess a proper web service will emerge if this workflow gets wide adoption. It might work similarly to those badges (coverage, versions, etc.).

kettlebell commented 2 years ago

It'd be cool to have a badge for it.

greenhat commented 2 years ago

The bounty is sent. Thank you!