Blockwell

Avastar

About

Stats

Public Functions 46
Event Types 14
Code Size 92,010 bytes

Approval Event

Parameters help
owner
address help
approved
address help
tokenId
uint256 help

ApprovalForAll Event

Parameters help
owner
address help
operator
address help
approved
bool help

AttributionSet Event

Parameters help
generation
Generation help
artist
string help
infoURI
string help

ContractPaused Event

Parameters help

ContractUnpaused Event

Parameters help

ContractUpgrade Event

Parameters help
newContract
address help

MetadataContractAddressSet Event

Parameters help
contractAddress
address help

NewPrime Event

Parameters help
id
uint256 help
serial
uint256 help
generation
Generation help
series
Series help
gender
Gender help
traits
uint256 help

NewReplicant Event

Parameters help
id
uint256 help
serial
uint256 help
generation
Generation help
gender
Gender help
traits
uint256 help

NewTrait Event

Parameters help
id
uint256 help
generation
Generation help
gene
Gene help
rarity
Rarity help
variation
uint8 help
name
string help

TraitAccessApproved Event

Parameters help
handler
address help
primeIds
uint256[] help

TraitArtExtended Event

Parameters help
id
uint256 help

TraitsUsed Event

Parameters help
handler
address help
primeId
uint256 help
used
bool[] help

Transfer Event

Parameters help
from
address help
to
address help
tokenId
uint256 help

Functions Expand All Collapse All

balanceOf keyboard_arrow_up

Parameters help

Name Type
owner
address help

Properties

Visibility help public
Mutability help view

Requirements help

Source Code
    function balanceOf(address owner) public view returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");

        return _ownedTokensCount[owner].current();
    }

ownerOf keyboard_arrow_up

Parameters help

Name Type
tokenId
uint256 help

Properties

Visibility help public
Mutability help view

Requirements help

Source Code
    function ownerOf(uint256 tokenId) public view returns (address) {
        address owner = _tokenOwner[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");

        return owner;
    }

safeTransferFrom keyboard_arrow_up

Parameters help

Name Type
from
address help
to
address help
tokenId
uint256 help

Properties

Visibility help public
Mutability help transaction
Source Code
    function safeTransferFrom(address from, address to, uint256 tokenId) public {
        safeTransferFrom(from, to, tokenId, "");
    }

transferFrom keyboard_arrow_up

Parameters help

Name Type
from
address help
to
address help
tokenId
uint256 help

Properties

Visibility help public
Mutability help transaction
Source Code
    function transferFrom(address from, address to, uint256 tokenId) public {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transferFrom(from, to, tokenId);
    }

approve keyboard_arrow_up

Parameters help

Name Type
to
address help
tokenId
uint256 help

Properties

Visibility help public
Mutability help transaction
Source Code
    function approve(address to, uint256 tokenId) public {
        address owner = ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _tokenApprovals[tokenId] = to;
        emit Approval(owner, to, tokenId);
    }

getApproved keyboard_arrow_up

Parameters help

Name Type
tokenId
uint256 help

Properties

Visibility help public
Mutability help view

Requirements help

null
Source Code
    function getApproved(uint256 tokenId) public view returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

setApprovalForAll keyboard_arrow_up

Parameters help

Name Type
to
address help
approved
bool help

Properties

Visibility help public
Mutability help transaction

Requirements help

Source Code
    function setApprovalForAll(address to, bool approved) public {
        require(to != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][to] = approved;
        emit ApprovalForAll(_msgSender(), to, approved);
    }

isApprovedForAll keyboard_arrow_up

Parameters help

Name Type
owner
address help
operator
address help

Properties

Visibility help public
Mutability help view
Source Code
    function isApprovedForAll(address owner, address operator) public view returns (bool) {
        return _operatorApprovals[owner][operator];
    }

safeTransferFrom keyboard_arrow_up

Parameters help

Name Type
from
address help
to
address help
tokenId
uint256 help
_data
bytes help

Properties

Visibility help public
Mutability help transaction
Source Code
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory _data) public {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransferFrom(from, to, tokenId, _data);
    }

name keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help view
Source Code
    function name() external view returns (string memory) {
        return _name;
    }

symbol keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help view
Source Code
    function symbol() external view returns (string memory) {
        return _symbol;
    }

tokenURI keyboard_arrow_up

Parameters help

Name Type
tokenId
uint256 help

Properties

Visibility help public
Mutability help view

Requirements help

null
Source Code
    function tokenURI(uint256 tokenId) external view returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        return _tokenURIs[tokenId];
    }

supportsInterface keyboard_arrow_up

Parameters help

Name Type
interfaceId
bytes4 help

Properties

Visibility help public
Mutability help view
Source Code
    function supportsInterface(bytes4 interfaceId) external view returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

totalSupply keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help view
Source Code
    function totalSupply() public view returns (uint256) {
        return _allTokens.length;
    }

tokenOfOwnerByIndex keyboard_arrow_up

Parameters help

Name Type
owner
address help
index
uint256 help

Properties

Visibility help public
Mutability help view
Source Code
    function tokenOfOwnerByIndex(address owner, uint256 index) public view returns (uint256) {
        require(index < balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

tokenByIndex keyboard_arrow_up

Parameters help

Name Type
index
uint256 help

Properties

Visibility help public
Mutability help view

Requirements help

Source Code
    function tokenByIndex(uint256 index) public view returns (uint256) {
        require(index < totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

upgradeContract keyboard_arrow_up

Parameters help

Name Type
_newAddress
address help

Properties

Visibility help public
Mutability help transaction

Modifiers help

Requirements help

Source Code
    function upgradeContract(address _newAddress) external onlySysAdmin whenPaused whenNotUpgraded {
        require(_newAddress != address(0));
        upgraded = true;
        newContractAddress = _newAddress;
        emit ContractUpgrade(_newAddress);
    }

addMinter keyboard_arrow_up

Parameters help

Name Type
_minterAddress
address help

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlySysAdmin checks for the following:
Source Code
    function addMinter(address _minterAddress) external onlySysAdmin {
        minters.add(_minterAddress);
        require(minters.has(_minterAddress));
    }

addOwner keyboard_arrow_up

Parameters help

Name Type
_ownerAddress
address help

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlySysAdmin checks for the following:
Source Code
    function addOwner(address _ownerAddress) external onlySysAdmin {
        owners.add(_ownerAddress);
        require(owners.has(_ownerAddress));
    }

addSysAdmin keyboard_arrow_up

Parameters help

Name Type
_sysAdminAddress
address help

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlySysAdmin checks for the following:
Source Code
    function addSysAdmin(address _sysAdminAddress) external onlySysAdmin {
        admins.add(_sysAdminAddress);
        require(admins.has(_sysAdminAddress));
    }

stripRoles keyboard_arrow_up

Parameters help

Name Type
_address
address help

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlyOwner checks for the following:
Source Code
    function stripRoles(address _address) external onlyOwner {
        require(msg.sender != _address);
        bool stripped = false;
        if (admins.has(_address)) {
            admins.remove(_address);
            stripped = true;
        }
        if (minters.has(_address)) {
            minters.remove(_address);
            stripped = true;
        }
        if (owners.has(_address)) {
            owners.remove(_address);
            stripped = true;
        }
        require(stripped == true);
    }

pause keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help transaction

Modifiers help

onlySysAdmin checks for the following:
Source Code
    function pause() external onlySysAdmin whenNotPaused {
        paused = true;
        emit ContractPaused();
    }

unpause keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help transaction

Modifiers help

Source Code
    function unpause() external onlySysAdmin whenPaused whenNotUpgraded {
        paused = false;
        emit ContractUnpaused();
    }

getTraitIdByGenerationGeneAndVariation keyboard_arrow_up

Parameters help

Name Type
_generation
Generation help
_gene
Gene help
_variation
uint8 help

Properties

Visibility help public
Mutability help view
Source Code
    function getTraitIdByGenerationGeneAndVariation(
        Generation _generation,
        Gene _gene,
        uint8 _variation
    )
    external view
    returns (uint256 traitId)
    {
        return traitIdByGenerationGeneAndVariation[uint8(_generation)][uint8(_gene)][_variation];
    }

getTraitInfoById keyboard_arrow_up

Parameters help

Name Type
_traitId
uint256 help

Properties

Visibility help public
Mutability help view
Source Code
    function getTraitInfoById(uint256 _traitId)
    external view
    returns (
        uint256 id,
        Generation generation,
        Series[] memory series,
        Gender gender,
        Gene gene,
        Rarity rarity,
        uint8 variation,
        string memory name
    ) {
        require(_traitId < traits.length);
        Trait memory trait = traits[_traitId];
        return (
            trait.id,
            trait.generation,
            trait.series,
            trait.gender,
            trait.gene,
            trait.rarity,
            trait.variation,
            trait.name
        );
    }

getTraitNameById keyboard_arrow_up

Parameters help

Name Type
_traitId
uint256 help

Properties

Visibility help public
Mutability help view
Source Code
    function getTraitNameById(uint256 _traitId)
    external view
    returns (string memory name) {
        require(_traitId < traits.length);
        name = traits[_traitId].name;
    }

getTraitArtById keyboard_arrow_up

Parameters help

Name Type
_traitId
uint256 help

Properties

Visibility help public
Mutability help view

Modifiers help

onlySysAdmin checks for the following:
Source Code
    function getTraitArtById(uint256 _traitId)
    external view onlySysAdmin
    returns (string memory art) {
        require(_traitId < traits.length);
        Trait memory trait = traits[_traitId];
        art = trait.svg;
    }

getAttributionByGeneration keyboard_arrow_up

Parameters help

Name Type
_generation
Generation help

Properties

Visibility help public
Mutability help view

Requirements help

Source Code
    function getAttributionByGeneration(Generation _generation)
    external view
    returns (
        string memory attribution
    ){
        Attribution memory attrib = attributionByGeneration[uint8(_generation)];
        require(bytes(attrib.artist).length > 0);
        attribution = strConcat(attribution, attrib.artist);
        attribution = strConcat(attribution, ' (');
        attribution = strConcat(attribution, attrib.infoURI);
        attribution = strConcat(attribution, ')');
    }

setAttribution keyboard_arrow_up

Parameters help

Name Type
_generation
Generation help
_artist
string help
_infoURI
string help

Properties

Visibility help public
Mutability help transaction

Modifiers help

Source Code
    function setAttribution(
        Generation _generation,
        string calldata _artist,
        string calldata _infoURI
    )
    external onlySysAdmin onlyBeforeProd(_generation)
    {
        require(bytes(_artist).length > 0 && bytes(_infoURI).length > 0);
        attributionByGeneration[uint8(_generation)] = Attribution(_generation, _artist, _infoURI);
        emit AttributionSet(_generation, _artist, _infoURI);
    }

createTrait keyboard_arrow_up

Parameters help

Name Type
_generation
Generation help
_series
Series[] help
_gender
Gender help
_gene
Gene help
_rarity
Rarity help
_variation
uint8 help
_name
string help
_svg
string help

Properties

Visibility help public
Mutability help transaction
Source Code
    function createTrait(
        Generation _generation,
        Series[] calldata _series,
        Gender _gender,
        Gene _gene,
        Rarity _rarity,
        uint8 _variation,
        string calldata _name,
        string calldata _svg
    )
    external onlySysAdmin whenNotPaused onlyBeforeProd(_generation)
    returns (uint256 traitId)
    {
        require(_series.length > 0);
        require(bytes(_name).length > 0);
        require(bytes(_svg).length > 0);

        // Get Trait ID
        traitId = traits.length;

        // Create and store trait
        traits.push(
            Trait(traitId, _generation, _gender, _gene, _rarity, _variation,  _series, _name, _svg)
        );

        // Create generation/gene/variation to traitId mapping required by assembleArtwork
        traitIdByGenerationGeneAndVariation[uint8(_generation)][uint8(_gene)][uint8(_variation)] = traitId;

        // Send the NewTrait event
        emit NewTrait(traitId, _generation, _gene, _rarity, _variation, _name);

        // Return the new Trait ID
        return traitId;
    }

extendTraitArt keyboard_arrow_up

Parameters help

Name Type
_traitId
uint256 help
_svg
string help

Properties

Visibility help public
Mutability help transaction
Source Code
    function extendTraitArt(uint256 _traitId, string calldata _svg)
    external onlySysAdmin whenNotPaused onlyBeforeProd(traits[_traitId].generation)
    {
        require(_traitId < traits.length);
        string memory art = strConcat(traits[_traitId].svg, _svg);
        traits[_traitId].svg = art;
        emit TraitArtExtended(_traitId);
    }

getAvastarWaveByTokenId keyboard_arrow_up

Parameters help

Name Type
_tokenId
uint256 help

Properties

Visibility help public
Mutability help view
Source Code
    function getAvastarWaveByTokenId(uint256 _tokenId)
    external view
    returns (Wave wave)
    {
        require(_tokenId < avastars.length);
        wave = avastars[_tokenId].wave;
    }

renderAvastar keyboard_arrow_up

Parameters help

Name Type
_tokenId
uint256 help

Properties

Visibility help public
Mutability help view
Source Code
    function renderAvastar(uint256 _tokenId)
    external view
    returns (string memory svg)
    {
        require(_tokenId < avastars.length);
        Avastar memory avastar = avastars[_tokenId];
        uint256 traits = (avastar.wave == Wave.PRIME)
        ? primesByGeneration[uint8(avastar.generation)][avastar.serial].traits
        : replicantsByGeneration[uint8(avastar.generation)][avastar.serial].traits;
        svg = assembleArtwork(avastar.generation, traits);
    }

getPrimeByGenerationAndSerial keyboard_arrow_up

Parameters help

Name Type
_generation
Generation help
_serial
uint256 help

Properties

Visibility help public
Mutability help view
Source Code
    function getPrimeByGenerationAndSerial(Generation _generation, uint256 _serial)
    external view
    returns (
        uint256 tokenId,
        uint256 serial,
        uint256 traits,
        Generation generation,
        Series series,
        Gender gender,
        uint8 ranking
    ) {
        require(_serial < primesByGeneration[uint8(_generation)].length);
        Prime memory prime = primesByGeneration[uint8(_generation)][_serial];
        return (
            prime.id,
            prime.serial,
            prime.traits,
            prime.generation,
            prime.series,
            prime.gender,
            prime.ranking
        );
    }

getPrimeByTokenId keyboard_arrow_up

Parameters help

Name Type
_tokenId
uint256 help

Properties

Visibility help public
Mutability help view
Source Code
    function getPrimeByTokenId(uint256 _tokenId)
    external view
    returns (
        uint256 tokenId,
        uint256 serial,
        uint256 traits,
        Generation generation,
        Series series,
        Gender gender,
        uint8 ranking
    ) {
        require(_tokenId < avastars.length);
        Avastar memory avastar = avastars[_tokenId];
        require(avastar.wave ==  Wave.PRIME);
        Prime memory prime = primesByGeneration[uint8(avastar.generation)][avastar.serial];
        return (
            prime.id,
            prime.serial,
            prime.traits,
            prime.generation,
            prime.series,
            prime.gender,
            prime.ranking
        );
    }

getPrimeReplicationByTokenId keyboard_arrow_up

Parameters help

Name Type
_tokenId
uint256 help

Properties

Visibility help public
Mutability help view
Source Code
    function getPrimeReplicationByTokenId(uint256 _tokenId)
    external view
    returns (
        uint256 tokenId,
        bool[12] memory replicated
    ) {
        require(_tokenId < avastars.length);
        Avastar memory avastar = avastars[_tokenId];
        require(avastar.wave ==  Wave.PRIME);
        Prime memory prime = primesByGeneration[uint8(avastar.generation)][avastar.serial];
        return (
            prime.id,
            prime.replicated
        );
    }

mintPrime keyboard_arrow_up

Parameters help

Name Type
_owner
address help
_traits
uint256 help
_generation
Generation help
_series
Series help
_gender
Gender help
_ranking
uint8 help

Properties

Visibility help public
Mutability help transaction

Modifiers help

Source Code
    function mintPrime(
        address _owner,
        uint256 _traits,
        Generation _generation,
        Series _series,
        Gender _gender,
        uint8 _ranking
    )
    external onlyMinter whenNotPaused
    returns (uint256 tokenId, uint256 serial)
    {
        require(_owner != address(0));
        require(_traits != 0);
        require(isHashUsedByGeneration[uint8(_generation)][_traits] == false);
        require(_ranking > 0 && _ranking <= 100);
        uint16 count = primeCountByGenAndSeries[uint8(_generation)][uint8(_series)];
        if (_series != Series.PROMO) {
            require(count < MAX_PRIMES_PER_SERIES);
        } else {
            require(count < MAX_PROMO_PRIMES_PER_GENERATION);
        }

        // Get Prime Serial and mint Avastar, getting tokenId
        serial = primesByGeneration[uint8(_generation)].length;
        tokenId = mintAvastar(_owner, serial, _traits, _generation, Wave.PRIME);

        // Create and store Prime struct
        bool[12] memory replicated;
        primesByGeneration[uint8(_generation)].push(
            Prime(tokenId, serial, _traits, replicated, _generation, _series, _gender, _ranking)
        );

        // Increment count for given Generation/Series
        primeCountByGenAndSeries[uint8(_generation)][uint8(_series)]++;

        // Send the NewPrime event
        emit NewPrime(tokenId, serial, _generation, _series, _gender, _traits);

        // Return the tokenId, serial
        return (tokenId, serial);
    }

getReplicantByGenerationAndSerial keyboard_arrow_up

Parameters help

Name Type
_generation
Generation help
_serial
uint256 help

Properties

Visibility help public
Mutability help view
Source Code
    function getReplicantByGenerationAndSerial(Generation _generation, uint256 _serial)
    external view
    returns (
        uint256 tokenId,
        uint256 serial,
        uint256 traits,
        Generation generation,
        Gender gender,
        uint8 ranking
    ) {
        require(_serial < replicantsByGeneration[uint8(_generation)].length);
        Replicant memory replicant = replicantsByGeneration[uint8(_generation)][_serial];
        return (
            replicant.id,
            replicant.serial,
            replicant.traits,
            replicant.generation,
            replicant.gender,
            replicant.ranking
        );
    }

getReplicantByTokenId keyboard_arrow_up

Parameters help

Name Type
_tokenId
uint256 help

Properties

Visibility help public
Mutability help view
Source Code
    function getReplicantByTokenId(uint256 _tokenId)
    external view
    returns (
        uint256 tokenId,
        uint256 serial,
        uint256 traits,
        Generation generation,
        Gender gender,
        uint8 ranking
    ) {
        require(_tokenId < avastars.length);
        Avastar memory avastar = avastars[_tokenId];
        require(avastar.wave ==  Wave.REPLICANT);
        Replicant memory replicant = replicantsByGeneration[uint8(avastar.generation)][avastar.serial];
        return (
            replicant.id,
            replicant.serial,
            replicant.traits,
            replicant.generation,
            replicant.gender,
            replicant.ranking
        );
    }

mintReplicant keyboard_arrow_up

Parameters help

Name Type
_owner
address help
_traits
uint256 help
_generation
Generation help
_gender
Gender help
_ranking
uint8 help

Properties

Visibility help public
Mutability help transaction

Modifiers help

Source Code
    function mintReplicant(
        address _owner,
        uint256 _traits,
        Generation _generation,
        Gender _gender,
        uint8 _ranking
    )
    external onlyMinter whenNotPaused
    returns (uint256 tokenId, uint256 serial)
    {
        require(_traits != 0);
        require(isHashUsedByGeneration[uint8(_generation)][_traits] == false);
        require(_ranking > 0 && _ranking <= 100);
        require(replicantCountByGeneration[uint8(_generation)] < MAX_REPLICANTS_PER_GENERATION);

        // Get Replicant Serial and mint Avastar, getting tokenId
        serial = replicantsByGeneration[uint8(_generation)].length;
        tokenId = mintAvastar(_owner, serial, _traits, _generation, Wave.REPLICANT);

        // Create and store Replicant struct
        replicantsByGeneration[uint8(_generation)].push(
            Replicant(tokenId, serial, _traits, _generation, _gender, _ranking)
        );

        // Increment count for given Generation
        replicantCountByGeneration[uint8(_generation)]++;

        // Send the NewReplicant event
        emit NewReplicant(tokenId, serial, _generation, _gender, _traits);

        // Return the tokenId, serial
        return (tokenId, serial);
    }

isAvastarTeleporter keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help pure
Source Code
    function isAvastarTeleporter() external pure returns (bool) {return true;}

setMetadataContractAddress keyboard_arrow_up

Parameters help

Name Type
_address
address help

Properties

Visibility help public
Mutability help transaction

Modifiers help

Source Code
    function setMetadataContractAddress(address _address)
    external onlySysAdmin whenPaused whenNotUpgraded
    {
        // Cast the candidate contract to the IAvastarMetadata interface
        IAvastarMetadata candidateContract = IAvastarMetadata(_address);

        // Verify that we have the appropriate address
        require(candidateContract.isAvastarMetadata());

        // Set the contract address
        metadataContractAddress = _address;

        // Emit the event
        emit MetadataContractAddressSet(_address);
    }

getMetadataContractAddress keyboard_arrow_up

Parameters help

This function has no parameters.

Properties

Visibility help public
Mutability help view
Source Code
    function getMetadataContractAddress()
    external view
    returns (address contractAddress) {
        return metadataContractAddress;
    }

tokenURI keyboard_arrow_up

Parameters help

Name Type
_tokenId
uint help

Properties

Visibility help public
Mutability help view
Source Code
    function tokenURI(uint _tokenId)
    external view
    returns (string memory uri)
    {
        require(_tokenId < avastars.length);
        return IAvastarMetadata(metadataContractAddress).tokenURI(_tokenId);
    }

approveTraitAccess keyboard_arrow_up

Parameters help

Name Type
_handler
address help
_primeIds
uint256[] help

Properties

Visibility help public
Mutability help transaction
Source Code
    function approveTraitAccess(address _handler, uint256[] calldata _primeIds)
    external
    {
        require(_primeIds.length > 0 && _primeIds.length <= 256);
        uint256 primeId;
        bool approvedAtLeast1 = false;
        for (uint8 i = 0; i < _primeIds.length; i++) {
            primeId = _primeIds[i];
            require(primeId < avastars.length);
            require(msg.sender == super.ownerOf(primeId), "Must be token owner");
            if (traitHandlerByPrimeTokenId[primeId] != _handler) {
                traitHandlerByPrimeTokenId[primeId] = _handler;
                approvedAtLeast1 = true;
            }
        }
        require(approvedAtLeast1, "No unhandled primes specified");

        // Emit the event
        emit TraitAccessApproved(_handler, _primeIds);
    }

useTraits keyboard_arrow_up

Parameters help

Name Type
_primeId
uint256 help
_traitFlags
bool[] help

Properties

Visibility help public
Mutability help transaction

Requirements help

Source Code
    function useTraits(uint256 _primeId, bool[12] calldata _traitFlags)
    external
    {
        // Make certain token id is valid
        require(_primeId < avastars.length);

        // Make certain caller is token owner OR approved handler
        require(msg.sender == super.ownerOf(_primeId) || msg.sender == traitHandlerByPrimeTokenId[_primeId],
        "Must be token owner or approved handler" );

        // Get the Avastar and make sure it's a Prime
        Avastar memory avastar = avastars[_primeId];
        require(avastar.wave == Wave.PRIME);

        // Get the Prime
        Prime storage prime = primesByGeneration[uint8(avastar.generation)][avastar.serial];

        // Set the flags.
        bool usedAtLeast1;
        for (uint8 i = 0; i < 12; i++) {
            if (_traitFlags.length > i ) {
                if ( !prime.replicated[i] && _traitFlags[i] ) {
                    prime.replicated[i] = true;
                    usedAtLeast1 = true;
                }
            } else {
                break;
            }
        }

        // Revert if no flags changed
        require(usedAtLeast1, "No reusable traits specified");

        // Clear trait handler
        traitHandlerByPrimeTokenId[_primeId] = address(0);

        // Emit the TraitsUsed event
        emit TraitsUsed(msg.sender, _primeId, prime.replicated);
    }