diff --git a/src/proto_alpha/lib_client/client_proto_context.ml b/src/proto_alpha/lib_client/client_proto_context.ml index 799676048..09fb24066 100644 --- a/src/proto_alpha/lib_client/client_proto_context.ml +++ b/src/proto_alpha/lib_client/client_proto_context.ml @@ -35,6 +35,9 @@ let get_balance (rpc : #Proto_alpha.rpc_context) ~chain ~block contract = let get_storage (rpc : #Proto_alpha.rpc_context) ~chain ~block contract = Alpha_services.Contract.storage_opt rpc (chain, block) contract +let get_big_map_value (rpc : #Proto_alpha.rpc_context) ~chain ~block contract key = + Alpha_services.Contract.big_map_get_opt rpc (chain, block) contract key + let get_script (rpc : #Proto_alpha.rpc_context) ~chain ~block contract = Alpha_services.Contract.script_opt rpc (chain, block) contract diff --git a/src/proto_alpha/lib_client/client_proto_context.mli b/src/proto_alpha/lib_client/client_proto_context.mli index dd46541f8..4a1d8e19f 100644 --- a/src/proto_alpha/lib_client/client_proto_context.mli +++ b/src/proto_alpha/lib_client/client_proto_context.mli @@ -39,6 +39,14 @@ val get_storage: Contract.t -> Script.expr option tzresult Lwt.t +val get_big_map_value: + #Proto_alpha.rpc_context -> + chain:Shell_services.chain -> + block:Shell_services.block -> + Contract.t -> + (Script.expr * Script.expr) -> + Script.expr option tzresult Lwt.t + val get_script: #Proto_alpha.rpc_context -> chain:Shell_services.chain -> diff --git a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml index 2ad7ae3a3..5e8bbdd37 100644 --- a/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml +++ b/src/proto_alpha/lib_client_commands/client_proto_context_commands.ml @@ -62,6 +62,11 @@ let file_parameter = else return p) +let data_parameter = + Clic.parameter (fun _ data -> + Lwt.return (Micheline_parser.no_parsing_error + @@ Michelson_v1_parser.parse_expression data)) + let group = { Clic.name = "context" ; title = "Block contextual commands (see option -block)" } @@ -133,6 +138,28 @@ let commands version () = return_unit end ; + command ~group ~desc: "Get the value associated to a key in the big map storage of a contract." + no_options + (prefixes [ "get" ; "big" ; "map" ; "value" ; "for" ] + @@ Clic.param ~name:"key" ~desc:"the key to look for" + data_parameter + @@ prefixes [ "of" ; "type" ] + @@ Clic.param ~name:"type" ~desc:"type of the key" + data_parameter + @@ prefix "in" + @@ ContractAlias.destination_param ~name:"src" ~desc:"source contract" + @@ stop) + begin fun () key key_type (_, contract) (cctxt : Proto_alpha.full) -> + get_big_map_value cctxt + ~chain:`Main ~block:cctxt#block + contract (key.expanded, key_type.expanded) >>=? function + | None -> + cctxt#error "No value associated to this key." + | Some value -> + cctxt#answer "%a" Michelson_v1_printer.print_expr_unwrapped value >>= fun () -> + return_unit + end ; + command ~group ~desc: "Get the storage of a contract." no_options (prefixes [ "get" ; "script" ; "code" ; "for" ] diff --git a/src/proto_alpha/lib_protocol/src/contract_services.ml b/src/proto_alpha/lib_protocol/src/contract_services.ml index b52f17f95..3951a34ae 100644 --- a/src/proto_alpha/lib_protocol/src/contract_services.ml +++ b/src/proto_alpha/lib_protocol/src/contract_services.ml @@ -127,6 +127,16 @@ module S = struct ~output: Script.expr_encoding RPC_path.(custom_root /: Contract.rpc_arg / "storage") + let big_map_get = + RPC_service.post_service + ~description: "Access the value associated with a key in the big map storage of the contract." + ~query: RPC_query.empty + ~input: (obj2 + (req "key" Script.expr_encoding) + (req "type" Script.expr_encoding)) + ~output: (option Script.expr_encoding) + RPC_path.(custom_root /: Contract.rpc_arg / "big_map_get") + let info = RPC_service.get_service ~description: "Access the complete status of a contract." @@ -187,6 +197,15 @@ let register () = unparse_script ctxt Readable script >>=? fun (script, ctxt) -> Script.force_decode ctxt script.storage >>=? fun (storage, _ctxt) -> return_some storage) ; + register1 S.big_map_get (fun ctxt contract () (key, key_type) -> + let open Script_ir_translator in + let ctxt = Gas.set_unlimited ctxt in + Lwt.return (parse_ty ctxt ~allow_big_map:false ~allow_operation:false (Micheline.root key_type)) + >>=? fun (Ex_ty key_type, ctxt) -> + parse_data ctxt key_type (Micheline.root key) >>=? fun (key, ctxt) -> + hash_data ctxt key_type key >>=? fun (key_hash, ctxt) -> + Contract.Big_map.get_opt ctxt contract key_hash >>=? fun (_ctxt, value) -> + return value) ; register_field S.info (fun ctxt contract -> Contract.get_balance ctxt contract >>=? fun balance -> Contract.get_manager ctxt contract >>=? fun manager -> @@ -249,3 +268,6 @@ let storage ctxt block contract = let storage_opt ctxt block contract = RPC_context.make_opt_call1 S.storage ctxt block contract () () + +let big_map_get_opt ctxt block contract key = + RPC_context.make_call1 S.big_map_get ctxt block contract () key diff --git a/src/proto_alpha/lib_protocol/src/contract_services.mli b/src/proto_alpha/lib_protocol/src/contract_services.mli index d68cd6ec4..0682c387b 100644 --- a/src/proto_alpha/lib_protocol/src/contract_services.mli +++ b/src/proto_alpha/lib_protocol/src/contract_services.mli @@ -78,5 +78,9 @@ val storage: val storage_opt: 'a #RPC_context.simple -> 'a -> Contract.t -> Script.expr option shell_tzresult Lwt.t +val big_map_get_opt: + 'a #RPC_context.simple -> 'a -> Contract.t -> Script.expr * Script.expr -> + Script.expr option shell_tzresult Lwt.t + val register: unit -> unit