Function validateLockSyntax
Validates the Lock script's syntax on its own. For user's safety, Agora's protocol rules disallow accepting an Output with a syntactically invalid Lock script. This prevents accidental loss of funds, for example in cases where the lock script is ill-formed (e.g. missing END blocks, dangling ELSE statements, etc).
string validateLockSyntax
(
in ref const(Lock) lock,
in const(ulong) StackMaxItemSize
) nothrow @nogc @safe;
The semantics of the lock script are not checked here as it requires an unlock script to run it with. This responsibility lies within the script execution engine.
Parameters
Name | Description |
---|---|
lock | the lock to validate |
StackMaxItemSize | maximum allowed payload size for a stack push operation |
Returns
null if the lock is syntactically valid, otherwise the string explaining the reason why it's invalid
Example
import agora .script .Opcodes;
import std .bitmanip;
immutable StackMaxItemSize = 512;
/* LockType.Key */
Lock lock = { type : LockType .Key };
assert(validateLockSyntax(lock, StackMaxItemSize) ==
"LockType.Key requires 32-byte key argument in the lock script");
lock .bytes .length = Point .sizeof;
assert(validateLockSyntax(lock, StackMaxItemSize) ==
"LockType.Key 32-byte public key in lock script is invalid");
const rand_key = Scalar .random() .toPoint();
lock .bytes = rand_key[];
assert(validateLockSyntax(lock, StackMaxItemSize) == null);
/* LockType.KeyHash */
lock .type = LockType .KeyHash;
lock .bytes .length = 0;
assert(validateLockSyntax(lock, StackMaxItemSize) ==
"LockType.KeyHash requires a 64-byte key hash argument in the lock script");
lock .bytes .length = Hash .sizeof; // any 64-byte number is a valid hash
assert(validateLockSyntax(lock, StackMaxItemSize) == null);
/* LockType.Script */
lock .type = LockType .Script;
lock .bytes .length = 0;
assert(validateLockSyntax(lock, StackMaxItemSize) ==
"Lock script must not be empty");
const ubyte[2] no_overflow = nativeToLittleEndian(
ushort(StackMaxItemSize));
const ubyte[2] size_overflow = nativeToLittleEndian(
ushort(StackMaxItemSize + 1));
const ubyte[StackMaxItemSize] max_payload;
lock .bytes = [ubyte(OP .PUSH_DATA_2)] ~ size_overflow ~ max_payload;
assert(validateLockSyntax(lock, StackMaxItemSize) ==
"PUSH_DATA_2 opcode payload size is not within StackMaxItemSize limits");
lock .bytes = [ubyte(OP .PUSH_DATA_2)] ~ no_overflow ~ max_payload;
assert(validateLockSyntax(lock, StackMaxItemSize) == null);
/* LockType.Redeem */
lock .type = LockType .Redeem;
lock .bytes .length = 0;
assert(validateLockSyntax(lock, StackMaxItemSize) ==
"LockType.Redeem requires 64-byte script hash in the lock script");
lock .bytes .length = Hash .sizeof; // any 64-byte number is a valid hash
assert(validateLockSyntax(lock, StackMaxItemSize) == null);