Updateable Multisig Pattern

In the light of ErgoHack III going on, I am revising different known contracts regarding privacy.

One of the most unknown things still, unfortunately, is how treasury contract is done. And there are some interesting things here. One of them is updateable threshold scheme, which can be interesting per se.

Treasury contract is done in ErgoTree, as ErgoScript was not available back then. In ErgoScript, the general idea can be expressed as:

  val selfOut = OUTPUTS(0)

  val sameScript = selfOut.propositionBytes == SELF.propositionBytes
  val sigScript = SELF.R4[SigmaProp].get
  sameScript && sigScript

So the script is ensuring that the template is stored (in OUTPUT #0), and a condition to spend the box is stored in register R4 actually. Register type is of [SigmaProp], which means a trivial boolean value (true/false) or a statement provable via a sigma protocol. In case of Treasury contract, the value is


which is AtLeast(2, Coll(Pk_A, PK_B, PK_C)) condition, so threshold signature requirement, written into register as a byte array.

So currently the Treasury is protected by 2-out-of-3 signature , where ring members are initial core developers, but the protection can be updated.

Similarly, updateable protection can be useful for DAOs, offchain banks, and other contracts.


[Reserved for description of offchain part]

Availability of SigmaProp type is indeed quite useful.

As a side note, to ensure that output does not become unspendable by mistake (if R4 is empty), it will be good to ensure that R4 has a SigmaProp simply by adding a line:

val outProp = selfOut.R4[SigmaProp].get

Need to test whether the above statement will actually be executed because script is generally evaluated lazily.

1 Like

ErgoTeam will as well support updating spending conditions. Upon voting, the team will be able to change the voting token which is equivalent to changing spending conditions.