bob-collective / bob

BOB is a hybrid L2 that combines the security of Bitcoin with the versatility of Ethereum.
https://app.gobob.xyz/
83 stars 41 forks source link

zkVM POC: Port an ordinals indexer to zkVM #3

Closed nud3l closed 1 year ago

nud3l commented 1 year ago

Is your feature request related to a problem? Please describe. One major drawback of overlay protocols like ordinals is that the data is not subject to Bitcoin consensus and thus BRC20 and ord NFT require additional verification by some entity. In practice, these are either trusted third parties or some form of committees that act as TTP. There are several issues with this as the TTP or committee can change the way the data is interpreted and in the committee setting, disagreements might occur between the members which would require implementing some form of consensus protocol to resolve the disagreements.

Describe the solution you'd like zkVM allows executing off-chain code written in Rust with an on-chain component in Solidity. It might be an avenue to enable Rust off-chain contracts together with a counterpart Solidity contract on the EVM side.

Port an ordinals indexer to zkVM. Porting an indexer in zkVM is an alternative to using some form of committee/TTP. zkVM would allow anyone to submit a bitcoin block that includes some ordinals following various standards and then verify that the ordinals inside are correctly processed by the indexer. The STARK proof can be verified by anyone and zkVM also gives you back return values, e.g., BRC20 deposits/withdrawals between a rollup that would support zkVM. If eventually BTC would support a ZK verify op code, you could also verify it there.

The approch is inspired by Zeth (https://www.risczero.com/news/zeth-release) to work with ord indexers/bitcoin instead of ethereum.

My hope is to understand the following:

nud3l commented 1 year ago

Rust Starter template and Foundry template should have information on how to connect everything together.

Here are the best places to get started: https://dev.risczero.com/bonsai/quickstart https://github.com/risc0/risc0/tree/main/templates/rust-starter https://api.bonsai.xyz/swagger-ui/

gregdhill commented 1 year ago

Joint investigation by @gregdhill and @sander2:

Port an ordinals indexer to zkVM

Allow anyone to submit a bitcoin block that includes some ordinals following various standards and then verify that the ordinals inside are correctly processed by the indexer

If we use the existing SPV relay to prove a block is valid, then parsing any inscriptions inside that block is trivial. The issue is with ordinals and determining their lineage, which depends on the contents of previous blocks. To do this in zkVM we need to store state similar to how Bitcoin Core / ord keeps the transaction history.

The problem is that we cannot store state in zkVM since it only verifies computation. Any state has to be passed as input, ZETH does this by passing a (succinct) DB state and then verifies block construction over that. We cannot feasibly supply this state via Solidity since it is too big - we would have to pass both the full Bitcoin block (~4 MB) and the ordinals DB of the previous block (this would contain the latest state of every ordinal at that height).

There exists one workaround:

  1. zkVM guest program updates Ordinal DB + outputs hash of DB state (Solidity relay stores the hash in the callback)
  2. Off-chain component submits Ordinal DB state. After completion, it stores the new DB and the Solidity contract waits for callback to update latest hash
  3. We need to maintain linearly growing list of Ordinal state hashes for future verification and somehow handle forks
  4. User wants to verify Ordinal transfer at some height (provides state hash and transaction) we still can’t submit Ordinal state via Solidity so we require two-step process:
    1. User requests proof of transfer (emit event containing Ordinal state hash and Txid)
    2. Off-chain client reads the event and calls bonsai on behalf of the user, fetching the ordinal state given the hash and passing it to the guest program.
    3. Solidity contract registers callback which passes the result back, guest program emits Ordinal state hash for verification

Problems

NOTE: We can already use zkVM for some other problems, for example we were able to move the OKD logic into a guest program. It was not possible to use the rust-bitcoin secp256k1 C lib due to compilation issues but for a toy example the Parity library worked well.

BRC20

The goal of verifying BRC-20 transfers can be achieved in one of three ways:

  1. Seller puts order with inscription (taproot UTXO) containing brc20 transfer + amount
  2. Buyer checks (off-chain) that brc20 balance is valid and accepts
  3. Seller spends that output and provides proof (we check it transfers the linked output and the new inscription is valid)

This is very simple to build but there are a few caveats: