You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the UTXO model, multiple UTXOs can live on the same address and are spendable under the same conditions. Many contracts, like multisig wallets, vaults, or escrows, work exactly this way. You compile the contract, share the address, and anyone can send funds to it. There is no "deployment" step: the contract is ready to use the moment you know its address.
9
9
10
-
Deployment becomes necessary when you're building **stateful contract systems with authentication**. In these systems, a unique CashToken category (token ID) identifies the contract and its state. The token ID is created through a special genesis transaction, and the contract UTXOs are initialized with the right tokens, capabilities, and state. This is what we mean by "deploying" a contract.
10
+
Deployment becomes necessary when you're building **stateful contract systems**. In these systems, a unique CashToken category (token ID) identifies the contract and its state. The token ID is created through a special genesis transaction, and the contract UTXOs are initialized with the right tokens, capabilities, and state. This is what we mean by "deploying" a contract.
11
11
12
12
:::tip
13
-
If your contract simply enforces spending conditions (like requiring multiple signatures or a timelock), you don't need a deployment. Just use the contract address. Deployment is for systems where CashTokens authenticate and track contract state.
13
+
If your contract simply enforces spending conditions, you don't need a deployment. Just use the contract address. Deployment is for systems where CashTokens authenticate and track contract state.
14
14
:::
15
15
16
16
## Before the Genesis Transaction
17
17
18
18
### Contract Addresses
19
19
20
-
CashScript contract addresses are **deterministic**: they are derived from the contract's compiled bytecode (the artifact) combined with the constructor arguments. Given the same artifact and the same arguments, you will always get the same address.
20
+
CashScript contract addresses are **deterministic**: they are derived from the contract's compiled bytecode combined with the constructor arguments. Given the same artifact and the same arguments, you will always get the same address.
21
21
22
22
```ts
23
23
import { Contract } from'cashscript';
@@ -33,9 +33,9 @@ This means you can reconstruct a contract's address at any time, on any machine,
33
33
34
34
### Preparing Constructor Arguments
35
35
36
-
Some constructor arguments are straightforward constants (block heights, timelocks). Others require preparation before deployment:
36
+
Some constructor arguments are straightforward constants, others require preparation before deployment:
37
37
38
-
-**Token IDs from other categories** — in complex systems with multiple token categories, contracts often reference each other's token IDs as constructor arguments. Note that token IDs must be byte-reversed when passed as constructor arguments, because the Bitcoin Cash VM uses little-endian byte order internally while token IDs are displayed in big-endian (the same applies to transaction IDs).
38
+
-**Token IDs from other categories** — in complex systems with multiple token categories, contracts often reference each other's token IDs as constructor arguments.
39
39
-**Locking bytecodes from other contracts** — in multi-contract systems, one contract may reference another by locking bytecode. This creates a dependency chain: you must instantiate the referenced contract first, extract its locking bytecode, and pass it as a constructor argument to the dependent contract.
40
40
-**Public keys** — for contracts that validate signed messages (e.g. from an oracle provider), you need the signer's public key. For owner authentication, you need to derive the public key hash from a keypair ahead of time.
41
41
@@ -48,36 +48,25 @@ function reverseHex(hex: string): string {
48
48
}
49
49
50
50
// Token IDs must be byte-reversed for use as constructor args
Constructor arguments are baked into the contract address. If any argument changes, even a single byte of a public key, the contract address changes entirely. Double-check all arguments before deploying. Some parameters, like fee destination addresses, are permanent once deployed and cannot be changed. The wallets behind these addresses require proper creation, backup, and security before deployment.
60
+
Double-check all arguments before deploying. Some parameters, like fee destination addresses, are permanent once deployed and cannot be changed. The wallets behind these addresses require proper creation, backup, and security before deployment.
65
61
:::
66
62
67
63
### Token IDs
68
64
69
-
In Bitcoin Cash, a new token category is created when a UTXO with `vout: 0` is spent as input index 0 of a transaction. Both conditions must be met. The resulting token ID equals the txid of that spent UTXO.
70
-
71
-
```ts
72
-
// The token ID equals the txid of the vout0 UTXO spent as input index 0
73
-
const tokenId =genesisUtxo.txid;
74
-
```
75
-
76
-
Once you have the vout0 UTXO, its txid (the future token ID) is already known before constructing the genesis transaction.
65
+
In Bitcoin Cash, a new token category can be created by spending a UTXO with `vout: 0`. The resulting token ID equals the txid of the UTXO with `vout: 0`. So if you already know which UTXO you will use for the genesis transaction, you already know what the token ID will be and can use it directly.
77
66
78
67
### Setup Wallet
79
68
80
-
To create vout0 UTXOs and broadcast the genesis transaction, you need a funded wallet. This is typically a standard P2PKH wallet derived from a WIF private key or an HD seed phrase, with enough BCH to fund all contract outputs (each needs at least dust amount, typically 1000 sats).
69
+
To create vout0 UTXOs and broadcast the genesis transaction, you need a funded wallet. This is typically a standard P2PKH wallet derived with enough BCH to fund all contract outputs (each needs at least dust amount, typically 1000 sats).
81
70
82
71
The setup wallet may already have UTXOs at vout 0, but usually you need to prepare them. You can do this by sending BCH from the setup wallet back to itself as the sole output of a transaction. Since it's the only output, it will be at index 0.
83
72
@@ -108,10 +97,6 @@ async function createVout0(
108
97
109
98
For deployments with multiple token categories, you need multiple vout0 UTXOs, one per token category you want to create. Since contracts may reference each other's token IDs as constructor arguments, it is recommended to prepare all vout0 UTXOs first so that every token ID is known before instantiating any contracts. The genesis transactions themselves can then be broadcast in parallel since they have no inter-transaction dependencies.
110
99
111
-
:::note
112
-
If you plan to include a BCMR OP_RETURN in your genesis transaction, keep the setup wallet "quiet" with minimal transaction history. Some wallets resolve token metadata by querying all transactions on the vout0 address, and a busy address can cause this resolution to be slow or fail.
113
-
:::
114
-
115
100
:::tip
116
101
Always test your full deployment flow on chipnet before mainnet. Validating your transaction structure, constructor arguments, and initial state encoding on chipnet first avoids costly mistakes.
For systems expecting concurrent usage, you can create multiple identical contract UTXOs in the same genesis transaction. Each duplicate UTXO sits on the same contract address with the same token type, allowing independent transactions to spend different UTXOs without conflicting. The number of duplicates you create determines the system's concurrency capacity. See [accidental race-conditions](/docs/guides/lifecycle#accidental-race-conditions) in the lifecycle guide for more on why this matters.
185
-
186
-
When duplicating contract UTXOs that hold fungible tokens, the total supply should be evenly distributed across them. The last UTXO can absorb the remainder to ensure the total is exact:
165
+
For systems expecting [concurrent usage](/docs/guides/concurrency), you can create multiple identical contract UTXOs in the same genesis transaction. Each duplicate UTXO sits on the same contract address with the same token type, allowing independent transactions to spend different UTXOs without conflicting. When duplicating contract UTXOs that hold fungible tokens, the total supply should be evenly distributed across them. The last UTXO can absorb the remainder to ensure the total is exact:
The [Bitcoin Cash Metadata Registry (BCMR)](https://cashtokens.org/docs/bcmr/chip/) is the standard for associating metadata (name, ticker, decimals, icon) with CashToken categories. The metadata is resolved through an authchain, a chain of transactions starting from a specific output in the genesis transaction.
197
176
198
-
To set up the authchain during deployment, include a dust output (e.g. 1000 sats) to a designated authchain address as part of the genesis transaction. This output becomes the starting point for metadata resolution. Wallets and indexers follow the authchain from this output to find the latest BCMR metadata.
177
+
To set up the authchain during deployment, include a dust output (e.g. 1000 sats) at output index 0 to a designated authchain address as part of the genesis transaction. This output becomes the starting point for metadata resolution. Wallets and indexers follow the authchain from this output to find the latest BCMR metadata.
0 commit comments