Giter Club home page Giter Club logo

Comments (9)

ilblackdragon avatar ilblackdragon commented on August 31, 2024 2

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.

DavidM-D avatar DavidM-D commented on August 31, 2024 2

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.

DavidM-D avatar DavidM-D commented on August 31, 2024 2

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.

DavidM-D avatar DavidM-D commented on August 31, 2024 1

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.

encody avatar encody commented on August 31, 2024 1

@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.

bowenwang1996 avatar bowenwang1996 commented on August 31, 2024

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.

ilblackdragon avatar ilblackdragon commented on August 31, 2024

@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.

akhi3030 avatar akhi3030 commented on August 31, 2024

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.

akhi3030 avatar akhi3030 commented on August 31, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.