-
Notifications
You must be signed in to change notification settings - Fork 102
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Map.toString() throwing Exception: An unhandled exception was thrown. Key not found in Map #860
Comments
Use primitive types. For example Map<string, string> myNft = new();
myNft["name"] = "My NFT";
myNft["description"] = "My NFT Description";
var tokenString = myNft; |
I did not see the same exception.... tests pass |
@Jim8y Its an |
I mean, why can't I reproduce the error. |
He said
So try blockchain? |
I'll wait for Rick to explain it. |
Hello. Could it be my compiler version? What version are you using? I'm using Devpack 3.6.2 This doesn't work:
This does work:
|
I am using the master of devpack tested your code in one of the test contracts, nothing happens, build and run normally. |
I was using the analyzer branch. I switched to the master branch, rebuilt it and got the same results. Here is the file: using System;
using System.ComponentModel;
using System.Numerics;
using Neo;
using Neo.SmartContract.Framework;
using Neo.SmartContract.Framework.Attributes;
using Neo.SmartContract.Framework.Native;
using Neo.SmartContract.Framework.Services;
namespace NFTCollection
{
[DisplayName("CSharpNFT")]
[ManifestExtra("Author", "Linkd Academy")]
[ManifestExtra("Description", "NFT Contract Example")]
[ContractPermission("*", "onNEP11Payment")]
public class NFTCollection : SmartContract
{
static readonly byte[] KeyTotalSupply = { 0x01 };
static readonly byte[] KeyOwner = { 0x02 };
static readonly byte[] PrefixTokenId = { 0x03 };
static readonly byte[] PrefixToken = { 0x04 };
static readonly byte[] PrefixAccountToken = { 0x05 };
static readonly byte[] PrefixBalance = { 0x06 };
public delegate void OnTransferDelegate(UInt160 from, UInt160 to, BigInteger amount, ByteString tokenId);
[DisplayName("Transfer")]
public static event OnTransferDelegate OnTransfer;
[Safe]
public static string Symbol()
{
return "NFTS";
}
[Safe]
public static int Decimals()
{
return 0;
}
[Safe]
public static BigInteger TotalSupply()
{
return (BigInteger)Storage.Get(KeyTotalSupply);
}
[Safe]
public static UInt160 OwnerOf(string tokenId)
{
return (UInt160)Storage.Get(PrefixToken.Concat(tokenId));
}
public class MyNFT
{
public string name;
public string description;
public string tokenId;
public Map<string, string> properties = new Map<string, string>();
}
public static MyNFT CreateNFT()
{
var nftName = "My NFT";
var nftDescription = "My NFT Description";
var nftProperties = new Map<string, string>();
nftProperties["key1"] = "value1";
nftProperties["key2"] = "value2";
var nftString = nftProperties.ToString();
// var nftString = StdLib.Serialize(nftProperties);
// Runtime.Notify("Debug", new object[] { nftString });
// Generate Token ID
var serializedProperties = StdLib.Serialize(nftProperties);
var transactionHash = (Transaction)Runtime.ScriptContainer;
var tokenHashInput = serializedProperties.Concat(transactionHash.Hash);
var tokenId = CryptoLib.Ripemd160(tokenHashInput);
var myNft = new MyNFT()
{
name = nftName,
description = nftDescription,
properties = nftProperties,
tokenId = tokenId
};
return myNft;
}
public static object TestNFT()
{
var transaction = (Transaction)Runtime.ScriptContainer;
var sender = transaction.Sender;
var nft = CreateNFT();
var serializedNFT = StdLib.Serialize(nft);
var tokenDetailsKey = PrefixToken.Concat(nft.tokenId);
//Persist the NFT
Storage.Put(tokenDetailsKey, serializedNFT);
//Persist the owner of the NFT
Storage.Put(PrefixTokenId.Concat(nft.tokenId), sender);
var existingTokens = Storage.Get(PrefixAccountToken.Concat(sender));
List<ByteString> deserializedTokens;
if (existingTokens is null)
{
deserializedTokens = new ByteString[] { };
}
else
{
deserializedTokens = (ByteString[])StdLib.Deserialize(existingTokens);
}
//Persist the NFT in the account
deserializedTokens.Add(nft.tokenId);
Storage.Put(PrefixAccountToken.Concat(sender), StdLib.Serialize(deserializedTokens));
// Update the balance of the sender
var balance = (BigInteger)Storage.Get(PrefixBalance.Concat(sender));
var newBalance = balance + 1;
Storage.Put(PrefixBalance.Concat(sender), newBalance);
//Increase the total supply
var totalSupply = (BigInteger)Storage.Get(KeyTotalSupply);
var newTotalSupply = totalSupply + 1;
Storage.Put(KeyTotalSupply, newTotalSupply);
return nft;
}
public static object Properties(string tokenId)
{
var rawNFT = Storage.Get(PrefixToken.Concat(tokenId));
if (rawNFT is null)
{
throw new Exception("Token does not exist");
}
var nft = (MyNFT)StdLib.Deserialize(rawNFT);
return nft.properties;
}
public static Iterator TokensOf(UInt160 account)
{
if (account is null || !account.IsValid)
throw new Exception("Invalid Parameter.");
var accountKey = PrefixAccountToken.Concat(account);
var tokenIds = (Iterator)StdLib.Deserialize(Storage.Get(accountKey));
return tokenIds;
}
[DisplayName("_deploy")]
public static void Deploy(object data, bool update)
{
if (update) return;
Storage.Put(KeyTotalSupply, 0);
var tx = (Transaction)Runtime.ScriptContainer;
Storage.Put(KeyOwner, tx.Sender);
}
[Safe]
public static BigInteger BalanceOf(UInt160 account)
{
if (account is null || !account.IsValid)
throw new Exception("Invalid Parameter.");
BigInteger balance = (BigInteger)Storage.Get(PrefixBalance.Concat(account));
return balance;
}
public static bool Transfer(UInt160 from, UInt160 to, String tokenId, object data)
{
if (from is null || !from.IsValid)
throw new Exception("Invalid from address.");
if (to is null || !to.IsValid)
throw new Exception("Invalid to address.");
if (!Runtime.CheckWitness(from))
throw new Exception("Invalid Signature");
var tokenOwner = (UInt160)Storage.Get(PrefixTokenId.Concat(tokenId));
if (tokenOwner is null)
throw new Exception("Token does not exist");
if (tokenOwner != from)
throw new Exception("Not Authorized");
if (from == to)
return true;
Storage.Put(PrefixTokenId.Concat(tokenId), to);
Storage.Put(PrefixBalance.Concat(from), BalanceOf(from) - 1);
Storage.Put(PrefixBalance.Concat(to), BalanceOf(to) + 1);
if (ContractManagement.GetContract(to) is not null)
{
Contract.Call(to, "onNEP11Payment", CallFlags.All, from, 1, tokenId, data);
}
OnTransfer(from, to, 1, tokenId);
return true;
}
public static void Update(ByteString nefFile, string manifest, object data)
{
if (Runtime.CheckWitness((UInt160)Storage.Get(KeyOwner)))
ContractManagement.Update(nefFile, manifest, data);
}
}
} |
This line is wrong |
It seems that there is a general issue with ToString().
|
What don't you understand? YOU CAN'T DO THAT!!!!!!!!!!!!YOU CAST!!!!!!!!!!! |
@cschuchardt88 I think what @lock9 want to say is it is normal C# operation, neo should allow it work that way. Not about how to make it work, but how it should work. |
Well than say that. After 20 times of telling him why he can't do something. He keeps saying I can't do this.
|
Hi @Jim8y , |
Problem:
When I call the toString() method in a map, the VM will throw an exception. The problems happen in runtime and not compile time. I'm not sure if this is a compiler error or not (probably is).
Compile and run the following code:
Result:
However, if I return the map and print it locally, it works.
The text was updated successfully, but these errors were encountered: