#
encode
Creates a transaction according to the Bitcoin Computer protocol.
#
Type
;(opts: {
exp: string // an expression
env?: Record<string, string> // a blockchain environment
mod?: string // a module specifier
// Funding options
fund?: boolean // whether to fund the transaction
include?: string[] // include specific UTXOs when funding
exclude?: string[] // exclude specific UTXOs when funding
// Signing options
sign?: boolean // whether to sign the transaction
sighashType?: number // signature hash type to use
inputIndex?: number // input index to be signed
inputScript?: Buffer // use input script (instead of signing)
// Mock options
mocks?: Record<string, any> // values to mock
}) =>
Promise<{
// the transaction with the expression inscribed
tx: NakamotoJS.Transaction
// the result of the evaluation
effect: { res: unknown; env: { [s: string]: unknown } }
}>
#
Parameters
#
opts
An object with a specification to build a transaction according to the Bitcoin Computer protocol.
#
Return Value
It returns an object { tx, effect }
where tx
is a NakamotoJS transaction and effect
is an object with keys res
and env
. The res
object contains the result of the evaluation. The env
object has the same keys as the blockchain environment. However, whereas the values of the blockchain environment are revision strings, the values of env
and the smart object at these revisions after evaluating the expression.
#
Description
The encode
function builds a Bitcoin transaction from a JavaScript expression. It returns a transaction and an object effect
containing the result of the evaluation in a property res
. If the expression contains undefined variables a blockchain environment env
must be passed into encode
. A blockchain environment maps the named of the undefined variable to UTXOs containing on-chain objects. A module specifier can be provided in order to make the exports of that module are available to the evaluation. Other options can customize the funding and signing process. It is also to pass in an object specifying mocked objects.
It is important to note that encode
does not broadcast the transaction. Nonetheless the effect
object reflects the on-chain state that will emerge once the transaction is broadcast.
The state update effected by a Bitcoin Computer transaction is completely predictable:
- If the transaction is included in a block the new state will be exactly the state returned from the
effect
function. - If the transaction is not included the state is not updated.
#
Example
import { Computer } from '@bitcoin-computer/lib'
import { chain, expect, network, url } from '../../utils'
// Create wallet
const computer = new Computer({ chain, network, url })
describe('encode', () => {
// Fund wallet
before('Fund wallet', async () => {
await computer.faucet(1e8)
})
// Basic types
it('Should encode a basic type', async () => {
// Encode the expression "1".repeat(1000000)
const { effect, tx } = await computer.encode({ exp: '"1".repeat(1000000)' })
// The value return contains the result
expect(effect).deep.eq({ res: '1'.repeat(1000000), env: {} })
// Broadcast transaction to store value on the blockchain
const txId = await computer.broadcast(tx)
// Syncing to the transaction always returns the effect
expect(await computer.sync(txId)).deep.eq(effect)
})
// Objects
it('Should work for a class', async () => {
// A smart contract
class Counter extends Contract {
n: number
constructor() {
super({ n: 0 })
}
inc() {
this.n += 1
}
}
// Encode a constructor cal
const { effect: e1, tx: tx1 } = await computer.encode({
exp: `${Counter} new Counter()`,
})
// Broadcast the transaction
const txId1 = await computer.broadcast(tx1)
// As above, synchronizing to a transaction id always returns the effect
expect(await computer.sync(txId1)).deep.eq(e1)
// The result of effect e1 is a counter
const counter = e1.res as unknown as Counter
// Encode a function call incrementing the counter
const { effect: e2, tx: tx2 } = await computer.encode({
// The expression
exp: `c.inc()`,
// The value for the counter is stored at counter._rev
env: { c: counter._rev },
})
// As before we can broadcast the transaction to update the on-chain state
const txId2 = await computer.broadcast(tx2)
// The sync function reads the on-chain state
expect(await computer.sync(txId2)).deep.eq(e2)
})
})