A perpetual token

In other words, a token which is guaranteed to exist forever, unless it gets garbage-collected!

{
  val isPerpetual = {(b: Box) =>
    b.propositionBytes == SELF.propositionBytes && b.tokens == SELF.tokens
  }

  sigmaProp(OUTPUTS.exists(isPerpetual))
}

(Actually, this is a perpetual collection of tokens (possibly of size zero). But if you protect a singleton token with this script, then it guarantees the token will never be destroyed other than by garbage collection.)

4 Likes

Nice example. Could be a cool idea to compile a list of short scripts like this one to to give people an idea of how to do basic design patterns which they could then utilize for their own more complex contracts.

2 Likes

Here it is in the real world: 3i6QAH4GMJDnicSdUo1UotuugYePfQTPDipHCZ67U7

1 Like

Preventing garbage collection is quite tricky. I guess you can add some more condition that amount is > some value (and maybe that value decreases over time). Other than that looks good.

Would be nice to have some use-cases for such a box. One (as you suggested elsewhere) is in protecting collateral in pooled mining. Perhaps elaborate a bit more on this?

Yes, in the case of mining pool collateral, I needed a singleton token (token with value 1) to prevent a particular edge case. If I add a condition that a specific token ID must be spent along with the collateral box, it prevents separate parallel transactions from being spent in the same block.

This perpetual token script could be used to ensure that the singleton token is not destroyed. There are no other conditions e.g. I could have ensured a minimum value as you suggested to prevent garbage collection. But I wanted to see if a minimal script would work. You can prevent garbage collection by spending the box frequently enough, which should be sufficient in the mining pool case.

2 Likes

I guess we need to start a topic with design patterns at some points. While working with @scalahub on “Multi-stage contracts…”, yAssets and so one, we discovered some patterns now mostly forgotten it seems :frowning_face:

1 Like

Yes, this is quite a useful design pattern and with possibly many interesting applications.
we should add it to the “Ergo handbook of tricks” :slight_smile:

I remember discussing with @kushti a couple of the other design patterns, like “cyclic references” and “proof of non-existence of some boxes”.

1 Like

What’s the cyclic reference design pattern?

2 Likes

In multi-stage protocols, one script refers to the script of the next stage (example in script1, we have the statement hash(OUTPUTS(0).propositionBytes) == script2Hash).

But suppose we also want the script2 to refer back to script1, (example we want hash(OUTPUTS(0).propositionBytes) == script1Hash), then its a cyclic reference.

One solution is to store script1Hash in register of the box containing script2. Additionally script1 is modified to ensure that the corresponding register of any box containing script2 equals hash(SELF.propositionBytes).

EDIT: While the “vanilla” perpetual token is interesting, the more powerful one is the “max-once-per-block-use” perpetual token, which should be a separate design pattern.

3 Likes