Macros specification
This page describes an overview of all macros that a Nana indexer should implement and make available to a program's method.
Some macros described here are of type view
. Any methods that are of type view
are restricted to only being able to call other "view
" macros. If a method is of type "view
" and attempts to call state-changing
macros, the NIP is invalid and will not be whitelisted.
View macros are prefixed with $
(just like NIP methods)
alloc()
The alloc()
macro takes in 3 parameters:
alloc(sender, recipient, nana, amount)
This function unallocates nanas from sender
and allocates them to recipient
nana
and amount
specify how much (amount
) of the nana (nana
)should be sent from the sender
to the recipient
(which is the opposite of whatever sender is)
If sender
does not have enough of nana
to satisfy the transfer of amount
, the function should error and therefore produce a rotten banana.
If nana
is set to all
, every nana balance from sender
is unallocated and allocated to recipient
with the amount
field being ignored. If a nana is set to all_recursive
and sender is a programId, all of the Nanas from the program and its boxes are unallocated and allocated to recipient. If sender is not of type programId, all_recursive
's logic is identical to all
.
If amount
is set to all
, all of nana
from sender
is unallocated and allocated to recipient
The following edge cases for parameters are considered invalid and produce a rotten banana:
nana
must be a valid Nana existing insender
's balance or be a string of "all" or "all_recursive". If neither present it is considered invalid.An
amount
that overflows an LEB128 or is not "all" is considered invalid.recipient
is a program that wasn't included in the NIPsuse
return field.
set()
The set()
macro takes 2 parameters:
set(key, value)
Under the hood every program on creation is assigned a JSON object - which they can alter by setting a key
, which sets a field in this object.
A key
can be separated with :
, which causes the key string to be split with :
with the items in the array referring to a field tree.
Example:
Is stored as:
If any parent specified by key
does not exist, the parent field and all child fields are recursively created.
Furthermore, the following edge cases should error and produce a rotten banana:
A set's
key
parameter starts with:
A set's
key
parameter ends with:
A set's
key
parameter has any repeating:
A set's
key
parameter attempts to assign a value (or a field tree) to an existing field already specifying a field tree (rather than just a value)A set's
key
parameter attempts to assign a field tree to an already existing value.A set's
value
parameter is not a string or integer.A set's
value
parameter is an integer that overflows an LEB128.A field tree has a depth of more than 10 fields
The indexer also needs to keep track of the total byte size used by all value
parameters on all sets
in a transaction's call tree. If at any point this tracker goes over 1000 bytes, set()
should error a rotten banana should be produced.
call()
set(program, method, params)
The call()
method allows any state_changing
method to call any other state_changing
method from another program or itself. 0:0
can be used to call a state_changing
method from itself (using the actual program id of self to call itself is considered invalid and such NIPs will not be whitelisted) while 0:nip_id
can be used to call a method from another NIP.
If params is excluded, the default of [0,0,0,0,0]
will be set instead
The call's return is inherited from whatever program or method it is calling (which can only be a String
or u128
)
Example:
Furthermore, the following edge cases should error and produce a rotten banana:
Every
state_changing
function has the same type for the params field (vector of 5 uints) - anything other than this is considered invalid and error.If the method being called was not imported in the programs
use
export field, the method is invalid and will error.In the future
ProgramId
will beblock:tx
, with the pointer being to an inscription specifying the Programs code. However, since this is currently disabled ( Programs ) - any "block" that is non-0 will be considered invalid and error.
inherit()
The inherit() method takes in 1 parameter:
inherit(program)
This method deep clones another programs storage into its own storage, overriding and deleting anything that previously existed there.
Furthermore, the following edge cases should error and produce a rotten banana:
A valid program is not provided (parameter is malformed, or program does not exist)
Program wasnt imported with
use
$assert()
The assert view method takes in one parameter:
balance(expression)
This method evaluates an expression to a boolean, exiting and erroring the program (and therefore producing a rotten banana) if it evaluates to false
, or continuing with execution and having no effect if it evaluates to true
.
Furthermore, the following edge cases should error and produce a rotten banana:
expression is not of type boolean
$exit()
The assert view method takes in one parameter:
exit(expression)
This method will forcefully exit the execution of a method. The method will be valid and change the Nana state if expression evaluates to true
or produce a rotten banana and revert changes from the call if expression evaluates to false
.
Furthermore, the following edge cases should error and produce a rotten banana:
expression is not of type boolean
$balance()
The balance view method takes in two parameters:
balance(sender, nana)
This view method gets the total balance of nana
from to the programs balance (self
) or the unallocated nana payload (unallocated
) or vice versa. You can switch between the check by using the string self
or the string nana
Returns -> This method returns a u128
repreenting the nana
balance of sender
.
Furthermore, the following edge cases should error and produce a rotten banana:
The Nana being referred to with NanaID doesn't exist (note, if the nana does exist but simply isnt in the balance this will return "0", but will not error)
Sender is not a string that is equivalent to
self
orunallocated
$sha256elided()
The hash view method takes in two parameter:
$sha256elided(value)
value
can be any input string into the sha256 hash function
-> Returns
The return value is a u128 representation of the hash, constructed from output bytes with the last 16 being elided.
Furthermore, the following edge cases should error and produce a rotten banana:
Value is not a string
$random()
Uses math.random() to produce a random integer.... just kidding hehe
The random view method takes in two parameters:
$random(min, max)
This view method gets a seed by running the following macros:
Then a range is determined with min and max:
Then using range seed is normalized to an integer between min and max
This normalized integer represents a random int within the scope of the block. Note - blockhashe's can be manipulated by miners, which the function depends on for the seed
. This should not be used in scenarios where a "correct value" encourages MEV. Such NIPs will be discarded.
Implementation in Javascript (returns BigInt):
-> Returns
u128
Furthermore, the following edge cases should error and produce a rotten banana:
Any of the parameters are malformed (min and max are not u128s)
$get()
The get view method takes in one parameter:
get(key)
Returns a value
from a programs local storage.
A key
can be separated with :
, which causes the key string to be split with :
with the items in the array referring to a field tree.
-> Returns
The exists
field is a boolean that checks for the existence of a non-fieldtree value at key
.
The value
field represents a string
or a u128
that represents the value stored at that specific field on the programs storage. If exists is false, this field will be set to NULL.
Furthermore, the following edge cases should error and produce a rotten banana:
A get's
key
parameter starts with:
A get's
key
parameter ends with:
A get's
key
parameter has any repeating:
A field tree has a depth of more than 10 fields
$block()
The block view method takes in one parameter:
$block(key)
Is able to fetch headers from the current block with key
. A map of available values can be found below:
-> Returns
Furthermore, the following edge cases should error and produce a rotten banana:
The
key
field isn't a valid property listed in the table above (or is not of type string)
$sender()
The sender view method takes in no parameters:
$sender()
Returns the owning address of the first vin
UTXO in a transaction's inputs that had Nanas allocated . In the case no input utxo had nanas present, output will be "GENESIS"
Furthermore, the following edge cases should error:
The view function is called outside the scope of a Banana process. This macro cannot produce a rotten banana, however, since if called within the processing of a Banana it will always have a sender assigned.
Last updated