Update an NFT
Making updates to the NFT, e.g. adding a red hat to a character requires signing and sending a transaction.
Signing transactions
All updates are transactions that must be signed via a prompt from MetaMask.
Sending transactions
There are two ways to make update transactions: Using the GetData method and the CallMethod
GetData method
Use the GetData
method to retrieve information from the blockchain. (READ functions do NOT require mining.). Other non-standard Get
functions are also available
These methods require:
- Contract Address
- ABI
The following extract is an example usage of the GetData method to retrieve information about an NFT:
private async UniTask<BigInteger> GetHat(BigInteger tokenID)
{
var getHatMessage = new GetHatMessage
{
CharacterId = tokenID.ToString()
};
var hatId = await _gameCharacterContract.GetData<GetHatMessage, BigInteger>(getHatMessage);
UpdateUILogs($"Hat Id: {hatId}");
return hatId;
}
CallMethod
Use the CallMethod
to write new information to the blockchain. These methods utilize gas.
The following extract is an example of how a CallMethod
is used to update an NFT:
public async void UpdateNFT()
{
// 1) Request nft parameters and signature for parameters
var info = await RequestPreparedParams(0);
// 2) Call method that check signature and update nft
var receipt = await _contract.CallMethod("updateTokenWithSignedMessage", new object[] { info });
Debug.Log($"Receipt: {receipt}");
}
Example: update NFT
This is an example from the SDK and illustrates how to update a GameItem NFT by user request.
-
Amend GameItem.sol to your purposes and deploy it to the network.
📃Ensure that the smart contract is deployed from the same account that uses the backend to sign data.
-
Create an instance of
Web3
class and callInitialize
method after logging in MetaMaskstring provider_url = "<ethereum node url>"; Web3 web3 = new Web3(provider_url); web3.Initialize();
-
The user sends a GET request
hero/{id}
to backend whereid
is the index of the NFT in the contract.UnityWebRequest request = UnityWebRequest.Get(url+$"hero/{tokenId}"); await request.Send();
-
The Backend prepares parameters for the hero NFT and signs it with EIP-712 standard. The user implements this signature to prove immutability of the data in the contract.
hero := &ItemInfo{ TokenId: id, ItemType: 1, Strength: 10, Level: 15, ExpireTime: 1642739319576, } hero.Signature = generateSignature(*hero)
-
After getting the parameters of the NFT and Signature, the user should call contract method
updateTokenWithSignedMessage
and pass it all data from the backend as tuple.ItemInfo info = await RequestPreparedParams(0); string receipt = await contract.CallMethod("updateTokenWithSignedMessage", new object[] {info});
-
The Contract verifies the signature and expireTime for data and updates the NFT.
function updateTokenWithSignedMessage(ItemInfo calldata itemInfo) public { address signer = _verifyItemInfo(itemInfo); require(hasRole(UPDATER_ROLE, signer), "Signature invalid"); require(itemInfo.expireTime > block.timestamp, "Voucher expired"); require(tokenDetails[itemInfo.tokenId].itemType > 0, "Token does not exist"); tokenDetails[itemInfo.tokenId] = Item(itemInfo.itemType, itemInfo.strength, itemInfo.level); }