Skip to content
/ koyn Public

A trustless and decentralized Bitcoin library for Arduino compatible boards

License

Notifications You must be signed in to change notification settings

elkrem/koyn

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Koyn: Bitcoin Library For Arduino Build Status

Overview

A fully decentralized and trustless Bitcoin light (aka SPV) client implementation for the Arduino platform based on Electrum protocol.

With its simple and easy-to-use API, it allows you to interface Arduino boards to the Bitcoin network. The sky is the limit, you can either do a physical action when a transaction is made or send transactions based on hardware events.

Readiness

The library should be working but it is still rough around the edges. It is considered to be a work-in-progress. It is by all means far from being production ready. It hasn't been thoroughly tested or gone through security reviews.

Currently, it can only works with Bitcoin testnet (no mainnet support yet). Be advised not to use real Bitcoins. We are not responsible for any loss of funds so use it at your own risk.

Arduino boards support is initially limited as well, please check below for more info.

Also, the public interface hasn't been finalized yet, it can be changed a bit during the initial releases.

Light Clients

Light Bitcoin clients (nodes) doesn't store the full transaction history (blockchain) of the network (unlike full clients). They only download the headers (80 bytes every ~10 minutes) of the created blocks to be able to verify that a particular transaction was indeed included and accepted by the network. The concept is often referred to by the term SPV (Simplified Payment Verification).

There are two popular protocols for SPV clients. Bitcoin Core and Electrum, they pretty much have the same concept. The core protocol works with raw bytes and Electrum is JSON based. This library supports only Electrum protocol for now, thus it only works with Electrum servers.

Hardware Requirements

The library requires an ESP8266 or ESP32 based board connected with an SPI microSD card module to work.

The microSD card needs to be a single partition, FAT formatted, fast (class 10) and has at least 1GB of space. It doesn't need to be empty as we create a new directory on its root named koyn.

Boards Support

These boards have been tested and are known to work:

ESP8266

  • Adafruit Huzzah ESP8266
  • Wemos D1
  • SparkFun ESP8266 Thing
  • NodeMCU

ESP32

  • DOIT ESP32 DEVKIT V1
  • ESPDUINO-32
  • SparkFun ESP32 Thing

These microSD card boards has been tested and known to work:

  • Wemos Micro SD Card Shield
  • SparkFun microSD Shield

Installation

Make sure you have the latest version of Arduino IDE with either ESP8266 or ESP32 cores installed.

Using Library Manager (Recommended)

Open the Arduino IDE, go to Sketch > Include Library > Manage Libraries.

And then, search for our library in the list, pick the latest version and click install.

Manual Method

Download the latest version of the library from the releases page. Unzip it in a new directory named Koyn inside your Arduino's libraries directory.

PlatformIO

If you are using PlatformIO, the library can be installed from their library manager as well, just search for Koyn.

Blockchain Headers Syncing

You can choose to sync and validate the headers on the board directly starting from the genesis block, but it can take from tens of minutes to hours depending on your sketch and network conditions.

So it is advised to preload the microSD card with the latest headers on a host machine before hand using one of the methods below, then rename it to blkhdrs and place it in /koyn directory on the microSD.

Using Our Tool (Recommended)

We developed a command line tool based on BitcoinJ library that validates and downloads the Bitcoin blockchain headers to a file on your local machine.

First make sure you have a Java Runtime Environment installed on your host machine and accessible from your PATH. Then download the latest release of our tool. Then run the executable or call java -jar koyn-sync-VERSION.jar from a command line terminal. (Make sure you are connected to the Internet, and the working directory is writable)

The tool will download the headers to your working directory and create either ./koyn/mainnet/blkhdrs or ./koyn/testnet/blkhdrs depending on the supplied flags. (Logging messages will show its progress)

From Electrum Website

If you trust Electrum.org, you can download the headers directly from their website and the library will sync the rest of the headers when started.

From Electrum App

Install Electrum client on your machine if you don't have it, run it, let it sync.

You may need to supply --testnet parameter before running the Electrum executable if you need to sync the testnet headers.

On Windows, the headers file is located in %APPDATA%\Electrum\blockchain_headers or %APPDATA%\Electrum\testnet\blockchain_headers if you are using the testnet. On Mac and Linux, the headers file is located in ~/.electrum/blockchain_headers or ~/.electrum/testnet/blockchain_headers if you are using the testnet.

Note: Electrum versions >=3.1.0 does not sync the headers from the genesis block and rely on the concept of checkpoints. So to sync using Electrum please use version below 3.1.0.

Usage

We tried to make our API as simple as possible, here are some samples.

Bare Minimum

#include "Koyn.h"

void setup() {
  Koyn.begin();
}

void loop() {
  Koyn.run();
}

Transaction Signing and Broadcasting

BitcoinAddress myAddress("PRIVATE_KEY", KEY_PRIVATE);
Koyn.trackAddress(&myAddress);
BitcoinAddress myFriendAddress("BITCOIN_ADDRESS", ADDRESS_ENCODED);
Koyn.spend(&myAddress, &myFriendAddress, 100000000, 100000);

Transactions Tracking

void paymentCallback(BitcoinTransaction tx){

}
Koyn.onNewTransaction(&paymentCallback);
if(Koyn.isSynced()){
    Koyn.trackAddress(&myAddress);
}

Complete Example: Flash a light bulb with Bitcoin

#include <Koyn.h>

#define LIGHT_BULB 13
#define PAYMENT_VALUE 1000000

BitcoinAddress myAddress("PRIVATE_KEY", KEY_PRIVATE);
BitcoinAddress myFriendAddress("BITCOIN_ADDRESS", ADDRESS_ENCODED);

void setup() {
  pinMode(LIGHT_BULB, OUTPUT);
  ..
  .. Connect to WiFi
  ..
  Koyn.begin(false);
  Koyn.onNewTransaction(&paymentCallback);
}

void loop() {
  if(Koyn.isSynced()){
    Koyn.trackAddress(&myAddress);
  }
  Koyn.run();
}

void paymentCallback(BitcoinTransaction tx){
  for(int i=0;i<tx.getInputsCount();i++)
  {
    BitcoinAddress from;
    tx.getInput(i, &from);
    if(from == myFriendAddress){
      for(int j=0;j<tx.getOutputsCount();j++)
      {
        BitcoinAddress to;
        tx.getOutput(j, &to);
        if(to == myAddress){
          if(tx.getOutputAmount(j) == PAYMENT_VALUE){
              digitalWrite(LIGHT_BULB, HIGH);
              Koyn.delay(1000);
              digitalWrite(LIGHT_BULB, LOW);
          }
          else{
              Koyn.spend(&myAddress, &myFriendAddress, tx.getOutputAmount(j), 100000);
          }
        break;          
        }
      }
      break;
    }
  }
}

Supported Networks

  • Bitcoin Testnet
  • Bitcoin Mainnet
  • Bitcoin Cash

Examples

Examples that cover most of our APIs can be found here.

Documentation

Documentation for all of the usable public methods, classes and configuration can be found in our Wiki.

Configuration And Defaults

Most of the hardcoded library defaults and configuration parameters can be edited here.

Debug messages can be enabled on the default Serial interface through the same file as well by uncommenting #define ENABLE_DEBUG_MESSAGES line.

Status and Roadmap

  • Connects to multiple Electrum servers.
  • Validates the headers one by one starting from the genesis block.
  • Downloads (syncs) the latest blockchain headers and validates them.
  • Track transactions to user's addresses.
  • Validates incoming transactions and making sure they were accepted by the network.
  • Sign and send transactions (from user's addresses) to the network.
  • Support headers checkpoints.
  • Support Bitcoin mainnet.
  • Support additional WiFi connected Arduino boards.
  • Support custom transactions.
  • Support P2SH transactions.
  • Support SegWit transactions and addresses.
  • Support hierarchical deterministic wallets (BIP32).
  • Support mnemonic seed wallets (BIP39).
  • Support logical hierarchy for deterministic wallets (BIP44).
  • Add APIs to ease the workflow of payment channels.
  • Add APIs to ease the prototyping of hardware wallets.

Notes and Caveats

  • Only P2PKH transactions and addresses are supported.
  • Only non-SegWit transactions and addresses are supported.
  • Only addresses generated from compressed public keys are supported.
  • The library connects to non-TLS Electrum servers only.
  • The library connects to a hardcoded list of bootnodes only for now, the server.peers.subscribe call hasn't been implemented yet.
  • The library works with Bitcoin testnet only for now.
  • The library does cache private keys in memory.
  • The library doesn't support true random generators yet (generated private keys and addresses rely on analog pin #0 noise).
  • Due to the limitation of hardware, there are some constraints on transaction sizes, tracked addresses number, transactions number kept in memory and others (Their defaults can be overwritten in Config.h file)

Acquiring Testnet Bitcoins

Testnet bitcoins can be easily acquired using online faucets like this and this.

Changelog

To see what has changed in recent versions of Koyn library, see the change log.

Contributing

We welcome all contributions from our community. If you've find a bug or can improve the code or want to add a new feature, please follow our contributions guidelines.

Learn More

Be the first to know about our future blockchain connected hardware products by subscribing to our mailing list at Elkrem.io.

Attributions and Credits

License and Copyright

This code is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General
Public License version 3 only, as published by the Free Software Foundation.

This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
version 3 for more details (a copy is included in the LICENSE.md file that accompanied this code).