@buenos_andres/contracts 0.1.1 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,806 +0,0 @@
1
- // SPDX-License-Identifier: MIT
2
- // MyFun Contracts v0.1.1 (token/NonFungibleToken.compact)
3
-
4
- pragma language_version >= 0.16.0;
5
-
6
- /**
7
- * @module NonFungibleToken
8
- * @description An unshielded Non-Fungible Token library.
9
- *
10
- * @notice One notable difference regarding this implementation and the EIP721 spec
11
- * consists of the token size. Uint<128> is used as the token size because Uint<256>
12
- * cannot be supported.
13
- * This is due to encoding limits on the midnight circuit backend:
14
- * https://github.com/midnightntwrk/compactc/issues/929
15
- *
16
- * @notice At the moment Midnight does not support contract-to-contract communication, but
17
- * there are ongoing efforts to enable this in the future. Thus, the main circuits of this module
18
- * restrict developers from sending tokens to contracts; however, we provide developers
19
- * the ability to experiment with sending tokens to contracts using the `_unsafe`
20
- * transfer methods. Once contract-to-contract communication is available we will follow the
21
- * deprecation plan outlined below:
22
- *
23
- * Initial Minor Version Change:
24
- *
25
- * - Mark _unsafeTransfer as deprecated and emit a warning if possible.
26
- * - Keep its implementation intact so existing callers continue to work.
27
- *
28
- * Later Major Version Change:
29
- *
30
- * - Drop _unsafeTransfer and remove `isContract` guard from `transfer`.
31
- * - By this point, anyone using _unsafeTransfer should have migrated to the now C2C-capable `transfer`.
32
- *
33
- * @notice Missing Features and Improvements:
34
- *
35
- * - Uint256 token IDs
36
- * - Transfer/Approval events
37
- * - safeTransfer functions
38
- * - _baseURI() support
39
- * - An ERC165-like interface
40
- */
41
-
42
- module NonFungibleToken {
43
- import CompactStandardLibrary;
44
- import "../security/Initializable" prefix Initializable_;
45
- import "../utils/Utils" prefix Utils_;
46
-
47
- /// Public state
48
- export sealed ledger _name: Opaque<"string">;
49
- export sealed ledger _symbol: Opaque<"string">;
50
-
51
- /**
52
- * @description Mapping from token IDs to their owner addresses.
53
- * @type {Uint<128>} tokenId - The unique identifier for a token.
54
- * @type {Either<ZswapCoinPublicKey, ContractAddress>} owner - The owner address (public key or contract).
55
- * @type {Map<tokenId, owner>}
56
- * @type {Map<Uint<128>, Either<ZswapCoinPublicKey, ContractAddress>>} _owners
57
- */
58
- export ledger _owners: Map<Uint<128>, Either<ZswapCoinPublicKey, ContractAddress>>;
59
-
60
- /**
61
- * @description Mapping from account addresses to their token balances.
62
- * @type {Either<ZswapCoinPublicKey, ContractAddress>} owner - The owner address.
63
- * @type {Uint<128>} balance - The balance of the owner.
64
- * @type {Map<owner, balance>}
65
- * @type {Map<Either<ZswapCoinPublicKey, ContractAddress>, Uint<128>>} _balances
66
- */
67
- export ledger _balances: Map<Either<ZswapCoinPublicKey, ContractAddress>, Uint<128>>;
68
-
69
- /**
70
- * @description Mapping from token IDs to approved addresses.
71
- * @type {Uint<128>} tokenId - The unique identifier for a token.
72
- * @type {Either<ZswapCoinPublicKey, ContractAddress>} approved - The approved address (public key or contract).
73
- * @type {Map<tokenId, approved>}
74
- * @type {Map<Uint<128>, Either<ZswapCoinPublicKey, ContractAddress>>} _tokenApprovals
75
- */
76
- export ledger _tokenApprovals: Map<Uint<128>, Either<ZswapCoinPublicKey, ContractAddress>>;
77
-
78
- /**
79
- * @description Mapping from owner addresses to operator approvals.
80
- * @type {Either<ZswapCoinPublicKey, ContractAddress>} owner - The owner address.
81
- * @type {Either<ZswapCoinPublicKey, ContractAddress>} operator - The operator address.
82
- * @type {Boolean} approved - Whether the operator is approved.
83
- * @type {Map<owner, Map<operator, approved>>}
84
- * @type {Map<Either<ZswapCoinPublicKey, ContractAddress>, Map<Either<ZswapCoinPublicKey, ContractAddress>, Boolean>>} _operatorApprovals
85
- */
86
- export ledger _operatorApprovals: Map<Either<ZswapCoinPublicKey, ContractAddress>, Map<Either<ZswapCoinPublicKey, ContractAddress>, Boolean>>;
87
-
88
- /**
89
- * @description Mapping from token IDs to their metadata URIs.
90
- * @type {Uint<128>} tokenId - The unique identifier for a token.
91
- * @type {Opaque<"string">} uri - The metadata URI for the token.
92
- * @type {Map<tokenId, uri>}
93
- * @type {Map<Uint<128>, Opaque<"string">>} _tokenURIs
94
- */
95
- export ledger _tokenURIs: Map<Uint<128>, Opaque<"string">>;
96
-
97
- /**
98
- * @description Initializes the contract by setting the name and symbol.
99
- *
100
- * This MUST be called in the implementing contract's constructor.
101
- * Failure to do so can lead to an irreparable contract.
102
- *
103
- * @circuitInfo k=10, rows=65
104
- *
105
- * Requirements:
106
- *
107
- * - Contract is not initialized.
108
- *
109
- * @param {Opaque<"string">} name_ - The name of the token.
110
- * @param {Opaque<"string">} symbol_ - The symbol of the token.
111
- * @return {[]} - Empty tuple.
112
- */
113
- export circuit initialize(name_: Opaque<"string">, symbol_: Opaque<"string">): [] {
114
- Initializable_initialize();
115
- _name = disclose(name_);
116
- _symbol = disclose(symbol_);
117
- }
118
-
119
- /**
120
- * @description Returns the number of tokens in `owner`'s account.
121
- *
122
- * @circuitInfo k=10, rows=309
123
- *
124
- * Requirements:
125
- *
126
- * - The contract is initialized.
127
- *
128
- * @param {Either<ZswapCoinPublicKey, ContractAddress>)} owner - The account to query.
129
- * @return {Uint<128>} - The number of tokens in `owner`'s account.
130
- */
131
- export circuit balanceOf(owner: Either<ZswapCoinPublicKey, ContractAddress>): Uint<128> {
132
- Initializable_assertInitialized();
133
- if (!_balances.member(disclose(owner))) {
134
- return 0;
135
- }
136
-
137
- return _balances.lookup(disclose(owner));
138
- }
139
-
140
- /**
141
- * @description Returns the owner of the `tokenId` token.
142
- *
143
- * @circuitInfo k=10, rows=290
144
- *
145
- * Requirements:
146
- *
147
- * - The contract is initialized.
148
- * - The `tokenId` must exist.
149
- *
150
- * @param {Uint<128>} tokenId - The identifier for a token.
151
- * @return {Either<ZswapCoinPublicKey, ContractAddress>} - The account that owns the token.
152
- */
153
- export circuit ownerOf(tokenId: Uint<128>): Either<ZswapCoinPublicKey, ContractAddress> {
154
- Initializable_assertInitialized();
155
- return _requireOwned(tokenId);
156
- }
157
-
158
- /**
159
- * @description Returns the token name.
160
- *
161
- * @circuitInfo k=10, rows=36
162
- *
163
- * Requirements:
164
- *
165
- * - The contract is initialized.
166
- *
167
- * @return {Opaque<"string">} - The token name.
168
- */
169
- export circuit name(): Opaque<"string"> {
170
- Initializable_assertInitialized();
171
- return _name;
172
- }
173
-
174
- /**
175
- * @description Returns the symbol of the token.
176
- *
177
- * @circuitInfo k=10, rows=36
178
- *
179
- * Requirements:
180
- *
181
- * - The contract is initialized.
182
- *
183
- * @return {Opaque<"string">} - The token symbol.
184
- */
185
- export circuit symbol(): Opaque<"string"> {
186
- Initializable_assertInitialized();
187
- return _symbol;
188
- }
189
-
190
- /**
191
- * @description Returns the token URI for the given `tokenId`. Returns the empty
192
- * string if a tokenURI does not exist.
193
- *
194
- * @circuitInfo k=10, rows=296
195
- *
196
- * Requirements:
197
- *
198
- * - The contract is initialized.
199
- * - The `tokenId` must exist.
200
- *
201
- * @notice Native strings and string operations aren't supported within the Compact language,
202
- * e.g. concatenating a base URI + token ID is not possible like in other NFT implementations.
203
- * Therefore, we propose the URI storage approach; whereby, NFTs may or may not have unique "base" URIs.
204
- * It's up to the implementation to decide on how to handle this.
205
- *
206
- * @param {Uint<128>} tokenId - The identifier for a token.
207
- * @return {Opaque<"string">} - the token id's URI.
208
- */
209
- export circuit tokenURI(tokenId: Uint<128>): Opaque<"string"> {
210
- Initializable_assertInitialized();
211
- _requireOwned(tokenId);
212
-
213
- if (!_tokenURIs.member(disclose(tokenId))) {
214
- return Utils_emptyString();
215
- }
216
-
217
- return _tokenURIs.lookup(disclose(tokenId));
218
- }
219
-
220
- /**
221
- * @description Sets the the URI as `tokenURI` for the given `tokenId`.
222
- *
223
- * @circuitInfo k=10, rows=253
224
- *
225
- * Requirements:
226
- *
227
- * - The contract is initialized.
228
- * - The `tokenId` must exist.
229
- *
230
- * @notice The URI for a given NFT is usually set when the NFT is minted.
231
- *
232
- * @param {Uint<128>} tokenId - The identifier of the token.
233
- * @param {Opaque<"string">} tokenURI - The URI of `tokenId`.
234
- * @return {[]} - Empty tuple.
235
- */
236
- export circuit _setTokenURI(tokenId: Uint<128>, tokenURI: Opaque<"string">): [] {
237
- Initializable_assertInitialized();
238
- _requireOwned(tokenId);
239
-
240
- return _tokenURIs.insert(disclose(tokenId), disclose(tokenURI));
241
- }
242
-
243
- /**
244
- * @description Gives permission to `to` to transfer `tokenId` token to another account.
245
- * The approval is cleared when the token is transferred.
246
- *
247
- * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
248
- *
249
- * @circuitInfo k=10, rows=966
250
- *
251
- * Requirements:
252
- *
253
- * - The contract is initialized.
254
- * - The caller must either own the token or be an approved operator.
255
- * - `tokenId` must exist.
256
- *
257
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} to - The account receiving the approval
258
- * @param {Uint<128>} tokenId - The token `to` may be permitted to transfer
259
- * @return {[]} - Empty tuple.
260
- */
261
- export circuit approve(
262
- to: Either<ZswapCoinPublicKey, ContractAddress>,
263
- tokenId: Uint<128>
264
- ): [] {
265
- Initializable_assertInitialized();
266
- const auth = left<ZswapCoinPublicKey,ContractAddress>(ownPublicKey());
267
- _approve(
268
- to,
269
- tokenId,
270
- auth
271
- );
272
- }
273
-
274
- /**
275
- * @description Returns the account approved for `tokenId` token.
276
- *
277
- * @circuitInfo k=10, rows=409
278
- *
279
- * Requirements:
280
- *
281
- * - The contract is initialized.
282
- * - `tokenId` must exist.
283
- *
284
- * @param {Uint<128>} tokenId - The token an account may be approved to manage
285
- * @return {Either<ZswapCoinPublicKey, ContractAddress>} Operator- The account approved to manage the token
286
- */
287
- export circuit getApproved(tokenId: Uint<128>): Either<ZswapCoinPublicKey, ContractAddress> {
288
- Initializable_assertInitialized();
289
- _requireOwned(tokenId);
290
-
291
- return _getApproved(tokenId);
292
- }
293
-
294
- /**
295
- * @description Approve or remove `operator` as an operator for the caller.
296
- * Operators can call {transferFrom} for any token owned by the caller.
297
- *
298
- * @circuitInfo k=10, rows=409
299
- *
300
- * Requirements:
301
- *
302
- * - The contract is initialized.
303
- * - The `operator` cannot be the address zero.
304
- *
305
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} operator - An operator to manage the caller's tokens
306
- * @param {Boolean} approved - A boolean determining if `operator` may manage all tokens of the caller
307
- * @return {[]} - Empty tuple.
308
- */
309
- export circuit setApprovalForAll(
310
- operator: Either<ZswapCoinPublicKey, ContractAddress>,
311
- approved: Boolean
312
- ): [] {
313
- Initializable_assertInitialized();
314
- const owner = left<ZswapCoinPublicKey,ContractAddress>(ownPublicKey());
315
- _setApprovalForAll(
316
- owner,
317
- operator,
318
- approved
319
- );
320
- }
321
-
322
- /**
323
- * @description Returns if the `operator` is allowed to manage all of the assets of `owner`.
324
- *
325
- * @circuitInfo k=10, rows=621
326
- *
327
- * Requirements:
328
- *
329
- * - The contract is initialized.
330
- *
331
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} owner - The owner of a token
332
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} operator - An account that may operate on `owner`'s tokens
333
- * @return {Boolean} - A boolean determining if `operator` is allowed to manage all of the tokens of `owner`
334
- */
335
- export circuit isApprovedForAll(
336
- owner: Either<ZswapCoinPublicKey, ContractAddress>,
337
- operator: Either<ZswapCoinPublicKey, ContractAddress>
338
- ): Boolean {
339
- Initializable_assertInitialized();
340
- if (_operatorApprovals.member(disclose(owner)) && _operatorApprovals.lookup(owner).member(disclose(operator))) {
341
- return _operatorApprovals.lookup(owner).lookup(disclose(operator));
342
- } else {
343
- return false;
344
- }
345
- }
346
-
347
- /**
348
- * @description Transfers `tokenId` token from `from` to `to`.
349
- *
350
- * @notice Transfers to contract addresses are currently disallowed until contract-to-contract interactions
351
- * are supported in Compact. This restriction prevents assets from being inadvertently locked in contracts that cannot
352
- * currently handle token receipt.
353
- *
354
- * @circuitInfo k=11, rows=1966
355
- *
356
- * Requirements:
357
- *
358
- * - The contract is initialized.
359
- * - `from` is not the zero address.
360
- * - `to` is not the zero address.
361
- * - `to` is not a ContractAddress.
362
- * - `tokenId` token must be owned by `from`.
363
- * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
364
- *
365
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} from - The source account from which the token is being transfered
366
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} to - The target account to transfer token to
367
- * @param {Uint<128>} tokenId - The token being transfered
368
- * @return {[]} - Empty tuple.
369
- */
370
- export circuit transferFrom(
371
- from: Either<ZswapCoinPublicKey, ContractAddress>,
372
- to: Either<ZswapCoinPublicKey, ContractAddress>,
373
- tokenId: Uint<128>
374
- ): [] {
375
- Initializable_assertInitialized();
376
- assert(!Utils_isContractAddress(to), "NonFungibleToken: Unsafe Transfer");
377
-
378
- _unsafeTransferFrom(from, to, tokenId);
379
- }
380
-
381
- /**
382
- * @description Transfers `tokenId` token from `from` to `to`. It does NOT check if the recipient is a ContractAddress.
383
- *
384
- * WARNING: Transfers to contract addresses are considered unsafe because contract-to-contract calls
385
- * are not currently supported. Tokens sent to a contract address may become irretrievable.
386
- * Once contract-to-contract calls are supported, this circuit may be deprecated.
387
- *
388
- * @circuitInfo k=11, rows=1963
389
- *
390
- * Requirements:
391
- *
392
- * - The contract is initialized.
393
- * - `from` is not the zero address.
394
- * - `to` is not the zero address.
395
- * - `tokenId` token must be owned by `from`.
396
- * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
397
- *
398
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} from - The source account from which the token is being transfered
399
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} to - The target account to transfer token to
400
- * @param {Uint<128>} tokenId - The token being transfered
401
- * @return {[]} - Empty tuple.
402
- */
403
- export circuit _unsafeTransferFrom(
404
- from: Either<ZswapCoinPublicKey, ContractAddress>,
405
- to: Either<ZswapCoinPublicKey, ContractAddress>,
406
- tokenId: Uint<128>
407
- ): [] {
408
- Initializable_assertInitialized();
409
- assert(!Utils_isKeyOrAddressZero(to), "NonFungibleToken: Invalid Receiver");
410
- // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists
411
- // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.
412
- const auth = left<ZswapCoinPublicKey,ContractAddress>(ownPublicKey());
413
- const previousOwner = _update(
414
- to,
415
- tokenId,
416
- auth
417
- );
418
- assert(previousOwner == from, "NonFungibleToken: Incorrect Owner");
419
- }
420
-
421
- /**
422
- * @description Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
423
- *
424
- * @circuitInfo k=10, rows=253
425
- *
426
- * Requirements:
427
- *
428
- * - The contract is initialized.
429
- *
430
- * @param {Uint<128>} tokenId - The target token of the owner query
431
- * @return {Either<ZswapCoinPublicKey, ContractAddress>} - The owner of the token
432
- */
433
- export circuit _ownerOf(tokenId: Uint<128>): Either<ZswapCoinPublicKey, ContractAddress> {
434
- Initializable_assertInitialized();
435
- if (!_owners.member(disclose(tokenId))) {
436
- return burnAddress();
437
- }
438
-
439
- return _owners.lookup(disclose(tokenId));
440
- }
441
-
442
- /**
443
- * @description Returns the approved address for `tokenId`. Returns the zero address if `tokenId` is not minted.
444
- *
445
- * @circuitInfo k=10, rows=253
446
- *
447
- * Requirements:
448
- *
449
- * - The contract is initialized.
450
- *
451
- * @param {Uint<128>} tokenId - The token to query
452
- * @return {Either<ZswapCoinPublicKey, ContractAddress>} - An account approved to spend `tokenId`
453
- */
454
- export circuit _getApproved(tokenId: Uint<128>): Either<ZswapCoinPublicKey, ContractAddress> {
455
- Initializable_assertInitialized();
456
- if (!_tokenApprovals.member(disclose(tokenId))) {
457
- return burnAddress();
458
- }
459
- return _tokenApprovals.lookup(disclose(tokenId));
460
- }
461
-
462
- /**
463
- * @description Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in
464
- * particular (ignoring whether it is owned by `owner`).
465
- *
466
- * @circuitInfo k=11, rows=1098
467
- *
468
- * Requirements:
469
- *
470
- * - The contract is initialized.
471
- *
472
- * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
473
- * assumption.
474
- *
475
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} owner - Owner of the token
476
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} spender - Account that wishes to spend `tokenId`
477
- * @param {Uint<128>} tokenId - Token to spend
478
- * @return {Boolean} - A boolean determining if `spender` may manage `tokenId`
479
- */
480
- export circuit _isAuthorized(
481
- owner: Either<ZswapCoinPublicKey, ContractAddress>,
482
- spender: Either<ZswapCoinPublicKey, ContractAddress>,
483
- tokenId: Uint<128>
484
- ): Boolean {
485
- Initializable_assertInitialized();
486
- return (
487
- !Utils_isKeyOrAddressZero(disclose(spender)) &&
488
- (disclose(owner) == disclose(spender) || isApprovedForAll(owner, spender) || _getApproved(tokenId) == disclose(spender))
489
- );
490
- }
491
-
492
- /**
493
- * @description Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.
494
- *
495
- * @circuitInfo k=11, rows=1121
496
- *
497
- * Requirements:
498
- *
499
- * - The contract is initialized.
500
- * - `spender` has approval from `owner` for `tokenId` OR `spender` has approval to manage all of `owner`'s assets.
501
- *
502
- * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
503
- * assumption.
504
- *
505
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} owner - Owner of the token
506
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} spender - Account operating on `tokenId`
507
- * @param {Uint<128>} tokenId - The token to spend
508
- * @return {[]} - Empty tuple.
509
- */
510
- export circuit _checkAuthorized(
511
- owner: Either<ZswapCoinPublicKey, ContractAddress>,
512
- spender: Either<ZswapCoinPublicKey, ContractAddress>,
513
- tokenId: Uint<128>
514
- ): [] {
515
- Initializable_assertInitialized();
516
- if (!_isAuthorized(owner, spender, tokenId)) {
517
- assert(!Utils_isKeyOrAddressZero(owner), "NonFungibleToken: Nonexistent Token");
518
- assert(false, "NonFungibleToken: Insufficient Approval");
519
- }
520
- }
521
-
522
- /**
523
- * @description Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner
524
- * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.
525
- *
526
- * @circuitInfo k=11, rows=1959
527
- *
528
- * Requirements:
529
- *
530
- * - The contract is initialized.
531
- * - If `auth` is non 0, then this function will check that `auth` is either the owner of the token,
532
- * or approved to operate on the token (by the owner).
533
- *
534
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} to - The intended recipient of the token transfer
535
- * @param {Uint<128>} tokenId - The token being transfered
536
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} auth - An account authorized to transfer the token
537
- * @return {Either<ZswapCoinPublicKey, ContractAddress>} - Owner of the token before it was transfered
538
- */
539
- circuit _update(
540
- to: Either<ZswapCoinPublicKey, ContractAddress>,
541
- tokenId: Uint<128>,
542
- auth: Either<ZswapCoinPublicKey, ContractAddress>
543
- ): Either<ZswapCoinPublicKey, ContractAddress> {
544
- Initializable_assertInitialized();
545
- const from = _ownerOf(tokenId);
546
-
547
- // Perform (optional) operator check
548
- if (!Utils_isKeyOrAddressZero(disclose(auth))) {
549
- _checkAuthorized(from, auth, tokenId);
550
- }
551
-
552
- // Execute the update
553
- if (!Utils_isKeyOrAddressZero(disclose(from))) {
554
- // Clear approval. No need to re-authorize
555
- _approve(burnAddress(), tokenId, burnAddress());
556
- const newBalance = _balances.lookup(disclose(from)) - 1 as Uint<128>;
557
- _balances.insert(disclose(from), disclose(newBalance));
558
- }
559
-
560
- if (!Utils_isKeyOrAddressZero(disclose(to))) {
561
- if (!_balances.member(disclose(to))) {
562
- _balances.insert(disclose(to), 0);
563
- }
564
- const newBalance = _balances.lookup(disclose(to)) + 1 as Uint<128>;
565
- _balances.insert(disclose(to), disclose(newBalance));
566
- }
567
-
568
- _owners.insert(disclose(tokenId), disclose(to));
569
-
570
- return from;
571
- }
572
-
573
- /**
574
- * @description Mints `tokenId` and transfers it to `to`.
575
- *
576
- * @circuitInfo k=11, rows=1013
577
- *
578
- * Requirements:
579
- *
580
- * - The contract is initialized.
581
- * - `tokenId` must not exist.
582
- * - `to` is not the zero address.
583
- * - `to` is not a ContractAddress.
584
- *
585
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} to - The account receiving `tokenId`
586
- * @param {Uint<128>} tokenId - The token to transfer
587
- * @return {[]} - Empty tuple.
588
- */
589
- export circuit _mint(
590
- to: Either<ZswapCoinPublicKey, ContractAddress>,
591
- tokenId: Uint<128>
592
- ): [] {
593
- Initializable_assertInitialized();
594
- assert(!Utils_isContractAddress(to), "NonFungibleToken: Unsafe Transfer");
595
-
596
- _unsafeMint(to, tokenId);
597
- }
598
-
599
- /**
600
- * @description Mints `tokenId` and transfers it to `to`. It does NOT check if the recipient is a ContractAddress.
601
- *
602
- * @circuitInfo k=11, rows=1010
603
- *
604
- * Requirements:
605
- *
606
- * - The contract is initialized.
607
- * - `tokenId` must not exist.
608
- * - `to` is not the zero address.
609
- *
610
- * WARNING: Transfers to contract addresses are considered unsafe because contract-to-contract
611
- * calls are not currently supported. Tokens sent to a contract address may become irretrievable.
612
- * Once contract-to-contract calls are supported, this circuit may be deprecated.
613
- *
614
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} to - The account receiving `tokenId`
615
- * @param {Uint<128>} tokenId - The token to transfer
616
- * @return {[]} - Empty tuple.
617
- */
618
- export circuit _unsafeMint(
619
- to: Either<ZswapCoinPublicKey, ContractAddress>,
620
- tokenId: Uint<128>
621
- ): [] {
622
- Initializable_assertInitialized();
623
- assert(!Utils_isKeyOrAddressZero(to), "NonFungibleToken: Invalid Receiver");
624
-
625
- const previousOwner = _update(to, tokenId, burnAddress());
626
-
627
- assert(Utils_isKeyOrAddressZero(previousOwner), "NonFungibleToken: Invalid Sender");
628
- }
629
-
630
- /**
631
- * @description Destroys `tokenId`.
632
- * The approval is cleared when the token is burned.
633
- * This circuit does not check if the sender is authorized to operate on the token.
634
- *
635
- * @circuitInfo k=10, rows=479
636
- *
637
- * Requirements:
638
- *
639
- * - The contract is initialized.
640
- * - `tokenId` must exist.
641
- *
642
- * @param {Uint<128>} tokenId - The token to burn
643
- * @return {[]} - Empty tuple.
644
- */
645
- export circuit _burn(tokenId: Uint<128>): [] {
646
- Initializable_assertInitialized();
647
- const previousOwner = _update(burnAddress(), tokenId, burnAddress());
648
- assert(!Utils_isKeyOrAddressZero(previousOwner), "NonFungibleToken: Invalid Sender");
649
- }
650
-
651
- /**
652
- * @description Transfers `tokenId` from `from` to `to`.
653
- * As opposed to {transferFrom}, this imposes no restrictions on ownPublicKey().
654
- *
655
- * @notice Transfers to contract addresses are currently disallowed until contract-to-contract
656
- * interactions are supported in Compact. This restriction prevents assets from being inadvertently
657
- * locked in contracts that cannot currently handle token receipt.
658
- *
659
- * @circuitInfo k=11, rows=1224
660
- *
661
- * Requirements:
662
- *
663
- * - The contract is initialized.
664
- * - `to` is not the zero address.
665
- * - `to` is not a ContractAddress.
666
- * - `tokenId` token must be owned by `from`.
667
- *
668
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} from - The source account of the token transfer
669
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} to - The target account of the token transfer
670
- * @param {Uint<128>} tokenId - The token to transfer
671
- * @return {[]} - Empty tuple.
672
- */
673
- export circuit _transfer(
674
- from: Either<ZswapCoinPublicKey, ContractAddress>,
675
- to: Either<ZswapCoinPublicKey, ContractAddress>,
676
- tokenId: Uint<128>
677
- ): [] {
678
- Initializable_assertInitialized();
679
- assert(!Utils_isContractAddress(to), "NonFungibleToken: Unsafe Transfer");
680
-
681
- _unsafeTransfer(from, to, tokenId);
682
- }
683
-
684
- /**
685
- * @description Transfers `tokenId` from `from` to `to`.
686
- * As opposed to {_unsafeTransferFrom}, this imposes no restrictions on ownPublicKey().
687
- * It does NOT check if the recipient is a ContractAddress.
688
- *
689
- * @circuitInfo k=11, rows=1221
690
- *
691
- * Requirements:
692
- *
693
- * - The contract is initialized.
694
- * - `to` is not the zero address.
695
- * - `tokenId` token must be owned by `from`.
696
- *
697
- * WARNING: Transfers to contract addresses are considered unsafe because contract-to-contract
698
- * calls are not currently supported. Tokens sent to a contract address may become irretrievable.
699
- * Once contract-to-contract calls are supported, this circuit may be deprecated.
700
- *
701
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} from - The source account of the token transfer
702
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} to - The target account of the token transfer
703
- * @param {Uint<128>} tokenId - The token to transfer
704
- * @return {[]} - Empty tuple.
705
- */
706
- export circuit _unsafeTransfer(
707
- from: Either<ZswapCoinPublicKey, ContractAddress>,
708
- to: Either<ZswapCoinPublicKey, ContractAddress>,
709
- tokenId: Uint<128>
710
- ): [] {
711
- Initializable_assertInitialized();
712
- assert(!Utils_isKeyOrAddressZero(to), "NonFungibleToken: Invalid Receiver");
713
-
714
- const previousOwner = _update(to, tokenId, burnAddress());
715
-
716
- assert(!Utils_isKeyOrAddressZero(previousOwner), "NonFungibleToken: Nonexistent Token");
717
- assert(previousOwner == from, "NonFungibleToken: Incorrect Owner");
718
- }
719
-
720
- /**
721
- * @description Approve `to` to operate on `tokenId`
722
- *
723
- * @circuitInfo k=11, rows=1109
724
- *
725
- * Requirements:
726
- *
727
- * - The contract is initialized.
728
- * - If `auth` is non 0, then this function will check that `auth` is either the owner of the token,
729
- * or approved to operate on the token (by the owner).
730
- *
731
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} to - The target account to approve
732
- * @param {Uint<128>} tokenId - The token to approve
733
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} auth - An account authorized to operate on all tokens held by the owner the token
734
- * @return {[]} - Empty tuple.
735
- */
736
- export circuit _approve(
737
- to: Either<ZswapCoinPublicKey, ContractAddress>,
738
- tokenId: Uint<128>,
739
- auth: Either<ZswapCoinPublicKey, ContractAddress>
740
- ): [] {
741
- Initializable_assertInitialized();
742
- if (!Utils_isKeyOrAddressZero(disclose(auth))) {
743
- const owner = _requireOwned(tokenId);
744
-
745
- // We do not use _isAuthorized because single-token approvals should not be able to call approve
746
- assert((owner == disclose(auth) || isApprovedForAll(owner, auth)), "NonFungibleToken: Invalid Approver");
747
- }
748
-
749
- _tokenApprovals.insert(disclose(tokenId), disclose(to));
750
- }
751
-
752
- /**
753
- * @description Approve `operator` to operate on all of `owner` tokens
754
- *
755
- * @circuitInfo k=10, rows=524
756
- *
757
- * Requirements:
758
- *
759
- * - The contract is initialized.
760
- * - `operator` is not the address zero.
761
- *
762
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} owner - Owner of a token
763
- * @param {Either<ZswapCoinPublicKey, ContractAddress>} operator - The account to approve
764
- * @param {Boolean} approved - A boolean determining if `operator` may operate on all of `owner` tokens
765
- * @return {[]} - Empty tuple.
766
- */
767
- export circuit _setApprovalForAll(
768
- owner: Either<ZswapCoinPublicKey, ContractAddress>,
769
- operator: Either<ZswapCoinPublicKey, ContractAddress>,
770
- approved: Boolean
771
- ): [] {
772
- Initializable_assertInitialized();
773
- assert(!Utils_isKeyOrAddressZero(operator), "NonFungibleToken: Invalid Operator");
774
-
775
- if (!_operatorApprovals.member(disclose(owner))) {
776
- _operatorApprovals.insert(
777
- disclose(owner),
778
- default<Map<Either<ZswapCoinPublicKey, ContractAddress>, Boolean>>
779
- );
780
- }
781
-
782
- _operatorApprovals.lookup(owner).insert(disclose(operator), disclose(approved));
783
- }
784
-
785
- /**
786
- * @description Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned).
787
- * Returns the owner.
788
- *
789
- * @circuitInfo k=10, rows=288
790
- *
791
- * Requirements:
792
- *
793
- * - The contract is initialized.
794
- * - `tokenId` must exist.
795
- *
796
- * @param {Uint<128>} tokenId - The token that should be owned
797
- * @return {Either<ZswapCoinPublicKey, ContractAddress>} - The owner of `tokenId`
798
- */
799
- export circuit _requireOwned(tokenId: Uint<128>): Either<ZswapCoinPublicKey, ContractAddress> {
800
- Initializable_assertInitialized();
801
- const owner = _ownerOf(tokenId);
802
-
803
- assert(!Utils_isKeyOrAddressZero(owner), "NonFungibleToken: Nonexistent Token");
804
- return owner;
805
- }
806
- }