Comments (9)
Additional consideration as account extensions are designed is to also introduce on receipt creation and receival hooks.
Right now receipt receival just happens without any action on the receiving account. The only way to do something on receival is to implement ft_transfer_call type of calls but in the case of account extensions there are new vectors open up. There is also a way to define which function can key call but to define a specific set of actions one needs a proxy contract on the account right now.
A receipt issuance and receival hooks can allow to implement things like:
- block receival of not interesting assets or from non whitelisted/black listed accounts
- prevent account from transferring out specific types of assets (eg borrowed NFTs)
- Specify usage limits on the account
from neps.
I'd like to propose instead of this being a protocol feature we prototype this using a capabilities contract and only move over to protocol when we have discovered clear limits to this approach. This project is many months of protocol work, substantially & irreversibly complicates the programming model and may not be what our users need in the end.
Capabilities contract
An example of a possible capabilities contract is a contract initialized with state
Controllers: Account ID => [ Action Type ]
And the endpoint
take_actions: [ Action ] -> ()
take_actions actions =
# What actions is this contract allowed to do
allowed_actions = Controllers.get(predecessor_id)
for (a in actions)
if allowed_actions.includes(a)
match a
CreateAccount(createAccountAction) => create_account(createAccountAction),
DeployContract(deployContractAction) => deploy_contract(deployContractAction),
FunctionCall(functionCallAction) => function_call(functionCallAction),
...
This allows for contract composition based on the state of Controllers
. An example initial configuration would be:
{
"multisig.near": [AddKey],
"neth.near": [FunctionCall, Stake],
"dead_man.near": [DeleteAccount],
}
So how well does this satisfy the motivations for the protocol change?
Composing contracts is non-trivial
This solves that. We can just as easily wrap this up and expose it through a wallet. It has the same security model as account extensions in that you have to trust that any contracts you give control of your account to.
Even if we compose contracts, storage staking for the contracts is economically infeasible for certain users.
This can be a very small contract, likely 5-10x the size of an existing zero balance account. The per user cost doesn't grow with the complexity of the controlling contracts.
Certain contracts are deployed over and over again, still costing the same for each user
This is a problem, the nodes can trivially memoize the contract code but they will still over-charge the account creators for storage, but this is a big protocol change to fix a relatively small economic problem.
I'd like to first wait for there to be a demonstrable need for this saving, say a contract that has spent 10,000 NEAR being deployed to many different accounts. This spending can then be stemmed with a hack if popular_contract then don't charge
followed by a more general rule.
There is no way for contracts to call each other synchronously
We don't solve this, but I'm not sure we want to.
I'd like to see a much clearer use case for this feature as it's a dramatic digression from our existing programming model. I have a few questions:
- How do you do a flash loan if account extension contracts don't share state?
- If they do share state how do you do actions synchronously, do you have to lock the contract across shards?
- Is there significant demand for this feature outside of Aurora who already have a solution?
- Do you have a single gas limit for all synchronous calls combined and how do contracts stay within that when they don't know how much their predecessor/successors will use?
There might be an argument for not prohibiting (although not guaranteeing) that cross contract calls on the same shard can run on the same block. It's almost invisible to application developers and very lightweight.
Solutions to Open questions
-
We need to have the subscribed contract wasm at the time of the execution. If we are not storing this on the account state, where do we get it? Do we store it on a special account? A special shard that every validator tracks? Or do we get with the function call?
Just store normal contracts -
Can contracts on different namespaces access each others' states?
Only to the extent that existing contracts can interact with one another -
To what extend the permissions be defined? Action level? Namespace level? Account level?
People can deploy proxy contracts with arbitrary rules and decide what works best for them. -
The economics of 'contract subscriptions'.
Each controlling contract can decide. -
Backwards compatibility of namespaces with current account structure.
Completely backwards compatible, because we don't change anything
from neps.
I'm going to move the discussion on Synchronous Execution over to #481 as it seems to be a more appropriate place.
So I understand that there is cost associated with deploying contracts. There are two sides to that, one is the dollar cost and the other is the on-boarding cost. The on-boarding cost is largely solved using relayers provided we can fix the faucet draining attacks.
This solution does have a higher cost per user (probably about 0.1 NEAR per user), but I assert that cost is outweighed by the benefit of having something we can release quickly and more importantly iterate on based on user feedback. Since the on node resource usage of a replicated contract is small, if 1 billion users show up on a Tuesday we can tweak the costs to reflect the resource usage on a dime.
from neps.
The capability contract would be one per user.
Multisig + NETH would be one per network/shard depending on usage
If we did compose them all into a single contract, people wouldn't be able to write new contracts that control accounts in new and interesting ways.
We could slim the capabilities contract down by moving much of it's logic into another contract though, but it probably saves minimal space while adding an extra hop and therefore latency.
from neps.
@DavidM-D I agree: it does complicate the programming model. However, I don't think the alternative contract-layer solution solves the same set of problems that the protocol-layer solution does. In particular: storage sharding (all storage relating to a single application stays on that contract's account and is not sharded), zero-cost (or near-zero-cost) contract deployments (the proposed "capabilities contract" will have a non-zero size (and non-zero deployment cost); even some of the smallest contracts in the ecosystem still weigh a few kilobytes).
Contract Composition
Although the capabilities contract does work for the use-cases where a contract may wish to perform actions on behalf of a user (push actions), it does not allow for those contracts to receive interactions. There is no way to "compose" an NFT contract, for example, using this model.
Storage
Perhaps the full intent is not clear: what if Metamask users were able to transition to using a native NEAR account (controlled via neth) for free or nearly free: at the very least, without needing to separately purchase mainnet NEAR tokens (a la KeyPom trial accounts). If we imagine scaling this solution to, say, a billion users, a cost of even ~0.1 NEAR (10kb contract) / user becomes prohibitive.
It would also be nice if mass-data contracts (like social.near) were able to easily distribute their data across multiple accounts, especially so that once dynamic resharding is active, the load is easier to spread over multiple shards.
Repetitive Deployments
I believe @BenKurrek has firsthand experience with spending large amounts of NEAR deploying the same contract over and over, through the development of KeyPom.
Synchronous Execution
The synchronous execution model proposed by NEPs #480 and #481 is not perfect, but is also limited in such a way as to not change the fundamentally asynchronous nature of NEAR. It allows for highly sandboxed private submodules to be deployed under namespaces. Submodules can only be invoked synchronously (with gas limit) by a non-sandboxed module on the account. They do not have access to any VM host functions besides those needed to communicate with the module that invoked it. This model, though highly restricted, would allow for the possibility of deploying arbitrary foreign code as a synchronous submodule on another account, which could (primitively) simulate synchronous cross-contract execution.
This synchronous execution model is not terribly flexible, and probably will not be useful to the majority of projects. However, it is not a large addition (probably, given the PoC implementation in #481) if namespaced contracts are also implemented. @firatNEAR might be able to speak on this point in more detail.
from neps.
Right now receipt receival just happens without any action on the receiving account. The only way to do something on receival is to implement ft_transfer_call type of calls but in the case of account extensions there are new vectors open up.
@ilblackdragon could you explain how account extension would enable receival hooks?
from neps.
@bowenwang1996 I'm just suggesting to consider this as additional use case.
Given the account model is getting extended, for example, extra field where hooks are configured can be stored.
from neps.
Some questions:
- Is there a single one of this capability contract on the network or one per user?
- what about the other contracts, e.g. multisig and neth? Is there a single one or one per user?
- If there are one per user for the above contracts, can we not compose all of them into a single contract?
from neps.
If we did compose them all into a single contract, people wouldn't be able to write new contracts that control accounts in new and interesting ways.
I suppose, I am thinking that many people will not want to do that and just want to use the functionality out of the box as is. So it might be good enough for them. For the more advanced users, I agree that a more flexible solution would be needed.
from neps.
Related Issues (20)
- relayer callback HOT 1
- Guideline for bytes encoding for JSON input and outuput types (smart contracts) HOT 1
- Atomic/Isolated/Synchronous transaction execution HOT 1
- Ethereum wallet & transaction support HOT 17
- run
- URL: https://explorer.mainnet.aurora.dev/api/eth-rpc
- Chain Signatures HOT 8
- Problems with storage staking HOT 7
- Security Policy violation Branch Protection HOT 2
- Security Policy violation SECURITY.md HOT 2
- Runtime: enable key prefix scan HOT 4
- Runtime triggers HOT 37
- Proposal for web3-compatible wallets support HOT 20
- Wrapped NEAR v2
- Privacy with Chain Signatures HOT 6
- Improvement to gas pricing and prioritization HOT 3
- Reduce storage staking price by 10x HOT 11
- On minimally volatile gas pricing
- Bounty: HOT 1
- Shared contract code HOT 17
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from neps.