Tutorial
This tutorial explains how smart objects can be created and updates on the Bitcoin blockchain and how multiple users can synchronize to the same smart object.

The Computer Object

The first step is to create an object computer from the Bitcoin Computer npm package.
1
import { Computer } from 'bitcoin-computer'
2
const computer = new Computer({
3
seed, // a bip39 mnemonic
4
chain, // 'BSV' or 'BCH'
5
network, // 'livenet' or 'testnet'
6
wocApiKey, // a woc api key (optional)
7
path = "m/44'/0'/0'/0", // a bip 32 path
8
})
Copied!
You can generate a fresh BIP39 seed phrase using a seed phrase generator. If no seed phrase is passed in a random Bitcoin wallet is generated.

Creating a Smart Object

A smart contract is a Javascript class.
A smart contract
1
class Counter {
2
constructor(n) {
3
this.n = n
4
}
5
inc() {
6
this.n += 1
7
}
8
}
Copied!
The new() method creates a smart object from a Javascript class and an array of arguments for the constructor.
Deploying a smart object
1
const counter = await computer.new(Counter, [2])
Copied!
Every smart object has a property _id that is set to the output on the Bitcoin blockchain that records the creation of the smart object. This id remains fixed throughout the lifecycle of the object.

Updating a Smart Object

A smart object can be updated by calling one of its functions.
When a smart object is updated a transaction is broadcast that records the state change. It is therefore necessary to awaiton function calls.
To update the counter smart object created above, we can call its inc function.
1
await counter.inc()
Copied!
When a smart object is updated a new output is created on the blockchain that stores the new revision. The property counter._rev.is always set to the output that stores the latest revision.

Synchronizing to a Smart Object

The computer.sync() method returns the smart object stored at a given location. This allows one user to create a smart object, send the id of the smart object to another user, and the second user can synchronize to the same object. For example a user Alice could run the following code
Code run on Alice's local computer
1
import { Computer } from 'bitcoin-computer'
2
3
const computerA = new Computer({ seed: 'seed phrase of Alice' })
4
const counterA = await computerA.new(Counter, [2])
5
6
console.log(counterA._rev)
7
// logs 'ac445f8aa0e6503cf2e...03cf2e:0'
Copied!
Next, Alice sends the revision 'ac445f8aa0e6503cf2e...03cf2e:0' to her friend Bob. Bob can create an instance of the same smart object on his local machine.
Code run on Bob's local computer
1
import { Computer } from 'bitcoin-computer'
2
3
const computerB = new Computer({ seed: 'seed phrase of Bob'})
4
const revision = 'ac445f8aa0e6503cf2e...03cf2e:0'
5
6
const counterB = await computerB.sync(revision)
Copied!
At this point, both Alice and Bob both have a local instance of the same smart object. Additionally, there is an instance of the counter object that is stored in the blockchain. The instances are synchronized so that if Alice calls a function on her smart object the instance on Bob's local computer updates automatically. Consider, for example, that Alice calls the inc function on her local machine:
Code run on Alice's local computer
1
await counterA.inc()
Copied!
The object on Alice's computer updates the counter to 1. Next, the update is recorded on the blockchain in a transaction. Finally, the instance on Bob's computer updates to the value 1 .
Code run on Bob's local computer
1
console.log(counterB.n)
2
// logs 1
Copied!
Smart objects create the illusion that both Alice and Bob have access to the same local machine when in reality, they could be at different ends of the planet. In this sense, the Bitcoin Computer is the one global computer that we can all use together.

Advanced Features

Bitcoin Computer adds two features to Javascript: Data ownership and storing cryptocurrency. These features are discussed in the following sections.

Data Ownership

Every smart object has a property _ownersthat can be set a list of public key strings. A smart object can only be updated by a user whose public key is in the _ownersarray. Specifically, a smart object can only be updated if it was created by a computer instance (either by computer.new or computer.sync ) that contains a mnemonic that corresponds to a public key in the current _owners property.
The _owners property can be set in a constructor call and updated in a function call. If no _owners property is specified, it defaults to a singleton array containing the public key of the current computer object.
In the example above Alice can call the inc function but Bob cannot:
Code run on Bob's local computer
1
await counterA.inc()
2
// works
3
4
await counterB.inc()
5
// throws an error
6
> Communication Error
7
> status 400 Bad Request
8
> message 16: mandatory-script-verify-flag-failed
9
> (Operation not valid with the current stack size). Code:-26
Copied!
The next example shows how the _owners property can be assigned in construction and function calls.
A smart contract
1
class OwnedCounter {
2
constructor(n, pKey) {
3
this.n = n
4
this._owners = [pKey]
5
}
6
inc(pKey) {
7
this.n += 1
8
this._owners = [pKey]
9
}
10
}
Copied!

Money

A smart object can store an amount of Bitcoin. The amount of Bitcoin, denominated in satoshi, is set through the _amount property. The Bitcoin is owned by the owners of the object, and each owner can send the Bitcoin to another user (like themselves).
As an example consider the class Wallet below.
1
class Wallet {
2
constructor(amount) {
3
this._amount = amount
4
}
5
6
send(amount, to) {
7
this._amount = amount
8
this._owners = [to]
9
}
10
}
Copied!
The following example shows how a wallet storing 30000 satoshi is created. The satoshi are taken out of the wallet of the computer object. If a function call reduces the amount of satoshi in an object the remaining satoshi (minus miner fee) are returned to the wallet in the computer object. The example also shows how the wallet can send Bitcoin.
1
import { Computer } from 'bitcoin-computer'
2
3
// create Bitcoin Computer instances
4
const computerA = new Computer({ seed: 'seed phrase of Alice'})
5
const computerB = new Computer({ seed: 'seed phrase of Bob'})
6
7
const wallet = await computerA.new(Wallet, [30000])
8
const pKeyB = computerB.db.wallet.getPublicKey().toString()
9
10
await wallet.send(20000, pKeyB)
Copied!
When the function call is executed, the _owners property of the smart object is updated to pKeyB so that subsequently only Bob owns the output containing the 20000 satoshi.
Last modified 10mo ago