Skip to content
This repository has been archived by the owner on Oct 4, 2019. It is now read-only.

ECIP-1046: Precompiled contract for verification of Merkle Inclusion Proofs #97

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
89 changes: 89 additions & 0 deletions ECIPs/ECIP-1046.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
### Title

ECIP: 1046
Title: Precompiled contract for verification of Merkle Inclusion Proofs
Authors: Kostis Karantias <kkarantias@gmail.com>, Dionysis Zindros <dionyziz@gmail.com>
Status: Draft
Type: Standard
Created: 2018-08-02

# ECIP 1046 - Precompiled contract for Merkle Inclusion Proofs

## Abstract

Verification of Merkle Inclusion Proofs is obviously possible in EVM bytecode.
However, the gas cost for such an operation is very high.

We propose adding this functionality to Ethereum Classic as a precompiled
contract in order to combat this cost.

## Motivation

Interoperability is a very important goal for Ethereum Classic. We believe that
having a way to efficiently tell whether a transaction is included in a
Bitcoin/Bitcoin Cash block by utilizing only the block's Merkle Tree Root and a
short proof is a great first step in that direction.

Moreover, new efficient constructions which enable cross-chain asset transfers
like [NIPoPoWs](https://nipopows.com/) heavily rely on Merkle Inclusion Proofs.

## Specification

If `block.number >= MERKLE_FORK_BLKNUM`, add a precompiled contract for Merkle
Inclusion Proofs (`MERKLEVERIFY`).

The proposal adds a new precompiled function `MERKLEVERIFY` with the following input and output.

`MERKLEVERIFY` takes as **input at least 72 bytes**:

1. **root hash**: the 256-bit merkle tree root hash
2. **leaf**: the 256-bit leaf we want to prove is included in the merkle tree
3. **leaf index**: the 64-bit index of the leaf
4. **siblings**: an array of 256-bit values, arranged from the leaves to the root

`MERKLEVERIFY` returns as **output 4 bytes**:

* `0x00000000` if the proof is valid
* any non-zero value indicates an invalid proof

### Address

The address of `MERKLEVERIFY` is **`0x9`.**

### Gas costs

Gas cost for `MERKLEVERIFY` is **????**.

## Implementation

The hash function used is `SHA256(SHA256(_))`, to be compatible with Bitcoin/Bitcoin Cash.

The merkle tree construction assumed is described in detail in the [Bitcoin
Developer Reference](https://bitcoin.org/en/developer-reference#merkle-trees).

Here follows an example implementation of the verification in Solidity:

```solidity
function merkleVerify(bytes32 root, bytes32 leaf, bytes8 leafIndex, bytes32[] siblings)
pure
public
returns (bool verificationSucceeded)
{
bytes32 h = leaf;
for (uint i = 0; i < siblings.length; ++i) {
bool siblingOnTheLeft = leafIndex & 0x1 == 1;
if (siblingOnTheLeft)
h = sha256(abi.encodePacked(sha256(abi.encodePacked(siblings[i], h))));
else
h = sha256(abi.encodePacked(sha256(abi.encodePacked(h, siblings[i]))));
leafIndex >>= 1;
}
return h == root;
}
```

## References

- [NIPoPoWs](https://nipopows.com/)
- [Original Solidity implementation](https://github.com/dionyziz/popow/blob/c82349f870eece524fc027ec787a8b3f3295d566/experiment/contractNipopow.sol#L242-L255)
- [Bitcoin Developer Reference](https://bitcoin.org/en/developer-reference#merkle-trees)