npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@summa-tx/bitcoin-spv-sol

v4.0.1

Published

bitcoin SPV proofs in Solidity

Downloads

1,391

Readme

Bitcoin SPV Proofs in Solidity

What is it?

bitcoin-spv is a collection of Solidity libraries for working with Bitcoin transactions in Solidity contracts. Basically, these tools help you parse, inspect, and authenticate Bitcoin transactions.

Supported by

Summa, Cross Chain Group


IMPORTANT WARNING

It is extremely easy to write insecure code using these libraries. We do not recommend a specific security model. Any SPV verification involves complex security assumptions. Please seek external review for your design before building with these libraries.

Breaking changes from 1.x:

  • Merkle proof indexes are 0-indexed (like they should have been all along)
  • Merkle proofs for ValidateSPV#prove no longer require the leaf or root hash

Solidity Compiler

Starting from version 1.1.0, required solidity compiler (solc) version is at least 0.5.10.

How are proofs formatted?

An SPV interaction has two players: a prover and a verifier. The prover submits an SPV proof, and the verifier checks it.

The proof must contain several elements: a transaction, an inclusion proof, and a header chain. For convenience and gas minimization, we have a standard format for these:

  1. The transaction is pre-parsed by the prover into 4 elements:
    1. The transaction version (currently always 1 or 2 as a 4-byte LE integer)
    2. The variable-length input vector
      1. No more than 0xfc inputs
      2. Prefixed with the number of inputs
      3. Tightly packed in a single bytearray called vin
    3. The variable-length output vector
      1. No more than 0xfc outputs
      2. Prefixed with the number of inputs
      3. Tightly packed in a single bytearray called vout
    4. The transaction locktime (a 4-byte LE integer)
  2. The header chain:
    1. Contains any number of 80-byte headers
    2. Is a single bytearray without prefix or padding
    3. Starts from the lowest height
    4. Must form a logical hash-linked chain
  3. The merkle inclusion proof, which contains 2 elements:
    1. The merkle branch containing any number of 32-byte double-sha2 digests
      1. In a single bytearray, without prefix or padding
      2. Ordered from leaf to root (but does not include leaf or root)
    2. The index of the leaf in the tree (an integer)

While the prover is off-chain, and makes Ethereum transactions, the verifier is implemented as a solidity contract that validates proofs contained in those transactions. The verifier must set one parameter on-chain: the required total work, expressed as accumulated difficulty. The verifier sums difficulty across the header chain by measuring the work in its component headers. In addition, the verifier may set any number of other acceptance constraints on the proof. E.g. the contract may check that the vout contains an output paying at least 30,000 satoshi to a particular scriptPubkey.

Why is there a library and a Delegate?

1.0.0 was accessible only by the EVM's DELEGATECALL. For v2.0.0 we give you the option to use DELEGATECALL or to compile the library methods into your contract.

Compiling them in will save several hundred gas per invocation. That's significant for higher-level functions like prove in ValidateSPV. But it does add additional deployment cost to your contracts.

If you're using the Delegate, make sure to add a linking step to your deployment scripts. :)

Usage Example:

import {BTCUtils} from "./contracts/BTCUtils.sol";
import {BTCUtilsDelegate} from "./contracts/BTCUtilsDelegate.sol";


contract CompilesIn {
    using BTCUtils for bytes;

    function multiHash(bytes memory _b) {
        return keccak256(_b.hash256());  // Compiled In
    }

}

contract DelegateCalls {
    using BTCUtilsDelegate for bytes;

    function multiHash(bytes memory _b) {
        return keccak256(_b.hash256());  // DELEGATECALL
    }
}

contract MixedAccess {

    function multiHash(bytes memory _b) {
        return keccak256(BTCUtils.hash256(_b));  // Compiled In
    }

    function multiHashWithDelegate(bytes memory _b) {
        return keccak256(BTCUtilsDelegate.hash256(_b)); // DELEGATECALL
    }

}

Deployed Instances (for DELEGATECALLs)

| Contract | Version | Solc | Main | Ropsten |-------------|---------|-----------|----------------------------------------------|------------------------------------------- | ValidateSPV | 1.0.0 | v0.4.25 | 0xaa75a0d48fca26ec2102ab68047e98a80a63df1d | 0x112ef10aef3bde1cd8fd062d805ae8173ec36d66 | BTCUtils | 1.0.0 | v0.4.25 | 0xD0d4EA34e4a5c27cA40e78838a4Ed5C1bB033BbC | 0x7a79d4112d79af980e741e0b10c47ffa543cc93a | BytesLib | 1.0.0 | v0.4.25 | 0x302A17fcE39E877966817b7cc5479D8BfCe05295 | 0xcc69fec9ba70d6b4e386bfdb70b94349aff15f53 | ValidateSPV | 1.1.0 | v0.5.10 | NOT YET DEPLOYED | NOT YET DEPLOYED | BTCUtils | 1.1.0 | v0.5.10 | NOT YET DEPLOYED | NOT YET DEPLOYED | BytesLib | 1.1.0 | v0.5.10 | NOT YET DEPLOYED | NOT YET DEPLOYED | ValidateSPV | 2.0.0 | v0.5.10 | NOT YET DEPLOYED | NOT YET DEPLOYED | BTCUtils | 2.0.0 | v0.5.10 | NOT YET DEPLOYED | NOT YET DEPLOYED | BytesLib | 2.0.0 | v0.5.10 | NOT YET DEPLOYED | NOT YET DEPLOYED

Development Setup

By default, you must run an instance of ganache-cli (or some other ganache VM) when running tests.

$ npm run compile # truffle compile
$ npm run test # truffle test
$ npm run coverage