Skip to content
Scala implementation of the Bitcoin Cash protocol
Scala Java
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
core-gen
core-test
core
doc
project
rpc
secp256k1 @ 54c4572
secp256k1jni
.gitignore
.gitmodules
.jvmopts
.travis.yml
BUILD_README.md
LICENSE
README.md
build.sbt
inThisBuild.sbt
version.sbt

README.md

Build Status Coverage Status Gitter chat

scash

this is a fork of bitcoin-s which is a library for bitcoin core. Work is still on the way to have a final product that fully supports all BCH features. Here is where we are at the moment: (WIP) enabling all current BCH functionality

This is the core functionality of scash.

This repostitory includes the following functionality:

Design Principles

  • Immutable data structures everywhere

  • Functional Programming (FP) following these 3 properties (WIP):

    • Totality
    • Determinism
    • No Side Effects
  • Algebraic Data Types to allow the compiler to check for exhaustiveness on match statements

  • Using property based testing to test robustness of code

Setting up libsecp256k1

libsecp256k1 needs to be built with the java interface enabled. Use the following commands to build secp256k1 with jni enabled. Here is the official documentation for doing this in secp256k1

$ cd secp256k1
$ sh autogen.sh && ./configure --enable-jni --enable-experimental --enable-module-ecdh && make
$ sudo make install #optional, this installs the lib on your system

By default, .jvmopts adds the freshly compiled secp256k1 to the JVM classpath. It should therefore be sufficient to start sbt by simply doing

$ sbt

If you run into classpath problems, you can manually specify the JVM classpath like this:

$ sbt -Djava.library.path=/your/class/path 

You can also copy libsecp256k1.so to your system library path.

TODO

Things to be done after BCH support

  • rewrite API to be FP principled
  • introduce FP friendly libraries
  • spv node scashspv

Creating fat jar

Here is how you build a scash fat jar file. Note this command will run the entire test suite in scash.

$ sbt assembly
...
[info] Merging files...
...
[info] Done packaging.

Examples

Every bitcoin protocol data structure (and some other data structures) extends NetworkElement. NetworkElement provides easier methods to convert the data structure to hex or a byte representation. When paired with our Factory we can easily serialize and deserialize data structures. Most data structures have companion objects that extends Factory to be able to easily create protocol data structures. An example of this is the ScriptPubKey companion object. You can use this companion object to create a SPK from hex or a byte array.

Transactions are run through the interpreter to check the validity of the Transaction. These are packaged up into an object called ScriptProgram, which contains the following:

  • The transaction that is being checked
  • The specific input index that it is checking
  • The scriptPubKey for the crediting transaction
  • The flags used to verify the script

Here is an example of a transaction spending a scriptPubKey which is correctly evaluated with our interpreter implementation:

sbt console
...

scala> import org.scash.core.protocol.script._
scala> import org.scash.core.protocol.transaction._
scala> import org.scash.core.script._
scala> import org.scash.core.script.interpreter._
scala> import org.scash.core.policy._

scala> val hexTx = hex"0100000000001ccf3...."
hexTx: ByteVector = ByteVector(...)
scala> val spendingTx = Transaction(hexTx)
scala> val scriptPubKey = ScriptPubKey("76a91431a420903c05a0a7de2de40c9f02ebedbacdc17288ac")
scriptPubKey: ScriptPubKey = P2PKHScriptPubKeyImpl(76a91431a420903c05a0a7de2de40c9f02ebedbacdc17288ac,List(OP_DUP, OP_HASH160, BytesToPushOntoStackImpl(20), ScriptConstantImpl(31a420903c05a0a7de2de40c9f02ebedbacdc172), OP_EQUALVERIFY, OP_CHECKSIG))

scala> val inputIndex = 0

scala> val program = ScriptProgram(spendingTx,scriptPubKey,inputIndex, Policy.standardScriptVerifyFlags)
scala> ScriptInterpreter.run(program)
res0: ScriptResult = ScriptOk

Running tests

To run the entire test suite all you need to do is run the following command

sbt test
...
[info] All tests passed.
[info] Passed: Total 909, Failed 0, Errors 0, Passed 909

To run a specific suite of tests you can specify the suite name in the following way

sbt
> testOnly *ScriptInterpreterTest*
...
[info] All tests passed.
>

Stand alone SPV Node

Please see our other project scashspv

You can’t perform that action at this time.