Functional Programming#
Our next examples demonstrate the functional features of ErgoScript. Suppose we want to allow a box to be spent if all the following conditions hold:
- Spender knows the discrete log of the above EC point
0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352
. - All input boxes must be protected by the same ErgoScript program.
The following program encodes these conditions:
{
val z = decodePoint(fromBase64("AlCGOtZKh66KL+g8GvGoQDy1P1PkhthRHa2KBIh+WyNS"))
def sameAsMe(box:Box) = box.propositionBytes == SELF.propositionBytes
proveDlog(z) && INPUTS.forall(sameAsMe)
}
The address corresponding to the above program is 3PwBHASpxaJa5i3vmLtUTvEqjbJWcpqnyuX9hSmUbaK2HAmoDLHmYSMm4up5pCRytSStEhsHnzTfpHzvCRZ
One may think that the lack of the var
keyword may seem restrictive as it enforces everything to be immutable.
For instance, to compute the sum of all the inputs, one might want to store the accumulated value in a var
and iterate
over all the inputs, updating the var
at each iteration.
The following code shows how to compute the sum of all inputs in ErgoScript. Assume that the additional condition is that the box can only be spent if the sum of all inputs is greater than 1 Erg (or 1000000000 nanoErgs).
{
val z = decodePoint(fromBase64("AlCGOtZKh66KL+g8GvGoQDy1P1PkhthRHa2KBIh+WyNS"))
def sameAsMe(box:Box) = box.propositionBytes == SELF.propositionBytes
val sum = INPUTS.fold(0L, { (accum:Long, box: Box) => accum + box.value })
proveDlog(z) && INPUTS.forall(sameAsMe) && sum > 1000000000
}
This corresponds to the address
49AkSSPuVSQHk17C4JLxhqxH7yL5NMWxdEsELp6MNzYeJZvF7iKk3Jgi4fh96o7RJeaU8JSVPvZ5EhCgboQy9d68QreWaYcVxSUcsd8UCamHPsv9kHzqhe4tAM5D7ZmF