How can we force a LogicSig to be used at most once?

I want to use LogicSig to make an atomic swap between Alice and any other person which gets the LogicSig of Alice, and I want the LogicSig to be used at most once.
Let’s call the other person Bob, the process would look like so :

  1. Alice creates the LogicSig whose logic enforces the transactions she wants in the group
  2. Bob happens to get the LogicSig (Alice does not know Bob) and he agrees with the atomic swap that Alice wants
  3. Bob creates the 2 transactions from Alice to Bob and from Bob to Alice and set the group id
  4. Bob creates the LogicSigTransaction with the transaction from Alice to Bob
  5. Bob sends the transactions to the network

My question is : is there a way to make the LogicSig usable at most once ?
If not, is there a trick in my specific case described here that could make the LogicSig to be used in at most one atomic swap (without using a statefull contract) ?

In your case, you might want to make the logic sig be such that whatever assets are to be swapped get moved into the escrow account for the logic. If it does get used by Bob, presumably the assets would be drained from the account. This would prevent it being used more than once (or if it is, it wont affect Alice’s current assets)


1 Like

Thanks @Ben . I have been thinking about this solution but I want all transactions to be in the same group (end to end atomicity), and it is only Bob in the end which can set the group id before sending everything to the network.
If Alice needs to sign a transaction to fund the contract account, Bob won’t be able to include this already signed transaction in the group and the whole process won’t be atomic (and I don’t want Bob to have to send back any transaction to Alice for signature).

So my question is how to get the 4 conditions below met at the same time :

  • Alice and Bob exchange assets atomically
  • the exchange can be made at most once
  • Alice never knows Bob’s address and vice versa (they don’t care with who they transact)
  • Data can flow only from Alice to Bob (through an intermediary social network for example) and Bob is in charge of sending everything to the network in the end.

Algorand already provides a simple solution in the case where Alice and Bob know each other (group transactions) but is there a simple solution in the case above where they don’t ?

@ismax First a very important security note: anyone can intercept logicsig. So nothing prevents Charlie to intercept Bob’s transaction, extracts the logicsig, and then transact with Alice instead of Bob. To work, this attack may require running a participation node with enough stake right now.

Now, in your specific use case, it looks like this is not an issue.

A simple solution for the logicsig to be usable only once is just to have Alice move the asset she wants to transfer in a fresh new account. This way, the only possible exchange is with this new asset. She then publishes a logic sig like you proposed.

Thanks @fabrice for the proposition but the whole process is not atomic in that case (in the end what I want is a simple atomic swap between 2 people who don’t know each other).
I mean if nobody ever uses the LogicSig of Alice, Alice will have moved her asset for nothing.
I would like a solution where Alice has to move something only if someone (here Bob) agrees to transact with her and does use here LogicSig.
So the question is : is there a solution which meet the 4 conditions ? With a stateful smart contract ? And if possible without a stateful smart contract.

In that case, I think one solution is that Alice creates an application App (stateful smart contract) that will store whether the logicsig was executed or not.
Then Bob makes a group of 3 transactions:

  • Payment from Bob to Alice signed by Bob
  • Call to the application by Alice signed using the LogicSig. This application call will update the application state to indicate the transfer was done (or just destroy the application - you can also use an ASA that you create and then destroy for the same purpose). The LogicSig will check that the third transaction is a transfer of the asset from Alice to Bob and the first one is a payment from Bob to Alice
  • Transfer of the asset from Alice to Bob signed using the LogicSig. The LogicSig will check that the third transaction is a transfer of the asset from Alice to Bob and the first one is a payment from Bob to Alice
1 Like

Thanks a lot ! Indeed it seems to meet all my requirements. I’ll try that and update the ticket with the result :slight_smile:

Your solution works like a charm @fabrice ! Thanks a lot ! :pray:

1 Like

Ah but the downside is :

cannot create app for xxxx : max created apps per acct is 10

So Alice will be able to offer at most 10 tokens for sale at one given time (with one account).


1 Like

@fabrice do you now when this update will reach mainnet ?

By the way I think having a LogicSig usable at most once (or N times) is a very basic use case and it would facilitate the life of many developers if there was an easy way to do it, which is not the case currently where we need to use a hack by creating a fake app whose sole purpose is to be deleted.

It will be release tomorrow:

It then requires 90% of the node to agree on it.
From then, it take around 1 week.

So by the end of next week, I think you should expect to have it on MainNet/TestNet.

1 Like