Skip to content

Commit 7ed2ec1

Browse files
authored
add cashtokens uses to guide (#364)
1 parent 2f9ba40 commit 7ed2ec1

File tree

3 files changed

+68
-27
lines changed

3 files changed

+68
-27
lines changed

website/docs/guides/adversarial.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ For an adversarial attack to pull off this time-sensitive attack, he would requi
3737

3838
### Late Double Spends
3939

40-
In the case of an late double spend (which does not try to exploit a race condition) the adversarial actor need help from a miner.
40+
In the case of a late double spend (which does not try to exploit a race condition) the adversarial actor need help from a miner.
4141
Either the adversarial actor needs to convince the miners to abandon their first seen rule or he needs to be mining himself to be able to construct his own block.
4242

4343
:::caution
@@ -100,7 +100,7 @@ Adversarial analysis should take into account that "first-seen rule" is just a c
100100
### Specialized Block-Builders
101101

102102

103-
As described in the section on "stale-state arbitrage" economic actors ay be incentivized to strategically create a competing transaction chain which takes advantage of an older price state/ratio which has not yet been confirmed in the blockchain. Although miners are not specialized in the optimal construction of DeFi transactions in a block, miner would over time be likely to team up with teams/companies creating this type of software for them.
103+
As described in the section on "stale-state arbitrage" economic actors may be incentivized to strategically create a competing transaction chain which takes advantage of an older price state/ratio which has not yet been confirmed in the blockchain. Although miners are not specialized in the optimal construction of DeFi transactions in a block, miner would over time be likely to team up with teams/companies creating this type of software for them.
104104

105105
:::note
106106
Ethereum with its large amount of MEV has already seen the emergence of specialized 'block builder' as a new class of relevant economic actors separate from the block proposer (who signs the block).

website/docs/guides/cashtokens.md

Lines changed: 65 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,31 @@ and their equivalent for outputs:
6060
- **`bytes tx.outputs[i].nftCommitment`** - NFT commitment data of a specific output
6161
- **`int tx.outputs[i].tokenAmount`** - Amount of fungible tokens of a specific output.
6262

63+
## CashTokens Use cases
64+
65+
The Jedex has a section on novel "[demonstrated concepts](https://github.com/bitjson/jedex#demonstrated-concepts)" enabled by CashTokens. The Jedex overview serves as the best reference to-date for the new possibilities enabled by CashTokens.
66+
67+
:::tip
68+
The [Jedex demo](https://github.com/bitjson/jedex) also introduces very advanced concepts on multi-threading and MEV avoidance through batching. This core feature of 'joint-execution' is how the DEX got its name.
69+
:::
70+
71+
Below we'll create a short list of the use cases which will be the most important to know about:
72+
73+
- **Covenant tracking tokens** - this is what enables unique authentication of contract deployments
74+
- **Commitment-based state management** - this is what `mutable` nfts are extremely useful for
75+
- **Depository covenants/token pools** - which we would call token sidecars
76+
- **Role tokens** - these are authentication tokens for admins
77+
- **Token-unlocked covenants** - this concept has also been called "pay-to-nft"
78+
- **Redeemable NFTs** - `immutable` nfts can carry state as a receipt which can be returned later for payout
79+
- **Coupled covenants/logic offloading** - which we would call sidecar functions
80+
- **Spin-off covenants** - the idea that contract create regular helper contracts to perform some task
81+
6382
## CashTokens Gotchas
64-
There are a few important "gotchas" to be aware of when developing with CashTokens in smart contracts for the first time.
83+
There are a few important "gotchas" to be aware of when developing with CashTokens in smart contracts for the first time. We'll separate them on gotchas on the contract side, and gotchas on the transaction building side.
84+
85+
### Contract Gotchas
6586

66-
#### 1) tokenCategory contains the nft-capability
87+
#### tokenCategory contains the nft-capability
6788
```solidity
6889
bytes tx.inputs[i].tokenCategory
6990
```
@@ -73,37 +94,37 @@ When accessing the `tokenCategory` through introspection the result returns `0x`
7394
If you want to check for an NFT using introspection, you have either split the `tokenCategory` from the `capability` or check the concatenation of the `tokenCategory` and `capability`.
7495

7596
```solidity
76-
// Constructor parameters: providedCategory
97+
// Constructor parameters: providedCategory
7798
78-
// Extract the separate tokenCategory and capability
79-
bytes32 tokenCategory, bytes capability = tx.inputs[0].tokenCategory.split(32);
99+
// Extract the separate tokenCategory and capability
100+
bytes32 tokenCategory, bytes capability = tx.inputs[0].tokenCategory.split(32);
80101
81-
// Check that the NFT is the correct category and has a "minting" capability
82-
require(providedCategory == tokenCategory);
83-
require(capability == 0x02);
102+
// Check that the NFT is the correct category and has a "minting" capability
103+
require(providedCategory == tokenCategory);
104+
require(capability == 0x02);
84105
85-
// Alternatively:
106+
// Alternatively:
86107
87-
// Check by concatenating the providedCategory and capability
88-
require(tx.inputs[0].tokenCategory == providedCategory + 0x02);
108+
// Check by concatenating the providedCategory and capability
109+
require(tx.inputs[0].tokenCategory == providedCategory + 0x02);
89110
```
90111

91-
#### 2) tokenCategory encoding
112+
#### protect the minting capability
92113

93-
The `tokenCategory` introspection variable returns the tokenCategory in the original unreversed order, this is unlike wallets and explorers which use the reversed byte-order. So be careful about the byte-order of `tokenCategory` when working with BCH smart contracts.
114+
If a covenant contains a `minting` NFT then all outputs should be carefully accounted for in the contract logic to not accidentally allow to mint extra new NFTs.
94115

95-
```ts
96-
// when using a standard encoded tokenId, reverse the hex before using it in your contract
97-
const contract = new Contract(artifact, [reverseHex(tokenId)], { provider })
98-
```
99-
100-
It is not recommended to do the byte-reversal in script, because this adds extra unnecessary overhead to the script.
116+
For a variable number of outputs you could use the following construction:
101117
```solidity
102-
// NOT THIS
103-
require(tx.inputs[0].tokenCategory == providedTokenId.reverse());
118+
// Optionally create bch-change output at outputIndex 5
119+
if (tx.outputs.length > 5) {
120+
require(tx.outputs[5].tokenCategory == 0x, "Invalid BCH change output - should not hold any tokens");
121+
}
122+
123+
// Don't allow more outputs to prevent minting extra NFTs
124+
require(tx.outputs.length <= 6, "Invalid number of outputs - should have 6 at most");
104125
```
105126

106-
#### 3) "invisible" empty nfts
127+
#### "invisible" empty nfts
107128
Because the nft-capability has no separate introspection item, and nothing is appended to the `tokenCategory` in case of capability `none`, empty nfts can be "invisible" when combined with fungible tokens.
108129

109130
First let's consider the case where a UTXO only holds an empty NFT:
@@ -134,7 +155,28 @@ This means that a covenant UTXO holding both a minting NFT and the fungible toke
134155
The easiest way to prevent issues with "junk" empty NFTs is to check that only NFTs with non-empty commitments can be interacted with in the contract system.
135156
:::
136157

137-
#### 4) Explicit vs implicit burning
158+
### Transaction Building Gotchas
159+
160+
#### tokenCategory encoding
161+
162+
The `tokenCategory` introspection variable returns the tokenCategory in the original unreversed order, this is unlike wallets and explorers which use the reversed byte-order. So be careful about the byte-order of `tokenCategory` when working with BCH smart contracts.
163+
164+
```ts
165+
// when using a standard encoded tokenId, reverse the hex before using it in your contract
166+
const contract = new Contract(artifact, [reverseHex(tokenId)], { provider })
167+
```
168+
169+
#### Combined BCH + CashTokens UTXOs
170+
171+
Most end-user CashTokens wallets expect CashTokens UTXOs to only hold a tiny amount of BCH like 1000 sats. Deviating from the expectation might cause unforeseen problems with user's wallets.
172+
173+
:::tip
174+
You can hard code in your contract that any user token output should have exactly `1000` sats, this avoids possible complicating freedom during transaction building.
175+
:::
176+
177+
However when constructing a transaction with user owned UTXOs, you should always make sure to check whether you handle the edge case of users with combined BCH + CashTokens UTXOs correctly in change output handling both for BCH and the tokens.
178+
179+
#### Explicit vs implicit burning
138180

139181
CashTokens can be burned explicitly by sending them to an OP_RETURN output, which is provably unspendable. CashTokens can also be burned implicitly, by including them in the inputs but not the outputs of a transaction. Always be mindful when adding token-carrying inputs to not forget to add the tokens in the outputs, otherwise they will be considered as an implicit burn.
140182

website/docs/guides/covenants.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,9 @@ All outputs of the `PooledFunds` contract need to be carefully controlled in the
322322
With contracts holding minting NFTs, all outputs need to be carefully controlled in the covenant contract code, so no additional (minting) NFTs can un-intentionally be created in other outputs.
323323
:::
324324

325-
326325
## Conclusion
327326
We have discussed the main uses for covenants as they exist on Bitcoin Cash today. We've seen how we can achieve different use cases by combining transaction output restrictions to `P2SH` and `P2PKH` outputs. We also touched on more advanced subjects such as keeping local state in NFTs. Covenants and CashTokens are the **main differentiating factor** for BCH smart contracts when compared to BTC, while keeping the same **efficient, atomic verification**.
328327

329-
Keeping local state in NFTs and issuing NFTs as receipts are two strategies which can be used to create much more sophisticated decentralized applications such as the AMM-style DEX named [Jedex](https://blog.bitjson.com/jedex-decentralized-exchanges-on-bitcoin-cash/).
328+
Keeping local state in NFTs and issuing NFTs as receipts are two strategies which can be used to create much more sophisticated decentralized applications. You can read more of these advanced CashTokens use cases in our [dedicated guide](/docs/guides/cashtokens#cashtokens-usecases)!
330329

331330
[bitcoin-covenants]: https://fc16.ifca.ai/bitcoin/papers/MES16.pdf

0 commit comments

Comments
 (0)