Add bytes(int), add address_literalsm add ecverify_secp25k1

hash -> bytes(32)
signature -> bytes(64)
address literals
This commit is contained in:
Hans Svensson
2019-04-12 13:20:05 +02:00
parent faa0ef9772
commit 4324bfd49e
17 changed files with 342 additions and 88 deletions
+18 -3
View File
@@ -4,6 +4,9 @@
-compile(export_all).
-define(SANDBOX(Code), sandbox(fun() -> Code end)).
-define(DUMMY_HASH_WORD, 16#123).
-define(DUMMY_HASH, <<0:30/unit:8, 127, 119>>). %% 16#123
-define(DUMMY_HASH_LIT, "#0000000000000000000000000000000000000000000000000000000000000123").
sandbox(Code) ->
Parent = self(),
@@ -97,7 +100,15 @@ calldata_test() ->
Map = #{ <<"a">> => 4 },
[{variant, 1, [Map]}, {{<<"b">>, 5}, {variant, 0, []}}] =
encode_decode_calldata("foo", ["variant", "r"], ["Blue({[\"a\"] = 4})", "{x = (\"b\", 5), y = Red}"]),
[16#123, 16#456] = encode_decode_calldata("foo", ["hash", "address"], ["#123", "#456"]),
[?DUMMY_HASH_WORD, 16#456] = encode_decode_calldata("foo", ["bytes(32)", "address"],
[?DUMMY_HASH_LIT, "ak_1111111111111111111111111111113AFEFpt5"]),
[?DUMMY_HASH_WORD, ?DUMMY_HASH_WORD] =
encode_decode_calldata("foo", ["bytes(32)", "hash"], [?DUMMY_HASH_LIT, ?DUMMY_HASH_LIT]),
[119, {0, 0}] = encode_decode_calldata("foo", ["int", "signature"], ["119", [$# | lists:duplicate(128, $0)]]),
[16#456] = encode_decode_calldata("foo", ["Remote"], ["ct_1111111111111111111111111111113AFEFpt5"]),
ok.
calldata_init_test() ->
@@ -126,7 +137,9 @@ parameterized_contract(FunName, Types) ->
parameterized_contract(ExtraCode, FunName, Types) ->
lists:flatten(
["contract Dummy =\n",
["contract Remote =\n"
" function bla : () => ()\n\n"
"contract Dummy =\n",
ExtraCode, "\n",
" type an_alias('a) = (string, 'a)\n"
" record r = {x : an_alias(int), y : variant}\n"
@@ -139,7 +152,9 @@ oracle_test() ->
" function question(o, q : oracle_query(list(string), option(int))) =\n"
" Oracle.get_question(o, q)\n",
{ok, _, {[word, word], {list, string}}, [16#123, 16#456]} =
aeso_compiler:check_call(Contract, "question", ["#123", "#456"], []),
aeso_compiler:check_call(Contract, "question", ["ok_111111111111111111111111111111ZrdqRz9",
"oq_1111111111111111111111111111113AFEFpt5"], []),
ok.
permissive_literals_fail_test() ->
+89 -5
View File
@@ -8,6 +8,8 @@
-module(aeso_compiler_tests).
-compile([export_all, nowarn_export_all]).
-include_lib("eunit/include/eunit.hrl").
%% Very simply test compile the given contracts. Only basic checks
@@ -16,10 +18,14 @@
simple_compile_test_() ->
[ {"Testing the " ++ ContractName ++ " contract",
fun() ->
#{byte_code := ByteCode,
contract_source := _,
type_info := _} = compile(ContractName),
?assertMatch(Code when is_binary(Code), ByteCode)
case compile(ContractName) of
#{byte_code := ByteCode,
contract_source := _,
type_info := _} -> ?assertMatch(Code when is_binary(Code), ByteCode);
ErrBin ->
io:format("\n~s", [ErrBin]),
error(ErrBin)
end
end} || ContractName <- compilable_contracts() ] ++
[ {"Testing error messages of " ++ ContractName,
fun() ->
@@ -98,7 +104,9 @@ compilable_contracts() ->
"state_handling",
"events",
"include",
"basic_auth"
"basic_auth",
"bitcoin_auth",
"address_literals"
].
%% Contracts that should produce type errors
@@ -218,4 +226,80 @@ failing_contracts() ->
, {"bad_include_and_ns",
[<<"Include of 'included.aes' at line 2, column 11\nnot allowed, include only allowed at top level.">>,
<<"Nested namespace not allowed\nNamespace 'Foo' at line 3, column 13 not defined at top level.">>]}
, {"bad_address_literals",
[<<"The type bytes(32) is not a contract type\n"
"when checking that the contract literal at line 32, column 5\n"
" ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ\n"
"has the type\n"
" bytes(32)">>,
<<"The type oracle(int, bool) is not a contract type\n"
"when checking that the contract literal at line 30, column 5\n"
" ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ\n"
"has the type\n"
" oracle(int, bool)">>,
<<"The type address is not a contract type\n"
"when checking that the contract literal at line 28, column 5\n"
" ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ\n"
"has the type\n"
" address">>,
<<"Cannot unify oracle_query('1, '2)\n"
" and Remote\n"
"when checking the type of the expression at line 25, column 5\n"
" oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY :\n"
" oracle_query('1, '2)\n"
"against the expected type\n"
" Remote">>,
<<"Cannot unify oracle_query('3, '4)\n"
" and bytes(32)\n"
"when checking the type of the expression at line 23, column 5\n"
" oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY :\n"
" oracle_query('3, '4)\n"
"against the expected type\n"
" bytes(32)">>,
<<"Cannot unify oracle_query('5, '6)\n"
" and oracle(int, bool)\n"
"when checking the type of the expression at line 21, column 5\n"
" oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY :\n"
" oracle_query('5, '6)\n"
"against the expected type\n"
" oracle(int, bool)">>,
<<"Cannot unify oracle('7, '8)\n"
" and Remote\n"
"when checking the type of the expression at line 18, column 5\n"
" ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5 :\n"
" oracle('7, '8)\n"
"against the expected type\n"
" Remote">>,
<<"Cannot unify oracle('9, '10)\n"
" and bytes(32)\n"
"when checking the type of the expression at line 16, column 5\n"
" ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5 :\n"
" oracle('9, '10)\n"
"against the expected type\n"
" bytes(32)">>,
<<"Cannot unify oracle('11, '12)\n"
" and oracle_query(int, bool)\n"
"when checking the type of the expression at line 14, column 5\n"
" ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5 :\n"
" oracle('11, '12)\n"
"against the expected type\n"
" oracle_query(int, bool)">>,
<<"Cannot unify address\n"
" and oracle(int, bool)\n"
"when checking the type of the expression at line 11, column 5\n"
" ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt : address\n"
"against the expected type\n"
" oracle(int, bool)">>,
<<"Cannot unify address\n"
" and Remote\n"
"when checking the type of the expression at line 9, column 5\n"
" ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt : address\n"
"against the expected type\n"
" Remote">>,
<<"Cannot unify address\n"
" and bytes(32)\n"
"when checking the type of the expression at line 7, column 5\n"
" ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt : address\n"
"against the expected type\n"
" bytes(32)">>]}
].
+2 -2
View File
@@ -48,7 +48,7 @@ all_tokens() ->
%% Literals
[ Lit(true), Lit(false)
, Tok(id, "foo"), Tok(id, "_"), Tok(con, "Foo")
, Tok(hash, Hash)
, Tok(bytes, Hash)
, Tok(int, 1234567890), Tok(hex, 9876543210)
, Tok(string, <<"bla\"\\\b\e\f\n\r\t\vbla">>)
].
@@ -78,7 +78,7 @@ show_token({param, _, P}) -> "@" ++ P;
show_token({string, _, S}) -> fmt(binary_to_list(S));
show_token({int, _, N}) -> fmt(N);
show_token({hex, _, N}) -> fmt("0x~.16b", N);
show_token({hash, _, <<N:256>>}) -> fmt("#~.16b", N);
show_token({bytes, _, <<N:256>>}) -> fmt("#~64.16.0b", N);
show_token({comment, _, S}) -> S;
show_token({_, _, _}) -> "TODO".
+14
View File
@@ -0,0 +1,14 @@
contract Remote =
function foo : () => ()
contract AddressLiterals =
function addr() : address =
ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt
function oracle() : oracle(int, bool) =
ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5
function query() : oracle_query(int, bool) =
oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY
function contr() : Remote =
ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ
+33
View File
@@ -0,0 +1,33 @@
contract Remote =
function foo : () => ()
contract AddressLiterals =
function addr1() : bytes(32) =
ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt
function addr2() : Remote =
ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt
function addr3() : oracle(int, bool) =
ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt
function oracle1() : oracle_query(int, bool) =
ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5
function oracle2() : bytes(32) =
ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5
function oracle3() : Remote =
ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5
function query1() : oracle(int, bool) =
oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY
function query2() : bytes(32) =
oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY
function query3() : Remote =
oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY
function contr1() : address =
ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ
function contr2() : oracle(int, bool) =
ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ
function contr3() : bytes(32) =
ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ
+18
View File
@@ -0,0 +1,18 @@
contract BitcoinAuth =
record state = { nonce : int, owner : bytes(64) }
function init(owner' : bytes(64)) = { nonce = 1, owner = owner' }
function authorize(n : int, s : signature) : bool =
require(n >= state.nonce, "Nonce too low")
require(n =< state.nonce, "Nonce too high")
put(state{ nonce = n + 1 })
switch(Auth.tx_hash)
None => abort("Not in Auth context")
Some(tx_hash) => Crypto.ecverify_secp256k1(to_sign(tx_hash, n), state.owner, s)
function to_sign(h : hash, n : int) : hash =
Crypto.blake2b((h, n))
private function require(b : bool, err : string) =
if(!b) abort(err)
+1 -1
View File
@@ -53,7 +53,7 @@ contract FundMe =
require(state.total >= state.goal, "Project was not funded")
spend({recipient = state.beneficiary,
amount = Contract.balance })
put(state{ beneficiary = #0 })
put(state{ beneficiary = ak_11111111111111111111111111111111273Yts })
private stateful function withdraw_contributor() =
if(state.total >= state.goal)