How to remove Smart Contract in NEAR Protocol? - rust

I am new to blockchain and Near Protocol. I have created 2 smart contracts on Near Protocol. The first one was successfully done but when I try to deploy the second one, I have deployed it but when I try to call a method ('increment' in this case) it gives error. I looked for the error and they say that this error executed because I tried to deploy another smart contract. So how can I remove the first one? Or can I? Or should I? Thanks. The error is below:
ServerTransactionError: {"index":0,"kind":{"ExecutionError":"Smart contract panicked: panicked at 'Cannot deserialize the contract state.: Custom { kind: InvalidData, error: \"Not all bytes read\" }

This depends. Are you running on testnet or mainnet and do you need to transfer any assets.
You can only deploy 1 smart contract per wallet and it seems that you need to delete the wallet to remove the contract afaik
You can use near delete accountName.networkName

I came across the same issue. Sounds like you were following Near's "Counter" tutorial.
It appears that in your first deployment, the counter data size (ex: u64) was bigger than the size (ex: u8) in your second deployment.
Had you started with u8, and then changed to u64, you would still get an error, but a different one.
Or, you may have even added a new field to your Contract struct. (That one I haven't tried yet).
So, yes, you need another account.

You can deploy an empty contract
pip install py-near
from pynear.account import Account
async def f():
acc = Account(
"accoun_id",
"private_key"
)
await acc.startup()
res = await acc.deploy_contract(b"")
asyncio.run(f())

Related

Is there a way to read NFT metadata in the anchor program(rust)?

I tried using mint account info (which obviously wouldn't work) and I also tried to deserialise the mint.to_account_info().data into the metadata struct from the mpl_token_metadata::state::Metadata. This gave errors.
I need the sellerFeeBasisPoints and the creators info from the NFT Metadata.
Also, is there a way to update the primarySaleHappened parameter? (I am writing a custom auction contract for an NFT Marketplace).
Thanks in Advance :)
You can deserialize the Metadata-struct by using the mpl_token_metadata-crate provided by Metaplex:
use mpl_token_metadata::state::Metadata;
let metadata: Metadata = Metadata::from_account_info(metadata_account_info)?;
For your second question, please open a new question.
For the second question if you are planning to update the primarySaleHappened from the program then you can do a CPI (Cross Program Invocation) to the Token metadata program to this function update_primary_sale_happened_via_token. Similarly, you can find createUpdatePrimarySaleHappenedViaTokenInstruction in the #metaplex-foundation/mpl-token-metadata npm package to do it in the js/ts side.

Security in in-game NFT mint

does anyone know how to create a secure in-game NFT mint? I think if we gave permission to users to create an NFT (this is the idea of the game - to assemble an NFT from different parts), it would be vulnerable because you can insert your own image URL into the function. I thought a mint function that can be used only by a game contract with the require(somePartsAmount), would it be secure?
Something like this:
function awardItem(address player, string memory tokenURI)
public
onlyGame
returns (uint256)
{
require(somePartsAmount);
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(player, newItemId);
_setTokenURI(newItemId, tokenURI);
return newItemId;
}
How to be with the presale mint, because we can't check parts here and creating by owner is too expensive?
Usually, you won't want to give users the opportunity to set a custom token URI to an nft. Thus, I would suggest making all the URI things in another function maybe. For you to have, let's say, 1000 minteable random nfts, you would first need 1000 tokenURIs for those nfts to have information attached to, and then you would have to use the default getTokenURI function which returns the base token URI you specify when creating the smart contract and just adds the nft id to the end of it.

Issue with validating Arm template using DeploymentsOperations.StartValidate

I am currently working on a project where i deploy multiple arm templates each deploying a VM and doing few operations on them. I wanted handle quota issues by calling template validation before triggerring the first deployment. So, i created a template which has logic to create required VMs and i am using this template only for validation (to check if quota will not be exceeded).
Since our code already has the ResourceManagementClient, i tried the following code:
Deployment parameters = new Deployment(
new DeploymentProperties(DeploymentMode.Incremental)
{
Template = templateFile,
Parameters = parameterFile,
});
DeploymentsValidateOperation dp = deployments.StartValidate(groupName, "validation", parameters);
But when i try to access the Value from the variable dp, i keep getting the following exception:
Generic Exception System.InvalidOperationException: The operation has
not completed yet. at Azure.Core.ArmOperationHelpers`1.get_Value()
at
Azure.ResourceManager.Resources.DeploymentsValidateOperation.get_Value()
at DeployTemplate.Program.d__3.MoveNext() in
\Program.cs:line 88
I even added a loop after the "StartValidate" to wait till the dp.HasCompleted is set to true. But this seems to run indefinetly. I also tried the "StartValidateAsync" method, which seems to have the same issue.
I wanted to understand if i am using this method correctly? if there is a better way to do the template validations? I could not find any examples on this method`s usage. if possible please share any code snippet where this method is used for my reference.
Note: Currently, Since this is not working, i am testing with Fluent Api way. That seems to be working. But, it requires lot of changes in our code as it creates ambiguity with many classes in "Azure.ResourceManager.Resources" which are already used for other operations.
I found that even though the deployment operations HasCompleted field is not set, when I call dp.GetRawResponse(), it returns the exact errors expected.
I now use this to validate my templates.

Microsoft Graph List outlookTask not returning immutable ID even if it's in preferred in header

So in the documentation, it says if you want to get tasks with immutable id instead of normal one just add a header 'Prefer: IdType="ImmutableId"'. I've done that but it still returns tasks with normal ID.
It works fine when I try it with outlook events and if I try to get outlook task by ID (get single task instead of listing all). But as soon as I try getting all tasks with immutable id it doesn't work. It doesn't say any error it just returns the data but with the normal id.
Also, I know that outlook tasks API is getting deprecated but todo list API is not going to cut it right now and I've already tried it - there is no way to retrieve any form of immutable ids, just normal ones.
This is the code I use to retrieve all tasks (list all tasks) in NodeJS:
let response = await client
.api('/me/outlook/tasks?$top=25000')
.header("Prefer", "IdType=\"ImmutableId\"")
.header('Prefer', `outlook.timezone="${timeZone}"`)
.version('beta')
.get();
It is very weird because when trying to get one specific task by ID and setting prefer id type header, it works.
Anyway here is how requests look:
LIST OUTLOOK TASKS (GET ALL OUTLOOK TASKS)
GET https://graph.microsoft.com/beta/me/outlook/tasks
GET ONE SPECIFIC TASK VIA ID
GET /me/outlook/tasks/{id}
HEADER FOR GETTING IMMUTABLE IDS INSTEAD OF NORMAL ONES
Prefer: IdType="ImmutableId"
POTENTIONALLY HELPFUL
This is the code I use to retrieve all events with Immutable ID's (this works compared to tasks)
let response = await client.
api('/me/calendar/events?$top=25000')
.header('Prefer', `outlook.timezone="${timeZone}"`)
.header("Prefer", "IdType='ImmutableId'")
.get();
MS Graph official documentation: How to retrieve a list of outlookTasks
MS Graph official documentation: outlookTask resource type
MS Graph official documentation: event resource type
MS Graph official documentation: Get immutable identifiers for Outlook resources
Okay, so I've found the solution and it's just ridiculous. If any MS Graph SDK developers see this please fix it.
Instead of this:
let response = await client
.api('/me/outlook/tasks?$top=25000')
.header("Prefer", "IdType=\"ImmutableId\"")
.header('Prefer', `outlook.timezone="${timeZone}"`)
.version('beta')
.get();
You MUST do this:
let response = await client
.api('/me/outlook/tasks?$top=25000')
.header("Prefer", `IdType="ImmutableId", outlook.timezone="${timeZone}"`)
.version('beta')
.get();
I guess setting the second Prefer header overrides the first one and consequentially only the second one is sent. Unfortunately, I've discovered this right after I implemented the solution via OpenTypeExtension.

Stripe: Getting Credit Card's Last 4 Digits

I have upgraded the Stripe.net to the latest version which is 20.3.0 and now I don't seem to find the .Last4 for the credit card. I had the following method:
public void CreateLocalCustomer(Stripe.Customer stipeCustomer)
{
var newCustomer = new Data.Models.Customer
{
Email = stipeCustomer.Email,
StripeCustomerId = stipeCustomer.Id,
CardLast4 = stipeCustomer.Sources.Data[0].Card.Last4
};
_dbService.Add(newCustomer);
_dbService.Save();
}
But now the stipeCustomer.Sources.Data[0].Card.Last4 says 'IPaymentSource' does not contain a definition for 'Card'. Does anyone know how I can get the card details now? The flow is that I create the customer by passing the Stripe token to Stripe, then I get the above stripeCustomer. So I expect it to be somewhere in that object. But I can't find it. The release notes can be found here.
Thank you.
In the old world of Stripe, there only used to be one type of payment method you could attach to a Customer; specifically, Card-objects. You would create a Card-object by using Stripe.js/v2 or the Create Token API Endpoint to first create a Token-object and then attach that token to a Customer-object with the Create Card API Endpoint.
Once Stripe expanded to support a number of other payment methods though, Stripe built support for a new object type that encapsulated a number of payment methods (including credit cards) called Source-objects. A Source-object is created either by using Stripe.js/v3 or the Create Source API Endpoint. It can also be attached to a Customer-object in much the same way as the Card-objects mentioned above, except they retain their object type. They're still a Source. You use the Attach Source API Endpoint to do this (that is notably identical to the Create Card API Endpoint mentioned above).
What I'm getting at here, is there are now two different object types (or more) that you can expect to see returned in the sources-array (or Sources in .NET). All of these methods though inherit from the IPaymentSource-interface. So if you know you have a Card-object getting returned, you can simply cast the returned object to the Card-class.
Something like this should get you going:
CardLast4 = ((Card) stipeCustomer.Sources.Data[0]).Last4
You can see what I mean by inheritance by looking at this line in the Card-class file:
https://github.com/stripe/stripe-dotnet/blob/master/src/Stripe.net/Entities/Cards/Card.cs#L7
Good luck!
As of Stripe.net.21.4.1, this is what works:
var chargeService = new ChargeService();
var charge = chargeService.Get(id);
CardLast4 = ((Card)charge.Source).Last4;
It's getting hard not to panic when code breaks because of all the micro-changes Stripe makes.
So after debugging, it looks like the Data[0] needs to be cast as Card to get the card.
So it will be CardLast4 = ((Card)stipeCustomer.Sources.Data[0]).Last4.

Resources