Oracle Demo BSV20
Schnorr-signed BSV20 oracle message verifier.
txt
# The Schnorr parameters are stored on the instance: generator, modulus, and oracle public key.
# The signed message is tied to the exact outpoint being spent.
import std.schnorr
Contract OracleDemoBsv20:
def main(msg: hex, R: hex, s: hex):
# Capture the outpoint bytes from the current unlocking input.
outpoint = BVM.unlockingInput.Slice(0, 36)
SetAlt(outpoint)
# Clone `msg` so it can be parsed after Schnorr verification consumes the original.
msg_for_parse = msg.Clone()
SetAlt(msg_for_parse)
schnorrVerify(msg, R, s, self.oraclePubKey, self.generator, self.modulus)
SetMain(msg_for_parse)
# Parse the signed payload in the agreed byte order.
# marker(1) | timestamp(4) | network(1) | outpoint(36) | flag(1) | amount(8) | id(rest)
{marker_b, r1} = Split(msg_for_parse, 1)
NumEqualVerify(BinToNum(marker_b), 4)
{ts_b, r2} = Split(r1, 4)
Delete(ts_b)
{net_b, r3} = Split(r2, 1)
NumEqualVerify(BinToNum(net_b), 0)
{op_b, r4} = Split(r3, 36)
SetMain(outpoint)
EqualVerify(op_b, outpoint)
{fung_b, r5} = Split(r4, 1)
NumEqualVerify(BinToNum(fung_b), 1)
{amt_b, id_b} = Split(r5, 8)
# Add a zero byte before numeric conversion so the amount is treated as unsigned.
amt_chk = GreaterOrEqual(BinToNum(Cat(amt_b, 0x00)), self.amt)
NumEqualVerify(amt_chk, 1)
EqualVerify(id_b, self.inscriptionId)