Compare commits

...

33 Commits

Author SHA1 Message Date
Hans Svensson 009e036192 Merge pull request #116 from aeternity/add_chain_network_id
Add NETWORK_ID FATE instruction
2023-06-30 18:25:31 +02:00
Hans Svensson 37808419a8 Bump version to 3.4.0 2023-06-22 10:12:46 +02:00
Hans Svensson f4c3782888 Patch check_numbering to allow for DBG_ at end 2023-06-22 10:08:41 +02:00
Hans Svensson 1688f85f2b Add NETWORK_ID and push DBG_* to higher opcodes 2023-06-22 08:35:32 +02:00
Gaith Hallak b38349274f Bump version to 3.3.0 (#115) 2023-05-28 13:40:20 +03:00
Hans Svensson b8d593e351 Add instructions for arbitrary sized byte arrays (#114)
* Encode/decode bytes()/{bytes, any} as bytes(-1)

* Add 5 new bytes instructions

* reorder instructions and clarify some operations
2023-05-27 17:13:20 +03:00
Gaith Hallak 0f7529b26a Introduce debugging instructions (#113)
* Add DBGLOC fate op

* Add DBGDEF and DBGUNDEF

* Change the type of arg for dbgdef and dbgundef

* Change DBGUNDEF to end_bb = true

* No safe sanity check for dbgundef

* Rename DBGDEF and DBGUNDEF to DBG_DEF and DBG_UNDEF

* Revert "No safe sanity check for dbgundef"

This reverts commit ee4949777f.

* Rename DBGLOC to DBG_LOC

* Remove column from DBG_LOC

* Add DBG_CALL and DBG_RETURN

* Update the docs for debug opcodes

* Add a DBG_CALL_R for remote calls

* Remove is_tail_call from DBG_CALL_R

* Revert "Remove is_tail_call from DBG_CALL_R"

This reverts commit a620c9c34b.

* Revert "Add a DBG_CALL_R for remote calls"

This reverts commit a336314cfc.

* Revert "Add DBG_CALL and DBG_RETURN"

This reverts commit db9766ac74.

* Add DBG_CONTRACT op

* Upgrade aeserialization dep

* Use aeserialization v1.0.0

* Use aeserialization tag v1.0.0

* Remove debug instructions from AEVM
2023-05-25 18:09:42 +03:00
Gaith Hallak 2a0a397afa Bump version to 3.2.0 (#112)
* Bump version to 3.2.0

* Bump version in rebar.config
2022-10-07 13:25:57 +03:00
Radosław Rowicki 093bcd6204 Merge pull request #111 from aeternity/enable-fate-code-mods
Export FATE code setters
2022-10-03 14:33:59 +02:00
radrow 6601ad2d38 Enable FATE code modifications 2022-09-16 10:54:48 +02:00
Dincho Todorov 578ebe2a8a Switch to OTP23 (#110) 2022-08-29 14:26:17 +03:00
Radosław Rowicki 8269dbd71e Update rebar3 and aeserialization (#109)
* Update rebar3 and aeserialization

* Version
2022-07-27 17:22:42 +04:00
Hans Svensson 08cc0a9fcd Merge pull request #108 from aeternity/fix_doc_generation
Fix document generation script
2021-12-10 14:00:20 +01:00
Hans Svensson 84f20ab683 Fix document generation script 2021-12-10 11:53:54 +01:00
Hans Svensson 7497345928 Merge pull request #106 from aeternity/ceres_extension
Add OPCODES for bitwise operations, addr_to_byte and poseidon hash
2021-11-25 08:33:33 +01:00
Hans Svensson 822a269f75 Add OPCODES for bitwise operations, addr_to_byte and poseidon hash 2021-11-18 16:31:07 +01:00
seanhinde 0699f35b03 Merge pull request #107 from aeternity/otp-24-support
Fix OTP-24 warnings and add OTP-24 compatible rebar3
2021-11-09 16:27:23 +01:00
Sean Hinde 3829e29a63 Fix dialyzer complaint about reading core erlang 2021-11-08 17:56:57 +01:00
Sean Hinde 52e9d30f76 Fix OTP-24 warnings and add OTP-24 compatible rebar3 2021-11-08 17:35:17 +01:00
Hans Svensson da7f00ae5d Merge pull request #105 from aeternity/doc-gen
Ease the process of doc generation
2021-11-04 08:45:26 +01:00
radrow 326fca709f Add opcodes gen 2021-06-08 13:33:33 +02:00
radrow e860e217a0 Better clone&create docs 2021-06-08 13:09:39 +02:00
radrow bc48b5d62f Styling in doc gen 2021-06-08 11:43:36 +02:00
radrow 7b9c1b856b Upgrade doc generation 2021-06-08 11:26:18 +02:00
Hans Svensson 05dfd7ffc7 Merge pull request #104 from aeternity/iris_gas_prices_adjustment
BYTECODE_HASH should be cheaper
2021-04-30 12:16:57 +02:00
Hans Svensson 7d4f3fed10 BYTECODE_HASH should be cheaper 2021-04-30 12:05:17 +02:00
Hans Svensson 4c0906398e Merge pull request #103 from aeternity/iris_gas_prices_adjustment
Revert CALL_R/GR/PGR gas changes
2021-04-30 09:45:18 +02:00
Hans Svensson 1bb24a485b Revert CALL_R/GR/PGR gas changes 2021-04-30 09:14:03 +02:00
Hans Svensson abd12b599f Merge pull request #102 from aeternity/iris_gas_prices_adjustment
Adjust FATE OPs gas price for Iris
2021-04-29 20:31:58 +02:00
Hans Svensson e4d46bd17a Adjust FATE OPs gas price for Iris 2021-04-29 15:16:48 +02:00
Hans Svensson 142502179c Merge pull request #101 from aeternity/protocol_bound_gas_price
Add mechanism for pricing FATE ops differently in IRIS
2021-04-28 15:10:43 +02:00
Hans Svensson 0318c60caf Add mechanism for pricing FATE ops differently in IRIS 2021-04-28 13:18:56 +02:00
Radosław Rowicki eb8810a783 Merge pull request #100 from aeternity/call-fee
Call fee
2021-04-27 09:50:31 +02:00
11 changed files with 355 additions and 238 deletions
+1 -1
View File
@@ -3,7 +3,7 @@ version: 2.1
executors:
aebuilder:
docker:
- image: aeternity/builder
- image: aeternity/builder:bionic-otp23
user: builder
working_directory: ~/aebytecode
+1 -1
View File
@@ -30,7 +30,7 @@ test: local
@$(REBAR) as local eunit
ebin/%.beam: src/%.erl
erlc -o $(dir $@) $<
erlc +debug_info -o $(dir $@) $<
$(GENERATED_SRC): $(GENERATOR_DEPS)
erl -pa ebin/ -noshell -s aeb_fate_generate_ops gen_and_halt src/ include/
+3 -3
View File
@@ -6,7 +6,7 @@
{deps, [ {eblake2, "1.0.0"}
, {aeserialization, {git, "https://github.com/aeternity/aeserialization.git",
{ref, "47aaa8f"}}}
{tag, "v1.0.0"}}}
, {getopt, "1.0.1"}
]}.
@@ -29,7 +29,7 @@
]}.
{relx, [{release, {aebytecode, "2.0.1"},
{relx, [{release, {aebytecode, "3.4.0"},
[aebytecode, eblake2, getopt]},
{dev_mode, true},
@@ -40,7 +40,7 @@
{profiles, [{binary, [
{deps, [ {eblake2, "1.0.0"}
, {aeserialization, {git, "https://github.com/aeternity/aeserialization.git",
{ref, "47aaa8f"}}}
{tag, "v1.0.0"}}}
, {getopt, "1.0.1"}
]},
+7 -4
View File
@@ -1,7 +1,7 @@
{"1.1.0",
{"1.2.0",
[{<<"aeserialization">>,
{git,"https://github.com/aeternity/aeserialization.git",
{ref,"47aaa8f5434b365c50a35bfd1490340b19241991"}},
{ref,"177bf604b2a05e940f92cf00e96e6e269e708245"}},
0},
{<<"base58">>,
{git,"https://github.com/aeternity/erl-base58.git",
@@ -10,11 +10,14 @@
{<<"eblake2">>,{pkg,<<"eblake2">>,<<"1.0.0">>},0},
{<<"enacl">>,
{git,"https://github.com/aeternity/enacl.git",
{ref,"26180f42c0b3a450905d2efd8bc7fd5fd9cece75"}},
{ref,"793ddb502f7fe081302e1c42227dca70b09f8e17"}},
1},
{<<"getopt">>,{pkg,<<"getopt">>,<<"1.0.1">>},0}]}.
[
{pkg_hash,[
{<<"eblake2">>, <<"EC8AD20E438AAB3F2E8D5D118C366A0754219195F8A0F536587440F8F9BCF2EF">>},
{<<"getopt">>, <<"C73A9FA687B217F2FF79F68A3B637711BB1936E712B521D8CE466B29CBF7808A">>}]}
{<<"getopt">>, <<"C73A9FA687B217F2FF79F68A3B637711BB1936E712B521D8CE466B29CBF7808A">>}]},
{pkg_hash_ext,[
{<<"eblake2">>, <<"3C4D300A91845B25D501929A26AC2E6F7157480846FAB2347A4C11AE52E08A99">>},
{<<"getopt">>, <<"53E1AB83B9CEB65C9672D3E7A35B8092E9BDC9B3EE80721471A161C10C59959C">>}]}
].
BIN
View File
Binary file not shown.
+2 -2
View File
@@ -356,7 +356,7 @@ parse_tuple(Tokens) ->
parse_variant([{start_variant,_line}
, {'[', _line}
, {'[', _}
| Rest]) ->
{Arities, Rest2} = parse_list(Rest),
%% Make sure Arities is a list of bytes.
@@ -364,7 +364,7 @@ parse_variant([{start_variant,_line}
is_integer(A), A < 256],
[{'|',_}
, {int,_line, Tag}
, {int,_, Tag}
, {'|',_}
, {'(',_} | Rest3] = Rest2,
{Elements , [{end_variant, _} | Rest4]} = parse_tuple(Rest3),
-2
View File
@@ -27,11 +27,9 @@
-include("../include/aeb_fate_opcodes.hrl").
-include("../include/aeb_fate_data.hrl").
-ifdef(EQC).
-export([ update_annotations/2
, update_functions/2
, update_symbols/2]).
-endif.
-record(fcode, { functions = #{} :: map()
, symbols = #{} :: map()
+8 -2
View File
@@ -238,6 +238,8 @@ serialize_type({tuple, Ts}) ->
N when N =< 255 ->
[?TYPE_TUPLE, N | [serialize_type(T) || T <- Ts]]
end;
serialize_type({bytes, any}) ->
[?TYPE_BYTES | binary_to_list(serialize_integer(-1))];
serialize_type({bytes, N}) when 0 =< N ->
[?TYPE_BYTES | binary_to_list(serialize_integer(N))];
serialize_type(address) -> [?TYPE_OBJECT, ?OTYPE_ADDRESS];
@@ -270,8 +272,12 @@ deserialize_type(<<?TYPE_TUPLE, N, Rest/binary>>) ->
{{tuple, Ts}, Rest2};
deserialize_type(<<?TYPE_BYTES, Rest/binary>>) ->
{N, Rest2} = deserialize_one(Rest),
true = is_integer(N) andalso N >= 0,
{{bytes, N}, Rest2};
true = is_integer(N),
if N == -1 ->
{{bytes, any}, Rest2};
0 =< N ->
{{bytes, N}, Rest2}
end;
deserialize_type(<<?TYPE_OBJECT, ObjectType, Rest/binary>>) ->
case ObjectType of
?OTYPE_ADDRESS -> {address, Rest};
+132
View File
@@ -0,0 +1,132 @@
-module(aeb_fate_generate_docs).
-export([generate_documentation/2, generate_documentation/3]).
-export(
[ gen_protocol_opcodes_flags_and_gas/1
, gen_protocol_description_of_operations/1
, gen_protocol_opcodes/1
]).
-define(LIMA_PROTOCOL_VSN, 4).
-define(IRIS_PROTOCOL_VSN, 5).
generate_documentation(Filename, Fields) ->
generate_documentation(Filename, Fields, fun(_) -> true end).
generate_documentation(Filename, Fields, Filter) when is_function(Filter, 1) ->
{ok, File} = file:open(Filename, [write, {encoding, utf8}]),
Header =
lists:flatten(
"|" ++ [" " ++ header_name(F) ++ " |" || F <- Fields] ++ "\n"
),
Separator =
lists:flatten(
"|" ++ [" " ++ ["-" || _ <- header_name(F)] ++ " |" || F <- Fields] ++ "\n"
),
Instructions =
lists:flatten(
[gen_doc_for_op(Op, Fields)
++ "\n" || Op <- aeb_fate_generate_ops:get_ops(), Filter(Op)]),
io:format(File, "~ts~ts~ts\n", [Header, Separator, Instructions]),
file:close(File).
header_name(opname) ->
"Name";
header_name(opcode) ->
"Opcode";
header_name(arity) ->
"Arity";
header_name(end_bb) ->
"Ends basic block";
header_name(in_auth) ->
"Allowed in auth";
header_name(offchain) ->
"Allowed offchain";
header_name(format) ->
"Args";
header_name(doc) ->
"Description";
header_name(gas) ->
"Gas cost";
header_name(arg_types) ->
"Arg types";
header_name(res_type) ->
"Res type".
gen_doc_for_op(#{ opname := OpName
, opcode := OpCode
, arity := Arity
, end_bb := EndBB
, in_auth := InAuth
, offchain := AllowedOffchain
, format := FateFormat
, doc := Doc
, gas := Gas
, arg_types := ArgTypes
, res_type := ResType
}, Fields) ->
"| " ++
string:join(
[ case Field of
opname -> io_lib:format("`~s`", [OpName]);
opcode -> io_lib:format("0x~.16b", [OpCode]);
arity -> io_lib:format("~p", [Arity]);
end_bb -> io_lib:format("~p", [EndBB]);
in_auth -> io_lib:format("~p", [InAuth]);
offchain -> io_lib:format("~p", [AllowedOffchain]);
format ->
case FateFormat of
[] -> "";
_ -> lists:join(
" ",
[format_arg_doc(A) ||
A <-
lists:zip(FateFormat,
lists:seq(0,length(FateFormat)-1))])
end;
doc -> Doc;
gas when is_integer(Gas) -> io_lib:format("~p", [Gas]);
gas when is_list(Gas) ->
lists:flatten(
string:join(
[ io_lib:format(
"~p (~s)",
[GasVal, protocol_name(Prot)]
)
|| {Prot, GasVal} <- Gas
], ", "));
arg_types -> io_lib:format("~p", [ArgTypes]);
res_type -> io_lib:format("~p", [ResType])
end
|| Field <- Fields
],
" | ") ++ " |".
protocol_name(?LIMA_PROTOCOL_VSN) ->
"lima";
protocol_name(?IRIS_PROTOCOL_VSN) ->
"iris".
format_arg_doc({a, N}) -> io_lib:format("Arg~w", [N]);
format_arg_doc({is,_N}) -> "Identifier";
format_arg_doc({ii,_N}) -> "Integer";
format_arg_doc({li,_N}) -> "[Integers]";
format_arg_doc({t,_N}) -> "Type".
%% --- protocol documentation ---
gen_protocol_description_of_operations(Filename) ->
generate_documentation(
Filename, [opname, format, doc, arg_types, res_type]
).
gen_protocol_opcodes_flags_and_gas(Filename) ->
generate_documentation(
Filename, [opcode, opname, end_bb, in_auth, offchain, gas]
).
gen_protocol_opcodes(Filename) ->
generate_documentation(
Filename, [opcode, opname]
).
+200 -222
View File
@@ -2,7 +2,6 @@
-export([ gen_and_halt/1
, generate/0
, generate_documentation/1
, get_ops/0
, test_asm_generator/1 ]).
@@ -33,206 +32,232 @@ check_numbering(N, [T|Rest]) ->
OpCode = element(2, T),
case OpCode of
N -> check_numbering(N+1, Rest);
16#f0 -> check_numbering(16#f0+1, Rest);
16#fa -> check_numbering(16#fa+1, Rest);
_ when OpCode < N -> {duplicate_opcode, OpCode};
_ when OpCode > N -> {missing_opcode, N}
end;
check_numbering(_, []) -> true.
-define(LIMA_PROTOCOL_VSN, 4).
-define(IRIS_PROTOCOL_VSN, 5).
-define(GAS(A), A).
-define(GAS_IRIS(A, B), [{?IRIS_PROTOCOL_VSN, B}, {?LIMA_PROTOCOL_VSN, A}]).
%% TODO: Some real gas numbers...
ops_defs() ->
%% Opname, Opcode, end_bb, in_auth offchain, gas, format, Constructor, ArgType, ResType, Documentation
[ { 'RETURN', 16#00, true, true, true, 10, [], return, {}, any, "Return from function call, top of stack is return value . The type of the retun value has to match the return type of the function."}
, { 'RETURNR', 16#01, true, true, true, 10, [a], returnr, {any}, any, "Push Arg0 and return from function. The type of the retun value has to match the return type of the function."}
, { 'CALL', 16#02, true, true, true, 10, [a], call, {string}, any, "Call the function Arg0 with args on stack. The types of the arguments has to match the argument typs of the function."}
, { 'CALL_R', 16#03, true, false, true, 100, [a,is,a,a,a], call_r, {contract, string, typerep, typerep, integer}, any, "Remote call to contract Arg0 and function Arg1 of type Arg2 => Arg3 with value Arg4. The types of the arguments has to match the argument types of the function."}
, { 'CALL_T', 16#04, true, true, true, 10, [a], call_t, {string}, any, "Tail call to function Arg0. The types of the arguments has to match the argument typs of the function. And the return type of the called function has to match the type of the current function."}
, { 'CALL_GR', 16#05, true, false, true, 100, [a,is,a,a,a,a], call_gr, {contract, string, typerep, typerep, integer, integer}, any, "Remote call with gas cap in Arg4. Otherwise as CALL_R."}
, { 'JUMP', 16#06, true, true, true, 10, [ii], jump, {integer}, none, "Jump to a basic block. The basic block has to exist in the current function."}
, { 'JUMPIF', 16#07, true, true, true, 10, [a,ii], jumpif, {boolean, integer}, none, "Conditional jump to a basic block. If Arg0 then jump to Arg1."}
, { 'SWITCH_V2', 16#08, true, true, true, 10, [a,ii,ii], switch, {variant, integer, ingeger}, none, "Conditional jump to a basic block on variant tag."}
, { 'SWITCH_V3', 16#09, true, true, true, 10, [a,ii,ii,ii], switch, {variant, integer, integer, ingeger}, none, "Conditional jump to a basic block on variant tag."}
, { 'SWITCH_VN', 16#0a, true, true, true, 10, [a, li], switch, {variant, {list, integer}}, none, "Conditional jump to a basic block on variant tag."}
, { 'CALL_VALUE', 16#0b, false, true, true, 10, [a], call_value, {}, integer, "The value sent in the current remote call."}
, { 'PUSH', 16#0c, false, true, true, 10, [a], push, {any}, any, "Push argument to stack."}
, { 'DUPA', 16#0d, false, true, true, 10, [], dup, {any}, any, "Duplicate top of stack."}
, { 'DUP', 16#0e, false, true, true, 10, [a], dup, {any}, any, "push Arg0 stack pos on top of stack."}
, { 'POP', 16#0f, false, true, true, 10, [a], pop, {integer}, integer, "Arg0 := top of stack."}
, { 'INCA', 16#10, false, true, true, 10, [], inc, {integer}, integer, "Increment accumulator."}
, { 'INC', 16#11, false, true, true, 10, [a], inc, {integer}, integer, "Increment argument."}
, { 'DECA', 16#12, false, true, true, 10, [], dec, {integer}, integer, "Decrement accumulator."}
, { 'DEC', 16#13, false, true, true, 10, [a], dec, {integer}, integer, "Decrement argument."}
, { 'ADD', 16#14, false, true, true, 10, [a,a,a], add, {integer, integer}, integer, "Arg0 := Arg1 + Arg2."}
, { 'SUB', 16#15, false, true, true, 10, [a,a,a], sub, {integer, integer}, integer, "Arg0 := Arg1 - Arg2."}
, { 'MUL', 16#16, false, true, true, 10, [a,a,a], mul, {integer, integer}, integer, "Arg0 := Arg1 * Arg2."}
, { 'DIV', 16#17, false, true, true, 10, [a,a,a], divide, {integer, integer}, integer, "Arg0 := Arg1 / Arg2."}
, { 'MOD', 16#18, false, true, true, 10, [a,a,a], modulo, {integer, integer}, integer, "Arg0 := Arg1 mod Arg2."}
, { 'POW', 16#19, false, true, true, 10, [a,a,a], pow, {integer, integer}, integer, "Arg0 := Arg1 ^ Arg2."}
, { 'STORE', 16#1a, false, true, true, 10, [a,a], store, {any}, any, "Arg0 := Arg1."}
, { 'SHA3', 16#1b, false, true, true, 100, [a,a], sha3, {any}, hash, "Arg0 := sha3(Arg1)."}
, { 'SHA256', 16#1c, false, true, true, 100, [a,a], sha256, {any}, hash, "Arg0 := sha256(Arg1)."}
, { 'BLAKE2B', 16#1d, false, true, true, 100, [a,a], blake2b, {any}, hash, "Arg0 := blake2b(Arg1)."}
, { 'LT', 16#1e, false, true, true, 10, [a,a,a], lt, {integer, integer}, boolean, "Arg0 := Arg1 < Arg2."}
, { 'GT', 16#1f, false, true, true, 10, [a,a,a], gt, {integer, integer}, boolean, "Arg0 := Arg1 > Arg2."}
, { 'EQ', 16#20, false, true, true, 10, [a,a,a], eq, {integer, integer}, boolean, "Arg0 := Arg1 = Arg2."}
, { 'ELT', 16#21, false, true, true, 10, [a,a,a], elt, {integer, integer}, boolean, "Arg0 := Arg1 =< Arg2."}
, { 'EGT', 16#22, false, true, true, 10, [a,a,a], egt, {integer, integer}, boolean, "Arg0 := Arg1 >= Arg2."}
, { 'NEQ', 16#23, false, true, true, 10, [a,a,a], neq, {integer, integer}, boolean, "Arg0 := Arg1 /= Arg2."}
, { 'AND', 16#24, false, true, true, 10, [a,a,a], and_op, {boolean, boolean}, boolean, "Arg0 := Arg1 and Arg2."}
, { 'OR', 16#25, false, true, true, 10, [a,a,a], or_op, {boolean, boolean}, boolean, "Arg0 := Arg1 or Arg2."}
, { 'NOT', 16#26, false, true, true, 10, [a,a], not_op, {boolean}, boolean, "Arg0 := not Arg1."}
, { 'TUPLE', 16#27, false, true, true, 10, [a,ii], tuple, {integer}, tuple, "Arg0 := tuple of size = Arg1. Elements on stack."}
, { 'ELEMENT', 16#28, false, true, true, 10, [a,a,a], element_op, {integer, tuple}, any, "Arg1 := element(Arg2, Arg3)."}
, { 'SETELEMENT', 16#29, false, true, true, 10, [a,a,a,a], setelement, {integer, tuple, any}, tuple, "Arg0 := a new tuple similar to Arg2, but with element number Arg1 replaced by Arg3."}
, { 'MAP_EMPTY', 16#2a, false, true, true, 10, [a], map_empty, {}, map, "Arg0 := #{}."}
, { 'MAP_LOOKUP', 16#2b, false, true, true, 10, [a,a,a], map_lookup, {map, any}, any, "Arg0 := lookup key Arg2 in map Arg1."}
, { 'MAP_LOOKUPD', 16#2c, false, true, true, 10, [a,a,a,a], map_lookup, {map, any, any}, any, "Arg0 := lookup key Arg2 in map Arg1 if key exists in map otherwise Arg0 := Arg3."}
, { 'MAP_UPDATE', 16#2d, false, true, true, 10, [a,a,a,a], map_update, {map, any, any}, map, "Arg0 := update key Arg2 in map Arg1 with value Arg3."}
, { 'MAP_DELETE', 16#2e, false, true, true, 10, [a,a,a], map_delete, {map, any}, map, "Arg0 := delete key Arg2 from map Arg1."}
, { 'MAP_MEMBER', 16#2f, false, true, true, 10, [a,a,a], map_member, {map, any}, boolean, "Arg0 := true if key Arg2 is in map Arg1."}
, { 'MAP_FROM_LIST', 16#30, false, true, true, 10, [a,a], map_from_list, {{list, {tuple, [any, any]}}}, map, "Arg0 := make a map from (key, value) list in Arg1."}
, { 'MAP_SIZE', 16#31, false, true, true, 10, [a,a], map_size_, {map}, integer, "Arg0 := The size of the map Arg1."}
, { 'MAP_TO_LIST', 16#32, false, true, true, 10, [a,a], map_to_list, {map}, list, "Arg0 := The tuple list representation of the map Arg1."}
, { 'IS_NIL', 16#33, false, true, true, 10, [a,a], is_nil, {list}, boolean, "Arg0 := true if Arg1 == []."}
, { 'CONS', 16#34, false, true, true, 10, [a,a,a], cons, {any, list}, list, "Arg0 := [Arg1|Arg2]."}
, { 'HD', 16#35, false, true, true, 10, [a,a], hd, {list}, any, "Arg0 := head of list Arg1."}
, { 'TL', 16#36, false, true, true, 10, [a,a], tl, {list}, list, "Arg0 := tail of list Arg1."}
, { 'LENGTH', 16#37, false, true, true, 10, [a,a], length, {list}, integer, "Arg0 := length of list Arg1."}
, { 'NIL', 16#38, false, true, true, 10, [a], nil, {}, list, "Arg0 := []."}
, { 'APPEND', 16#39, false, true, true, 10, [a,a,a], append, {list, list}, list, "Arg0 := Arg1 ++ Arg2."}
, { 'STR_JOIN', 16#3a, false, true, true, 10, [a,a,a], str_join, {string, string}, string, "Arg0 := string Arg1 followed by string Arg2."}
, { 'INT_TO_STR', 16#3b, false, true, true, 100, [a,a], int_to_str, {integer}, string, "Arg0 := turn integer Arg1 into a string."}
, { 'ADDR_TO_STR', 16#3c, false, true, true, 100, [a,a], addr_to_str, {address}, string, "Arg0 := turn address Arg1 into a string."}
, { 'STR_REVERSE', 16#3d, false, true, true, 100, [a,a], str_reverse, {string}, string, "Arg0 := the reverse of string Arg1."}
, { 'STR_LENGTH', 16#3e, false, true, true, 10, [a,a], str_length, {string}, integer, "Arg0 := The length of the string Arg1."}
, { 'BYTES_TO_INT', 16#3f, false, true, true, 10, [a,a], bytes_to_int, {bytes}, integer, "Arg0 := bytes_to_int(Arg1)"}
, { 'BYTES_TO_STR', 16#40, false, true, true, 100, [a,a], bytes_to_str, {bytes}, string, "Arg0 := bytes_to_str(Arg1)"}
, { 'BYTES_CONCAT', 16#41, false, true, true, 10, [a,a,a], bytes_concat, {bytes, bytes}, bytes, "Arg0 := bytes_concat(Arg1, Arg2)"}
, { 'BYTES_SPLIT', 16#42, false, true, true, 10, [a,a,a], bytes_split, {bytes, integer}, bytes, "Arg0 := bytes_split(Arg2, Arg1), where Arg2 is the length of the first chunk."}
, { 'INT_TO_ADDR', 16#43, false, true, true, 10, [a,a], int_to_addr, {integer}, address, "Arg0 := turn integer Arg1 into an address."}
, { 'VARIANT', 16#44, false, true, true, 10, [a,a,a,a], variant, {integer, integer, integer}, variant, "Arg0 := create a variant of size Arg1 with the tag Arg2 (Arg2 < Arg1) and take Arg3 elements from the stack."}
, { 'VARIANT_TEST', 16#45, false, true, true, 10, [a,a,a], variant_test, {variant, integer}, boolean, "Arg0 := true if variant Arg1 has the tag Arg2."}
, { 'VARIANT_ELEMENT', 16#46, false, true, true, 10, [a,a,a], variant_element, {variant, integer}, any, "Arg0 := element number Arg2 from variant Arg1."}
, { 'BITS_NONEA', 16#47, false, true, true, 10, [], bits_none, {}, bits, "push an empty bitmap on the stack."}
, { 'BITS_NONE', 16#48, false, true, true, 10, [a], bits_none, {}, bits, "Arg0 := empty bitmap."}
, { 'BITS_ALLA', 16#49, false, true, true, 10, [], bits_all, {}, bits, "push a full bitmap on the stack."}
, { 'BITS_ALL', 16#4a, false, true, true, 10, [a], bits_all, {}, bits, "Arg0 := full bitmap."}
, { 'BITS_ALL_N', 16#4b, false, true, true, 10, [a,a], bits_all_n, {integer}, bits, "Arg0 := bitmap with Arg1 bits set."}
, { 'BITS_SET', 16#4c, false, true, true, 10, [a,a,a], bits_set, {bits, integer}, bits, "Arg0 := set bit Arg2 of bitmap Arg1."}
, { 'BITS_CLEAR', 16#4d, false, true, true, 10, [a,a,a], bits_clear, {bits, integer}, bits, "Arg0 := clear bit Arg2 of bitmap Arg1."}
, { 'BITS_TEST', 16#4e, false, true, true, 10, [a,a,a], bits_test, {bits, integer}, boolean, "Arg0 := true if bit Arg2 of bitmap Arg1 is set."}
, { 'BITS_SUM', 16#4f, false, true, true, 10, [a,a], bits_sum, {bits}, integer, "Arg0 := sum of set bits in bitmap Arg1. Exception if infinit bitmap."}
, { 'BITS_OR', 16#50, false, true, true, 10, [a,a,a], bits_or, {bits, bits}, bits, "Arg0 := Arg1 v Arg2."}
, { 'BITS_AND', 16#51, false, true, true, 10, [a,a,a], bits_and, {bits, bits}, bits, "Arg0 := Arg1 ^ Arg2."}
, { 'BITS_DIFF', 16#52, false, true, true, 10, [a,a,a], bits_diff, {bits, bits}, bits, "Arg0 := Arg1 - Arg2."}
, { 'BALANCE', 16#53, false, true, true, 10, [a], balance, {}, integer, "Arg0 := The current contract balance."}
, { 'ORIGIN', 16#54, false, true, true, 10, [a], origin, {}, address, "Arg0 := Address of contract called by the call transaction."}
, { 'CALLER', 16#55, false, true, true, 10, [a], caller, {}, address, "Arg0 := The address that signed the call transaction."}
, { 'BLOCKHASH', 16#56, false, true, true, 10, [a,a], blockhash, {integer}, variant, "Arg0 := The blockhash at height."}
, { 'BENEFICIARY', 16#57, false, true, true, 10, [a], beneficiary, {}, address, "Arg0 := The address of the current beneficiary."}
, { 'TIMESTAMP', 16#58, false, true, true, 10, [a], timestamp, {}, integer, "Arg0 := The current timestamp. Unrelaiable, don't use for anything."}
, { 'GENERATION', 16#59, false, true, true, 10, [a], generation, {}, integer, "Arg0 := The block height of the cureent generation."}
, { 'MICROBLOCK', 16#5a, false, true, true, 10, [a], microblock, {}, integer, "Arg0 := The current micro block number."}
, { 'DIFFICULTY', 16#5b, false, true, true, 10, [a], difficulty, {}, integer, "Arg0 := The current difficulty."}
, { 'GASLIMIT', 16#5c, false, true, true, 10, [a], gaslimit, {}, integer, "Arg0 := The current gaslimit."}
, { 'GAS', 16#5d, false, true, true, 10, [a], gas, {}, integer, "Arg0 := The amount of gas left."}
, { 'ADDRESS', 16#5e, false, true, true, 10, [a], address, {}, address, "Arg0 := The current contract address."}
, { 'GASPRICE', 16#5f, false, true, true, 10, [a], gasprice, {}, integer, "Arg0 := The current gas price."}
%% Opname, Opcode, end_bb, in_auth,offchain, gas, format, Constructor, ArgType, ResType, Documentation
[ { 'RETURN', 16#00, true, true, true, ?GAS(10), [], return, {}, any, "Return from function call, top of stack is return value . The type of the retun value has to match the return type of the function."}
, { 'RETURNR', 16#01, true, true, true, ?GAS(10), [a], returnr, {any}, any, "Push Arg0 and return from function. The type of the retun value has to match the return type of the function."}
, { 'CALL', 16#02, true, true, true, ?GAS(10), [a], call, {string}, any, "Call the function Arg0 with args on stack. The types of the arguments has to match the argument typs of the function."}
, { 'CALL_R', 16#03, true, false, true, ?GAS(100), [a,is,a,a,a], call_r, {contract, string, typerep, typerep, integer}, any, "Remote call to contract Arg0 and function Arg1 of type Arg2 => Arg3 with value Arg4. The types of the arguments has to match the argument types of the function."}
, { 'CALL_T', 16#04, true, true, true, ?GAS(10), [a], call_t, {string}, any, "Tail call to function Arg0. The types of the arguments has to match the argument typs of the function. And the return type of the called function has to match the type of the current function."}
, { 'CALL_GR', 16#05, true, false, true, ?GAS(100), [a,is,a,a,a,a], call_gr, {contract, string, typerep, typerep, integer, integer}, any, "Remote call with gas cap in Arg4. Otherwise as CALL_R."}
, { 'JUMP', 16#06, true, true, true, ?GAS(10), [ii], jump, {integer}, none, "Jump to a basic block. The basic block has to exist in the current function."}
, { 'JUMPIF', 16#07, true, true, true, ?GAS(10), [a,ii], jumpif, {boolean, integer}, none, "Conditional jump to a basic block. If Arg0 then jump to Arg1."}
, { 'SWITCH_V2', 16#08, true, true, true, ?GAS(10), [a,ii,ii], switch, {variant, integer, ingeger}, none, "Conditional jump to a basic block on variant tag."}
, { 'SWITCH_V3', 16#09, true, true, true, ?GAS(10), [a,ii,ii,ii], switch, {variant, integer, integer, ingeger}, none, "Conditional jump to a basic block on variant tag."}
, { 'SWITCH_VN', 16#0a, true, true, true, ?GAS(10), [a, li], switch, {variant, {list, integer}}, none, "Conditional jump to a basic block on variant tag."}
, { 'CALL_VALUE', 16#0b, false, true, true, ?GAS(10), [a], call_value, {}, integer, "The value sent in the current remote call."}
, { 'PUSH', 16#0c, false, true, true, ?GAS(10), [a], push, {any}, any, "Push argument to stack."}
, { 'DUPA', 16#0d, false, true, true, ?GAS(10), [], dup, {any}, any, "Duplicate top of stack."}
, { 'DUP', 16#0e, false, true, true, ?GAS(10), [a], dup, {any}, any, "push Arg0 stack pos on top of stack."}
, { 'POP', 16#0f, false, true, true, ?GAS(10), [a], pop, {integer}, integer, "Arg0 := top of stack."}
, { 'INCA', 16#10, false, true, true, ?GAS(10), [], inc, {integer}, integer, "Increment accumulator."}
, { 'INC', 16#11, false, true, true, ?GAS(10), [a], inc, {integer}, integer, "Increment argument."}
, { 'DECA', 16#12, false, true, true, ?GAS(10), [], dec, {integer}, integer, "Decrement accumulator."}
, { 'DEC', 16#13, false, true, true, ?GAS(10), [a], dec, {integer}, integer, "Decrement argument."}
, { 'ADD', 16#14, false, true, true, ?GAS(10), [a,a,a], add, {integer, integer}, integer, "Arg0 := Arg1 + Arg2."}
, { 'SUB', 16#15, false, true, true, ?GAS(10), [a,a,a], sub, {integer, integer}, integer, "Arg0 := Arg1 - Arg2."}
, { 'MUL', 16#16, false, true, true, ?GAS(10), [a,a,a], mul, {integer, integer}, integer, "Arg0 := Arg1 * Arg2."}
, { 'DIV', 16#17, false, true, true, ?GAS(10), [a,a,a], divide, {integer, integer}, integer, "Arg0 := Arg1 / Arg2."}
, { 'MOD', 16#18, false, true, true, ?GAS(10), [a,a,a], modulo, {integer, integer}, integer, "Arg0 := Arg1 mod Arg2."}
, { 'POW', 16#19, false, true, true, ?GAS(10), [a,a,a], pow, {integer, integer}, integer, "Arg0 := Arg1 ^ Arg2."}
, { 'STORE', 16#1a, false, true, true, ?GAS(10), [a,a], store, {any}, any, "Arg0 := Arg1."}
, { 'SHA3', 16#1b, false, true, true, ?GAS(100), [a,a], sha3, {any}, hash, "Arg0 := sha3(Arg1)."}
, { 'SHA256', 16#1c, false, true, true, ?GAS(100), [a,a], sha256, {any}, hash, "Arg0 := sha256(Arg1)."}
, { 'BLAKE2B', 16#1d, false, true, true, ?GAS(100), [a,a], blake2b, {any}, hash, "Arg0 := blake2b(Arg1)."}
, { 'LT', 16#1e, false, true, true, ?GAS(10), [a,a,a], lt, {integer, integer}, boolean, "Arg0 := Arg1 < Arg2."}
, { 'GT', 16#1f, false, true, true, ?GAS(10), [a,a,a], gt, {integer, integer}, boolean, "Arg0 := Arg1 > Arg2."}
, { 'EQ', 16#20, false, true, true, ?GAS(10), [a,a,a], eq, {integer, integer}, boolean, "Arg0 := Arg1 = Arg2."}
, { 'ELT', 16#21, false, true, true, ?GAS(10), [a,a,a], elt, {integer, integer}, boolean, "Arg0 := Arg1 =< Arg2."}
, { 'EGT', 16#22, false, true, true, ?GAS(10), [a,a,a], egt, {integer, integer}, boolean, "Arg0 := Arg1 >= Arg2."}
, { 'NEQ', 16#23, false, true, true, ?GAS(10), [a,a,a], neq, {integer, integer}, boolean, "Arg0 := Arg1 /= Arg2."}
, { 'AND', 16#24, false, true, true, ?GAS(10), [a,a,a], and_op, {boolean, boolean}, boolean, "Arg0 := Arg1 and Arg2."}
, { 'OR', 16#25, false, true, true, ?GAS(10), [a,a,a], or_op, {boolean, boolean}, boolean, "Arg0 := Arg1 or Arg2."}
, { 'NOT', 16#26, false, true, true, ?GAS(10), [a,a], not_op, {boolean}, boolean, "Arg0 := not Arg1."}
, { 'TUPLE', 16#27, false, true, true, ?GAS(10), [a,ii], tuple, {integer}, tuple, "Arg0 := tuple of size = Arg1. Elements on stack."}
, { 'ELEMENT', 16#28, false, true, true, ?GAS(10), [a,a,a], element_op, {integer, tuple}, any, "Arg1 := element(Arg2, Arg3)."}
, { 'SETELEMENT', 16#29, false, true, true, ?GAS(10), [a,a,a,a], setelement, {integer, tuple, any}, tuple, "Arg0 := a new tuple similar to Arg2, but with element number Arg1 replaced by Arg3."}
, { 'MAP_EMPTY', 16#2a, false, true, true, ?GAS(10), [a], map_empty, {}, map, "Arg0 := #{}."}
, { 'MAP_LOOKUP', 16#2b, false, true, true, ?GAS(10), [a,a,a], map_lookup, {map, any}, any, "Arg0 := lookup key Arg2 in map Arg1."}
, { 'MAP_LOOKUPD', 16#2c, false, true, true, ?GAS(10), [a,a,a,a], map_lookup, {map, any, any}, any, "Arg0 := lookup key Arg2 in map Arg1 if key exists in map otherwise Arg0 := Arg3."}
, { 'MAP_UPDATE', 16#2d, false, true, true, ?GAS(10), [a,a,a,a], map_update, {map, any, any}, map, "Arg0 := update key Arg2 in map Arg1 with value Arg3."}
, { 'MAP_DELETE', 16#2e, false, true, true, ?GAS(10), [a,a,a], map_delete, {map, any}, map, "Arg0 := delete key Arg2 from map Arg1."}
, { 'MAP_MEMBER', 16#2f, false, true, true, ?GAS(10), [a,a,a], map_member, {map, any}, boolean, "Arg0 := true if key Arg2 is in map Arg1."}
, { 'MAP_FROM_LIST', 16#30, false, true, true, ?GAS(10), [a,a], map_from_list, {{list, {tuple, [any, any]}}}, map, "Arg0 := make a map from (key, value) list in Arg1."}
, { 'MAP_SIZE', 16#31, false, true, true, ?GAS(10), [a,a], map_size_, {map}, integer, "Arg0 := The size of the map Arg1."}
, { 'MAP_TO_LIST', 16#32, false, true, true, ?GAS(10), [a,a], map_to_list, {map}, list, "Arg0 := The tuple list representation of the map Arg1."}
, { 'IS_NIL', 16#33, false, true, true, ?GAS(10), [a,a], is_nil, {list}, boolean, "Arg0 := true if Arg1 == []."}
, { 'CONS', 16#34, false, true, true, ?GAS(10), [a,a,a], cons, {any, list}, list, "Arg0 := [Arg1|Arg2]."}
, { 'HD', 16#35, false, true, true, ?GAS(10), [a,a], hd, {list}, any, "Arg0 := head of list Arg1."}
, { 'TL', 16#36, false, true, true, ?GAS(10), [a,a], tl, {list}, list, "Arg0 := tail of list Arg1."}
, { 'LENGTH', 16#37, false, true, true, ?GAS(10), [a,a], length, {list}, integer, "Arg0 := length of list Arg1."}
, { 'NIL', 16#38, false, true, true, ?GAS(10), [a], nil, {}, list, "Arg0 := []."}
, { 'APPEND', 16#39, false, true, true, ?GAS(10), [a,a,a], append, {list, list}, list, "Arg0 := Arg1 ++ Arg2."}
, { 'STR_JOIN', 16#3a, false, true, true, ?GAS(10), [a,a,a], str_join, {string, string}, string, "Arg0 := string Arg1 followed by string Arg2."}
, { 'INT_TO_STR', 16#3b, false, true, true, ?GAS(100), [a,a], int_to_str, {integer}, string, "Arg0 := turn integer Arg1 into a string."}
, { 'ADDR_TO_STR', 16#3c, false, true, true, ?GAS(100), [a,a], addr_to_str, {address}, string, "Arg0 := turn address Arg1 into a string."}
, { 'STR_REVERSE', 16#3d, false, true, true, ?GAS(100), [a,a], str_reverse, {string}, string, "Arg0 := the reverse of string Arg1."}
, { 'STR_LENGTH', 16#3e, false, true, true, ?GAS(10), [a,a], str_length, {string}, integer, "Arg0 := The length of the string Arg1."}
, { 'BYTES_TO_INT', 16#3f, false, true, true, ?GAS(10), [a,a], bytes_to_int, {bytes}, integer, "Arg0 := bytes_to_int(Arg1)"}
, { 'BYTES_TO_STR', 16#40, false, true, true, ?GAS(100), [a,a], bytes_to_str, {bytes}, string, "Arg0 := bytes_to_str(Arg1)"}
, { 'BYTES_CONCAT', 16#41, false, true, true, ?GAS(10), [a,a,a], bytes_concat, {bytes, bytes}, bytes, "Arg0 := bytes_concat(Arg1, Arg2)"}
, { 'BYTES_SPLIT', 16#42, false, true, true, ?GAS(10), [a,a,a], bytes_split, {bytes, integer}, bytes, "Arg0 := bytes_split(Arg2, Arg1), where Arg2 is the length of the first chunk."}
, { 'INT_TO_ADDR', 16#43, false, true, true, ?GAS(10), [a,a], int_to_addr, {integer}, address, "Arg0 := turn integer Arg1 into an address."}
, { 'VARIANT', 16#44, false, true, true, ?GAS(10), [a,a,a,a], variant, {integer, integer, integer}, variant, "Arg0 := create a variant of size Arg1 with the tag Arg2 (Arg2 < Arg1) and take Arg3 elements from the stack."}
, { 'VARIANT_TEST', 16#45, false, true, true, ?GAS(10), [a,a,a], variant_test, {variant, integer}, boolean, "Arg0 := true if variant Arg1 has the tag Arg2."}
, { 'VARIANT_ELEMENT', 16#46, false, true, true, ?GAS(10), [a,a,a], variant_element, {variant, integer}, any, "Arg0 := element number Arg2 from variant Arg1."}
, { 'BITS_NONEA', 16#47, false, true, true, ?GAS(10), [], bits_none, {}, bits, "push an empty bitmap on the stack."}
, { 'BITS_NONE', 16#48, false, true, true, ?GAS(10), [a], bits_none, {}, bits, "Arg0 := empty bitmap."}
, { 'BITS_ALLA', 16#49, false, true, true, ?GAS(10), [], bits_all, {}, bits, "push a full bitmap on the stack."}
, { 'BITS_ALL', 16#4a, false, true, true, ?GAS(10), [a], bits_all, {}, bits, "Arg0 := full bitmap."}
, { 'BITS_ALL_N', 16#4b, false, true, true, ?GAS(10), [a,a], bits_all_n, {integer}, bits, "Arg0 := bitmap with Arg1 bits set."}
, { 'BITS_SET', 16#4c, false, true, true, ?GAS(10), [a,a,a], bits_set, {bits, integer}, bits, "Arg0 := set bit Arg2 of bitmap Arg1."}
, { 'BITS_CLEAR', 16#4d, false, true, true, ?GAS(10), [a,a,a], bits_clear, {bits, integer}, bits, "Arg0 := clear bit Arg2 of bitmap Arg1."}
, { 'BITS_TEST', 16#4e, false, true, true, ?GAS(10), [a,a,a], bits_test, {bits, integer}, boolean, "Arg0 := true if bit Arg2 of bitmap Arg1 is set."}
, { 'BITS_SUM', 16#4f, false, true, true, ?GAS(10), [a,a], bits_sum, {bits}, integer, "Arg0 := sum of set bits in bitmap Arg1. Exception if infinit bitmap."}
, { 'BITS_OR', 16#50, false, true, true, ?GAS(10), [a,a,a], bits_or, {bits, bits}, bits, "Arg0 := Arg1 v Arg2."}
, { 'BITS_AND', 16#51, false, true, true, ?GAS(10), [a,a,a], bits_and, {bits, bits}, bits, "Arg0 := Arg1 ^ Arg2."}
, { 'BITS_DIFF', 16#52, false, true, true, ?GAS(10), [a,a,a], bits_diff, {bits, bits}, bits, "Arg0 := Arg1 - Arg2."}
, { 'BALANCE', 16#53, false, true, true, ?GAS(10), [a], balance, {}, integer, "Arg0 := The current contract balance."}
, { 'ORIGIN', 16#54, false, true, true, ?GAS(10), [a], origin, {}, address, "Arg0 := Address of contract called by the call transaction."}
, { 'CALLER', 16#55, false, true, true, ?GAS(10), [a], caller, {}, address, "Arg0 := The address that signed the call transaction."}
, { 'BLOCKHASH', 16#56, false, true, true, ?GAS_IRIS(10, 1000), [a,a], blockhash, {integer}, variant, "Arg0 := The blockhash at height."}
, { 'BENEFICIARY', 16#57, false, true, true, ?GAS(10), [a], beneficiary, {}, address, "Arg0 := The address of the current beneficiary."}
, { 'TIMESTAMP', 16#58, false, true, true, ?GAS(10), [a], timestamp, {}, integer, "Arg0 := The current timestamp. Unrelaiable, don't use for anything."}
, { 'GENERATION', 16#59, false, true, true, ?GAS(10), [a], generation, {}, integer, "Arg0 := The block height of the cureent generation."}
, { 'MICROBLOCK', 16#5a, false, true, true, ?GAS(10), [a], microblock, {}, integer, "Arg0 := The current micro block number."}
, { 'DIFFICULTY', 16#5b, false, true, true, ?GAS(10), [a], difficulty, {}, integer, "Arg0 := The current difficulty."}
, { 'GASLIMIT', 16#5c, false, true, true, ?GAS(10), [a], gaslimit, {}, integer, "Arg0 := The current gaslimit."}
, { 'GAS', 16#5d, false, true, true, ?GAS(10), [a], gas, {}, integer, "Arg0 := The amount of gas left."}
, { 'ADDRESS', 16#5e, false, true, true, ?GAS(10), [a], address, {}, address, "Arg0 := The current contract address."}
, { 'GASPRICE', 16#5f, false, true, true, ?GAS(10), [a], gasprice, {}, integer, "Arg0 := The current gas price."}
, { 'LOG0', 16#60, false, true, true, 1000, [a], log, {string}, none, "Create a log message in the call object."}
, { 'LOG1', 16#61, false, true, true, 1100, [a,a], log, {integer, string}, none, "Create a log message with one topic in the call object."}
, { 'LOG2', 16#62, false, true, true, 1200, [a,a,a], log, {integer, integer, string}, none, "Create a log message with two topics in the call object."}
, { 'LOG3', 16#63, false, true, true, 1300, [a,a,a,a], log, {integer, integer, integer, string}, none, "Create a log message with three topics in the call object."}
, { 'LOG4', 16#64, false, true, true, 1400, [a,a,a,a,a], log, {integer, integer, integer, integer, string}, none, "Create a log message with four topics in the call object."}
, { 'LOG0', 16#60, false, true, true, ?GAS(1000), [a], log, {string}, none, "Create a log message in the call object."}
, { 'LOG1', 16#61, false, true, true, ?GAS(1100), [a,a], log, {integer, string}, none, "Create a log message with one topic in the call object."}
, { 'LOG2', 16#62, false, true, true, ?GAS(1200), [a,a,a], log, {integer, integer, string}, none, "Create a log message with two topics in the call object."}
, { 'LOG3', 16#63, false, true, true, ?GAS(1300), [a,a,a,a], log, {integer, integer, integer, string}, none, "Create a log message with three topics in the call object."}
, { 'LOG4', 16#64, false, true, true, ?GAS(1400), [a,a,a,a,a], log, {integer, integer, integer, integer, string}, none, "Create a log message with four topics in the call object."}
%% Transaction ops
, { 'SPEND', 16#65, false, false, true, 100, [a,a], spend, {address, integer}, none, "Transfer Arg1 tokens to account Arg0. (If the contract account has at least that many tokens."}
, { 'ORACLE_REGISTER', 16#66, false, false, false, 100, [a,a,a,a,a,a,a], oracle_register, {signature, address, integer, variant, typerep, typerep}, oracle, "Arg0 := New oracle with address Arg2, query fee Arg3, TTL Arg4, query type Arg5 and response type Arg6. Arg0 contains delegation signature."}
, { 'ORACLE_QUERY', 16#67, false, false, false, 100, [a,a,a,a,a,a,a,a], oracle_query, {oracle, any, integer, variant, variant, typerep, typerep}, oracle_query, "Arg0 := New oracle query for oracle Arg1, question in Arg2, query fee in Arg3, query TTL in Arg4, response TTL in Arg5. Typereps for checking oracle type is in Arg6 and Arg7."}
, { 'ORACLE_RESPOND', 16#68, false, false, false, 100, [a,a,a,a,a,a], oracle_respond, {signature, oracle, oracle_query,any, typerep, typerep}, none, "Respond as oracle Arg1 to query in Arg2 with response Arg3. Arg0 contains delegation signature. Typereps for checking oracle type is in Arg4 and Arg5."}
, { 'ORACLE_EXTEND', 16#69, false, false, false, 100, [a,a,a], oracle_extend, {signature, oracle, variant}, none, "Extend oracle in Arg1 with TTL in Arg2. Arg0 contains delegation signature."}
, { 'ORACLE_GET_ANSWER', 16#6a, false, false, true, 100, [a,a,a,a,a], oracle_get_answer, {oracle, oracle_query, typerep, typerep}, any, "Arg0 := option variant with answer (if any) from oracle query in Arg1 given by oracle Arg0. Typereps for checking oracle type is in Arg3 and Arg4."}
, { 'ORACLE_GET_QUESTION', 16#6b, false, false, true, 100, [a,a,a,a,a], oracle_get_question, {oracle, oracle_query, typerep, typerep}, any, "Arg0 := question in oracle query Arg2 given to oracle Arg1. Typereps for checking oracle type is in Arg3 and Arg4."}
, { 'ORACLE_QUERY_FEE', 16#6c, false, false, true, 100, [a,a], oracle_query_fee, {oracle}, integer, "Arg0 := query fee for oracle Arg1"}
, { 'AENS_RESOLVE', 16#6d, false, false, true, 100, [a,a,a,a], aens_resolve, {string, string, typerep}, variant, "Resolve name in Arg0 with tag Arg1. Arg2 describes the type parameter of the resolved name."}
, { 'AENS_PRECLAIM', 16#6e, false, false, false, 100, [a,a,a], aens_preclaim, {signature, address, hash}, none, "Preclaim the hash in Arg2 for address in Arg1. Arg0 contains delegation signature."}
, { 'AENS_CLAIM', 16#6f, false, false, false, 100, [a,a,a,a,a], aens_claim, {signature, address, string, integer, integer}, none, "Attempt to claim the name in Arg2 for address in Arg1 at a price in Arg4. Arg3 contains the salt used to hash the preclaim. Arg0 contains delegation signature."}
, { 'AENS_UPDATE', 16#70, false, false, false, 100, [a,a,a,a,a,a], aens_update, {signature, address, string, variant, variant, variant}, none, "Updates name in Arg2 for address in Arg1. Arg3 contains optional ttl (of type Chain.ttl), Arg4 contains optional client_ttl (of type int), Arg5 contains optional pointers (of type map(string, pointee))"}
, { 'AENS_TRANSFER', 16#71, false, false, false, 100, [a,a,a,a], aens_transfer,{signature, address, address, string}, none, "Transfer ownership of name Arg3 from account Arg1 to Arg2. Arg0 contains delegation signature."}
, { 'AENS_REVOKE', 16#72, false, false, false, 100, [a,a,a], aens_revoke, {signature, address, string}, none, "Revoke the name in Arg2 from owner Arg1. Arg0 contains delegation signature."}
, { 'BALANCE_OTHER', 16#73, false, true, true, 50, [a,a], balance_other, {address}, integer, "Arg0 := The balance of address Arg1."}
, { 'SPEND', 16#65, false, false, true, ?GAS_IRIS(100, 5000), [a,a], spend, {address, integer}, none, "Transfer Arg1 tokens to account Arg0. (If the contract account has at least that many tokens."}
, { 'ORACLE_REGISTER', 16#66, false, false, false, ?GAS_IRIS(100, 10000), [a,a,a,a,a,a,a], oracle_register, {signature, address, integer, variant, typerep, typerep}, oracle, "Arg0 := New oracle with address Arg2, query fee Arg3, TTL Arg4, query type Arg5 and response type Arg6. Arg0 contains delegation signature."}
, { 'ORACLE_QUERY', 16#67, false, false, false, ?GAS_IRIS(100, 10000), [a,a,a,a,a,a,a,a], oracle_query, {oracle, any, integer, variant, variant, typerep, typerep}, oracle_query, "Arg0 := New oracle query for oracle Arg1, question in Arg2, query fee in Arg3, query TTL in Arg4, response TTL in Arg5. Typereps for checking oracle type is in Arg6 and Arg7."}
, { 'ORACLE_RESPOND', 16#68, false, false, false, ?GAS_IRIS(100, 10000), [a,a,a,a,a,a], oracle_respond, {signature, oracle, oracle_query,any, typerep, typerep}, none, "Respond as oracle Arg1 to query in Arg2 with response Arg3. Arg0 contains delegation signature. Typereps for checking oracle type is in Arg4 and Arg5."}
, { 'ORACLE_EXTEND', 16#69, false, false, false, ?GAS_IRIS(100, 10000), [a,a,a], oracle_extend, {signature, oracle, variant}, none, "Extend oracle in Arg1 with TTL in Arg2. Arg0 contains delegation signature."}
, { 'ORACLE_GET_ANSWER', 16#6a, false, false, true, ?GAS_IRIS(100, 2000), [a,a,a,a,a], oracle_get_answer, {oracle, oracle_query, typerep, typerep}, any, "Arg0 := option variant with answer (if any) from oracle query in Arg1 given by oracle Arg0. Typereps for checking oracle type is in Arg3 and Arg4."}
, { 'ORACLE_GET_QUESTION', 16#6b, false, false, true, ?GAS_IRIS(100, 2000), [a,a,a,a,a], oracle_get_question, {oracle, oracle_query, typerep, typerep}, any, "Arg0 := question in oracle query Arg2 given to oracle Arg1. Typereps for checking oracle type is in Arg3 and Arg4."}
, { 'ORACLE_QUERY_FEE', 16#6c, false, false, true, ?GAS_IRIS(100, 2000), [a,a], oracle_query_fee, {oracle}, integer, "Arg0 := query fee for oracle Arg1"}
, { 'AENS_RESOLVE', 16#6d, false, false, true, ?GAS_IRIS(100, 2000), [a,a,a,a], aens_resolve, {string, string, typerep}, variant, "Resolve name in Arg0 with tag Arg1. Arg2 describes the type parameter of the resolved name."}
, { 'AENS_PRECLAIM', 16#6e, false, false, false, ?GAS_IRIS(100, 10000), [a,a,a], aens_preclaim, {signature, address, hash}, none, "Preclaim the hash in Arg2 for address in Arg1. Arg0 contains delegation signature."}
, { 'AENS_CLAIM', 16#6f, false, false, false, ?GAS_IRIS(100, 10000), [a,a,a,a,a], aens_claim, {signature, address, string, integer, integer}, none, "Attempt to claim the name in Arg2 for address in Arg1 at a price in Arg4. Arg3 contains the salt used to hash the preclaim. Arg0 contains delegation signature."}
, { 'AENS_UPDATE', 16#70, false, false, false, ?GAS_IRIS(100, 10000), [a,a,a,a,a,a], aens_update, {signature, address, string, variant, variant, variant}, none, "Updates name in Arg2 for address in Arg1. Arg3 contains optional ttl (of type Chain.ttl), Arg4 contains optional client_ttl (of type int), Arg5 contains optional pointers (of type map(string, pointee))"}
, { 'AENS_TRANSFER', 16#71, false, false, false, ?GAS_IRIS(100, 10000), [a,a,a,a], aens_transfer,{signature, address, address, string}, none, "Transfer ownership of name Arg3 from account Arg1 to Arg2. Arg0 contains delegation signature."}
, { 'AENS_REVOKE', 16#72, false, false, false, ?GAS_IRIS(100, 10000), [a,a,a], aens_revoke, {signature, address, string}, none, "Revoke the name in Arg2 from owner Arg1. Arg0 contains delegation signature."}
, { 'BALANCE_OTHER', 16#73, false, true, true, ?GAS_IRIS( 50, 2000), [a,a], balance_other, {address}, integer, "Arg0 := The balance of address Arg1."}
, { 'VERIFY_SIG', 16#74, false, true, true, 1300, [a,a,a,a], verify_sig, {bytes, address, bytes}, boolean, "Arg0 := verify_sig(Hash, PubKey, Signature)"}
, { 'VERIFY_SIG_SECP256K1',16#75, false, true, true, 1300, [a,a,a,a], verify_sig_secp256k1, {bytes, bytes, bytes}, boolean, "Arg0 := verify_sig_secp256k1(Hash, PubKey, Signature)"}
, { 'VERIFY_SIG', 16#74, false, true, true, ?GAS(1300), [a,a,a,a], verify_sig, {bytes, address, bytes}, boolean, "Arg0 := verify_sig(Hash, PubKey, Signature)"}
, { 'VERIFY_SIG_SECP256K1',16#75, false, true, true, ?GAS(1300), [a,a,a,a], verify_sig_secp256k1, {bytes, bytes, bytes}, boolean, "Arg0 := verify_sig_secp256k1(Hash, PubKey, Signature)"}
, { 'CONTRACT_TO_ADDRESS', 16#76, false, true, true, 10, [a,a], contract_to_address, {contract}, address, "Arg0 := Arg1 - A no-op type conversion"}
, { 'AUTH_TX_HASH', 16#77, false, true, true, 10, [a], auth_tx_hash, {}, variant, "If in GA authentication context return Some(TxHash) otherwise None."}
, { 'CONTRACT_TO_ADDRESS', 16#76, false, true, true, ?GAS(10), [a,a], contract_to_address, {contract}, address, "Arg0 := Arg1 - A no-op type conversion"}
, { 'AUTH_TX_HASH', 16#77, false, true, true, ?GAS(10), [a], auth_tx_hash, {}, variant, "If in GA authentication context return Some(TxHash) otherwise None."}
, { 'ORACLE_CHECK', 16#78, false, false, true, 100, [a,a,a,a], oracle_check, {oracle, typerep, typerep}, bool, "Arg0 := is Arg1 an oracle with the given query (Arg2) and response (Arg3) types"}
, { 'ORACLE_CHECK_QUERY', 16#79, false, false, true, 100, [a,a,a,a,a], oracle_check_query, {oracle, oracle_query, typerep, typerep}, bool, "Arg0 := is Arg2 a query for the oracle Arg1 with the given types (Arg3, Arg4)"}
, { 'ORACLE_CHECK', 16#78, false, false, true, ?GAS(100), [a,a,a,a], oracle_check, {oracle, typerep, typerep}, bool, "Arg0 := is Arg1 an oracle with the given query (Arg2) and response (Arg3) types"}
, { 'ORACLE_CHECK_QUERY', 16#79, false, false, true, ?GAS(100), [a,a,a,a,a], oracle_check_query, {oracle, oracle_query, typerep, typerep}, bool, "Arg0 := is Arg2 a query for the oracle Arg1 with the given types (Arg3, Arg4)"}
, { 'IS_ORACLE', 16#7a, false, false, true, 100, [a,a], is_oracle, {address}, bool, "Arg0 := is Arg1 an oracle"}
, { 'IS_CONTRACT', 16#7b, false, false, true, 100, [a,a], is_contract, {address}, bool, "Arg0 := is Arg1 a contract"}
, { 'IS_PAYABLE', 16#7c, false, false, true, 100, [a,a], is_payable, {address}, bool, "Arg0 := is Arg1 a payable address"}
, { 'CREATOR', 16#7d, false, true, true, 10, [a], contract_creator, {}, address, "Arg0 := contract creator"}
, { 'IS_ORACLE', 16#7a, false, false, true, ?GAS(100), [a,a], is_oracle, {address}, bool, "Arg0 := is Arg1 an oracle"}
, { 'IS_CONTRACT', 16#7b, false, false, true, ?GAS(100), [a,a], is_contract, {address}, bool, "Arg0 := is Arg1 a contract"}
, { 'IS_PAYABLE', 16#7c, false, false, true, ?GAS(100), [a,a], is_payable, {address}, bool, "Arg0 := is Arg1 a payable address"}
, { 'CREATOR', 16#7d, false, true, true, ?GAS(10), [a], contract_creator, {}, address, "Arg0 := contract creator"}
, { 'ECVERIFY_SECP256K1', 16#7e, false, true, true, 1300, [a,a,a,a], ecverify_secp256k1, {bytes, bytes, bytes}, bytes, "Arg0 := ecverify_secp256k1(Hash, Addr, Signature)"}
, { 'ECRECOVER_SECP256K1', 16#7f, false, true, true, 1300, [a,a,a], ecrecover_secp256k1, {bytes, bytes}, bytes, "Arg0 := ecrecover_secp256k1(Hash, Signature)"}
, { 'ECVERIFY_SECP256K1', 16#7e, false, true, true, ?GAS(1300), [a,a,a,a], ecverify_secp256k1, {bytes, bytes, bytes}, bytes, "Arg0 := ecverify_secp256k1(Hash, Addr, Signature)"}
, { 'ECRECOVER_SECP256K1', 16#7f, false, true, true, ?GAS(1300), [a,a,a], ecrecover_secp256k1, {bytes, bytes}, bytes, "Arg0 := ecrecover_secp256k1(Hash, Signature)"}
, { 'ADDRESS_TO_CONTRACT', 16#80, false, true, true, 10, [a,a], address_to_contract, {address}, contract, "Arg0 := Arg1 - A no-op type conversion"}
, { 'ADDRESS_TO_CONTRACT', 16#80, false, true, true, ?GAS(10), [a,a], address_to_contract, {address}, contract, "Arg0 := Arg1 - A no-op type conversion"}
, { 'BLS12_381_G1_NEG', 16#81, false, true, true, 100, [a,a], bls12_381_g1_neg, {tuple}, tuple, "Arg0 := BLS12_381.g1_neg(Arg1) - Negate a G1-value"}
, { 'BLS12_381_G1_NORM', 16#82, false, true, true, 100, [a,a], bls12_381_g1_norm, {tuple}, tuple, "Arg0 := BLS12_381.g1_normalize(Arg1) - Normalize a G1-value"}
, { 'BLS12_381_G1_VALID', 16#83, false, true, true, 2000, [a,a], bls12_381_g1_valid, {tuple}, bool, "Arg0 := BLS12_381.g1_valid(Arg1) - Check if G1-value is a valid group member"}
, { 'BLS12_381_G1_IS_ZERO', 16#84, false, true, true, 30, [a,a], bls12_381_g1_is_zero, {tuple}, bool, "Arg0 := BLS12_381.g1_is_zero(Arg1) - Check if G1-value is zero"}
, { 'BLS12_381_G1_ADD', 16#85, false, true, true, 100, [a,a,a], bls12_381_g1_add, {tuple, tuple}, tuple, "Arg0 := BLS12_381.g1_add(Arg1, Arg2) - Add two G1-values"}
, { 'BLS12_381_G1_MUL', 16#86, false, true, true, 1000, [a,a,a], bls12_381_g1_mul, {tuple, tuple}, tuple, "Arg0 := BLS12_381.g1_mul(Arg1, Arg2) - Scalar multiplication for a G1-value (Arg1), and an Fr-value"}
, { 'BLS12_381_G1_NEG', 16#81, false, true, true, ?GAS(100), [a,a], bls12_381_g1_neg, {tuple}, tuple, "Arg0 := BLS12_381.g1_neg(Arg1) - Negate a G1-value"}
, { 'BLS12_381_G1_NORM', 16#82, false, true, true, ?GAS(100), [a,a], bls12_381_g1_norm, {tuple}, tuple, "Arg0 := BLS12_381.g1_normalize(Arg1) - Normalize a G1-value"}
, { 'BLS12_381_G1_VALID', 16#83, false, true, true, ?GAS(2000), [a,a], bls12_381_g1_valid, {tuple}, bool, "Arg0 := BLS12_381.g1_valid(Arg1) - Check if G1-value is a valid group member"}
, { 'BLS12_381_G1_IS_ZERO', 16#84, false, true, true, ?GAS(30), [a,a], bls12_381_g1_is_zero, {tuple}, bool, "Arg0 := BLS12_381.g1_is_zero(Arg1) - Check if G1-value is zero"}
, { 'BLS12_381_G1_ADD', 16#85, false, true, true, ?GAS(100), [a,a,a], bls12_381_g1_add, {tuple, tuple}, tuple, "Arg0 := BLS12_381.g1_add(Arg1, Arg2) - Add two G1-values"}
, { 'BLS12_381_G1_MUL', 16#86, false, true, true, ?GAS(1000), [a,a,a], bls12_381_g1_mul, {tuple, tuple}, tuple, "Arg0 := BLS12_381.g1_mul(Arg1, Arg2) - Scalar multiplication for a G1-value (Arg1), and an Fr-value"}
, { 'BLS12_381_G2_NEG', 16#87, false, true, true, 100, [a,a], bls12_381_g2_neg, {tuple}, tuple, "Arg0 := BLS12_381.g2_neg(Arg1) - Negate a G2-value"}
, { 'BLS12_381_G2_NORM', 16#88, false, true, true, 100, [a,a], bls12_381_g2_norm, {tuple}, tuple, "Arg0 := BLS12_381.g2_normalize(Arg1) - Normalize a G2-value"}
, { 'BLS12_381_G2_VALID', 16#89, false, true, true, 2000, [a,a], bls12_381_g2_valid, {tuple}, bool, "Arg0 := BLS12_381.g2_valid(Arg1) - Check if G2-value is a valid group member"}
, { 'BLS12_381_G2_IS_ZERO', 16#8a, false, true, true, 30, [a,a], bls12_381_g2_is_zero, {tuple}, bool, "Arg0 := BLS12_381.g2_is_zero(Arg1) - Check if G2-value is zero"}
, { 'BLS12_381_G2_ADD', 16#8b, false, true, true, 100, [a,a,a], bls12_381_g2_add, {tuple, tuple}, tuple, "Arg0 := BLS12_381.g2_add(Arg1, Arg2) - Add two G2-values"}
, { 'BLS12_381_G2_MUL', 16#8c, false, true, true, 1000, [a,a,a], bls12_381_g2_mul, {tuple, tuple}, tuple, "Arg0 := BLS12_381.g2_mul(Arg1, Arg2) - Scalar multiplication for a G2-value (Arg2), and an Fr-value"}
, { 'BLS12_381_G2_NEG', 16#87, false, true, true, ?GAS(100), [a,a], bls12_381_g2_neg, {tuple}, tuple, "Arg0 := BLS12_381.g2_neg(Arg1) - Negate a G2-value"}
, { 'BLS12_381_G2_NORM', 16#88, false, true, true, ?GAS(100), [a,a], bls12_381_g2_norm, {tuple}, tuple, "Arg0 := BLS12_381.g2_normalize(Arg1) - Normalize a G2-value"}
, { 'BLS12_381_G2_VALID', 16#89, false, true, true, ?GAS(2000), [a,a], bls12_381_g2_valid, {tuple}, bool, "Arg0 := BLS12_381.g2_valid(Arg1) - Check if G2-value is a valid group member"}
, { 'BLS12_381_G2_IS_ZERO', 16#8a, false, true, true, ?GAS(30), [a,a], bls12_381_g2_is_zero, {tuple}, bool, "Arg0 := BLS12_381.g2_is_zero(Arg1) - Check if G2-value is zero"}
, { 'BLS12_381_G2_ADD', 16#8b, false, true, true, ?GAS(100), [a,a,a], bls12_381_g2_add, {tuple, tuple}, tuple, "Arg0 := BLS12_381.g2_add(Arg1, Arg2) - Add two G2-values"}
, { 'BLS12_381_G2_MUL', 16#8c, false, true, true, ?GAS(1000), [a,a,a], bls12_381_g2_mul, {tuple, tuple}, tuple, "Arg0 := BLS12_381.g2_mul(Arg1, Arg2) - Scalar multiplication for a G2-value (Arg2), and an Fr-value"}
, { 'BLS12_381_GT_INV', 16#8d, false, true, true, 100, [a,a], bls12_381_gt_inv, {tuple}, tuple, "Arg0 := BLS12_381.gt_inv(Arg1) - Invert a GT-value"}
, { 'BLS12_381_GT_ADD', 16#8e, false, true, true, 100, [a,a,a], bls12_381_gt_add, {tuple, tuple}, tuple, "Arg0 := BLS12_381.gt_add(Arg1, Arg2) - Add two GT-values"}
, { 'BLS12_381_GT_MUL', 16#8f, false, true, true, 100, [a,a,a], bls12_381_gt_mul, {tuple, tuple}, tuple, "Arg0 := BLS12_381.gt_mul(Arg1, Arg2) - Multiply two GT-values"}
, { 'BLS12_381_GT_POW', 16#90, false, true, true, 2000, [a,a,a], bls12_381_gt_pow, {tuple, tuple}, tuple, "Arg0 := BLS12_381.gt_pow(Arg1, Arg2) - Scalar exponentiation for a GT-value (Arg2), and an Fr-value"}
, { 'BLS12_381_GT_IS_ONE', 16#91, false, true, true, 30, [a,a], bls12_381_gt_is_one, {tuple}, bool, "Arg0 := BLS12_381.gt_is_one(Arg1) - Check if a GT value is \"one\""}
, { 'BLS12_381_PAIRING', 16#92, false, true, true, 12000, [a,a,a], bls12_381_pairing, {tuple, tuple}, tuple, "Arg0 := BLS12_381.pairing(Arg1, Arg2) - Find the pairing of a G1-value (Arg1) and a G2-value (Arg2)"}
, { 'BLS12_381_MILLER_LOOP', 16#93, false, true, true, 5000, [a,a,a], bls12_381_miller_loop, {tuple, tuple}, tuple, "Arg0 := BLS12_381.miller_loop(Arg1, Arg2) - Do the Miller-loop step of pairing for a G1-value (Arg1) and a G2-value (Arg2)"}
, { 'BLS12_381_FINAL_EXP', 16#94, false, true, true, 7000, [a,a], bls12_381_final_exp, {tuple}, tuple, "Arg0 := BLS12_381.final_exp(Arg1) - Do the final exponentiation in pairing"}
, { 'BLS12_381_GT_INV', 16#8d, false, true, true, ?GAS(100), [a,a], bls12_381_gt_inv, {tuple}, tuple, "Arg0 := BLS12_381.gt_inv(Arg1) - Invert a GT-value"}
, { 'BLS12_381_GT_ADD', 16#8e, false, true, true, ?GAS(100), [a,a,a], bls12_381_gt_add, {tuple, tuple}, tuple, "Arg0 := BLS12_381.gt_add(Arg1, Arg2) - Add two GT-values"}
, { 'BLS12_381_GT_MUL', 16#8f, false, true, true, ?GAS(100), [a,a,a], bls12_381_gt_mul, {tuple, tuple}, tuple, "Arg0 := BLS12_381.gt_mul(Arg1, Arg2) - Multiply two GT-values"}
, { 'BLS12_381_GT_POW', 16#90, false, true, true, ?GAS(2000), [a,a,a], bls12_381_gt_pow, {tuple, tuple}, tuple, "Arg0 := BLS12_381.gt_pow(Arg1, Arg2) - Scalar exponentiation for a GT-value (Arg2), and an Fr-value"}
, { 'BLS12_381_GT_IS_ONE', 16#91, false, true, true, ?GAS(30), [a,a], bls12_381_gt_is_one, {tuple}, bool, "Arg0 := BLS12_381.gt_is_one(Arg1) - Check if a GT value is \"one\""}
, { 'BLS12_381_PAIRING', 16#92, false, true, true, ?GAS(12000), [a,a,a], bls12_381_pairing, {tuple, tuple}, tuple, "Arg0 := BLS12_381.pairing(Arg1, Arg2) - Find the pairing of a G1-value (Arg1) and a G2-value (Arg2)"}
, { 'BLS12_381_MILLER_LOOP', 16#93, false, true, true, ?GAS(5000), [a,a,a], bls12_381_miller_loop, {tuple, tuple}, tuple, "Arg0 := BLS12_381.miller_loop(Arg1, Arg2) - Do the Miller-loop step of pairing for a G1-value (Arg1) and a G2-value (Arg2)"}
, { 'BLS12_381_FINAL_EXP', 16#94, false, true, true, ?GAS(7000), [a,a], bls12_381_final_exp, {tuple}, tuple, "Arg0 := BLS12_381.final_exp(Arg1) - Do the final exponentiation in pairing"}
, { 'BLS12_381_INT_TO_FR', 16#95, false, true, true, 30, [a,a], bls12_381_int_to_fr, {tuple}, tuple, "Arg0 := to_montgomery(Arg1) - Convert (Big)integer to montgomery representation (32 bytes)"}
, { 'BLS12_381_INT_TO_FP', 16#96, false, true, true, 30, [a,a], bls12_381_int_to_fp, {tuple}, tuple, "Arg0 := to_montgomery(Arg1) - Convert (Big)integer to montgomery representation (48 bytes)"}
, { 'BLS12_381_FR_TO_INT', 16#97, false, true, true, 30, [a,a], bls12_381_fr_to_int, {tuple}, tuple, "Arg0 := from_montgomery(Arg1) - Convert montgomery representation (32 bytes) to integer"}
, { 'BLS12_381_FP_TO_INT', 16#98, false, true, true, 30, [a,a], bls12_381_fp_to_int, {tuple}, tuple, "Arg0 := from_montgomery(Arg1) - Convert montgomery representation (48 bytes) to integer"}
, { 'BLS12_381_INT_TO_FR', 16#95, false, true, true, ?GAS(30), [a,a], bls12_381_int_to_fr, {tuple}, tuple, "Arg0 := to_montgomery(Arg1) - Convert (Big)integer to montgomery representation (32 bytes)"}
, { 'BLS12_381_INT_TO_FP', 16#96, false, true, true, ?GAS(30), [a,a], bls12_381_int_to_fp, {tuple}, tuple, "Arg0 := to_montgomery(Arg1) - Convert (Big)integer to montgomery representation (48 bytes)"}
, { 'BLS12_381_FR_TO_INT', 16#97, false, true, true, ?GAS(30), [a,a], bls12_381_fr_to_int, {tuple}, tuple, "Arg0 := from_montgomery(Arg1) - Convert montgomery representation (32 bytes) to integer"}
, { 'BLS12_381_FP_TO_INT', 16#98, false, true, true, ?GAS(30), [a,a], bls12_381_fp_to_int, {tuple}, tuple, "Arg0 := from_montgomery(Arg1) - Convert montgomery representation (48 bytes) to integer"}
, { 'AENS_LOOKUP', 16#99, false, false, true, 100, [a,a], aens_lookup, {string}, variant, "Lookup the name of Arg0. Returns option(AENS.name)"}
, { 'ORACLE_EXPIRY', 16#9a, false, false, true, 100, [a,a], oracle_expiry, {oracle}, int, "Arg0 := expiry block for oracle Arg1"}
, { 'AUTH_TX', 16#9b, false, true, true, 100, [a], auth_tx, {}, variant, "If in GA authentication context return Some(Tx) otherwise None."}
, { 'AENS_LOOKUP', 16#99, false, false, true, ?GAS(2000), [a,a], aens_lookup, {string}, variant, "Lookup the name of Arg0. Returns option(AENS.name)"}
, { 'ORACLE_EXPIRY', 16#9a, false, false, true, ?GAS(2000), [a,a], oracle_expiry, {oracle}, int, "Arg0 := expiry block for oracle Arg1"}
, { 'AUTH_TX', 16#9b, false, true, true, ?GAS(100 ), [a], auth_tx, {}, variant, "If in GA authentication context return Some(Tx) otherwise None."}
, { 'STR_TO_LIST', 16#9c, false, true, true, 100, [a,a], str_to_list, {string}, list, "Arg0 := string converted to list of characters"}
, { 'STR_FROM_LIST', 16#9d, false, true, true, 100, [a,a], str_from_list, {list}, string, "Arg0 := string converted from list of characters"}
, { 'STR_TO_UPPER', 16#9e, false, true, true, 100, [a,a], str_to_upper, {string}, string, "Arg0 := to_upper(string)"}
, { 'STR_TO_LOWER', 16#9f, false, true, true, 100, [a,a], str_to_lower, {string}, string, "Arg0 := to_lower(string)"}
, { 'CHAR_TO_INT', 16#a0, false, true, true, 10, [a,a], char_to_int, {char}, int, "Arg0 := integer representation of UTF-8 character"}
, { 'CHAR_FROM_INT', 16#a1, false, true, true, 10, [a,a], char_from_int, {int}, variant, "Arg0 := Some(UTF-8 character) from integer if valid, None if not valid."}
, { 'STR_TO_LIST', 16#9c, false, true, true, ?GAS(100), [a,a], str_to_list, {string}, list, "Arg0 := string converted to list of characters"}
, { 'STR_FROM_LIST', 16#9d, false, true, true, ?GAS(100), [a,a], str_from_list, {list}, string, "Arg0 := string converted from list of characters"}
, { 'STR_TO_UPPER', 16#9e, false, true, true, ?GAS(100), [a,a], str_to_upper, {string}, string, "Arg0 := to_upper(string)"}
, { 'STR_TO_LOWER', 16#9f, false, true, true, ?GAS(100), [a,a], str_to_lower, {string}, string, "Arg0 := to_lower(string)"}
, { 'CHAR_TO_INT', 16#a0, false, true, true, ?GAS(10), [a,a], char_to_int, {char}, int, "Arg0 := integer representation of UTF-8 character"}
, { 'CHAR_FROM_INT', 16#a1, false, true, true, ?GAS(10), [a,a], char_from_int, {int}, variant, "Arg0 := Some(UTF-8 character) from integer if valid, None if not valid."}
, { 'CALL_PGR', 16#a2, true, false, true, 100, [a,is,a,a,a,a,a], call_pgr, {contract, string, typerep, typerep, integer, integer, bool}, variant, "Potentially protected remote call. Arg5 is protected flag, otherwise as CALL_GR."}
, { 'CALL_PGR', 16#a2, true, false, true, ?GAS(100), [a,is,a,a,a,a,a], call_pgr, {contract, string, typerep, typerep, integer, integer, bool}, variant, "Potentially protected remote call. Arg5 is protected flag, otherwise as CALL_GR."}
, { 'CREATE', 16#a3, true, false, true, 10000, [a,a,a], create, {contract_bytearray, typerep, integer}, contract, "Deploys a contract with a bytecode Arg1 and value Arg3. The `init` arguments should be placed on the stack and match the type in Arg2. Writes contract address to stack top."}
, { 'CLONE', 16#a4, true, false, true, 1000, [a,a,a,a], clone, {contract, typerep, integer, bool}, any, "Clones the contract under Arg1 and deploys it with value of Arg3. The `init` arguments should be placed on the stack and match the type in Arg2. Writes contract (or `None` on fail when protected) to stack top."}
, { 'CLONE_G', 16#a5, true, false, true, 1000, [a,a,a,a,a], clone_g, {contract, typerep, integer, integer, bool}, any, "Like `CLONE` but additionally limits gas of `init` call to Arg3"}
, { 'BYTECODE_HASH', 16#a6, false, true, true, 100, [a,a], bytecode_hash, {contract}, variant, "Arg0 := hash of the deserialized contract's bytecode under address given in Arg1 (or `None` on fail)."}
, { 'CREATE', 16#a3, true, false, true, ?GAS(10000), [a,a,a], create, {contract_bytearray, typerep, integer}, contract, "Deploys a contract with a bytecode Arg1 and value Arg3. The `init` arguments should be placed on the stack and match the type in Arg2. Writes contract address to the top of the accumulator stack. If an account on the resulting address did exist before the call, the `payable` flag will be updated."}
, { 'CLONE', 16#a4, true, false, true, ?GAS(5000), [a,a,a,a], clone, {contract, typerep, integer, bool}, any, "Clones the contract under Arg1 and deploys it with value of Arg3. The `init` arguments should be placed on the stack and match the type in Arg2. Writes contract (or `None` on fail when protected) to the top of the accumulator stack. Does not copy the existing contract's store it will be initialized by a fresh call to the `init` function. If an account on the resulting address did exist before the call, the `payable` flag will be updated."}
, { 'CLONE_G', 16#a5, true, false, true, ?GAS(5000), [a,a,a,a,a], clone_g, {contract, typerep, integer, integer, bool}, any, "Like `CLONE` but additionally limits the gas of the `init` call by Arg3"}
, { 'BYTECODE_HASH', 16#a6, false, true, true, ?GAS(100), [a,a], bytecode_hash, {contract}, variant, "Arg0 := hash of the deserialized contract's bytecode under address given in Arg1 (or `None` on fail). Fails on AEVM contracts and contracts deployed before Iris."}
, { 'FEE', 16#a7, false, true, true, 10, [a], fee, {}, integer, "Arg0 := The fee for the current call tx."}
, { 'FEE', 16#a7, false, true, true, ?GAS(10), [a], fee, {}, integer, "Arg0 := The fee for the current call tx."}
, { 'DEACTIVATE', 16#fa, false, true, true, 10, [], deactivate, {}, none, "Mark the current contract for deactivation."}
, { 'ABORT', 16#fb, true, true, true, 10, [a], abort, {string}, none, "Abort execution (dont use all gas) with error message in Arg0."}
, { 'EXIT', 16#fc, true, true, true, 10, [a], exit, {string}, none, "Abort execution (use upp all gas) with error message in Arg0."}
, { 'NOP', 16#fd, false, true, true, 1, [], nop, {}, none, "The no op. does nothing."}
, { 'ADDRESS_TO_BYTES', 16#a8, false, true, true, ?GAS(10), [a, a], addr_to_bytes, {address}, bytes, "Arg0 := the byte representation of the address"}
, { 'POSEIDON', 16#a9, false, true, true, ?GAS(6000), [a, a, a], poseidon, {integer, integer}, integer, "Arg0 := the Poseidon hash of Arg1 and Arg2 - all integers in the BLS12-381 scalar field"}
, { 'MULMOD', 16#aa, false, true, true, ?GAS(10), [a, a, a, a], mulmod, {integer, integer, integer}, integer, "Arg0 := (Arg1 * Arg2) mod Arg3"}
, { 'BAND', 16#ab, false, true, true, ?GAS(10), [a, a, a], bin_and, {integer, integer}, integer, "Arg0 := Arg1 & Arg2"}
, { 'BOR', 16#ac, false, true, true, ?GAS(10), [a, a, a], bin_or, {integer, integer}, integer, "Arg0 := Arg1 | Arg2"}
, { 'BXOR', 16#ad, false, true, true, ?GAS(10), [a, a, a], bin_xor, {integer, integer}, integer, "Arg0 := Arg1 ^ Arg2"}
, { 'BNOT', 16#ae, false, true, true, ?GAS(10), [a, a], bin_not, {integer}, integer, "Arg0 := ~Arg1"}
, { 'BSL', 16#af, false, true, true, ?GAS(10), [a, a, a], bin_sl, {integer, integer}, integer, "Arg0 := Arg1 << Arg2"}
, { 'BSR', 16#b0, false, true, true, ?GAS(10), [a, a, a], bin_sr, {integer, integer}, integer, "Arg0 := Arg1 >> Arg2"}
, { 'BYTES_SPLIT_ANY', 16#b1, false, true, true, ?GAS(10), [a, a, a], bytes_split_any, {bytes, integer}, variant, "Arg0 := bytes_split_any(Arg1, Arg2), where a positive Arg2 is the length of the first chunk, and a negative Arg2 is the length of the second chunk. Returns None if byte array is not long enough."}
, { 'BYTES_SIZE', 16#b2, false, true, true, ?GAS(10), [a, a], bytes_size, {bytes}, integer, "Arg0 := bytes_size(Arg1), returns the number of bytes in the byte array."}
, { 'BYTES_TO_FIXED_SIZE', 16#b3, false, true, true, ?GAS(10), [a, a, a], bytes_to_fixed_size, {bytes, integer}, variant, "Arg0 := bytes_to_fixed_size(Arg1, Arg2), returns Some(Arg1') if byte_size(Arg1) == Arg2, None otherwise. The type of Arg1' is bytes(Arg2) but the value is unchanged"}
, { 'INT_TO_BYTES', 16#b4, false, true, true, ?GAS(10), [a, a, a], int_to_bytes, {integer, integer}, bytes, "Arg0 := turn integer Arg1 into a byte array (big endian) length Arg2 (truncating if not fit)."}
, { 'STR_TO_BYTES', 16#b5, false, true, true, ?GAS(10), [a, a], str_to_bytes, {integer}, bytes, "Arg0 := turn string Arg1 into the corresponding byte array."}
, { 'NETWORK_ID', 16#b6, false, true, true, ?GAS(10), [a], network_id, {}, string, "Arg0 := The network_id of the chain."}
, { 'DBG_LOC', 16#f0, false, true, true, ?GAS(0), [a, a], dbg_loc, {string, integer}, none, "Debug Op: Execution location. Args = {file_name, line_num}" }
, { 'DBG_DEF', 16#f1, false, true, true, ?GAS(0), [a, a], dbg_def, {string, any}, none, "Debug Op: Define a variable. Args = {var_name, register}" }
, { 'DBG_UNDEF', 16#f2, false, true, true, ?GAS(0), [a, a], dbg_undef, {string, any}, none, "Debug Op: Undefine a variable. Args = {var_name, register}" }
, { 'DBG_CONTRACT', 16#f3, false, true, true, ?GAS(0), [a], dbg_contract, {string}, none, "Debug Op: Name the current contract. Args: {contract_name}"}
, { 'DEACTIVATE', 16#fa, false, true, true, ?GAS(10), [], deactivate, {}, none, "Mark the current contract for deactivation."}
, { 'ABORT', 16#fb, true, true, true, ?GAS(10), [a], abort, {string}, none, "Abort execution (dont use all gas) with error message in Arg0."}
, { 'EXIT', 16#fc, true, true, true, ?GAS(10), [a], exit, {string}, none, "Abort execution (use upp all gas) with error message in Arg0."}
, { 'NOP', 16#fd, false, true, true, ?GAS(1), [], nop, {}, none, "The no op. does nothing."}
%% FUNCTION 16#fe "Function declaration and entrypoint."
%% EXTEND 16#ff "Reserved for future extensions beyond one byte opcodes."
].
@@ -774,50 +799,3 @@ gen_variant() ->
3 -> "(| 2 | 0 | ( " ++ imm_arg() ++ ", " ++ imm_arg() ++ " ) |)"
end.
%% TODO: add gas cost and end_bb/in_auth?
generate_documentation(Filename) ->
{ok, File} = file:open(Filename, [write]),
Instructions = lists:flatten([gen_doc(Op)++"\n" || Op <- get_ops()]),
io:format(File,
"### Operations\n\n"
"| OpCode | Name | Args | Description |\n"
"| --- | --- | --- | --- |\n"
"~s"
, [Instructions]),
io:format(File, "\n", []),
file:close(File).
gen_doc(#{ opname := Name
, opcode := OpCode
, arity := _Arity
, end_bb := _EndBB
, format := FateFormat
, macro := _Macro
, type_name := _TypeName
, doc := Doc
, gas := _Gas
, type := _Type
, constructor := _Constructor
, constructor_type := _ConstructorType
}) ->
Arguments =
case FateFormat of
[] -> "";
_ -> lists:join(" ",
[format_arg_doc(A) ||
A <-
lists:zip(FateFormat,
lists:seq(0,length(FateFormat)-1))])
end,
io_lib:format("| 0x~.16b | ~w | ~s | ~s |\n",
[ OpCode
, Name
, Arguments
, Doc]).
format_arg_doc({a, N}) -> io_lib:format("Arg~w", [N]);
format_arg_doc({is,_N}) -> "Identifier";
format_arg_doc({ii,_N}) -> "Integer";
format_arg_doc({li,_N}) -> "[Integers]";
format_arg_doc({t,_N}) -> "Type".
+1 -1
View File
@@ -1,6 +1,6 @@
{application, aebytecode,
[{description, "Bytecode definitions, serialization and deserialization for aeternity."},
{vsn, "2.1.0"},
{vsn, "3.4.0"},
{registered, []},
{applications,
[kernel,