EOSIO / eos

An open source smart contract platform
https://developers.eos.io/manuals/eos
MIT License
11.27k stars 3.76k forks source link

make get_required_keys error on missing available keys more permissive #8610

Closed mmcs85 closed 4 years ago

mmcs85 commented 4 years ago

I would like to discuss the possibility to make get_required_keys error on missing available keys more permissive. Example just the intersection of required keys with in the provided available keys. (I think that there might be some constraint on providing all the keys if available keys where optional)

This would be useful for creating a transaction with multiple actions that are signed by multiple parties on different wallets. the transaction can be sent to each party in turns and the last one can push the transaction. This would need to be done before it expires.

mharrisb1 commented 4 years ago

@mmcs85 can you expand a little more on the use case?

@lparisc I have also tagged this as documentation since we have continuously seen users running into confusion around some of the rpc calls like get_required_keys.

mmcs85 commented 4 years ago

There is a lot of use cases that can benefit from this change. But is not necessarily required for them to work.

Main use case is transaction cpu payment from a provider using first_authorizer feature, includes two authorization's (provider permission, user permission) but on the user wallet there is only the user permission key and on the provider wallet the provider permission key) When the wallets try to call get_required_keys in eosjs it only calls with 1 available key resulting in an exception. The conflicting call is here https://github.com/EOSIO/eosjs/blob/master/src/eosjs-api.ts#L316

The alternative to this is hack available keys, to give both or create an alternative authority provider that avoids calling get_required_keys directly.

More use cases: 1 - Direct NFT sales between a server and a user without even using a smart contract for exchange. 1.1 - Server generates a transaction with 2 actions (Act 1 - server transfer NFT to user, Action 2 - user transfers X amount of EOS to server) 1.2 - Server signs it with a expiration and sends it to the user. 1.3 - User signs with wallet + eosjs and broadcasts to a node.

2 - p2p exchange of Tokens (requires that both be online) without using even a exchange. 2.1 - User 1 or 2 generates a transaction with 2 actions (Act 1 - user1 transfer 1 EOS to user 2, user 2 transfers 1 SYS to user 1) 2.2 - User 1 or 2 signs it and sends to the other 2.2 - The other user signs it and broadcasts to a node.

3 - Quorum multisig between multiple servers (using wallets) without using a smart contract. ....

Basically this allows p2p multisig without a contract in the middle to manage it.

The downside is that it requires all the parties to be known, to be online and act within the expiration of the transaction.

deckb commented 4 years ago

Hello @mmcs85 ,

In this instance it seems that you could do all of these things by generating an unsigned transaction. The Anchor wallet does something similar.

// not necessarily valid TAPoS numbers
const serializedTransaction = await api.transact({...}, {
        blocksBehind: 4000,
        expireSeconds: 98000,    // some large number in the future
        broadcast: false,
        sign: false
    }
// magic get abi/chainId/requiredKeys

// sign
pushTransactionArgs = await this.signatureProvider.sign({
                chainId,
                requiredKeys,
                serializedTransaction,
                [],
                abis,
            });
// push transaction or pass to next signer.

Would that solve the issue?

mmcs85 commented 4 years ago

@deckb Yes that's a good alternative as well.