Bitcoin Script and Arkade Script
An Arkade virtual output is a Taproot output. Its script tree has two kinds of leaf. A tapscript leaf is Bitcoin Script that miners run when someone spends the leaf on L1. The CSV exit leaf is one of these, and it needs no signature from the operator or the Emulator. A covenant leaf holds a spending condition in Arkade Script, which Bitcoin never runs. The leaf that Bitcoin sees needs two signatures, one from the Arkade operator and one from the Emulator key, and the script tweaks that key. The Emulator signs only if the script passes.
You write contracts in Arkade Language, and
arkadec makes both kinds of leaf. The Bitcoin Script wiki lists the opcodes of Bitcoin.
How a covenant spend is checked
- The wallet adds an Emulator Packet to the Arkade transaction. The packet holds the Arkade Script and the witness of each covenant input.
- The wallet sends the transaction to the
/v1/txendpoint of the Emulator. - The Emulator runs each script in the packet against the transaction.
- The Emulator signs only if each script succeeds.
- The Emulator sends the transaction to the Arkade operator and returns the finalized transaction.
Opcodes
Arkade Script keeps the opcode values of Bitcoin Script and uses unused values for new opcodes.OP_MERKLEBRANCHROOT uses the value of OP_NOP4. The opcode table of the engine is opcode.go. The README describes the new opcodes.
The groups follow the Bitcoin Script wiki. A stack effect shows the inputs, an arrow, and the outputs. The top of the stack is on the right.
Same as Bitcoin Script
The numeric opcodes take BigNums, not 4-byte numbers.
Stack
OP_PUT is new.
Splice
Bitcoin Script disablesOP_CAT, OP_SUBSTR, OP_LEFT, and OP_RIGHT, but they work in Arkade Script, and OP_REVERSEBYTES is new.
Bitwise logic
Bitcoin Script disables these opcodes, but they work in Arkade Script.Arithmetic
A BigNum is a minimally encoded integer of up to 520 bytes. Bitcoin Script disables the first seven opcodes below, but they work in Arkade Script, and the last three opcodes are new.OP_NUM2BIN and OP_BIN2NUM convert between BigNums and byte strings of fixed width.
Disabled in Bitcoin Script
New
Cryptography
OP_CHECKSIG, OP_CHECKSIGVERIFY, and OP_CHECKSIGADD keep their words but check a different digest (Signature checks). OP_CHECKMULTISIG and OP_CHECKMULTISIGVERIFY fail, as in tapscript. Use OP_CHECKSIGADD. These opcodes are new:
Elliptic curves
All opcodes in this group are new.curve_id selects the curve. Coordinates are BigNums.
Locktime and time
OP_CHECKLOCKTIMEVERIFY and OP_CHECKSEQUENCEVERIFY work as in Bitcoin Script. They compare with the locktime of the spending transaction and the sequence of the input. The SDK builds covenant spends with nLockTime 0, so these opcodes cannot control those spends. These opcodes are new:
OP_CHECKTIME checks the clock of the Emulator, not Bitcoin block time. The first script below fails before a time threshold, and the second script passes from the given number of seconds before the virtual output expires.
Transaction introspection
All opcodes in this group are new. Inputs
Outputs
Transaction
Packets and intents
All opcodes in this group are new.OP_INSPECTPACKET and OP_INSPECTINPUTPACKET read ARK extension packets, for example the asset packet.
Continuation
OP_TUNNEL is new. It expresses native delegation: someone other than the owner renews a virtual output in each batch settlement.
Assets
All opcodes in this group are new. An Asset ID has two stack items:asset_txid, the ID of the issuance transaction, and asset_gidx, the group index of the issuance.
k is the position of a group in the asset packet of the transaction. OP_FINDASSETGROUPBYASSETID converts an Asset ID to k. The source transaction ID of an intent input is not an Asset ID.
Reserved
OP_NOP1 and OP_NOP5–OP_NOP10 do nothing. OP_RESERVED, OP_VER, OP_VERIF, OP_VERNOTIF, OP_RESERVED1, OP_RESERVED2, and each unassigned value fail the script.
Advanced
Key tweak
A covenant leaf uses the Emulator key. The hash of the Arkade Script of the leaf tweaks the key:P_even is the Emulator key with even y. The tweak binds the key to one script. A different script gives a different key, so nobody can show another script when the Emulator signs. The SDK function computeArkadeScriptPublicKey calculates P_tweaked. OP_INSPECTINPUTARKADESCRIPTHASH pushes h.
Signature checks
OP_CHECKSIG, OP_CHECKSIGVERIFY, OP_CHECKSIGADD, and OP_SIGHASH use a digest that is not the BIP342 digest. There are two differences. The final BIP-340 tag is ArkadeTapSighash, not TapSighash. A signature for one digest fails for the other.
The digest also ignores the witness of each Emulator Packet entry: the witness length is 0 in sha_outputs. A party can sign a script before anyone gives witness arguments. The arguments can change between spend attempts. The signatures that the Emulator adds to the transaction use the standard BIP342 digest.
The TypeScript SDK does not calculate the Arkade digest. To check a signature over your own message, use OP_CHECKSIGFROMSTACK. The complete function of the escrow vault does this.
Emulator Packet
An Emulator Packet carries the script and the witness of each covenant input. It is a TLV record of type0x01 in an ARK extension. An ARK extension is an OP_RETURN output that starts with the bytes ARK (0x41524b). The README gives the format and the limits.
OP_INSPECTPACKET and OP_INSPECTINPUTPACKET read the packet bytes. A script that uses them depends on the exact byte format. A format change is a protocol change.
Compute limits
The Emulator limits how many times each heavy opcode can run in one input. Other opcodes have no limit. One request can use the limits of 4 inputs in total. An operator can change the limits withEMULATOR_COMPUTE_LIMITS.
Endpoints
The/v1/info endpoint returns signerPubkey and deprecatedSignerPubkeys.
Other networks have no pin. Pass the key of the Emulator as
emulatorPubkey to Arkade.connect.
Check the pinned key
The SDK builds covenants with the key that it pins for the network, and it never uses the key that the Emulator reports. If this code printsfalse, the Emulator has a new key. Halt covenant operations and verify the cause before you upgrade @arkade-os/sdk — a mismatch can also indicate a compromised key or a man-in-the-middle at the network boundary. During a key rotation, the Emulator also signs with deprecated keys. The operator can set EMULATOR_DEPRECATED_KEYS_VALID_UNTIL to end that period.
emulator-key.ts