From 7437d7b53af2783dc84cb5706274292ee6e736c6 Mon Sep 17 00:00:00 2001 From: BenRey Date: Mon, 9 Dec 2024 10:40:45 +0100 Subject: [PATCH 1/8] Add MRC721 metadata --- .../contracts/MRC20/__tests__/wrapper.spec.ts | 16 ++-- .../assembly/contracts/MRC721/MRC721.ts | 14 ++-- ...{MRC721-example.spec.ts => MRC721.spec.ts} | 2 +- .../MRC721/__tests__/metadata.spec.ts | 79 +++++++++++++++++++ .../MRC721/enumerable/MRC721Enumerable.ts | 5 +- .../examples/ER721EnumerableMetadata.ts | 47 +++++++++++ .../contracts/MRC721/metadata/index.ts | 2 + .../MRC721/metadata/metadata-internal.ts | 78 ++++++++++++++++++ .../contracts/MRC721/metadata/metadata.ts | 27 +++++++ 9 files changed, 249 insertions(+), 21 deletions(-) rename smart-contracts/assembly/contracts/MRC721/__tests__/{MRC721-example.spec.ts => MRC721.spec.ts} (98%) create mode 100644 smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts create mode 100644 smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts create mode 100644 smart-contracts/assembly/contracts/MRC721/metadata/index.ts create mode 100644 smart-contracts/assembly/contracts/MRC721/metadata/metadata-internal.ts create mode 100644 smart-contracts/assembly/contracts/MRC721/metadata/metadata.ts diff --git a/smart-contracts/assembly/contracts/MRC20/__tests__/wrapper.spec.ts b/smart-contracts/assembly/contracts/MRC20/__tests__/wrapper.spec.ts index f2996fd..e46e929 100644 --- a/smart-contracts/assembly/contracts/MRC20/__tests__/wrapper.spec.ts +++ b/smart-contracts/assembly/contracts/MRC20/__tests__/wrapper.spec.ts @@ -1,8 +1,7 @@ +// These tests serve as an example of how to use the MRC20Wrapper class to interact with the MRC20 contract. import { MRC20Wrapper } from '../wrapper'; import { Address, - balance, - balanceOf, changeCallStack, mockBalance, mockScCall, @@ -14,13 +13,17 @@ import { u256 } from 'as-bignum/assembly'; const tokenName = 'myToken'; const userAddr = 'AU1mhPhXCfh8afoNnbW91bXUVAmu8wU7u8v54yNTMvY7E52KBbz3'; -const tokenAddress = 'AU12BqZEQ6sByhRLyEuf0YbQmcF2PsDdkNNG1akBJu9XcjZA1eT'; +const tokenAddress = 'AS12BqZEQ6sByhRLyEuf0YbQmcF2PsDdkNNG1akBJu9XcjZA1eT'; const tokenContract = new MRC20Wrapper(new Address(tokenAddress)); +function switchUser(user: string): void { + changeCallStack(user + ' , ' + tokenAddress); +} + describe('Wrapper tests', () => { beforeAll(() => { - changeCallStack(userAddr + ' , ' + tokenAddress); + switchUser(userAddr); }); test('token name', () => { @@ -45,9 +48,6 @@ describe('Wrapper tests', () => { mockScCall([]); tokenContract.transfer(recipient, amount); - - expect(balance()).toBe(0); - expect(balanceOf(tokenAddress)).toBe(0); }); test('transfer with coins', () => { @@ -61,7 +61,5 @@ describe('Wrapper tests', () => { mockScCall([]); tokenContract.transfer(recipient, amount, coins); - expect(balance()).toBe(0); - expect(balanceOf(tokenAddress)).toBe(0); }); }); diff --git a/smart-contracts/assembly/contracts/MRC721/MRC721.ts b/smart-contracts/assembly/contracts/MRC721/MRC721.ts index e2eda0d..f24a86f 100644 --- a/smart-contracts/assembly/contracts/MRC721/MRC721.ts +++ b/smart-contracts/assembly/contracts/MRC721/MRC721.ts @@ -35,9 +35,10 @@ import { onlyOwner } from '../utils/ownership'; import { Context, isDeployingContract } from '@massalabs/massa-as-sdk'; import { _setOwner } from '../utils/ownership-internal'; +const NAME = 'MASSA_NFT'; +const SYMBOL = 'NFT'; + /** - * @param binaryArgs - serialized strings representing the name and the symbol of the NFT - * * @remarks This is the constructor of the contract. It can only be called once, when the contract is being deployed. * It expects two serialized arguments: the name and the symbol of the NFT. * Once the constructor has handled the deserialization, of the arguments, @@ -45,14 +46,9 @@ import { _setOwner } from '../utils/ownership-internal'; * * Finally, it sets the owner of the contract to the caller of the constructor. */ -export function constructor(binaryArgs: StaticArray): void { +export function constructor(_: StaticArray): void { assert(isDeployingContract()); - const args = new Args(binaryArgs); - const name = args.nextString().expect('name argument is missing or invalid'); - const symbol = args - .nextString() - .expect('symbol argument is missing or invalid'); - _constructor(name, symbol); + _constructor(NAME, SYMBOL); _setOwner(Context.caller().toString()); } diff --git a/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721-example.spec.ts b/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721.spec.ts similarity index 98% rename from smart-contracts/assembly/contracts/MRC721/__tests__/MRC721-example.spec.ts rename to smart-contracts/assembly/contracts/MRC721/__tests__/MRC721.spec.ts index 47638c0..1b0d782 100644 --- a/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721-example.spec.ts +++ b/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721.spec.ts @@ -45,7 +45,7 @@ beforeEach(() => { resetStorage(); switchUser(contractOwner); setDeployContext(contractOwner); - constructor(new Args().add(NFTName).add(NFTSymbol).serialize()); + constructor([]); }); describe('Initialization', () => { diff --git a/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts b/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts new file mode 100644 index 0000000..d594ff2 --- /dev/null +++ b/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts @@ -0,0 +1,79 @@ +import { resetStorage, setDeployContext } from '@massalabs/massa-as-sdk'; +import { Args, NoArg, stringToBytes } from '@massalabs/as-types'; +import { constructor } from '../MRC721'; +import { u256 } from 'as-bignum/assembly'; +import { + _baseURI, + _setBaseURI, + _setURI, + _tokenURI, + _uri, + uri, +} from '../metadata'; + +const user1Address = 'AU12UBnqTHDQALpocVBnkPNy7y5CndUJQTLutaVDDFgMJcq5kQiKq'; + +const TOKEN_URI = 'ipfs://QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'; + +beforeEach(() => { + resetStorage(); + setDeployContext(user1Address); + constructor(NoArg.serialize()); +}); + +describe('_setBaseURI', () => { + test('should set base URI', () => { + const newBaseUri = 'ipfs://QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'; + _setBaseURI(newBaseUri); + expect(_baseURI()).toStrictEqual(newBaseUri); + }); +}); + +describe('_setURI', () => { + test('should set URI', () => { + const id = u256.One; + const newUri = 'QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'; + _setURI(id, newUri); + expect(_tokenURI(id)).toStrictEqual(newUri); + }); +}); + +describe('_uri', () => { + test('should return token URI without base', () => { + const id = u256.One; + const newUri = 'QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'; + _setURI(id, newUri); + expect(_uri(id)).toStrictEqual(newUri); + }); + + test('should return token URI with base', () => { + const id = u256.One; + const newUri = 'QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'; + _setURI(id, newUri); + _setBaseURI('ipfs://'); + expect(_uri(id)).toStrictEqual('ipfs://' + newUri); + }); +}); + +describe('uri', () => { + test('should return token URI without base', () => { + const id = u256.One; + const newUri = 'QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'; + + _setURI(id, newUri); + expect(uri(new Args().add(id).serialize())).toStrictEqual( + stringToBytes(newUri), + ); + }); + + test('should return token URI with base', () => { + const id = u256.One; + const newUri = 'QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'; + + _setURI(id, newUri); + _setBaseURI('ipfs://'); + expect(uri(new Args().add(id).serialize())).toStrictEqual( + stringToBytes('ipfs://' + newUri), + ); + }); +}); diff --git a/smart-contracts/assembly/contracts/MRC721/enumerable/MRC721Enumerable.ts b/smart-contracts/assembly/contracts/MRC721/enumerable/MRC721Enumerable.ts index 4a66792..bfc9b7e 100644 --- a/smart-contracts/assembly/contracts/MRC721/enumerable/MRC721Enumerable.ts +++ b/smart-contracts/assembly/contracts/MRC721/enumerable/MRC721Enumerable.ts @@ -61,7 +61,8 @@ import { _transferFrom, _totalSupply, } from './MRC721Enumerable-internals'; -import { setOwner, onlyOwner } from '../../utils/ownership'; +import { onlyOwner } from '../../utils/ownership'; +import { _setOwner } from '../../utils/ownership-internal'; import { Context, isDeployingContract } from '@massalabs/massa-as-sdk'; const NAME = 'MASSA_NFT'; @@ -80,7 +81,7 @@ const SYMBOL = 'NFT'; export function constructor(_: StaticArray): void { assert(isDeployingContract()); _constructor(NAME, SYMBOL); - setOwner(new Args().add(Context.caller().toString()).serialize()); + _setOwner(Context.caller().toString()); } /** diff --git a/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts b/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts new file mode 100644 index 0000000..23c94e8 --- /dev/null +++ b/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts @@ -0,0 +1,47 @@ +import { Args } from '@massalabs/as-types'; +import { _setBaseURI } from '../metadata/metadata-internal'; +import { onlyOwner } from '../../utils'; +import { Context, isDeployingContract } from '@massalabs/massa-as-sdk'; +import { _setOwner } from '../../utils/ownership-internal'; +import { _constructor } from '../enumerable'; + +const NAME = 'MassaNft'; +const SYMBOL = 'MNFT'; +const BASE_URI = 'ipfs://QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'; + +export function constructor(_binaryArgs: StaticArray): void { + assert(isDeployingContract()); + _setOwner(Context.caller().toString()); + _constructor(NAME, SYMBOL); + _setBaseURI(BASE_URI); +} + +/** + * Set the base URI for all token IDs + * @param newBaseUri - the new base URI + */ +export function setBaseURI(_args: StaticArray): void { + onlyOwner(); + const args = new Args(_args); + const newBaseUri = args + .nextString() + .expect('newBaseUri argument is missing or invalid'); + + _setBaseURI(newBaseUri); +} + +export { + isApprovedForAll, + setApprovalForAll, + totalSupply, + getApproved, + approve, + transferFrom, + balanceOf, + symbol, + name, + // mint, // Add this line if you want your contract to be able to mint tokens + // burn, // Add this line if you want your contract to be able to burn tokens +} from '../enumerable/MRC721Enumerable'; +export { uri } from '../metadata/metadata'; +export { setOwner, ownerAddress } from '../../utils/ownership'; diff --git a/smart-contracts/assembly/contracts/MRC721/metadata/index.ts b/smart-contracts/assembly/contracts/MRC721/metadata/index.ts new file mode 100644 index 0000000..57cb764 --- /dev/null +++ b/smart-contracts/assembly/contracts/MRC721/metadata/index.ts @@ -0,0 +1,2 @@ +export * from './metadata'; +export * from './metadata-internal'; diff --git a/smart-contracts/assembly/contracts/MRC721/metadata/metadata-internal.ts b/smart-contracts/assembly/contracts/MRC721/metadata/metadata-internal.ts new file mode 100644 index 0000000..df42b6d --- /dev/null +++ b/smart-contracts/assembly/contracts/MRC721/metadata/metadata-internal.ts @@ -0,0 +1,78 @@ +import { bytesToString, stringToBytes, u256ToBytes } from '@massalabs/as-types'; +import { Storage, createEvent, generateEvent } from '@massalabs/massa-as-sdk'; +import { u256 } from 'as-bignum/assembly'; + +export const BASE_URI_KEY = stringToBytes('BASE_URI'); +export const TOKENS_URI_KEY = stringToBytes('TOKENS_URI'); +export const URI_EVENT: string = 'URI'; + +/** + * @returns the key for the base uri + */ +function baseUriKey(): StaticArray { + return BASE_URI_KEY; +} + +/** + * @param id - the id of the token + * @returns the key for the token uri + */ +function tokenUrisKey(id: u256): StaticArray { + return TOKENS_URI_KEY.concat(u256ToBytes(id)); +} + +/** + * Set the base URI for all token IDs + * @param newBaseUri - the new base URI + */ +export function _setBaseURI(newBaseUri: string): void { + const baseURIKey = baseUriKey(); + Storage.set(baseURIKey, stringToBytes(newBaseUri)); +} + +/** + * @returns the base URI + */ +export function _baseURI(): string { + return Storage.has(BASE_URI_KEY) + ? bytesToString(Storage.get(BASE_URI_KEY)) + : ''; +} + +/** + * @param id - the id of the token + * @returns the URI for the token + */ +export function _tokenURI(id: u256): string { + const tokenUriKey = tokenUrisKey(id); + const tokenUri = Storage.has(tokenUriKey) + ? bytesToString(Storage.get(tokenUriKey)) + : ''; + + return tokenUri; +} + +/** + * Set the URI for a token + * @param id - the id of the token + * @param newUri - the new URI + */ +export function _setURI(id: u256, newUri: string): void { + const tokenUriKey = tokenUrisKey(id); + + Storage.set(tokenUriKey, stringToBytes(newUri)); + generateEvent(createEvent(URI_EVENT, [newUri, id.toString()])); +} + +/** + * Returns the URI for a given token ID. + * + * It returns the base uri concatenated to the tokenUri if the tokenUri is not empty + * And if it is empty it returns the super uri from token-internal + * + * @param id - The token ID + * @returns the URI for the given token ID + */ +export function _uri(id: u256): string { + return _baseURI().concat(_tokenURI(id)); +} diff --git a/smart-contracts/assembly/contracts/MRC721/metadata/metadata.ts b/smart-contracts/assembly/contracts/MRC721/metadata/metadata.ts new file mode 100644 index 0000000..c3b1035 --- /dev/null +++ b/smart-contracts/assembly/contracts/MRC721/metadata/metadata.ts @@ -0,0 +1,27 @@ +/** + * + * This is an extension to the MRC1155 standard. + * + * It allows to store uri for each token id + * It should be used with the internal functions from metadata-internal + * + */ + +import { _uri } from './metadata-internal'; +import { Args, stringToBytes } from '@massalabs/as-types'; + +/** + * + * Get the URI for a token id + * + * @param id - the id of the token + * + * @returns the URI for the token + * + */ +export function uri(binaryArgs: StaticArray): StaticArray { + const args = new Args(binaryArgs); + const id = args.nextU256().expect('id argument is missing or invalid'); + + return stringToBytes(_uri(id)); +} From bb9e511e903b85cce1872d4b0165213d778e845c Mon Sep 17 00:00:00 2001 From: BenRey Date: Mon, 9 Dec 2024 11:26:06 +0100 Subject: [PATCH 2/8] Remove unused TOKEN_URI constant from metadata tests --- .../assembly/contracts/MRC721/__tests__/metadata.spec.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts b/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts index d594ff2..d4193fb 100644 --- a/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts +++ b/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts @@ -13,8 +13,6 @@ import { const user1Address = 'AU12UBnqTHDQALpocVBnkPNy7y5CndUJQTLutaVDDFgMJcq5kQiKq'; -const TOKEN_URI = 'ipfs://QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'; - beforeEach(() => { resetStorage(); setDeployContext(user1Address); From 3389e74e34f369e48fc31689bd18d076f2ec827d Mon Sep 17 00:00:00 2001 From: BenRey Date: Mon, 9 Dec 2024 11:48:43 +0100 Subject: [PATCH 3/8] Refactor MRC721 constructor to accept dynamic name and symbol parameters --- smart-contracts/assembly/contracts/MRC721/MRC721.ts | 10 +++++----- .../contracts/MRC721/enumerable/MRC721Enumerable.ts | 7 ++----- .../MRC721/examples/ER721EnumerableMetadata.ts | 8 +++----- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/smart-contracts/assembly/contracts/MRC721/MRC721.ts b/smart-contracts/assembly/contracts/MRC721/MRC721.ts index f24a86f..98c442f 100644 --- a/smart-contracts/assembly/contracts/MRC721/MRC721.ts +++ b/smart-contracts/assembly/contracts/MRC721/MRC721.ts @@ -35,10 +35,9 @@ import { onlyOwner } from '../utils/ownership'; import { Context, isDeployingContract } from '@massalabs/massa-as-sdk'; import { _setOwner } from '../utils/ownership-internal'; -const NAME = 'MASSA_NFT'; -const SYMBOL = 'NFT'; - /** + * @param binaryArgs - serialized strings representing the name and the symbol of the NFT + * * @remarks This is the constructor of the contract. It can only be called once, when the contract is being deployed. * It expects two serialized arguments: the name and the symbol of the NFT. * Once the constructor has handled the deserialization, of the arguments, @@ -46,9 +45,10 @@ const SYMBOL = 'NFT'; * * Finally, it sets the owner of the contract to the caller of the constructor. */ -export function constructor(_: StaticArray): void { +export function constructor(name: string, symbol: string): void { assert(isDeployingContract()); - _constructor(NAME, SYMBOL); + + _constructor(name, symbol); _setOwner(Context.caller().toString()); } diff --git a/smart-contracts/assembly/contracts/MRC721/enumerable/MRC721Enumerable.ts b/smart-contracts/assembly/contracts/MRC721/enumerable/MRC721Enumerable.ts index bfc9b7e..f9e4006 100644 --- a/smart-contracts/assembly/contracts/MRC721/enumerable/MRC721Enumerable.ts +++ b/smart-contracts/assembly/contracts/MRC721/enumerable/MRC721Enumerable.ts @@ -65,9 +65,6 @@ import { onlyOwner } from '../../utils/ownership'; import { _setOwner } from '../../utils/ownership-internal'; import { Context, isDeployingContract } from '@massalabs/massa-as-sdk'; -const NAME = 'MASSA_NFT'; -const SYMBOL = 'NFT'; - /** * @param binaryArgs - serialized strings representing the name and the symbol of the NFT * @@ -78,9 +75,9 @@ const SYMBOL = 'NFT'; * * Finally, it sets the owner of the contract to the caller of the constructor. */ -export function constructor(_: StaticArray): void { +export function constructor(name: string, symbol: string): void { assert(isDeployingContract()); - _constructor(NAME, SYMBOL); + _constructor(name, symbol); _setOwner(Context.caller().toString()); } diff --git a/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts b/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts index 23c94e8..7d18105 100644 --- a/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts +++ b/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts @@ -1,9 +1,8 @@ import { Args } from '@massalabs/as-types'; import { _setBaseURI } from '../metadata/metadata-internal'; import { onlyOwner } from '../../utils'; -import { Context, isDeployingContract } from '@massalabs/massa-as-sdk'; -import { _setOwner } from '../../utils/ownership-internal'; -import { _constructor } from '../enumerable'; +import { isDeployingContract } from '@massalabs/massa-as-sdk'; +import { constructor as mrc721Constructor } from '../enumerable'; const NAME = 'MassaNft'; const SYMBOL = 'MNFT'; @@ -11,8 +10,7 @@ const BASE_URI = 'ipfs://QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'; export function constructor(_binaryArgs: StaticArray): void { assert(isDeployingContract()); - _setOwner(Context.caller().toString()); - _constructor(NAME, SYMBOL); + mrc721Constructor(NAME, SYMBOL); _setBaseURI(BASE_URI); } From d1365a0004130ff3fbff63d090a6b9c28e126b38 Mon Sep 17 00:00:00 2001 From: BenRey Date: Mon, 9 Dec 2024 11:50:22 +0100 Subject: [PATCH 4/8] Update constructor in ER721EnumerableMetadata to use hardcoded name and symbol values --- .../contracts/MRC721/examples/ER721EnumerableMetadata.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts b/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts index 7d18105..85f2079 100644 --- a/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts +++ b/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts @@ -4,14 +4,10 @@ import { onlyOwner } from '../../utils'; import { isDeployingContract } from '@massalabs/massa-as-sdk'; import { constructor as mrc721Constructor } from '../enumerable'; -const NAME = 'MassaNft'; -const SYMBOL = 'MNFT'; -const BASE_URI = 'ipfs://QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'; - export function constructor(_binaryArgs: StaticArray): void { assert(isDeployingContract()); - mrc721Constructor(NAME, SYMBOL); - _setBaseURI(BASE_URI); + mrc721Constructor('MassaNft', 'MNFT'); + _setBaseURI('ipfs://QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'); } /** From 0414b29b43cfeaabce51aee8d9cbfd0453b7ac34 Mon Sep 17 00:00:00 2001 From: BenRey Date: Mon, 9 Dec 2024 11:55:07 +0100 Subject: [PATCH 5/8] Update constructor documentation in MRC721 to clarify parameters and usage --- smart-contracts/assembly/contracts/MRC721/MRC721.ts | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/smart-contracts/assembly/contracts/MRC721/MRC721.ts b/smart-contracts/assembly/contracts/MRC721/MRC721.ts index 98c442f..a6d6d2d 100644 --- a/smart-contracts/assembly/contracts/MRC721/MRC721.ts +++ b/smart-contracts/assembly/contracts/MRC721/MRC721.ts @@ -36,14 +36,9 @@ import { Context, isDeployingContract } from '@massalabs/massa-as-sdk'; import { _setOwner } from '../utils/ownership-internal'; /** - * @param binaryArgs - serialized strings representing the name and the symbol of the NFT - * - * @remarks This is the constructor of the contract. It can only be called once, when the contract is being deployed. - * It expects two serialized arguments: the name and the symbol of the NFT. - * Once the constructor has handled the deserialization, of the arguments, - * it calls the _constructor function from the NFT-internals. - * - * Finally, it sets the owner of the contract to the caller of the constructor. + * @param name - the name of the NFT + * @param symbol - the symbol of the NFT + * @remarks You must call this function in your contract's constructor !!! */ export function constructor(name: string, symbol: string): void { assert(isDeployingContract()); From 4451a982676bc14fe28a48ad9a3848c68409d8fc Mon Sep 17 00:00:00 2001 From: BenRey Date: Mon, 9 Dec 2024 12:00:04 +0100 Subject: [PATCH 6/8] Refactor MRC1155 and MRC721 tests to use dynamic NFT name and symbol parameters --- .../{MRC1155-exemple.ts => example/MRC1155.ts} | 16 ++++++++-------- .../contracts/MRC721/__tests__/MRC721.spec.ts | 2 +- .../MRC721/__tests__/MRC721Enumerable.spec.ts | 2 +- .../contracts/MRC721/__tests__/metadata.spec.ts | 4 ++-- 4 files changed, 12 insertions(+), 12 deletions(-) rename smart-contracts/assembly/contracts/MRC1155/{MRC1155-exemple.ts => example/MRC1155.ts} (78%) diff --git a/smart-contracts/assembly/contracts/MRC1155/MRC1155-exemple.ts b/smart-contracts/assembly/contracts/MRC1155/example/MRC1155.ts similarity index 78% rename from smart-contracts/assembly/contracts/MRC1155/MRC1155-exemple.ts rename to smart-contracts/assembly/contracts/MRC1155/example/MRC1155.ts index 165acbc..2eeb0b9 100644 --- a/smart-contracts/assembly/contracts/MRC1155/MRC1155-exemple.ts +++ b/smart-contracts/assembly/contracts/MRC1155/example/MRC1155.ts @@ -1,9 +1,9 @@ import { Args, stringToBytes } from '@massalabs/as-types'; import { u256 } from 'as-bignum/assembly'; -import * as token from './MRC1155'; -import * as mint from './mintable/mint'; +import * as token from '../MRC1155'; +import * as mint from '../mintable/mint'; import { Context } from '@massalabs/massa-as-sdk'; -import { grantRole } from '../utils/accessControl'; +import { grantRole } from '../../utils/accessControl'; export function constructor(binaryArgs: StaticArray): void { const args = new Args(binaryArgs); @@ -31,10 +31,10 @@ export function constructor(binaryArgs: StaticArray): void { ); } -export * from './burnable/burn'; -export * from './mintable/mint'; -export * from '../utils/accessControl'; -export * from '../utils/ownership'; +export * from '../burnable/burn'; +export * from '../mintable/mint'; +export * from '../../utils/accessControl'; +export * from '../../utils/ownership'; // export everything from the token module except the constructor export { uri, @@ -44,4 +44,4 @@ export { isApprovedForAll, safeTransferFrom, safeBatchTransferFrom, -} from './MRC1155'; +} from '../MRC1155'; diff --git a/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721.spec.ts b/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721.spec.ts index 1b0d782..3a0f07f 100644 --- a/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721.spec.ts +++ b/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721.spec.ts @@ -45,7 +45,7 @@ beforeEach(() => { resetStorage(); switchUser(contractOwner); setDeployContext(contractOwner); - constructor([]); + constructor(NFTName, NFTSymbol); }); describe('Initialization', () => { diff --git a/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721Enumerable.spec.ts b/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721Enumerable.spec.ts index efc2a0c..eea18c3 100644 --- a/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721Enumerable.spec.ts +++ b/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721Enumerable.spec.ts @@ -56,7 +56,7 @@ beforeEach(() => { resetStorage(); switchUser(contractOwner); setDeployContext(contractOwner); - constructor(NoArg.serialize()); + constructor(NFTName, NFTSymbol); }); describe('NFT Enumerable Contract', () => { diff --git a/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts b/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts index d4193fb..8c56f91 100644 --- a/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts +++ b/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts @@ -1,5 +1,5 @@ import { resetStorage, setDeployContext } from '@massalabs/massa-as-sdk'; -import { Args, NoArg, stringToBytes } from '@massalabs/as-types'; +import { Args, stringToBytes } from '@massalabs/as-types'; import { constructor } from '../MRC721'; import { u256 } from 'as-bignum/assembly'; import { @@ -16,7 +16,7 @@ const user1Address = 'AU12UBnqTHDQALpocVBnkPNy7y5CndUJQTLutaVDDFgMJcq5kQiKq'; beforeEach(() => { resetStorage(); setDeployContext(user1Address); - constructor(NoArg.serialize()); + constructor('MassaNft', 'MNFT'); }); describe('_setBaseURI', () => { From d3e76387534d6d4a9223b2844adc392e2bab330e Mon Sep 17 00:00:00 2001 From: BenRey Date: Mon, 9 Dec 2024 14:28:41 +0100 Subject: [PATCH 7/8] Refactor constructors in MRC20, MRC721, and MRC1155 to use specific naming conventions --- .../assembly/contracts/MRC1155/MRC1155.ts | 8 ++- .../MRC1155/__tests__/MRC1155.spec.ts | 4 +- .../MRC1155/__tests__/burnable.spec.ts | 4 +- .../MRC1155/__tests__/metadata.spec.ts | 5 +- .../MRC1155/__tests__/mintable.spec.ts | 4 +- .../contracts/MRC1155/example/MRC1155.ts | 6 ++- .../assembly/contracts/MRC20/MRC20.ts | 50 +++++-------------- .../MRC20/__tests__/MRC20-burn.spec.ts | 11 +--- .../MRC20/__tests__/MRC20-mint.spec.ts | 11 +--- .../contracts/MRC20/__tests__/MRC20.spec.ts | 11 +--- .../contracts/MRC20/__tests__/WMAS.spec.ts | 6 +-- .../assembly/contracts/MRC20/example/MRC20.ts | 19 +++++++ .../assembly/contracts/MRC721/MRC721.ts | 4 +- .../contracts/MRC721/__tests__/MRC721.spec.ts | 4 +- .../MRC721/__tests__/MRC721Enumerable.spec.ts | 5 +- .../MRC721/__tests__/metadata.spec.ts | 4 +- .../MRC721/enumerable/MRC721Enumerable.ts | 13 ++--- .../examples/ER721EnumerableMetadata.ts | 2 +- 18 files changed, 68 insertions(+), 103 deletions(-) create mode 100644 smart-contracts/assembly/contracts/MRC20/example/MRC20.ts diff --git a/smart-contracts/assembly/contracts/MRC1155/MRC1155.ts b/smart-contracts/assembly/contracts/MRC1155/MRC1155.ts index 3fa76ee..49939bd 100644 --- a/smart-contracts/assembly/contracts/MRC1155/MRC1155.ts +++ b/smart-contracts/assembly/contracts/MRC1155/MRC1155.ts @@ -40,15 +40,13 @@ import { _setOwner } from '../utils/ownership-internal'; /** * Constructs a new Multi-NFT contract. * + * @remarks You must call this function in your contract's constructor or re-write it to fit your needs ! + * * @param uri - the URI for the NFT contract */ -export function constructor(binaryArgs: StaticArray): void { +export function mrc1155Constructor(uri: string): void { assert(isDeployingContract()); - const args = new Args(binaryArgs); - const uri = args.nextString().expect('uri argument is missing or invalid'); - _setOwner(Context.caller().toString()); - _constructor(uri); } diff --git a/smart-contracts/assembly/contracts/MRC1155/__tests__/MRC1155.spec.ts b/smart-contracts/assembly/contracts/MRC1155/__tests__/MRC1155.spec.ts index eaee45f..3eb5ccf 100644 --- a/smart-contracts/assembly/contracts/MRC1155/__tests__/MRC1155.spec.ts +++ b/smart-contracts/assembly/contracts/MRC1155/__tests__/MRC1155.spec.ts @@ -15,8 +15,8 @@ import { import { balanceOf, balanceOfBatch, - constructor, isApprovedForAll, + mrc1155Constructor, safeBatchTransferFrom, safeTransferFrom, setApprovalForAll, @@ -48,7 +48,7 @@ beforeEach(() => { switchUser(user1Address); resetStorage(); setDeployContext(user1Address); - constructor(new Args().add(stringToBytes(TOKEN_URI)).serialize()); + mrc1155Constructor(TOKEN_URI); }); describe('Initialization', () => { diff --git a/smart-contracts/assembly/contracts/MRC1155/__tests__/burnable.spec.ts b/smart-contracts/assembly/contracts/MRC1155/__tests__/burnable.spec.ts index 51885cb..afb848c 100644 --- a/smart-contracts/assembly/contracts/MRC1155/__tests__/burnable.spec.ts +++ b/smart-contracts/assembly/contracts/MRC1155/__tests__/burnable.spec.ts @@ -13,7 +13,7 @@ import { import { balanceOf, balanceOfBatch, - constructor, + mrc1155Constructor, setApprovalForAll, } from '../MRC1155'; import { u256 } from 'as-bignum/assembly'; @@ -37,7 +37,7 @@ beforeEach(() => { switchUser(user1Address); resetStorage(); setDeployContext(user1Address); - constructor(new Args().add(stringToBytes(TOKEN_URI)).serialize()); + mrc1155Constructor(TOKEN_URI); }); describe('burn', () => { diff --git a/smart-contracts/assembly/contracts/MRC1155/__tests__/metadata.spec.ts b/smart-contracts/assembly/contracts/MRC1155/__tests__/metadata.spec.ts index 1690cc0..4958abb 100644 --- a/smart-contracts/assembly/contracts/MRC1155/__tests__/metadata.spec.ts +++ b/smart-contracts/assembly/contracts/MRC1155/__tests__/metadata.spec.ts @@ -1,6 +1,6 @@ import { resetStorage, setDeployContext } from '@massalabs/massa-as-sdk'; import { Args, stringToBytes } from '@massalabs/as-types'; -import { constructor } from '../MRC1155'; + import { u256 } from 'as-bignum/assembly'; import { _baseURI, @@ -10,6 +10,7 @@ import { _uri, uri, } from '../metadata'; +import { mrc1155Constructor } from '../MRC1155'; const user1Address = 'AU12UBnqTHDQALpocVBnkPNy7y5CndUJQTLutaVDDFgMJcq5kQiKq'; @@ -18,7 +19,7 @@ const TOKEN_URI = 'ipfs://QmW77ZQQ7Jm9q8WuLbH8YZg2K7T9Qnjbzm7jYVQQrJY5Yd'; beforeEach(() => { resetStorage(); setDeployContext(user1Address); - constructor(new Args().add(stringToBytes(TOKEN_URI)).serialize()); + mrc1155Constructor(TOKEN_URI); }); describe('_setBaseURI', () => { diff --git a/smart-contracts/assembly/contracts/MRC1155/__tests__/mintable.spec.ts b/smart-contracts/assembly/contracts/MRC1155/__tests__/mintable.spec.ts index ddd77ac..a3acf8d 100644 --- a/smart-contracts/assembly/contracts/MRC1155/__tests__/mintable.spec.ts +++ b/smart-contracts/assembly/contracts/MRC1155/__tests__/mintable.spec.ts @@ -4,7 +4,7 @@ import { setDeployContext, } from '@massalabs/massa-as-sdk'; import { Args, stringToBytes, u256ToBytes } from '@massalabs/as-types'; -import { balanceOf, constructor } from '../MRC1155'; +import { balanceOf, mrc1155Constructor } from '../MRC1155'; import { u256 } from 'as-bignum/assembly'; import { _balanceOfBatch } from '../MRC1155-internal'; import { MINTER_ROLE, mint, mintBatch } from '..'; @@ -27,7 +27,7 @@ beforeEach(() => { switchUser(user1Address); resetStorage(); setDeployContext(user1Address); - constructor(new Args().add(stringToBytes(TOKEN_URI)).serialize()); + mrc1155Constructor(TOKEN_URI); }); describe('mint', () => { diff --git a/smart-contracts/assembly/contracts/MRC1155/example/MRC1155.ts b/smart-contracts/assembly/contracts/MRC1155/example/MRC1155.ts index 2eeb0b9..d17a706 100644 --- a/smart-contracts/assembly/contracts/MRC1155/example/MRC1155.ts +++ b/smart-contracts/assembly/contracts/MRC1155/example/MRC1155.ts @@ -1,6 +1,6 @@ import { Args, stringToBytes } from '@massalabs/as-types'; import { u256 } from 'as-bignum/assembly'; -import * as token from '../MRC1155'; +import { mrc1155Constructor } from '../MRC1155'; import * as mint from '../mintable/mint'; import { Context } from '@massalabs/massa-as-sdk'; import { grantRole } from '../../utils/accessControl'; @@ -14,7 +14,9 @@ export function constructor(binaryArgs: StaticArray): void { const amounts = args .nextFixedSizeArray() .expect('amounts argument is missing or invalid'); - token.constructor(new Args().add(uri).serialize()); + + mrc1155Constructor(uri); + grantRole( new Args() .add(mint.MINTER_ROLE) diff --git a/smart-contracts/assembly/contracts/MRC20/MRC20.ts b/smart-contracts/assembly/contracts/MRC20/MRC20.ts index a52671e..a778dbc 100644 --- a/smart-contracts/assembly/contracts/MRC20/MRC20.ts +++ b/smart-contracts/assembly/contracts/MRC20/MRC20.ts @@ -22,55 +22,29 @@ export const DECIMALS_KEY = stringToBytes('DECIMALS'); /** * Initialize the ERC20 contract - * Can be called only once * - * @example - * ```typescript - * constructor( - * new Args() - * .add('TOKEN_NAME') - * .add('TOKEN_SYMBOL') - * .add(3) // decimals - * .add(1000) // total supply - * .serialize(), - * ); - * ``` + * @remarks You must call this function in your contract's constructor or re-write it to fit your needs ! * - * @param stringifyArgs - Args object serialized as a string containing: - * - the token name (string) - * - the token symbol (string). - * - the decimals (u8). - * - the totalSupply (u256) - * - first owner (address)e + * @param name - the name of the token + * @param symbol - the symbol of the token + * @param decimals - the number of decimals + * @param totalSupply - the total supply of the token */ -export function constructor(stringifyArgs: StaticArray): void { +export function mrc20Constructor( + name: string, + symbol: string, + decimals: u8, + totalSupply: u256, +): void { assert(isDeployingContract()); - const args = new Args(stringifyArgs); - - // initialize token name - const name = args.nextString().expect('Error while initializing tokenName'); Storage.set(NAME_KEY, stringToBytes(name)); - - // initialize token symbol - const symbol = args - .nextString() - .expect('Error while initializing tokenSymbol'); Storage.set(SYMBOL_KEY, stringToBytes(symbol)); - - // initialize token decimals - const decimals = args - .nextU8() - .expect('Error while initializing tokenDecimals'); Storage.set(DECIMALS_KEY, [decimals]); - - // initialize totalSupply - const totalSupply = args - .nextU256() - .expect('Error while initializing totalSupply'); Storage.set(TOTAL_SUPPLY_KEY, u256ToBytes(totalSupply)); setOwner(new Args().add(Context.caller().toString()).serialize()); + _setBalance(Context.caller(), totalSupply); } diff --git a/smart-contracts/assembly/contracts/MRC20/__tests__/MRC20-burn.spec.ts b/smart-contracts/assembly/contracts/MRC20/__tests__/MRC20-burn.spec.ts index f9b0c6b..fe7fac2 100644 --- a/smart-contracts/assembly/contracts/MRC20/__tests__/MRC20-burn.spec.ts +++ b/smart-contracts/assembly/contracts/MRC20/__tests__/MRC20-burn.spec.ts @@ -18,7 +18,7 @@ import { symbol, decimals, version, - constructor, + mrc20Constructor, increaseAllowance, transfer, allowance, @@ -51,14 +51,7 @@ const DECIMALS: u8 = 2; const TOTAL_SUPPLY = new u256(10000, 0, 0, 100); describe('ERC20 BURN - Initialization', () => { - constructor( - new Args() - .add(TOKEN_NAME) - .add(TOKEN_SYMBOL) - .add(DECIMALS) - .add(TOTAL_SUPPLY) - .serialize(), - ); + mrc20Constructor(TOKEN_NAME, TOKEN_SYMBOL, DECIMALS, TOTAL_SUPPLY); test('total supply is properly initialized', () => { expect(totalSupply([])).toStrictEqual(u256ToBytes(TOTAL_SUPPLY)); diff --git a/smart-contracts/assembly/contracts/MRC20/__tests__/MRC20-mint.spec.ts b/smart-contracts/assembly/contracts/MRC20/__tests__/MRC20-mint.spec.ts index 760311f..703cdd2 100644 --- a/smart-contracts/assembly/contracts/MRC20/__tests__/MRC20-mint.spec.ts +++ b/smart-contracts/assembly/contracts/MRC20/__tests__/MRC20-mint.spec.ts @@ -14,7 +14,7 @@ import { mint } from '../mintable/mint'; import { VERSION, balanceOf, - constructor, + mrc20Constructor, decimals, name, symbol, @@ -43,14 +43,7 @@ const TOTAL_SUPPLY = new u256(10000, 1000, 100, 10); beforeAll(() => { resetStorage(); setDeployContext(user1Address); - constructor( - new Args() - .add(TOKEN_NAME) - .add(TOKEN_SYMBOL) - .add(DECIMALS) - .add(TOTAL_SUPPLY) - .serialize(), - ); + mrc20Constructor(TOKEN_NAME, TOKEN_SYMBOL, DECIMALS, TOTAL_SUPPLY); }); describe('ERC20 MINT - Initialization', () => { diff --git a/smart-contracts/assembly/contracts/MRC20/__tests__/MRC20.spec.ts b/smart-contracts/assembly/contracts/MRC20/__tests__/MRC20.spec.ts index 0fc30ef..2769794 100644 --- a/smart-contracts/assembly/contracts/MRC20/__tests__/MRC20.spec.ts +++ b/smart-contracts/assembly/contracts/MRC20/__tests__/MRC20.spec.ts @@ -23,7 +23,7 @@ import { allowance, increaseAllowance, decreaseAllowance, - constructor, + mrc20Constructor, VERSION, } from '../MRC20'; import { u256 } from 'as-bignum/assembly'; @@ -49,14 +49,7 @@ function switchUser(user: string): void { beforeAll(() => { resetStorage(); setDeployContext(user1Address); - constructor( - new Args() - .add(TOKEN_NAME) - .add(TOKEN_SYMBOL) - .add(DECIMALS) - .add(TOTAL_SUPPLY) - .serialize(), - ); + mrc20Constructor(TOKEN_NAME, TOKEN_SYMBOL, DECIMALS, TOTAL_SUPPLY); }); describe('Initialization', () => { diff --git a/smart-contracts/assembly/contracts/MRC20/__tests__/WMAS.spec.ts b/smart-contracts/assembly/contracts/MRC20/__tests__/WMAS.spec.ts index 6446c4c..d404a22 100644 --- a/smart-contracts/assembly/contracts/MRC20/__tests__/WMAS.spec.ts +++ b/smart-contracts/assembly/contracts/MRC20/__tests__/WMAS.spec.ts @@ -9,7 +9,7 @@ import { import { Args, u256ToBytes } from '@massalabs/as-types'; import { balanceOf, - constructor, + mrc20Constructor, deposit, withdraw, computeMintStorageCost, @@ -33,9 +33,7 @@ function switchUser(user: string): void { beforeEach(() => { resetStorage(); setDeployContext(user1Address); - constructor( - new Args().add('Wrapped MAS').add('WMAS').add(9).add(u256.Zero).serialize(), - ); + mrc20Constructor('Wrapped MAS', 'WMAS', 9, u256.Zero); }); describe('deposit', () => { diff --git a/smart-contracts/assembly/contracts/MRC20/example/MRC20.ts b/smart-contracts/assembly/contracts/MRC20/example/MRC20.ts new file mode 100644 index 0000000..852c654 --- /dev/null +++ b/smart-contracts/assembly/contracts/MRC20/example/MRC20.ts @@ -0,0 +1,19 @@ +import { u256 } from 'as-bignum/assembly'; +import { mrc20Constructor } from '../MRC20'; + +export function constructor(): void { + mrc20Constructor('MassaToken', 'MT', 18, u256.fromU64(1010101010)); +} + +export { + name, + symbol, + totalSupply, + decimals, + balanceOf, + transfer, + allowance, + increaseAllowance, + decreaseAllowance, + transferFrom, +} from '../MRC20'; diff --git a/smart-contracts/assembly/contracts/MRC721/MRC721.ts b/smart-contracts/assembly/contracts/MRC721/MRC721.ts index a6d6d2d..aec0a49 100644 --- a/smart-contracts/assembly/contracts/MRC721/MRC721.ts +++ b/smart-contracts/assembly/contracts/MRC721/MRC721.ts @@ -38,9 +38,9 @@ import { _setOwner } from '../utils/ownership-internal'; /** * @param name - the name of the NFT * @param symbol - the symbol of the NFT - * @remarks You must call this function in your contract's constructor !!! + * @remarks You must call this function in your contract's constructor or re-write it to fit your needs ! */ -export function constructor(name: string, symbol: string): void { +export function mrc721Constructor(name: string, symbol: string): void { assert(isDeployingContract()); _constructor(name, symbol); diff --git a/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721.spec.ts b/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721.spec.ts index 3a0f07f..30c6386 100644 --- a/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721.spec.ts +++ b/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721.spec.ts @@ -6,7 +6,7 @@ import { import { name, symbol, - constructor, + mrc721Constructor, mint, ownerOf, balanceOf, @@ -45,7 +45,7 @@ beforeEach(() => { resetStorage(); switchUser(contractOwner); setDeployContext(contractOwner); - constructor(NFTName, NFTSymbol); + mrc721Constructor(NFTName, NFTSymbol); }); describe('Initialization', () => { diff --git a/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721Enumerable.spec.ts b/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721Enumerable.spec.ts index eea18c3..314c743 100644 --- a/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721Enumerable.spec.ts +++ b/smart-contracts/assembly/contracts/MRC721/__tests__/MRC721Enumerable.spec.ts @@ -6,7 +6,6 @@ import { import { Args, - NoArg, byteToBool, bytesToString, bytesToU256, @@ -17,7 +16,6 @@ import { approve, balanceOf, burn, - constructor, getApproved, isApprovedForAll, mint, @@ -28,6 +26,7 @@ import { symbol, totalSupply, transferFrom, + mrc721Constructor, } from '../enumerable/MRC721Enumerable'; import { getOwnedTokens } from './helpers'; @@ -56,7 +55,7 @@ beforeEach(() => { resetStorage(); switchUser(contractOwner); setDeployContext(contractOwner); - constructor(NFTName, NFTSymbol); + mrc721Constructor(NFTName, NFTSymbol); }); describe('NFT Enumerable Contract', () => { diff --git a/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts b/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts index 8c56f91..85e461a 100644 --- a/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts +++ b/smart-contracts/assembly/contracts/MRC721/__tests__/metadata.spec.ts @@ -1,6 +1,6 @@ import { resetStorage, setDeployContext } from '@massalabs/massa-as-sdk'; import { Args, stringToBytes } from '@massalabs/as-types'; -import { constructor } from '../MRC721'; +import { mrc721Constructor } from '../MRC721'; import { u256 } from 'as-bignum/assembly'; import { _baseURI, @@ -16,7 +16,7 @@ const user1Address = 'AU12UBnqTHDQALpocVBnkPNy7y5CndUJQTLutaVDDFgMJcq5kQiKq'; beforeEach(() => { resetStorage(); setDeployContext(user1Address); - constructor('MassaNft', 'MNFT'); + mrc721Constructor('MassaNft', 'MNFT'); }); describe('_setBaseURI', () => { diff --git a/smart-contracts/assembly/contracts/MRC721/enumerable/MRC721Enumerable.ts b/smart-contracts/assembly/contracts/MRC721/enumerable/MRC721Enumerable.ts index f9e4006..527e33a 100644 --- a/smart-contracts/assembly/contracts/MRC721/enumerable/MRC721Enumerable.ts +++ b/smart-contracts/assembly/contracts/MRC721/enumerable/MRC721Enumerable.ts @@ -66,16 +66,11 @@ import { _setOwner } from '../../utils/ownership-internal'; import { Context, isDeployingContract } from '@massalabs/massa-as-sdk'; /** - * @param binaryArgs - serialized strings representing the name and the symbol of the NFT - * - * @remarks This is the constructor of the contract. It can only be called once, when the contract is being deployed. - * It expects two serialized arguments: the name and the symbol of the NFT. - * Once the constructor has handled the deserialization of the arguments, - * it calls the _constructor function from the NFT-enumerable-internals. - * - * Finally, it sets the owner of the contract to the caller of the constructor. + * @param name - the name of the NFT + * @param symbol - the symbol of the NFT + * @remarks You must call this function in your contract's constructor or re-write it to fit your needs ! */ -export function constructor(name: string, symbol: string): void { +export function mrc721Constructor(name: string, symbol: string): void { assert(isDeployingContract()); _constructor(name, symbol); _setOwner(Context.caller().toString()); diff --git a/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts b/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts index 85f2079..fbd19c1 100644 --- a/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts +++ b/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts @@ -2,7 +2,7 @@ import { Args } from '@massalabs/as-types'; import { _setBaseURI } from '../metadata/metadata-internal'; import { onlyOwner } from '../../utils'; import { isDeployingContract } from '@massalabs/massa-as-sdk'; -import { constructor as mrc721Constructor } from '../enumerable'; +import { mrc721Constructor } from '../enumerable'; export function constructor(_binaryArgs: StaticArray): void { assert(isDeployingContract()); From e681f14d69c95e754681851ab3424f0fa83be336 Mon Sep 17 00:00:00 2001 From: BenRey Date: Mon, 9 Dec 2024 14:40:16 +0100 Subject: [PATCH 8/8] Update setBaseURI documentation to clarify optional nature of the function --- .../contracts/MRC721/examples/ER721EnumerableMetadata.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts b/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts index fbd19c1..cdd2b56 100644 --- a/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts +++ b/smart-contracts/assembly/contracts/MRC721/examples/ER721EnumerableMetadata.ts @@ -13,6 +13,8 @@ export function constructor(_binaryArgs: StaticArray): void { /** * Set the base URI for all token IDs * @param newBaseUri - the new base URI + * + * @remarks This function is optional and can be removed if you don't need to change the base URI */ export function setBaseURI(_args: StaticArray): void { onlyOwner();