Skip to content

Commit b41f0c1

Browse files
committed
Small updated to CashTokens guide and update cSpell lists
1 parent f2d46dd commit b41f0c1

2 files changed

Lines changed: 36 additions & 11 deletions

File tree

.cspell.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"algolia",
99
"altstack",
1010
"antlr",
11+
"authchain",
1112
"anyhedge",
1213
"anyonecanpay",
1314
"badlength",
@@ -66,6 +67,7 @@
6667
"fromaltstack",
6768
"gitattributes",
6869
"gitlab",
70+
"gotchas",
6971
"greaterthan",
7072
"greaterthanorequal",
7173
"hardcodes",
@@ -211,6 +213,7 @@
211213
"branchup",
212214
"bchguru",
213215
"bchn",
216+
"bcmr",
214217
"c0ffee",
215218
"cashcompiler",
216219
"cashninjas",

website/docs/guides/cashtokens.md

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ sidebar_label: CashTokens
44
---
55

66
CashTokens are native tokens on Bitcoin Cash, meaning that they are validated by all full nodes on the network and their transaction rules checked by each miner when constructing new blocks. CashTokens added fungible and non-fungible token primitives.
7-
CashTokens was first proposed in February of 2022 and activated on Bitcoin Cash mainchain in May of 2023.
7+
CashTokens was first proposed in February of 2022 and activated on Bitcoin Cash mainnet in May of 2023.
88

99
:::tip
1010
You can read more about CashTokens on [cashtokens.org](https://cashtokens.org/) which has the full specification as well as a list of [usage examples](https://cashtokens.org/docs/spec/examples).
1111
:::
1212

13-
## CashTokens Utxo data
13+
## CashTokens UTXO data
1414

1515
To understand CashTokens it is helpful to start with the layout of the UTXO data. In the `networkProvider` data from the SDK, the `token` property contains the new CashTokens fields:
1616

@@ -31,7 +31,7 @@ interface TokenDetails {
3131
};
3232
}
3333
```
34-
### Fungible Tokens
34+
### Fungible Tokens
3535

3636
The `amount` field is the amount of fungible tokens on the UTXO, the `category` is the "tokenId" for the token on the UTXO.
3737
The maximum size for a fungible token `amount` is the max signed 64-bit integer or `9223372036854775807`.
@@ -61,14 +61,32 @@ and their equivalent for outputs:
6161
- **`int tx.outputs[i].tokenAmount`** - Amount of fungible tokens of a specific output.
6262

6363
## CashTokens Gotchas
64-
There are two important "gotchas" to be aware of when developing with CashTokens in smart contracts for the first time
64+
There are a few important "gotchas" to be aware of when developing with CashTokens in smart contracts for the first time.
6565

6666
#### 1) tokenCategory contains the nft-capability
6767
```solidity
6868
bytes tx.inputs[i].tokenCategory
6969
```
7070

71-
When accessing the `tokenCategory` through introspection the result returns `0x` when that specific item does not contain tokens. If the item does have tokens it returns the `bytes32 tokenCategory`. When the item contains an NFT with a capability, the 32-byte `tokenCategory` is concatenated together with `0x01` for a mutable NFT and `0x02` for a minting NFT.
71+
When accessing the `tokenCategory` through introspection the result returns `0x` (empty byte string) when that specific item does not contain tokens. If the item does have tokens it returns the `bytes32 tokenCategory`. When the item contains an NFT with a capability, the 32-byte `tokenCategory` is concatenated together with `0x01` for a mutable NFT and `0x02` for a minting NFT.
72+
73+
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`.
74+
75+
```solidity
76+
// Constructor parameters: providedCategory
77+
78+
// Extract the separate tokenCategory and capability
79+
bytes32 tokenCategory, bytes capability = tx.inputs[0].tokenCategory.split(32);
80+
81+
// Check that the NFT is the correct category and has a "minting" capability
82+
require(providedCategory == tokenCategory);
83+
require(capability == 0x02);
84+
85+
// Alternatively:
86+
87+
// Check by concatenating the providedCategory and capability
88+
require(tx.inputs[0].tokenCategory == providedCategory + 0x02);
89+
```
7290

7391
#### 2) tokenCategory encoding
7492

@@ -79,7 +97,7 @@ The `tokenCategory` introspection variable returns the tokenCategory in the orig
7997
const contract = new Contract(artifact, [reverseHex(tokenId)], { provider })
8098
```
8199

82-
generally not recommended to do the byte-reversal in script
100+
It is not recommended to do the byte-reversal in script, because this adds extra unnecessary overhead to the script.
83101
```solidity
84102
// NOT THIS
85103
require(tx.inputs[0].tokenCategory == providedTokenId.reverse());
@@ -108,15 +126,19 @@ Contrast this with the scenario where a UTXO holds both an empty NFT and fungibl
108126
require(tx.inputs[0].tokenCategory == providedTokenId);
109127
```
110128

111-
Both scenarios look the same from the point of the smart contract.
129+
The NFT introspection fields (`nftCommitment` and `tokenCategory`) of these UTXOs look the same to the smart contract in both of these scenarios.
130+
131+
This means that a covenant UTXO holding both a minting NFT and the fungible token supply for the same token `category` cannot prevent that empty nfts are created by users when they are allowed to create a fungible token output. The possibility of these "junk" empty NFTs should be taken into account so they do not present any security problems for the contract system.
112132

113-
This means that a covenant UTXO holding both a minting NFT and the fungible token supply for the same token `category` cannot prevent that empty nfts are created by users when they are allowed to create a fungible token output. The possibility of these "junk" empty NFTs should be taken into account so they do not present any security problems for the contract system.
133+
:::tip
134+
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.
135+
:::
114136

115137
#### 4) Explicit vs implicit burning
116138

117-
CashTokens can be burned explicitly by sending them to an opreturn 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.
139+
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.
118140

119-
:::tip
141+
:::note
120142
Signing for CashTokens inputs is designed in such a way that pre-CashTokens wallets - which only know how to send and receive Bitcoin Cash - cannot spend CashTokens inputs and thus can never accidentally burn CashTokens this way.
121143
:::
122144

@@ -134,7 +156,7 @@ CashTokens Creation is illustrated very nicely by transaction diagram in the spe
134156

135157
Although not directly related to smart contracts, BCMR metadata is important for user-facing CashTokens. This way users can see your token name, icon, description and any relevant project links directly in their wallet. Many CashTokens wallets use the [Paytaca BCMR indexer](https://bcmr.paytaca.com/) to fetch BCMR metadata info about CashTokens.
136158

137-
The Paytaca BCMR indexer listens for on-chain [authchain](https://github.com/bitjson/chip-bcmr?tab=readme-ov-file#zeroth-descendant-transaction-chains) transactions which publish metadata with an opreturn publication output. These type of metadata updates are self-published on-chain identity claims. The zero-th output chain since the token genesis is the authchain. The UTXO at the "head" of this chain holds the authority to update the token's metadata.
159+
The Paytaca BCMR indexer listens for on-chain [authchain](https://github.com/bitjson/chip-bcmr?tab=readme-ov-file#zeroth-descendant-transaction-chains) transactions which publish metadata with an OP_RETURN publication output. These type of metadata updates are self-published on-chain identity claims. The zero-th output chain since the token genesis is the authchain. The UTXO at the "head" of this chain holds the authority to update the token's metadata.
138160

139161
:::tip
140162
For easy creation of CashTokens with BCMR metadata there is the Paytaca [CashTokens Studio](https://cashtokens.studio/) or to programmatically publish on-chain BCMR authchain updates there is the [AuthUpdate](https://github.com/mr-zwets/AuthUpdate) JS program.

0 commit comments

Comments
 (0)