Can a contract remove itself in NEAR Protocol? - nearprotocol

I want to design the flow of upgrading a locked contract.
(A locked contract is the one that has no access keys allowing to alter the code; e.g. the full access key is removed once the code is deployed).
By design, there are no keys that can sign the transaction on behalf of the account to initiate the account deletion for a locked account, but I wonder if the code deployed on the account (the contract code) can still remove itself (self-destroy) [I assume it is possible since it seems that it can issue receipts from self to self].
Would the following upgrade strategy work?
Initial phase:
Create an account
Deploy code with some upgradability helpers
Lock the account (remove the full access key)
Upgrade:
Create a new account
Deploy new code to the new account
Lock the new account
Call the migration method, which reaches to the old version (via a cross-contract call) and requests to transfer the ownership (give all the data and remove itself)
It seems that some sort of owner validation will need to be implemented in the upgradability helpers to make sure that only an owner can transfer the ownership from the old version to the new one, but that is another question; first, I want to know if a contract can destroy itself.

I believe it is possible. You can have a method that uses promise_batch_action_delete_account to delete self and then add an access key to the contract that allows it to call that method.

Delete contracts or accounts using
Promise::new(contract_id).delete_account(beneficiary_id);
Reference: https://docs.rs/near-sdk/3.1.0/near_sdk/struct.Promise.html#method.delete_account
Source code: https://github.com/near/near-sdk-rs/blob/9d99077c6acfde68c06845f2a1eb2b5ed7983401/near-sdk/src/promise.rs#L309

Related

How do you hand off and rename a custodial NEAR account to a user?

A toy example:
The application NFTApp created a new account throwaway.near for a new user and minted some NFTs into it. NFTApp has the only full access key to throwaway.near. The user doesn't even know what a seed phrase is.
At a later time, the user decides they want to take possession of this account and its contents but name it keeper.near. Maybe they have created keeper.near previously or maybe they create it fresh as part of this process. Either way, the user controls the only full access key to keeper.near.
NFTApp then deletes throwaway.near and recovers the storage tokens from it.
How can we effect this handoff without needing to manually send contents from throwaway.near to keeper.near?

How do I use 'create_account_and_claim'

I've had some success creating accounts using create_account with the JSON RPC.
I've read from the co-founder of NEAR that we can create accounts and generate links for those accounts to be claimed.
The documentation doesn't mention it, I guess they're updating.
When I try to use call it I get an error saying left and right accounts don't match
NEAR Linkdrop contract README has the description on the high-level: https://github.com/near/near-linkdrop
Receiver, that doesn't have NEAR:
Receives link to the wallet with privkey1.
Wallet creates new key pair for this user (or they generate it via HSM) (pk2, privkey2).
Enters the new_account_id receiver want for their new account.
Wallet creates a transaction to create_account_and_claim(new_account_id, pk2).
Contract creates new account with new_account_id name and pk2 as full access key and transfers NEAR that Sender sent.
P.S. This linkdrop contract is exactly the one that is deployed to the account that is named near on mainnet.

How do I sign a message with a newly created Near account in a 3rd party app?

I'm setting up a new Near account, and I want to use its keys to sign a message in an app I'm building. How can I do this?
I used the wallet.nearprotocol.com page to create an account. Then, I used nearlib to connect to the testnet, and verify the account's balance and public keys.
But I couldn't find a way to add the account into the localStorage key store or otherwise access a method to sign a message. Nor could I find a wallet plugin or extension that would provide me access.
Generally the idea is that you never transfer given private key between 2 devices / security contexts.
So normally instead of getting private key out of wallet you just want to generate new key pair and request wallet to add public key.
https://github.com/nearprotocol/nearlib/blob/master/src.ts/wallet-account.ts provides relatively easy way to do it for webapp.
Note that it limits access to a give contract ID, so if you need unrestricted access you basically just need to omit contractId.
See examples at https://near.dev/ for WalletAccount usage.

How to verify requests to my Parse.com app?

I have an app that uses parse.com as backend.
If I want to store information about user's in-app purchases in table there, how can I be sure that some guy is not going to create a simple app where users of my app can log (like in my own) in and write in parse-tables whatever they want (for ex.: that they made in-apps when they really didn't). This info is used to give the user access to app's features so it's important that the user really paid for that.
Don't make the table name public knowledge, so don't ever access it directly from the app, always use cloud code. Pass the cloud code some salted hashed details to verify against, and do the verification on save of any new objects being added toot that table with a before save hook. Drop any new objects which don't pass the test.

Dynamics CRM in low-trust helpdesk scenario

Ok, so imagine a bank has a call-centre filled with low-trust staff. The staff need to provide basic service to customers over the phone. The call centre staff take calls from a customer, ask them certain security questions, and then service the accounts in some way.
Now, from the customer's point of view, the bank is verifying who they are by asking the security questions. This is subtly different from the bank's point of view: It is verifying that the call centre employee is talking to the customer.
Why is this difference important? The bank wants to restrict these low trust staff, so they cannot view any details of the accounts until the customer calls them. So a call centre employee can't browse account details of customers that haven't just contacted him and asked for service.
So the question is:
Is this sort of setup possible in Dynamics CRM 2011? How would one go about implementing it? Some level of customization would be OK, but a bespoke application driven from the CRM data is not.
I'm thinking that maybe it's possible to create a custom component that temporarily modifies the user's permissions to a record (and all its children) after answering some security questions. However, I'm not even sure that record-based security (beyond Ownership) is supported in CRM...? I guess one could temporarily assign ownership to the user. Is that wise?
Please note: Simply hiding views & find buttons from the GUI isn't the sort of level of security we're looking for here. We're looking to literally restrict the user from accesing the records in question.
I can see a couple of options:
Working within the permissions model. This could work. You could have access restricted by default, and then have another entity where you'd enter in the account details, a plugin would run and verify the details, and then share the record to the current user. I'd be a little concerned, however, on how the unsharing would work. What would trigger it? Would there be a process that just runs outside of CRM and unshares records periodically. What if that process fails? We've also had performance issues in the past with this type of model... CRM seems to do a lot of work under the hood every time an individual record's permissions are changed like this.
Reassigning the owner, as you suggest. Would multiple users ever need to look at the same data? Does the owner of the record need to be maintained for any other reason (e.g. This is Joe's account because he's the owner).
Working exclusively with plugins. You could have a plugin registered on Retrieve and RetrieveMultiple of a record. This plugin could filter out all the details you want to hide from the end user. When the user needs to view the rest of the data, they fill out a form or dialog or something with the data. This data is then included in the Retrieve call for the record. The plugin checks for the hidden data, verifies that it's there and correct, then strips it out and lets the request continue, only this time it retrieves all attributes, and the form populates as expected.
Disclaimer: this answer is based on plenty of CRM 4.0 experience and reading the release notes for 2011.
Short answer: no.
Long answer: yes, but the customisation would be major. The 'easiest' option that springs to mind, is that the authentication process is carried out as a bespoke asp.net page that either a) uses a service account to re-assign an entity to an individual and then returns them to the relevant CRM form, then a plug in that re-assigns it back on saving changes
or
b) has it's own set of forms to that update and retrieve information as a service account, and only do so after answering the security questions.
As an aside, any kind of 'scripted' form is almost impossible in CRM 4.0. I believe 2011 slightly improves on that, but what I've seen is still not encouraging. Using CRM in a contact centre for us has meant investing in a piece of third party form building software and creating bespoke forms that can be launched from CRM and return data via the web services (which are impressively flexible). We only use the CRM interface for viewing historic requests - even most updates trigger one of the bespoke forms.
If I was to implement such a scenario I would create a customer access record (new_custaccess) that is linked to the customer record (new_customer). For this example - keeping it simple - I'm going to assume that the customer has a simple access code they must provide before the bank employee (Operator) can access the record. The access code is stored on new_custaccess in a field (new_secretcode).
Security is that the Operator has no privileges to new_customer and read/update privileges to new_custaccess.
There is a single field (new_secretcodeoperator) on new_custaccess that the operator can update. All other fields are restricted from update (and, if appropriate, read) to the Operator.
When the Customer calls and the Operator searches for the appropriate new_custaccess record. Once they locate the record they enter the Customer provided secret code into the field new_secretcode and do a save.
A Pre-Update query executes on new_custaccess in the context of a user with full privileges (call it MASTER, for fun here.) That plug-in checks to see if the provided code matches the secret code. If it doesn't it throws an error and the Operator can retry. If it does match the plug-in strips the field new_secretcodeoperator from the record, to keep it from saving the value. It also shares appropriate permission on the record new_customer to the appropriate operator.
The Operator now has access to the Customer record (you'll have to decide whether to cascade permissions or share on each record - that decision is beyond this discussion.)
We now need to deal with rescinding permission on the Customer record. I would handle this by having an entity new_customeraccess that is generated by the previous plug-in whenever access is granted to a Customer record. A workflow should be triggered on Create of new_customeraccess that cause new_customeraccess to be updated every 20 minutes (or whatever time the client prefers.)
A plugin is registered on Update of new_customeraccess that fires when the field updated by the workflow is modified. This plug-in will determine - via whatever criteria is decided on by the business - whether to continue sharing or revoke sharing.
I would also create some javascript/html based pop-up from the new_customer ribbon to end sharing by updating a field on new_customeraccess. Provide the Operator with limited Update privs on new_customeraccess via field level security.
This should accomplish what you want without going outside the standard CRM customization model. Not exactly sure of where you draw the line on bespoke but this is probably as close as you'll get to OOTB. A few plug-ins are all the C# you'll need. And the only JavaScript will be for usability, not functionality.
Let me know if you have questions.

Resources