Ah, it’s different to that: it takes the approach where soft forked opcodes must be run in a subprogram that returns nil (or aborts); within that subprogram the soft forked opcodes can do whatever they please. So the new (coinid P H A)
operation can calculate and return a hash value, but (prior to a hardfork) you can only use that within a program that has “verify” behaviour, eg something like:
(softfork COST 0
(q a (i (= (coinid P H A) X) (q q nil) (q x)))
1
)
With a structure like that, you could have P H A X
pulled from the environment (1
), the code within softfork
checks that X
is calculated correctly (manually aborting if it’s not via the (a (i COND (q q nil) (q x)))
pattern), then additional code outside the softfork
can make use of an otherwise untrusted X
, having now established it correctly matches P H A
.