diff --git a/CHANGELOG.md b/CHANGELOG.md index ba8f031..a980bc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `Option.force_msg` - Loading namespaces into the current scope (e.g. `using Pair`) - Assign patterns to variables (e.g. `let x::(t = y::_) = [1, 2, 3, 4]` where `t == [2, 3, 4]`) +- Add builtin types (`AENS.name, AENS.pointee, Chain.ttl, Chain.base_tx, Chain.ga_meta_tx, Chain.paying_for_tx`) to + the calldata and result decoder ### Changed - Fixed the ACI renderer, it shouldn't drop the `stateful` modifier ### Removed diff --git a/src/aeso_ast_to_fcode.erl b/src/aeso_ast_to_fcode.erl index 128fe9b..69378d5 100644 --- a/src/aeso_ast_to_fcode.erl +++ b/src/aeso_ast_to_fcode.erl @@ -287,7 +287,7 @@ state_layout(Env) -> maps:get(state_layout, Env, {reg, 1}). -spec init_type_env() -> type_env(). init_type_env() -> BaseTx = {variant, [[address, integer, string], [], [], [], [], [], [string], - [hash], [hash], [address, hash], [address], + [{bytes, 32}], [{bytes, 32}], [address, {bytes, 32}], [address], [address, integer], [address, integer], [address], [address], [address], [address], [address], [address], [integer], [address, integer], []]}, diff --git a/src/aeso_vm_decode.erl b/src/aeso_vm_decode.erl index efd7183..54cf299 100644 --- a/src/aeso_vm_decode.erl +++ b/src/aeso_vm_decode.erl @@ -120,10 +120,98 @@ from_fate({constr_t, _, Con, Types}, Args) when length(Types) == length(Args) -> {app, [], Con, [ from_fate(Type, Arg) || {Type, Arg} <- lists:zip(Types, Args) ]}; +from_fate({qid, _, QType}, Val) -> + from_fate_builtin(QType, Val); from_fate(_Type, _Data) -> throw(cannot_translate_to_sophia). +from_fate_builtin(QType, Val) -> + Con = fun([Name | _] = Names) when is_list(Name) -> {qcon, [], Names}; + (Name) -> {con, [], Name} end, + App = fun(Name, []) -> Con(Name); + (Name, Value) -> {app, [], Con(Name), Value} end, + Chk = fun(Type, Value) -> from_fate(Type, Value) end, + Int = {id, [], "int"}, + Str = {id, [], "string"}, + Adr = {id, [], "address"}, + Hsh = {bytes_t, [], 32}, + Qid = fun(Name) -> {qid, [], Name} end, + Map = fun(KT, VT) -> {app_t, [], {id, [], "map"}, [KT, VT]} end, + ChainTxArities = [3, 0, 0, 0, 0, 0, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2, 0], + + case {QType, Val} of + {["Chain", "ttl"], {variant, [1, 1], 0, {X}}} -> App("RelativeTTL", [Chk(Int, X)]); + {["Chain", "ttl"], {variant, [1, 1], 1, {X}}} -> App("FixedTTL", [Chk(Int, X)]); + + {["AENS", "name"], {variant, [3], 0, {Addr, TTL, Ptrs}}} -> + App(["AENS","Name"], [Chk(Adr, Addr), Chk(Qid(["Chain", "ttl"]), TTL), + Chk(Map(Str, Qid(["AENS", "pointee"])), Ptrs)]); + + {["AENS", "pointee"], {variant, [1, 1, 1, 1], 0, {Addr}}} -> + App(["AENS","AccountPt"], [Chk(Adr, Addr)]); + {["AENS", "pointee"], {variant, [1, 1, 1, 1], 1, {Addr}}} -> + App(["AENS","OraclePt"], [Chk(Adr, Addr)]); + {["AENS", "pointee"], {variant, [1, 1, 1, 1], 2, {Addr}}} -> + App(["AENS","ContractPt"], [Chk(Adr, Addr)]); + {["AENS", "pointee"], {variant, [1, 1, 1, 1], 3, {Addr}}} -> + App(["AENS","ChannelPt"], [Chk(Adr, Addr)]); + + {["Chain", "ga_meta_tx"], {variant, [2], 0, {Addr, X}}} -> + App(["Chain","GAMetaTx"], [Chk(Adr, Addr), Chk(Int, X)]); + + {["Chain", "paying_for_tx"], {variant, [2], 0, {Addr, X}}} -> + App(["Chain","PayingForTx"], [Chk(Adr, Addr), Chk(Int, X)]); + + {["Chain", "base_tx"], {variant, ChainTxArities, 0, {Addr, Fee, Payload}}} -> + App(["Chain","SpendTx"], [Chk(Adr, Addr), Chk(Int, Fee), Chk(Str, Payload)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 1, {}}} -> + App(["Chain","OracleRegisterTx"], []); + {["Chain", "base_tx"], {variant, ChainTxArities, 2, {}}} -> + App(["Chain","OracleQueryTx"], []); + {["Chain", "base_tx"], {variant, ChainTxArities, 3, {}}} -> + App(["Chain","OracleResponseTx"], []); + {["Chain", "base_tx"], {variant, ChainTxArities, 4, {}}} -> + App(["Chain","OracleExtendTx"], []); + {["Chain", "base_tx"], {variant, ChainTxArities, 5, {}}} -> + App(["Chain","NamePreclaimTx"], []); + {["Chain", "base_tx"], {variant, ChainTxArities, 6, {Name}}} -> + App(["Chain","NameClaimTx"], [Chk(Str, Name)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 7, {NameHash}}} -> + App(["Chain","NameUpdateTx"], [Chk(Hsh, NameHash)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 8, {NameHash}}} -> + App(["Chain","NameRevokeTx"], [Chk(Hsh, NameHash)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 9, {NewOwner, NameHash}}} -> + App(["Chain","NameTransferTx"], [Chk(Adr, NewOwner), Chk(Hsh, NameHash)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 10, {Addr}}} -> + App(["Chain","ChannelCreateTx"], [Chk(Adr, Addr)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 11, {Addr, Amount}}} -> + App(["Chain","ChannelDepositTx"], [Chk(Adr, Addr), Chk(Int, Amount)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 12, {Addr, Amount}}} -> + App(["Chain","ChannelWithdrawTx"], [Chk(Adr, Addr), Chk(Int, Amount)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 13, {Addr}}} -> + App(["Chain","ChannelForceProgressTx"], [Chk(Adr, Addr)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 14, {Addr}}} -> + App(["Chain","ChannelCloseMutualTx"], [Chk(Adr, Addr)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 15, {Addr}}} -> + App(["Chain","ChannelCloseSoloTx"], [Chk(Adr, Addr)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 16, {Addr}}} -> + App(["Chain","ChannelSlashTx"], [Chk(Adr, Addr)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 17, {Addr}}} -> + App(["Chain","ChannelSettleTx"], [Chk(Adr, Addr)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 18, {Addr}}} -> + App(["Chain","ChannelSnapshotSoloTx"], [Chk(Adr, Addr)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 19, {Amount}}} -> + App(["Chain","ContractCreateTx"], [Chk(Int, Amount)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 20, {Addr, Amount}}} -> + App(["Chain","ContractCallTx"], [Chk(Adr, Addr), Chk(Int, Amount)]); + {["Chain", "base_tx"], {variant, ChainTxArities, 21, {}}} -> + App(["Chain","GAAttachTx"], []); + + _ -> + throw(cannot_translate_to_sophia) + end. + make_bits(N) -> Id = fun(F) -> {qid, [], ["Bits", F]} end, if N < 0 -> make_bits(Id("clear"), Id("all"), 0, bnot N); diff --git a/test/aeso_calldata_tests.erl b/test/aeso_calldata_tests.erl index 58d66e3..f10fc3e 100644 --- a/test/aeso_calldata_tests.erl +++ b/test/aeso_calldata_tests.erl @@ -112,8 +112,28 @@ compilable_contracts() -> {"funargs", "traffic_light", ["Green"]}, {"funargs", "traffic_light", ["Pantone(12)"]}, {"funargs", "tuples", ["()"]}, - %% TODO {"funargs", "due", ["FixedTTL(1020)"]}, + {"funargs", "due", ["FixedTTL(1020)"]}, {"funargs", "singleton_rec", ["{x = 1000}"]}, + {"funargs", "aens_name", ["AENS.Name(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR, RelativeTTL(100), {[\"pt1\"] = AENS.AccountPt(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR)})"]}, + {"funargs", "aens_pointee", ["AENS.AccountPt(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR)"]}, + {"funargs", "aens_pointee", ["AENS.OraclePt(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR)"]}, + {"funargs", "aens_pointee", ["AENS.ContractPt(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR)"]}, + {"funargs", "aens_pointee", ["AENS.ChannelPt(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR)"]}, + {"funargs", "chain_ga_meta_tx", ["Chain.GAMetaTx(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR, 42)"]}, + {"funargs", "chain_paying_for_tx", ["Chain.PayingForTx(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR, 42)"]}, + {"funargs", "chain_base_tx", ["Chain.SpendTx(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR, 42,\"foo\")"]}, + {"funargs", "chain_base_tx", ["Chain.ContractCreateTx(12234)"]}, + {"funargs", "chain_base_tx", ["Chain.ContractCallTx(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR, 12234)"]}, + {"funargs", "chain_base_tx", ["Chain.OracleRegisterTx"]}, + {"funargs", "chain_base_tx", ["Chain.OracleQueryTx"]}, + {"funargs", "chain_base_tx", ["Chain.OracleResponseTx"]}, + {"funargs", "chain_base_tx", ["Chain.OracleExtendTx"]}, + {"funargs", "chain_base_tx", ["Chain.NamePreclaimTx"]}, + {"funargs", "chain_base_tx", ["Chain.NameClaimTx(\"acoolname.chain\")"]}, + {"funargs", "chain_base_tx", ["Chain.NameUpdateTx(#ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)"]}, + {"funargs", "chain_base_tx", ["Chain.NameRevokeTx(#ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)"]}, + {"funargs", "chain_base_tx", ["Chain.NameTransferTx(ak_2dATVcZ9KJU5a8hdsVtTv21pYiGWiPbmVcU1Pz72FFqpk9pSRR, #ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)"]}, + {"funargs", "chain_base_tx", ["Chain.GAAttachTx"]}, {"variant_types", "init", []}, {"basic_auth", "init", []}, {"address_literals", "init", []}, diff --git a/test/contracts/funargs.aes b/test/contracts/funargs.aes index f2339e4..cd54fa5 100644 --- a/test/contracts/funargs.aes +++ b/test/contracts/funargs.aes @@ -50,3 +50,10 @@ contract FunctionArguments = entrypoint singleton_rec(r : singleton_r) = r.x + + entrypoint aens_name(n : AENS.name) = true + entrypoint aens_pointee(p : AENS.pointee) = true + + entrypoint chain_ga_meta_tx(tx : Chain.ga_meta_tx) = true + entrypoint chain_paying_for_tx(tx : Chain.paying_for_tx) = true + entrypoint chain_base_tx(tx : Chain.base_tx) = true