Skip to content
This repository has been archived by the owner on Oct 4, 2019. It is now read-only.

ECIP-? Atomic Transactions #40

Open
splix opened this issue Mar 21, 2017 · 23 comments
Open

ECIP-? Atomic Transactions #40

splix opened this issue Mar 21, 2017 · 23 comments

Comments

@splix
Copy link
Contributor

splix commented Mar 21, 2017

Current transaction execution model lacks of Atomicity for multiple transactions.

An atomic [database] transaction is an indivisible and irreducible series of database operations such that either all occur, or nothing occurs. https://en.wikipedia.org/wiki/Atomicity_(database_systems)

Applied to Ethereum it’s a set of calls to several contracts, when either all of them should be executed or none if error happened at any of the steps.

An example would be transferring token to an exchange, making an exchange operation and transfer new tokens back. This should happen atomically, all or none. If at any of the steps an error will occur, state should be reverted to an initial state before first transaction in this set.

Solution

It’s proposed here to create joint transaction type of transaction, which would be literally joined binary data of several transactions, which should be executed atomically.

nonce and gasPrice fields can be added just once, as well as tx signature details. But gasLimit, to, value and data can be repeated.

[nonce, gasPrice, [[gasLimit, to, value, data], [gasLimit, to, value, data]], v, r, s]

Cons

Hard Fork protocol upgrade, change to both p2p protocol (=consensus) and to RPC API

@splix
Copy link
Contributor Author

splix commented Mar 21, 2017

I also had an idea about execution arbitrary code within a transaction. Like "ephemeral contract" executed just once without actual deploy. But this is a completely separate idea, and most probably doesn't provide much benefits besides a small gas economy. I can submit it as a separate ECIP though, if it worth discussion

@elaineo
Copy link
Member

elaineo commented Mar 21, 2017

  • Are joint transactions going to be executable from contracts, or just accounts?
  • Would this prevent the race-to-empty attack on the DAO? (contract was drained before it encountered a throw, if I remember correctly.)

@ghost
Copy link

ghost commented Mar 21, 2017

Distributed or joined transactions, normally is very heavy structure, we need to find very important usecase before we will start thinking about it. What about state machine logic in smart contract, perhaps there are more cheaper alternatives?

@splix
Copy link
Contributor Author

splix commented Mar 21, 2017

@elaineo only from account. it's a change to a serialization format of a transaction. an it doesn't affect contract excution

@splix
Copy link
Contributor Author

splix commented Mar 21, 2017

@dulanov transactions are serialized into RLP, which already supports arrays. Currently it's
[nonce, gasPrice, gasLimit, to, value, data, v, r, s]
we add an additional structure
[nonce, gasPrice, [[gasLimit, to, value, data], [gasLimit, to, value, data]], v, r, s]

@arvicco
Copy link
Contributor

arvicco commented Mar 21, 2017

With guaranteed atomicity, looks like it would be trivial to arrange trustless crypto-asset swaps at a protocol level.

@avtarsehra
Copy link

@splix this is interesting. But would this make previous contracts deployed incompatible with this change?

@arvicco It seems in this case the "From" address will always be the sending account, so while the "To" addresses can be different, at most it seems you can send ether to multiple addresses. I guess you could use one array to send ether to that address and the other array to represent some asset flow in the Data field. But still would not be real DVP like in Bitcoin, where you can have multiple inputs (with separate signatures) and multiple outputs with an Op_Return.

Playing devils advocate. Would be interesting to first assess the real benefits of this, in terms of real use-cases, as why couldn't you just send two transactions rather than doing this or using a smart contract? I guess saving time and simplicity would be one reason.

@arvicco
Copy link
Contributor

arvicco commented Mar 21, 2017

Ah, I stand corrected. Real use case of tx atomicity would be to have trustless multi-party transactions, imho.

@splix
Copy link
Contributor Author

splix commented Mar 21, 2017

@avtarsehra it touches only transaction serialization in blockchain and p2p, so it shouldn't affect existing contracts

Regarding "From" fields. That's interesting moment, if we allow to have different From per subtx it will be much more flexible. It can be following:

[ 
  [nonce, gasPrice, gasLimit, to, value, data, v, r, s], 
  [nonce, gasPrice, gasLimit, to, value, data, v, r, s]
] 

So you''' be able to make atomic operations like A -> B, C -> B, B -> E

With two different transaction the problem that 1) you have to wait transaction mined into a block and validate state before sending second. so operation spread across multiple blocks. 2) or you create a contract, deploy it, execute, delete. several transactions again

@Dexaran
Copy link
Member

Dexaran commented Mar 21, 2017

@splix the problem you are trying to solve is already solved.
I solved the same problem developing ERC23 token.
You can send ERC23 token to exchange contract, exchange token1 to token2, receive token2, deliver token1 to order owner where you bought token2 with a single transaction.
There is no need to change protocol to solve theis problem while it is already solved.
Here is my ERC23 token proposal:#36
Here is an example of _data payload realization: https://github.com/Dexaran/dataPayload
If you want me to write described exchange contract I can do.

@Dexaran
Copy link
Member

Dexaran commented Mar 21, 2017

I wrote the described exchange. You can browse it here: https://github.com/Dexaran/dataPayload/tree/master/PayloadExchange_example
This is a single-exchange-transaction you are looking for: https://testnet.etherscan.io/tx/0xf41529fb61de85a3e1ea45682f285ce7e23ea0c9f5283c392a4ca445eb14c92b

There is also a way to do so without bytes _data attached to token transaction. The only thing that is really needed is fallback function to handle incoming transactions.

@splix
Copy link
Contributor Author

splix commented Mar 21, 2017

@Dexaran exchange was just a particular problem we have discussed recently, so i've added it as an example. This ECIP not for Exchanges, it can be used in many different scenarios. Maybe it's not clear, but this joint transaction can have more that two transactions, 2 was used just for example. 2..n in general

@Dexaran
Copy link
Member

Dexaran commented Mar 21, 2017

@splix I understand it but there is already a possible way of interaction between contracts. Can you name any scenarios that need such changes in protocol and can't be executed without it?

@splix
Copy link
Contributor Author

splix commented Mar 21, 2017

@Dexaran the advantage that you don't need to deploy a contract for such one-time execution (gas economy, data efficiency and simplicity). When user need to execute same series of operations many times, it worth to implement a special contract for that.

@splix
Copy link
Contributor Author

splix commented Mar 21, 2017

My use case was some kind of "optimistic locking" contract, when group of users have a shared contract, and they are safe to execute their own independent operations with using this shared contract as a lock.

execute X when Y have value 1, then set Y to 2

Which makes 3 transactions:

  1. Y.expect(1) - validate that contract Y have 1, will throw error if not 1
  2. X.executeSomething() - execute X, it can throw error
  3. Y.set(2) - set Y to 2

See https://en.wikipedia.org/wiki/Optimistic_concurrency_control

@splix
Copy link
Contributor Author

splix commented Mar 21, 2017

"locking" can be executed with a new contract too, actually nearly everything can be implemented as a smart contract. But it seems to be a common pattern of execution, it can be applied in many areas, and it maybe worth it to move it to transaction layer

@Dexaran
Copy link
Member

Dexaran commented Mar 25, 2017

@splix can you describe your proposal more detailed?
I'd like to see any code or something that I can execute and try to fully understand how will it work. Or even detailed description.

I think that receiver of joint transaction must know if the transaction is joint or single.
And what about this scheme:
A executes B and C in joint transaction. C is a contract that is invoking B. So B will be locked if C is changing its content and this kind of transaction will fail in any cases?

@nmushegian
Copy link

nmushegian commented Mar 26, 2017

You can write the general case into a singleton contract anyone can use:

composeActions(code, data) {
    deploy(code).delegatecall(data)
}

Now write your atomic sequence in solidity

dapp1.doThis();
dapp2.doThat();
assert( something(arg) );

will be publicizing solution at github.com/dapphub/ds-proxy when it is usable

@splix
Copy link
Contributor Author

splix commented Mar 26, 2017

@Dexaran yes, maybe it's useful for contract to know if it's executed from joint transactions, but I didn't have any plans to add a new OP for that. can be considered later.

Nothing gets locked. It's same as with standard transactions, executed one by one not in parallel.

Atomic transactions:

  • guaranties all transactions comes into same block
  • executed one by one in specified order
  • no other transaction executed between them
  • if any of them failed, other not executed, state for that transactions not saved (i.e. reverted)

@splix
Copy link
Contributor Author

splix commented Mar 26, 2017

@nmushegian right, you can always write a contract, if you need that more than once. This is proposed for one-time execution, for an arbitrary series of calls. Deploy a contract, executing it, and removing it becomes too expensive and complicated for an operation executed just once.

On other hand, I see that a good Wallet can automate that process for a user, i.e deploying a simple one-time contract for certain operations.

@splix
Copy link
Contributor Author

splix commented Mar 26, 2017

Smart contract are much more powerful technology, it includes "atomicity" and any other logic a developer would implement in it, and this proposal doesn't replace smart contracts.

I proposing this as a "nice to have" feature, for a discussion. Maybe we need it, maybe not.

@Dexaran
Copy link
Member

Dexaran commented Mar 30, 2017

@splix finaly I found this feature useful. It is a good idea but I'm not sure we need to change protocol to implement it.

@sorpaas
Copy link
Contributor

sorpaas commented Sep 3, 2017

I think this is somewhat related to ethereum/EIPs#86 and ethereum/EIPs#208. If transaction fields can be abstracted to dataload, then it is possible to create a single contract, and just call that contract simply with multiple of the transaction dataload for all atomic transaction execution.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants