A private proof of authority blockchain where blocks are SQLite databases, in Go
Documentation and articles:
Private hybrid blockchain & SQL database software usable for distributed data collection, data storage and data distribution. Daisy combines the specific benefits of the blockchain: distributed data collection and data immutability through cryptographic signatures of blocks, with the convenience of SQL databases, which means businesses can more easily adopt it in their existing environments.
What if there is a blockchain where only certain nodes, in possession of one of accepted private keys, can add data (i.e. new blocks) to a blockchain, whose blocks are (SQLite) databases, and where those existing nodes can accept new ones into their ranks by signing the candidate's keys in a web-of-trust style?
What if public (government) documents were distributed in this way...? What if Wikipedia was...?
What if all this doesn't involve just one global blockchain instance but instead is implemented by software which enables multiple blockchains to be instantiated as easily as new Git repos, and just as easily distributed?
Some possible use cases I've thought of for blockchains where everyone can download and verify the data, but only a few parties can publish (which is the model Daisy implements):
The blockchain is basically very well suited to data exchange between otherwise competitive or hostile parties - the "trustless" principle is how Bitcoin manages to work in a really hostile global environment. Daisy could help bridge such environments.
daisy pullcommand similar to "docker pull" which would replicate a blockchain from an existing node
When the command line app is started, Daisy will initialise its databases and install the default blockchain. It will then connect to a list of peers it maintains and fetch new blocks, if any.
All the blocks in the blockchain can be queried at the same time by using a command such as
./daisy query "SELECT COUNT(*) FROM wikinews_titles"(note the quotes!). This will iterate over all the blocks, and in those blocks where the query is successful, will output the results to stdout as JSON objects separated by newlines. Of course, this is limited to read-only queries.
Since this is a private blockchain, not everyone has the ability to create new blocks. I'm thinking of this as a more of a framework for creating new single-purpose blockchain instances. If you want to contribute to the default blockchain (i.e. store data, i.e. add new sqlite databases to the blockchain), run the
./daisy mykeyscommand, send me the public key hash to sign, and an explanation / introductory letter saying why and what do you want to do with it, and I'll sign your key and accept it into the blockchain as one of the signatories.
When you have a private key whose public part is added to the list of signatories, running
./daisy signimportblock mydata.dbwill import the mydata.db file into the blockchain. Before it's imported, the database is modified to contain the Daisy metadata tables.
Basic crypto, block and db operations are implemented, the network part is mostly done. A simple form of DB queries is done. Automated key management operations (i.e. signing someone else's key) are pending (they're manual now).
WARNING: This is mostly alpha quality code.
Talks / presentations I gave about Daisy:
Note: All this is fluid and can be changed as development progresses.
_keystable contains new signatory keys additions and revocations. Both operations must be signed by a number of currently valid signatories, where the number is given as
1 if height < 149 else floor(log(height)*2)
How to deal with blockchain abuse? I.e. one of the signatories turns out to be an adversary? Some ideas:
Blocks are SQLite database files. Every party in posession of an accepted private key (i.e. a signatory) can create new blocks, sign them, and publish them into the peer-to-peer network. Blocks are accepted (if other criteria are satisfied) only if they are signed by one of the accepted keys.
New blocks can contain operations which add or remove keys from a (global) list of accepted keys, if they contain a sufficient number of signatures from a list of already accepted keys. See the
_keystable description in the section on Block metadata.
To be accepted as blocks, the SQLite database files have some soft and hard restrictions:
This table contains key operations for block creators. Keys can be either accepted or revoked. It is invalid for a
_keystable to contain both acceptance and revocation records for a single key. Both acceptance and revocation operations require a quorum, where Q different keys which are already accepted sign the hash of the key in question. The number Q is calculated as:
Q = 1 if H < 149 else floor(log(H)*2)
His the block height of the block containing these records.
For example, if
Qis 3, to add a key
Kto the list of accepted keys, there must be exactly 3 records in the
_keystable pertaining to
K. Each of the records must contain a valid signature by a different, already accepted key. The key
Kcan be then used to sign new blocks immediately after the block which contain this records has been accepted.
A table of quorums required for specific block heights is:
1 1 149 10 245 11 404 12 666 13 1097 14 1809 15 2981 16 4915 17 8104 18 13360 19 22027 20 36316 21 59875 22 98716 23 162755 24
E.g. for block 100000, 23 signatures are required to accept a new signature.
ECDSA P-256 is used for public key crypto operations.
Strings refered in Daisy as "public keys" are SHA256 hashes of public keys and begin with the string "1:" (the 1 is to indicate a key type, should it need to change in the future). They look like "1:9569f0894e3d2b435a4c49c6a97501f4191b9729ff53be5acee2c7bd4be0e439".