GithubHelp home page GithubHelp logo

bitcom's People

Contributors

mathiasrw avatar unwriter avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

bitcom's Issues

Bit init error

After running bit init command, I get following error.

/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/bitcore-explorers/lib/insight.js:138
      throw e;
      ^
Invalid Argument
Error
    at new NodeError (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/bitcore-lib/lib/errors/index.js:20:41)
    at Object.checkArgument (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/bitcore-lib/lib/util/preconditions.js:14:13)
    at new AddressInfo (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/bitcore-explorers/lib/models/addressinfo.js:20:5)
    at Function.AddressInfo.fromInsight (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/bitcore-explorers/lib/models/addressinfo.js:33:10)
    at Request._callback (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/bitcore-explorers/lib/insight.js:133:26)
    at Request.self.callback (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/request/request.js:185:22)
    at Request.emit (events.js:321:20)
    at Request.<anonymous> (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/request/request.js:1154:10)
    at Request.emit (events.js:321:20)
    at IncomingMessage.<anonymous> (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/request/request.js:1076:12) {
  message: 'Invalid Argument',
  stack: 'Invalid Argument\n' +
    'Error\n' +
    '    at new NodeError (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/bitcore-lib/lib/errors/index.js:20:41)\n' +
    '    at Object.checkArgument (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/bitcore-lib/lib/util/preconditions.js:14:13)\n' +
    '    at new AddressInfo (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/bitcore-explorers/lib/models/addressinfo.js:20:5)\n' +
    '    at Function.AddressInfo.fromInsight (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/bitcore-explorers/lib/models/addressinfo.js:33:10)\n' +
    '    at Request._callback (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/bitcore-explorers/lib/insight.js:133:26)\n' +
    '    at Request.self.callback (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/request/request.js:185:22)\n' +
    '    at Request.emit (events.js:321:20)\n' +
    '    at Request.<anonymous> (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/request/request.js:1154:10)\n' +
    '    at Request.emit (events.js:321:20)\n' +
    '    at IncomingMessage.<anonymous> (/Users/oscar/.nvm/versions/node/v13.7.0/lib/node_modules/bitcom/node_modules/request/request.js:1076:12)'
}

Not working anymore since network upgrade

Bitcom OP_RETURNs should include OP_FALSE as the first character. Bitcom is still using and old version of the datapay library which has not been updated to include OP_FALSE.

Bitcom Protocol Prefix space efficiency

Currently a base58 encoded bitcoin address is used as a protocol identifier.

For example WeatherSV uses "1LtyME6b5AnMopQrBPLk4FGN8UBuhxKqrn", a 34 byte string. In its raw form, this data requires 25 20 bytes.

Base58 Pro's - inbuilt checksum, human readable (kind of)
Base58 Con's - it's big

Is it worth switching to the raw form for efficiencies sake?

Login command

I have an existing BitCom prefix which is created before. Now I'm using another computer and I'd like to login.
Is there any way to login? I only have BitCom prefix address.

Bitcom Unix Pipeline

Unix Pipeline in OP_RETURN

Example: "Upload a video, store its filename and frame rate, and then set admin rights, all in a single transaction, but using 3 separate protocols."

OP_RETURN 
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] video/mp4 |
  1EKrfyTD6UoXR85vpfxZ7e8h2h8C5XEroy video.mp4 60 |
  1M16gTfEL8f6SkXnTzBepF56KDNG9Qka7Y SET ADMIN

Following the Unix Pipe (|) system design, we can:

  1. Not only pipe multiple OP_RETURN protocols together in a single atomic transaction
  2. But also embed a piece of executable code into push data that will generate outputs.

This spec proposal is inspired by


This pipeline idea DOES NOT require mandatory usage of the Bitcom convention (Usage of Bitcoin address as "prefix" instead of using a centralized registry), any protocol can adopt this today.

But the Bicom CLI intends to implement this, and will be much more synergistic if the protocols that adopt this pipeline scheme adopt the Bitcom convention since the pipeline proposal assumes a world where there are infinite number of protocols, which isn't possible if all protocols are managed in a central repository, in a human curated fashion.

The pipeline can potentially solve the immediate problem of:

  1. How to "scale" the B:// protocol without introducing technical debt
  2. while giving room for extreme flexibility, such as adding filename or fps (frames per second), resolution, etc.

The key insight of Bicom pipeline:

  • We have started looking at Bitcom as an "embeddable OS" instead of Bitcom itself being a standalone protocol.
  • Following the Unix Philosophy, each module (a protocol) stays as simple as possible and as modular as possible.
  • Simply adopting the "convention", any OP_RETURN protocol can communicate with other app protocols, just like how Unix pipeline allows various Unix programs to intercommunicate through pipes.

How it Works

You can pipe two protocols together like unix programs.

Let's think of the B:// protocol for example.

Instead of packing every possible metadata into the single protocol, we could:

  1. keep B very minimal: Only keep the [DATA] and [Content-Type]
  2. And use the pipeline system to pass the Blob into another protocol.

Example

Before

Without a pipeline feature, whenever we want to add a new feature or an attribute, we will have to extend the base protocol itself, and the protocol will become larger and larger as time goes on, collecting technical debt, and become a nightmare to maintain:

OP_RETURN 19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] image/png binary flower.png ...

But what if we can make each protocol as minimal as possible, and then pipe them into one another?

After

With a piping feature, we could create a combination of two or more protocols that pipe linearly from one to the next:

  1. A protocol to write raw blob using B://
  2. A protocol to write metadata
  3. A protocol to assign property rights
  4. etc.

1. Write File

We can write a file using the same simple B:// protocol:

OP_RETURN 19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] video/mp4

Now, the protocol ONLY has 2 arguments: DATA and Media Type.

The rest can be determined by passing the B:// output to another protocol and let them take care of it. For example let's say we want to create a video storage system:

2. Write Metadata

Let's think of a hypothetical protocol that lets you:

  1. Take ANY input object
  2. Attach more metadata to it
  3. And return the resulting object

It would be like JavaScript's Object.assign()

For example, the following command is executed independently,

OP_RETURN 1EKrfyTD6UoXR85vpfxZ7e8h2h8C5XEroy video.mp4 60

It would return an object with the video.mp4 and 60 as attributes.

However if we pass in the File object from the b:// protocol, like this:

OP_RETURN
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] video/mp4 |
  1EKrfyTD6UoXR85vpfxZ7e8h2h8C5XEroy video.mp4 60

It would return an aggregate object containing all of the [DATA], video/mp4, video.mp4, and 60 attributes.

This command is saying,

  1. First write the binary image data using b://
  2. Pass the output to the next protocol 1EKrfyTD6UoXR85vpfxZ7e8h2h8C5XEroy which happens to be a video metadata protocol, which attaches additional metadata
  3. And post it as a single atomic OP_RETURN output.

With this we can ensure that this blob is atomically associated with this set of metadata.

Important: Note that the ordering is important. In this scenario, the metadata protocol can accept any random object, but the b:// protocol is a sole data producer protocol and cannot accept an input from another protocol. This will be explained below in FAQ.

Also, if you simply want to store a blob with media type and nothing else, you can do so as well, you just need to end with B://.

OP_RETURN
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] image/png

You have a choice.

Extensibility

By following the unix pipeline system, we can create a sequence of as many OP_RETURN protocols as we want.

You can pipe as many protocols as you want.

For example, there can be 3 protocols in the pipeline:

  1. Write Blob: B:// for writing a data blob
  2. Write Metadata: Video metadata protocol for attaching video metadata
  3. Assign Moderation Rights: Property rights / Moderation rights protocol for assigning the resulting asset to a certain address or a Bitcoin script

The important part here is that each protocol can be a standalone module that:

  1. accepts an input of a predefined schema
  2. and returns an output of a predefined schema

But in this particular case we can write an OP_RETURN program that pipes one into another:

OP_RETURN 
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] image/png |
  1EKrfyTD6UoXR85vpfxZ7e8h2h8C5XEroy video.mp4 60 |
  1M16gTfEL8f6SkXnTzBepF56KDNG9Qka7Y SET ADMIN

Lastly, if you decide to adopt the Bitcom OS protocol into your application protocol, you can use the $ echo A > B command to define the schema directly in a standardized manner, so other apps can look it up in order to make sense of what the inputs and outputs from the protocol represent within the context of the Bitcom pipeline.

Decentralized Protocol Emergence instead of Central Planning

The great part about this approach is that you DO NOT have to decide how your protocol will interact with the outside world from the beginning.

At first you can just define a self contained protocol that doesn't interact with the outside world but does one thing.

And as you become more comfortable with opening up access, you can define a schema that describes:

  1. how it processes incoming input
  2. what output it produces and passes on to the next program in the pipeline.

For example, I can create a blob upload protocol like b:// WITHOUT any pipeline schema.

Then people may want to either fork the protocol to build their own protocol, or ask me for certain features they want to use from the b:// protocol. Then based on this feedback I can come up with an "Open API" of the b:// protocol which is essentially a schema definition of inputs and outputs within the pipeline system.

And once defined, other protocol developers can easily reference the schema and build their own application protocols by mashing up with my protocol.

And the best part: this schema itself can be stored on-chain using the Bitcom $ echo command.

FAQ

1. Isn't this more like a & than a |?

There's a subtle but important difference.

& implies that there is no order between commands, whereas | assumes a single linear order of execution. Without a fixed order, various apps may use these protocols in various orders, which will make it hard to query for them.

For example, let's say we're using & instead of | to describe a file upload + naming + admin rights assignment. It can be expressed in 6 different ways:

OP_RETURN 
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] video/mp4 &
  1EKrfyTD6UoXR85vpfxZ7e8h2h8C5XEroy video.mp4 60 &
  1M16gTfEL8f6SkXnTzBepF56KDNG9Qka7Y SET ADMIN

OP_RETURN 
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] video/mp4 &
  1M16gTfEL8f6SkXnTzBepF56KDNG9Qka7Y SET ADMIN &
  1EKrfyTD6UoXR85vpfxZ7e8h2h8C5XEroy video.mp4 60

OP_RETURN 
  1EKrfyTD6UoXR85vpfxZ7e8h2h8C5XEroy video.mp4 60 &
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] video/mp4 &
  1M16gTfEL8f6SkXnTzBepF56KDNG9Qka7Y SET ADMIN

OP_RETURN 
  1EKrfyTD6UoXR85vpfxZ7e8h2h8C5XEroy video.mp4 60 &
  1M16gTfEL8f6SkXnTzBepF56KDNG9Qka7Y SET ADMIN &
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] video/mp4

OP_RETURN 
  1M16gTfEL8f6SkXnTzBepF56KDNG9Qka7Y SET ADMIN &
  1EKrfyTD6UoXR85vpfxZ7e8h2h8C5XEroy video.mp4 60 &
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] video/mp4

OP_RETURN 
  1M16gTfEL8f6SkXnTzBepF56KDNG9Qka7Y SET ADMIN &
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] video/mp4 &
  1EKrfyTD6UoXR85vpfxZ7e8h2h8C5XEroy video.mp4 60 &

This will make it very difficult to query the pattern from the blockchain through indexing services such as bitdb or realtime push subscription services such as bitsocket

However with a fixed sequence of what each protocol expects via pipeline (|), we only have one sequence:

OP_RETURN 
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [DATA] video/mp4 |
  1EKrfyTD6UoXR85vpfxZ7e8h2h8C5XEroy video.mp4 60 |
  1M16gTfEL8f6SkXnTzBepF56KDNG9Qka7Y SET ADMIN

which means we only need one query to deal with this specific template.

Of course, the & feature also has a great potential use case and will be supported in the future, but at this stage, if we were to introduce one more feature to solve as many problems as possible, it makes more sense to use the |.

Conclusion

The main value proposition of pipeline system is:

  1. Keep each protocol as Minimal as possible
  2. Make protocols interoperable through a standardized pipeline interface
  3. Get rid of central planning in protocol design and let it emerge based on usage.

lowercaseing strings with `bit echo`

Hi command:
bit echo "Hi, this is a protocol for pageshot app. PageShot automatically generates images from provided URL" to README
produced

"data": [
"$",
"echo",
"hi, this is a protocol for pageshot app. pageshot automatically generates images from provided url",
"to",
"readme"],

all strings were lowecased unexpectedly :)

Bitcom as OS

Bitcom as OS

Proposed by @torusJKL

Original Proposal on Bitcoin: https://viewer.bitdb.network/#e52864d04efa56d94b1a3cf6347a752ed4114349caf191ed6ea08f865643e085

Further explanation: https://twitter.com/_unwriter/status/1089517509437464578

Instead of thinking of Bitcom as a "global computer that all application protocols register to",
think of Bitcom as "an OS (operating system) that gets installed into protocols".

Let's say your OP_RETURN protocol for a game controller looked like this:

1. Up
  OP_RETURN 1Frooui3mqRQa1nAv8VRUDaRLxSXRFyNXA Up

2. Down
  OP_RETURN 1Frooui3mqRQa1nAv8VRUDaRLxSXRFyNXA Down

3. Left
  OP_RETURN 1Frooui3mqRQa1nAv8VRUDaRLxSXRFyNXA Left

4. Right
  OP_RETURN 1Frooui3mqRQa1nAv8VRUDaRLxSXRFyNXA Right

5. A Key
  OP_RETURN 1Frooui3mqRQa1nAv8VRUDaRLxSXRFyNXA A

6. B Key
  OP_RETURN 1Frooui3mqRQa1nAv8VRUDaRLxSXRFyNXA B

To "install Bitcom OS" to your protocol, you can "activate" the Bitcom OS by starting your
OP_RETURN with "$" to indicate the "Admin mode":

OP_RETURN 1Frooui3mqRQa1nAv8VRUDaRLxSXRFyNXA $ echo "Torus Game Controller" to description

Basically,

  1. you didn't have to register to anywhere.
  2. the "Bitcom" protocol is just a part of your protocol

"su": authentication command

Spec website

Check out the website:

https://su.planaria.network

This is version 0.0.1. The spec is not 100% set in stone yet, so feel free to provide feedback and discuss.

Below is a copy/paste of the su specification.

what

su is a simple protocol for authenticating bitcoin applications.

su is a Bitcom command, inspired by the Unix "su" command.

However su is the first of its kind. If Bitcom commands have been all about admin purposes, su is the first Bitcom command designed for powering actual application transactions themselves by acting as an authentication extension to all apps.

The following command concatenates and signs the push data items at <sign_position> with <pubkey>'s private key pair and attaches the result <signature> to the transaction, which then can be verified later:

command


why

Because most bitcoin wallets generate a new address for every new transaction, it is impossible to identify a user by simply looking at a sender address for a transaction.

We need ways to separately attach user identity and its proof (signature) to transactions.

There are other existing authentication protocols such as AIP and HAIP which focus on flexibility, but sometimes you may just want a simple opinionated protocol that "just works".


design

here are the design principles of su:

  1. Umbrella protocol: su is a native Bitcom command, using the $ su prompt to indicate the authentication protocol. Thanks to its simplicity, it can easily plug into any bitcoin script protocol to attach signature.
  2. Focus on Simplicity: the protocol spec is as minimal as it can get. No redundant metadata. Less data, lower cost. The su syntax consists of only three attributes:
  • <PUBKEY>
  • <SIGN_POSITION>
  • <SIGNATURE>
  1. Convention over Configuration: To achieve simplicity, su makes certain assumptions about how the signing should be carried out. There is no "configuration". su assumes the following convention:
  • Hex: Uses hex encoding.
  • SHA256: The hex data is always SHA256-hashed before being signed.
  • ECDSA: Uses ECDSA to sign the data.
  • Base64 Signature: The final signature is represented as a Base64 string.
  1. Easy to Filter: su always shows up at the beginning of an output script sequence (Instead of showing up anywhere within a Bitcom pipeline). This deliberate constraint makes it easy to detect, index, and filter transactions that contain signed data, through systems like Planaria.

syntax

Just like the Metanet protocol, we can think of su as an "umbrella protocol" for authenticating ANYTHING. Because of this nature, the su protocol appears at the beginning of an output script sequence.

OP_FALSE OP_RETURN $ su <PUBKEY> <SIGN_POSITION> <SIGNATURE>

Where <SIGN_POSITION> is used to select one or more pushdata within a script, and takes the following form:

<SIGN_POSITION> ::= <digit>
                  | <digit>-<digit>
                  | <SIGN_POSITION>,<SIGN_POSITION>

Here are some <SIGN_POSITION> examples:

  • 0: Select the pushdata at index 0
  • 0,1,2: Select and concatenate pushdata at index 0,1,2
  • 0-4: Select and concatenate pushdata at index 0,1,2,3,4
  • 0-4,7: Select and concatenate pushdata at index 0,1,2,3,4,7
  • 0-4,7-9: Select and concatenate pushdata at index 0,1,2,3,4,7,8,9

example

Note that su always appears at the beginning of an output script sequence.

1. basic

A su command implementation which signs a B protocol upload (Bitcom: 19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut)

0    OP_FALSE
1    OP_RETURN
2    $
3      su
4      03836714653ab7b17569be03eaf6593d59116700a226a3c812cc1f3b3c8f1cbd6c
5      9
6      HyOG2TVUR/Hdru7G8ZMl/MNkIEcjWFNgNDNF76FbOrHletOkb8He0in6G+g4uuDq5ee/YOiBV9OOfmYZYXjdqX4=
7    |
8    19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut
9      <html><body>hello</body></html>
10     text/html
11     utf-8
12     index.html

Let's take a look at the relevant parts:

  • Line 2: Bitcom prompt $
  • Line 3: Bitcom command su
  • Line 4: Signer Pubkey 03836714653ab7b17569be03eaf6593d59116700a226a3c812cc1f3b3c8f1cbd6c
  • Line 5: Push data sign position 9
  • Line 6: Signature HyOG2TVUR/Hdru7G8ZMl/MNkIEcjWFNgNDNF76FbOrHletOkb8He0in6G+g4uuDq5ee/YOiBV9OOfmYZYXjdqX4=

How it works:

  1. Select the data at index 9: <html><body>hello</body></html>
  2. Get its hex format: 3c68746d6c3e3c626f64793e68656c6c6f3c2f626f64793e3c2f68746d6c3e
  3. Hash it with SHA256: f97a8935f1bb9b75c4ee5d9968e76aae46debaacde6a8126ce9298698693704d
  4. Sign it with PUBKEY 03836714653ab7b17569be03eaf6593d59116700a226a3c812cc1f3b3c8f1cbd6c's private key pair.
  5. The result should match the SIGNATURE: HyOG2TVUR/Hdru7G8ZMl/MNkIEcjWFNgNDNF76FbOrHletOkb8He0in6G+g4uuDq5ee/YOiBV9OOfmYZYXjdqX4=

We can easily filter the transactions on Neon Genesis using:

{
  "v": 3,
  "q": {
    "find": {
      "out.s4": "03836714653ab7b17569be03eaf6593d59116700a226a3c812cc1f3b3c8f1cbd6c"
    }
  }
}

Or on BOB using:

{
  "v": 3,
  "q": {
    "find": {
      "out.tape.cell.s": "03836714653ab7b17569be03eaf6593d59116700a226a3c812cc1f3b3c8f1cbd6c"
    }
  }
}

2. multi-field signature

The same data, but signing multiple pushdata.

0    OP_FALSE
1    OP_RETURN
2    $
3    su
4    03836714653ab7b17569be03eaf6593d59116700a226a3c812cc1f3b3c8f1cbd6c
5    8,9,10,11,12
6    1b3ffcb62a3bce00c9b4d2d66196d123803e31fa88d0a276c125f3d2524858f4d16bf05479fb1f988b852fe407f39e680a1d6d954afa0051cc34b9d444ee6cb0af
7    |
8    19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut
9    <html><body>hello</body></html>
10   text/html
11   utf-8
12   index.html
  1. Get the pushdata at index 8,9,10,11,12 (line 5)
  • 8: 19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut
  • 9: <html><body>hello</body></html>
  • 10: text/html
  • 11: utf-8
  • 12: index.html
  1. Get the hex value for each
  • hex(8): 31394878696756345179427633744870515663554551797131707a5a56646f417574
  • hex(9): 3c68746d6c3e3c626f64793e68656c6c6f3c2f626f64793e3c2f68746d6c3e
  • hex(10): 746578742f68746d6c
  • hex(11): 7574662d38
  • hex(12): 696e6465782e68746d6c
  1. Concatenate the hex values and create a sha256 hash
  • 3aae6932baf004abc7e0355eeed704bb486f74d95bcd49232992df5aa88cb121
  1. Sign it with PUBKEY 03836714653ab7b17569be03eaf6593d59116700a226a3c812cc1f3b3c8f1cbd6c's private key pair (line 4)
  2. The result should match the SIGNATURE 1b3ffcb62a3bce00c9b4d2d66196d123803e31fa88d0a276c125f3d2524858f4d16bf05479fb1f988b852fe407f39e680a1d6d954afa0051cc34b9d444ee6cb0af (line 4)

bit init error: EISDIR: illegal operation on a directory

Trying to initialize an admin address for Open Directory using bit init

I'm getting the following error:

bit init
events.js:167
throw er; // Unhandled 'error' event
^

Error: EISDIR: illegal operation on a directory, open 'C:\Users\Aristophanes\opendirectory-admin.bit'
Emitted 'error' event at:
at fs.open (internal/fs/streams.js:288:12)
at FSReqCallback.oncomplete (fs.js:148:20)

Bitcoin Script Schema

Bitcoin Script Schema

A Schema for Bitcoin Script, Stored on Bitcoin.

Define, Publish, and Consume Bitcoin Script Schema, over Bitcoin.

preview

Problem

In the past when someone wanted to create an "overlay protocol" on top of Bitcoin script, they didn't have many options but to do it the old way of storing the protocol specification:

  1. In an unstructured document (As a "spec documentation" README.md)
  2. On a centralized repository (like Github)

But this is far from ideal because:

  1. Unstructured documentation can be intepreted subjectively by multiple different parties, and there is no way to "enforce" which interpretation is the right one when the original spec was written in an ambiguous manner. It is no secret that the very whitepaper of Bitcoin has been interpreted by humans in thousands of subjective ways, just like blind men touching an elephant.
  2. Unstructured means NOT machine processable: We want these protocols to be processed by autonomous machines on Bitcoin in the future, and to do that we need a machine processable description language for defining protocols.
  3. Centralized repository means it is mutable and susceptible to human politics. All protocols must be set in stone from day 1 and if there ever is a change it should be recorded on-chain 100% transparently.

Solution

This proposal solves above problems with a Bitcoin script schema that is:

  1. Human Friendly: Easily human readable thanks to the declarative syntax
  2. Machine Friendly: Designed to be programmatically processed by machines, with minimal ambiguity, using a portable JSON format
  3. Bitcoin Native: Based on the native push data structure of Bitcoin script itself.
  4. Transparent and Decentralized: The schema itself is published on Bitcoin.
  5. Easily queryable: Easily queryable because it's based on Bitcoin script push data instead of another foreign embedded data structure.
  6. Works today: It's not some pseudo-science theory. It works today because all the tools are there, you can start using it right now.

How to Use

In this section we will walk through a workflow of how this schema can be used:

  1. Define Schema
  2. Publish Schema to Bitcoin
  3. Usage
  4. Advanced Usage

1. Define Schema

There are two things to note about Bitcoin scripts:

  1. Linear: Bitcoin scripts are 2-dimensional code.
  2. Various Encoding: The push data could come in various encoding, such as hex format or ASCII format, or binary.

For a schema to work, we should be able to express what each push data means while taking above factors into account.

And in this proposal, I suggest a schema scheme that's inspired by the BitDB transaction serialization format, because BitDB has already solved all these problems for its own use case. (However anyone can come up with their own schema scheme and replace with their scheme as well, because the idea itself is applicable to any type of schema).

Example - B://

here's an example schema for the B:// protocol:

{
  "v": 1,
  "s": {
    "out.s2": "{{blob}}",
    "out.s3": "{{mediatype}}"
  }
}
  • v: The schema scheme version number
  • s: Schema description

Inside the s, we specify key/value pairs of Bitcoin script push data & its values. If a value is wrapped inside a {{ }} pair, that means it's a schema attribute.

In above case, the schema is saying:

  1. out.s2 is used to represent blob.
  2. out.s3 is used to represent mediatype.

2. Publish Schema to Bitcoin

So now that we've decided on the schema, how do we publish it to the blockchain itself?

You can do this using the Bitcom scheme. More specifically you can use the $ echo command to write a file to the protocol's root folder. (Note that this syntax is based on the upcoming "Bitcom as OS" update), and therefore the $ echo command is embedded into the 19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut application protocol (instead of Bitcom being a standalone protocol)

Here's an example of writing the schema to B:// protocol's root folder, using the Bitcom scheme:

OP_RETURN
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut
  $
  echo
  {"v":1,"s":{"out.s2":"{{blob}}","out.s3":"{{mediatype}}"}}
  to
  schema.json

3. Usage

Now that the schema has been published, you have opened up an "official" API endpoint for your protocol.

This means now others can look up the schema to understand what each push data means in your protocol transactions.

Here's a Bitquery to find the schema transaction:

{
  "v": 3,
  "q": {
    "find": {
      "out.s1": "19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut",
      "out.s2": "$",
      "out.s3": "echo",
      "out.s5": "to",
      "out.s6": "schema.json"
    }
  },
  "r": {
    "f": "[{schema: .out[0].s4}]
  }
}

4. Advanced Usage

The example above is a simple one because there's only a single pattern. But sometimes you may want to have a single protocol with multiple patterns. You may want this type of protocol management if you want a single Bitcoin address to control multiple "API points" for a single protocol via the Bitcom scheme.

Let's think of a hypothetical Memo.cash clone that uses this scheme. This app will have two APIs:

  1. Set username: OP_RETURN 17yyXL4raLZFU95ixkRESa2ZBPSSYxSsS5 0x01 Johndoe
  2. Post a message: OP_RETURN 17yyXL4raLZFU95ixkRESa2ZBPSSYxSsS5 0x02 Hello

Let's describe a schema. This time we have two APIs to describe instead of one, so we will put it inside an array:

{
  "v": 1,
  "s": [
    {"out.h2":"01", "out.s3":"{{username}}"},
    {"out.h2":"02", "out.s3":"{{message}}"}
  ]
}

The difference here is that h2 attributes are not variables wrapped in {{ }} pairs. They are static values, so they are used to pattern match in the following manner:

  1. if out.h2 is 01, then out.s3 matches to "{{username}}"
  2. if out.h2 is 02, then out.s3 matches to "{{message}}"

We can publish this schema like this, using the bitcom scheme:

OP_RETURN
  17yyXL4raLZFU95ixkRESa2ZBPSSYxSsS5
  $
  echo
  {"v":1,"s":[{"out.h2":"01","out.s3":"{{username}}"},{"out.h2":"02","out.s3":"{{message}}"}]}
  to
  schema.json

Case Study: File Metadata API

Let's take a look at how this can be applied in a real world scenario. We will use a real world example protocol: B://.

Step 1. Define a schema

A. Define B:// Schema

First we define a B:// schema for uploading blobs to the blockchain.

Since we are discussing a new way of doing things, let's assume for a moment that we are using a different version of B:// spec where it ONLY has a single attribute: {{blob}}.

In this hypothetical version, B:// acts purely as a "blob upload scheme". It only has one attribute: blob.

{
  "v": 1,
  "s": {
    "out.s2": "{{blob}}"
  }
}

We publish this schema to Bitcoin with an OP_RETURN:

OP_RETURN 
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut
  $
  echo
  {"v":1,"s":{"out.s2":"{{blob}}"}}
  to
  schema.json

B. Define Media Header Protocol Schema

Next, we want to attach more header metadata to the blob by utilizing the Unix Pipeline concept, instead of packing all the extra attributes into the B:// protocol.

This way B:// can stay minimal, as a purely raw blob upload protocol, and developers can build extension protocols on top of the blob protocol simply by piping B:// into their header metadata protocols.

Let's define a simple metadata protocol schema as an example:

{
  "v": 1,
  "s": {
    "out.s2": "{{mediatype}}",
    "out.s3": "{{filename}}"
  }
}

We also publish this schema to Bitcoin using an OP_RETURN:

OP_RETURN
  18SuCAXiTgcq5Wj7J91JSkKhrqQ16qPQxW
  $
  echo
  {"v":1,"s":{"out.s2":"{{mediatype}}","out.s3":"{{filename}}"}}
  to
  schema.json

C. Usage

Now that we've defined two protocols:

  1. A blob upload protocol: 19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut
  2. A file metadata protocol: 18SuCAXiTgcq5Wj7J91JSkKhrqQ16qPQxW

let's pipe them.

Here's an actual usage of the two protocols being pipelined to:

  1. Upload a blob, pipe it to the next step.
  2. Attach metadata and return.
OP_RETURN
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [File_Buffer_Data] |
  18SuCAXiTgcq5Wj7J91JSkKhrqQ16qPQxW image/png logo.png

D. Interpret

Now, blob viewer services can interpret above OP_RETURN transaction by:

  1. Reading the schema for each protocol
  2. Parsing the OP_RETURN from the schema

To read the schema for 19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut, we can query BitDB using:

{
  "v": 3,
  "q": {
    "find": {
      "in.e.a": "19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut",
      "out.s1": "19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut",
      "out.s2": "$",
      "out.s3": "echo",
      "out.s5": "to",
      "out.s6": "schema.json"
    }
  }
}

Next, to read the schema for 18SuCAXiTgcq5Wj7J91JSkKhrqQ16qPQxW, we can query BitDB using:

{
  "v": 3,
  "q": {
    "find": {
      "in.e.a": "18SuCAXiTgcq5Wj7J91JSkKhrqQ16qPQxW",
      "out.s1": "18SuCAXiTgcq5Wj7J91JSkKhrqQ16qPQxW",
      "out.s2": "$",
      "out.s3": "echo",
      "out.s5": "to",
      "out.s6": "schema.json"
    }
  }
}

Above queries will return the schema files for both protocols:

{
  "v": 1,
  "s": {
    "out.s2": "{{blob}}"
  }
}

and

{
  "v": 1,
  "s": {
    "out.s2": "{{mediatype}}",
    "out.s3": "{{filename}}"
  }
}

Now we can finally go back to the original OP_RETURN and interpret what each push data means:

OP_RETURN
  19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut [...] |
  18SuCAXiTgcq5Wj7J91JSkKhrqQ16qPQxW image/png logo.png

And the interpretations are:

  1. According to the first schema, [...] is a {{blob}}!!
  2. According to the second schema, image/png is a {{mediatype}}, and logo.png is a {{filename}}!!

Extensibility

This schema scheme is based on how Bitcoin scripts natively work: It's based on Bitcoin push data sequencing and encoding.

This means this can be further extended in the future to describe:

  1. Non OP_RETURN output scripts
  2. An entire transaction (not just outputs)

Conclusion

The Bitcoin Script Schema is just one proposal to declaratively describe a Bitcoin script template, which makes it easy to:

  1. Not only filter Bitcoin scripts using a declarative and portable query language.
  2. But also tie in seamlessly into how Bitcoin scripts work natively.

There can be other indexing and schema description schemes, but the best ones will probably be very closely integrated with how Bitcoin script natively works.

The current proposal is one such attempt, and one that can be used Today.

The great thing about this approach is that we can easily switch out the schema to a new scheme if the community comes up with a better scheme.

Thoughts on Including Bitcom Address as Output?

I was wondering if you had any thoughts on using the bitcom protocol address as an actual output of transactions, as a norm, or in any way at all.

Doing this would make it much easier to filter on the transactions in existing wallets. For example, SPV wallets do not have access to the whole blockchain, but they do have access to all transactions for a given address. Using the protocol address as an output would open a path for SPV clients to enumerate content in a peer-to-peer way.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.