Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/docs/Examples/chat.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ order: -20
icon: comment-discussion
---

# Encrypted Chat
# Chat

## Smart Contract

Expand Down
2 changes: 1 addition & 1 deletion packages/docs/Examples/fungible-token.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
order: -10
icon: database
icon: circle
---

# Fungible Token
Expand Down
2 changes: 1 addition & 1 deletion packages/docs/Examples/non-fungible-token.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ order: 0
icon: image
---

# Non Fungible Token (NFT)
# Non Fungible Token

## Smart Contract

Expand Down
2 changes: 1 addition & 1 deletion packages/docs/Lib/index.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
order: -60
icon: tools
icon: book
expanded: true
14 changes: 9 additions & 5 deletions packages/docs/Lib/lib.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,13 @@ order: -40

# Lib

This API describes the functionality of the `Computer` [library](https://github.com/bitcoin-computer/monorepo/tree/main/packages/lib#readme).
The Bitcoin Computer Library (available on [Github](https://github.com/bitcoin-computer/monorepo/tree/main/packages/lib#readme) and [Npm](https://www.npmjs.com/package/@bitcoin-computer/lib)) provides all the functionality needed to write smart contracts with the Bitcoin Computer.

## Basic
To interface with the blockchain, the Bitcoin Computer Lib connects to a Bitcoin Computer node. By default the Bitcoin Computer Lib connects to a node in regtest node that we provide. You can find more information about configuration options in the section [constructor](./constructor.md).

## Api

### Basic

You can build almost all smart contracts with following methods.

Expand All @@ -18,7 +22,7 @@ You can build almost all smart contracts with following methods.
| [query](./query.md) | Finds the latest revisions of smart object |
| [sync](./sync.md) | Computes the state of a smart object from a given revision |

## Advanced
### Advanced

To build advanced applications like swaps have a look at the following.

Expand All @@ -31,7 +35,7 @@ To build advanced applications like swaps have a look at the following.
| [decode](./decode.md) | Parses a Bitcoin transaction and returns Javascript expression |
| [faucet](./faucet) | Fund a computer object on Regtest |

## Modules
### Modules

You can save transaction fees by using our ES6 module system.

Expand All @@ -41,7 +45,7 @@ You can save transaction fees by using our ES6 module system.
| [deploy](./deploy.md) | Deploys an ES6 module on the blockchain |
| [load](./load.md) | Loads an ES6 module from the blockchain |

## Wallet
### Wallet

The wallet functionality within a `Computer` instance can be accessed using the following.

Expand Down
13 changes: 11 additions & 2 deletions packages/docs/comparison.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ out of the blockchain (layer-1) and can ultimately settle
back efficiently to the blockchain.

### Side Chains
* [Stacks](https://docs.stacks.co/)
* [Rootstock](https://dev.rootstock.io/)
* [Stacks](https://docs.stacks.co/)
* [Internet Computer](https://internetcomputer.org/docs/current/home)

### Payment Channel Networks
Expand Down Expand Up @@ -73,15 +73,18 @@ fraud proof, the users need to wait (usually a week) until their
deposits can be withdrawn, while in ZK-rollups, deposits can
be withdrawn immediately. [1]

* [BitVM](https://bitvm.org/) (is this L2?)
* [SatoshiVM](https://docs.satoshivm.io/)
* [BOB](https://docs.gobob.xyz/)
* [Citrea](https://docs.citrea.xyz/)
* [Alpen](https://www.alpenlabs.io/)
* [Merlin](https://docs.merlinchain.io/merlin-docs)
* [Dovi](https://dovil2.com/)

## Layer 1

### Miner Validated
* [Bitcoin Script]()
* [BitVM](https://bitvm.org/) (is this L2?)

### Client Validated
* [EPOBC](https://github.com/chromaway/ngcccbase/wiki/EPOBC_simple)
Expand All @@ -99,6 +102,10 @@ be withdrawn immediately. [1]
* https://www.hiro.so/blog/building-on-bitcoin-project-comparison
* https://www.hiro.so/

## Videos

[BitVM: Smarter Bitcoin Contracts - Robin Linus (zerosync)](https://www.youtube.com/live/VIg7BjX_lJw)

## Articles
[1] [SoK: Applications of Sketches and Rollups in Blockchain Networks](https://drive.google.com/file/d/1dJ2OsAc4QvIWzxR1JFFmMfMVYIrnXOWW/view), Arad Kotzer, Daniel Gandelman and Ori Rottenstreich; Technion, Florida State University
* [Blockchain Scaling Using Rollups: A Comprehensive Survey](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=9862815), LOUIS TREMBLAY THIBAULT, TOM SARRY, AND ABDELHAKIM SENHAJI HAFID; Montreal
Expand All @@ -112,6 +119,8 @@ Roberto Zunino
* [SoK: Decentralized Finance (DeFi)](https://dl.acm.org/doi/pdf/10.1145/3558535.3559780)
* [SoK: Communication Across Distributed Ledgers](https://eprint.iacr.org/2019/1128.pdf)
* [Colored Coins whitepaper](https://www.etoro.com/wp-content/uploads/2022/03/Colored-Coins-white-paper-Digital-Assets.pdf), Yoni Assia, Vitalik Buterin, liorhakiLior, Meni Rosenfeld, Rotem Lev
* [BitSNARK & Grail - Bitcoin Rails for Unlimited Smart Contracts & Scalability](https://assets-global.website-files.com/661e3b1622f7c56970b07a4c/662a7a89ce097389c876db57_BitSNARK__Grail.pdf)
* [BitVMX: A CPU for Universal Computation on Bitcoin](https://bitvmx.org/files/bitvmx-whitepaper.pdf)



87 changes: 24 additions & 63 deletions packages/docs/how-it-works.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,108 +9,69 @@ icon: light-bulb

A Bitcoin Computer transaction is a Bitcoin transaction with a Javascript expression inscribed. The value of the expression is associated with the first output of the transaction. If the value is an object or array that has sub-objects, then each sub-object is associated with a distinct output of the transaction.

If the expression contains a free variable (for example the variable `x` is free in the expression `x + 1`), then that free variable has to be associated with an input of the transaction. To determine the values of the outputs, the Bitcoin Computer will recursively determine the values of each output spent. The free variable is then substituted with the value before the expression is evaluated.
If the expression contains a free variable (for example the variable `x` is free in the expression `x + 1`), then that free variable has to be associated with an input of the transaction. To determine the values of the outputs, the Bitcoin Computer recursively determines the values of each output spent. The free variable is then substituted with the value before the expression is evaluated.

### Notation
### Basic Example

![](/static/legend@1x.png)-
We will use some visual notion in the example that we describe first. White boxes represent transactions and grey boxes represent expressions that are inscribed into the transactions. Inputs and outputs are displayed as circles and spending relations are shown as arrows.

To keep the explanation simple, we will pretend that any user (not just miners) can create transactions without inputs.
In the examples below, white boxes represent transactions and grey boxes represent expressions inscribed. Inputs and outputs are displayed as circles and spending relations are shown as arrows.
<div style="clear: right;"></div>

### Example

-![](/static/int-example@1x.png)
Now consider a transaction with one output and the expression `1+2` inscribed. As this expression evaluates to `3`, the Bitcoin Computer will associate the first output with the value `3`.
Consider a transaction with the expression `1+2` inscribed. As this expression evaluates to `3`, the Bitcoin Computer will associate the first output with the value `3`.

If this output is then spent by a transaction with an inscription `x+4` and the first input is labelled by `x`, the Bitcoin Computer will first determine the value of the output spent by that input. As described above that output is has the value `3`. Hence, the output of the second transaction has the value `7`.
If this output is spent by a transaction with an inscription `x+4` and the first input is associated with `x`, the Bitcoin Computer determines the value of the output spent by that input. In the example that output has the value `3`. Hence, the output of the second transaction has the value `7`.
<div style="clear: left;"></div>

## Data Ownership

The method of associating data values to outputs described above gives rise to a natural notion of data ownership: A piece of data that is stored in an output is owned by all users that can spend that output. This is analogous to how satoshis are owned by the users that can spend the output that store the satoshis.

In the case that a value is an object (as opposed to an array or a basic type), the Bitcoin Computer will add an extra property `_owners` to the object that contains the list of public keys that are owners. Conversely, if an object is created with a property `_owners` that is set to an array of string encoded public keys, the Bitcoin Computer will arrange the transaction so that the Bitcoin script of the output that represents that object can only be spent by the users that control the public keys in the array.

## Creating Objects and Object Identity

One advantage of associating values with transaction outputs is that the transaction id and output number can be used as an identity for the object. Specifically, whenever an object is created (as in a new memory is allocated) we assign the transaction id and output number to a property called `_id`. The id cannot be reassigned and remains immutable throughout the lifetime of the object.

## Updating Objects and Object Revisions

Whenever a smart object is updated, it's new state is stored in a new output. The transaction id and output number is assigned to a property `_rev` of the object. As any two Bitcoin transactions have distinct ids, each new version of a smart object has a fresh revision.

## Roots and Families of Objects

When a new object is created in an expression that is either a constructor call (that is of the form `new C(...)`) or a function call (that is of the form `x.f(...)`) we can keep track of this occurrence. Specifically, the root of an object is it's id if it is not created within a constructor or function call. If it is created in a constructor call it's root is the id of the newly created object. If an object `y` is created within a function call `x.f(...)` the the root of `y` is the root of `x`.
## Detailed Description

<!--
## Example
### Smart Contracts and Objects

Consider a transaction that has the expression `1+2` inscribed. The Bitcoin Computer will associate the value `3` to it's first output. If we spend this transaction with a transaction that is inscribed with the expression `x+4`.
We will refer to a Javascript expression that is inscribed in a transaction as a *smart contract*. The value that such an expression evaluates to is called a *smart value*. If a smart value is of object type we refer to it as a *smart object*.

### Data Ownership

## Storing Values
The method of associating data values to outputs described above gives rise to a natural notion of data ownership: A smart value that is *owned* by the users that can spend that output. This is analogous to how satoshis in an output are owned by the users that can spend the output.

When an expression is evaluated with the Bitcoin Computer, the expression is inscribed into a Bitcoin transaction. If the value of the expression has object type, this object is considered a "smart object" and an output of the transaction is considered the object's *id*. If the value has multiple sub-objects, each sub-object is assigned a separate output as its id.
The Bitcoin Computer adds a property `_owners` to every smart object. It is set to the array of the public keys of the owners. Conversely, if an object is created with a property `_owners` that is set to an array of *n* string encoded public keys, then the output that represents the object has a *1*-of-*n* multisig script with these public keys.

## Reading Values
### Creating Objects and Object Identity

To determine the value of a given smart object id, the Bitcoin Computer library will download the corresponding transaction and compute the value of the expression. As the mapping from sub-objects to outputs is deterministic and one-to-one, the software can determine which sub-object of the value is the smart object for the given id.
One advantage of associating values with transaction outputs is that the transaction id and output number can be used as an *identity* for the object. Whenever a smart object is created the Bitcoin Computer assigns the identity to a property `_id` of the object. The object identity cannot be reassigned and remains fixed throughout the lifetime of the object.

## Updating Values
### Updating Objects and Object Revisions

In order to explain how updating values works we need the notions of "free variable", "environment", and "closure". Consider the Javascript expression:
Whenever a smart object is updated a transaction is broadcast that spends the outputs representing the object's old state. The outputs of the transaction are associated with the new state of the object. The transaction id and output number that is associated with the new state of an object is referred to as it's *revision*. The revision is assigned to a property `_rev` of the object.

```js
const x = 1;
counter.add(x);
```
### Ancestors and Roots of Objects

It contains two variables, `x` and `counter`. The variable `x` is defined in the expression and one can determine that the value of `x` is `1`. The variable `counter` is not defined so it is impossible to tell what the value of `counter` is. Such variables are called *free variables*. In order to evaluate an expression with free variables, a definition of the values of the free variables is required. This is what an *environment* does: it maps free variables to values. A *<a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures" target="_blank">closure</a>* is a pair consisting of an expression and an environment.
If an object is created in a function call of the form `x.f(...)` we say that `x` is its parent. We say that an object `x1` is the ancestor of an object `xn` if there is a sequence of objects `z2 ... zn-1` such that `xi` is the parent of `xi_1` for all `i`. The *root* of an object is its (unique) ancestor that does not have a parent. The Bitcoin Computer assigns the root of an smart object to the property `_root`. The root can be used to create fungible tokens with the Bitcoin Computer.

To evaluate an expression $e$ containing free variables $x_1\ ...\ x_n$ with the Bitcoin Computer, the user needs to provide a *Bitcoin environment* $\{ x_1: o_1\ ...\ x_n: o_n \}$ that maps the free variables of $e$ to outputs $o_1\ ...\ o_n$. The Bitcoin Computer will recursively determine the values $v_1\ ...\ v_n$ of the outputs $o_1\ ...\ o_n$ respectively. It then creates a closure consisting of the expression $e$ and the environment $\{ x_1: v_1\ ...\ x_n: v_n \}$ and evaluates this closure with a standard Javascript runtime.
## Examples

All sub-objects of the value returned are designated one output of the transaction. We refer to both the outputs as well as the values they represent as *revisions*. Note that when a closure is evaluated, the values $v_1\ ...\ v_n$ can change (for example if $e$ is a function call $f(x_1\ ...\ x_n)$ with side effects). Therefore a these transactions must have outputs that represent the new revisions for these values as well.
### Non Fungible Tokens

The Bitcoin Computer protocol requires that a transaction spends all outputs in the environment. A practical advantage is that this provides a space efficient way to store the environment: Only a list of variable names needs to be stored as meta data and the full environment can be reconstructed from the inputs. It also has two important consequences: It provides a notion of data ownership as it is necessary to be able to spend an output in order to update it's value. And it makes it possible to run the Bitcoin Computer as a light client as the inputs of a transaction contain pointers to the transactions that contain the expressions that need to be evaluated first.
-->




<!-- ### Storing Values

Consider the code in the picture below. It defines a class `NFT` with two properties `_owners` and `url` and a method to update the `_owners`. The `_owners` property of a smart contract can be set to an array of string encoded public keys. The output that will store that

To allocate a memory cell and to store a new smart object in it, a transaction that contains a Javascript expression <code>e<sub>1</sub>; e<sub>2</sub> ... e<sub>n</sub></code> where <code>e<sub>n</sub></code> is of the form `new C(...)` must be broadcast. The class `C` can be defined in the expression or it can be passed in from a module.
The code on the left side of the picture below defines a class `NFT` with two properties `_owners` and `url` and a method `send` to update the `_owners`. The `_owners` property of a smart contract can be set to an array of string encoded public keys.

![](/static/nft-create@1x.png)

The function `computer.sync` computes Javascript objects from outputs as shown in the figure. Note that `_id`, `_rev`, and `_root` are all set to the same output.

### Updating Values
The right side of the picture shows a transaction in which both the class and a constructor call is inscribed. This expression evaluates to a new object of class `NFT`. It also shows that all three special properties `_id`, `_rev`, `_root_` are assigned the same value: the transaction id of the transaction shown and output number 1 (we represent this string as a blue circle in the picture).

To update a smart object stored in the shared global memory, a Bitcoin transaction must be broadcast that includes a Javascript expression of the form of `x.f(...)`. To determine which memory cell the free variable `x` is stored in, the blockchain environment must associate `x` with an input. In the example this input is shown as `nft`.
The picture below shows the same object after two updates. First, the expression `nft.send('038e2...')` is evaluated where `nft` refers to the object immediately after the constructor call. The second update is due to the evaluation of the expression `nft.send('03f0b...')` where this time `nft` refers to the object after the first update. We can see that the revision is changed after every update but the identity and the root stays the same.

![](/static/nft-update@1x.png)

The transaction will create corresponding outputs to these inputs, which represent the updated state of the memory cells. These outputs are called the *revisions* of a smart object, and the most recent revision is stored in the `_rev` property of the smart object.

The `computer.sync` function can be called with each revision of a smart object. This provides access to all historical states of a smart object.

### Sub-Objects

When a function call on a smart object returns a value of type object, a new memory cell is allocated to store the returned value.
### Fungible Tokens

The figure below illustrates the minting and sending of 100 fungible tokens. The blue user, with public key 03a1d..., mints the tokens in the first transaction, producing one output that represents the 100 newly minted tokens. The second transaction represents the distribution of tokens after the blue user sends 3 tokens to the green user, with public key 03f0b....

![](/static/ft-create@1x.png)

The blue output of the second transaction represents the 97 tokens that the blue user still holds, while the green output represents the three tokens now owned by the green user. The _root property of both outputs in the second transaction is linked to the output of the first transaction, as the memory cell for the three tokens was allocated within a function call.

This setup prevents forgery, as any two tokens with the same root can be traced back to the same mint. To mint a second token with the same root, one would have to broadcast a transaction with the transaction id of the first transaction, which is impossible. -->
This setup prevents forgery, as any two tokens with the same root can be traced back to the same mint. To mint a second token with the same root, one would have to broadcast a transaction with the transaction id of the first transaction, which is impossible.

<!-- ## Passing Objects as Arguments

Expand Down
Loading