Skip to content

Instantly share code, notes, and snippets.

@yoshihiro503
Last active August 3, 2020 10:12
Show Gist options
  • Save yoshihiro503/395a587a0adbef7cf914a9e19fe37ced to your computer and use it in GitHub Desktop.
Save yoshihiro503/395a587a0adbef7cf914a9e19fe37ced to your computer and use it in GitHub Desktop.

概要

ブロックチェーン Tezos において、ノードの立ち上げやクライアントを使ったインタラクションをOCaml上で実行できるフレームワーク Tezt が爆誕したので試してみる。

Tezt とはなに?

Tezos開発者がOCamlでTezosの tezos プロジェクトに内包される形で提供されようとして現在 Merge Request が出ている段階である。

できること

  • Nodeを別プロセスとして新しく起動する、終了する
  • Nodeプロセスを監視して、準備中になるまで待つとか、一定のblockレベル溜まるまで待つとかできる
  • RPCコール経由でNodeに働きかける
  • Clientからbakeする

今できないこと

  • すでに起動しているNodeの扱い (イベント補足とかの整合性を考えなければできる?未確認)
  • Clientでの任意のコマンド実行 (簡単な改造でいける)

FAQ

TODO

私の環境

  • Ubuntu 18.04
  • opam 2.0.4
@yoshihiro503
Copy link
Author

commit: e83c47a68 からの差分:

tezt_sample_on_e83c47a68.diff

diff --git a/tezt/lib_tezos/client.ml b/tezt/lib_tezos/client.ml
index dc7956f23..80f6dc30d 100644
--- a/tezt/lib_tezos/client.ml
+++ b/tezt/lib_tezos/client.ml
@@ -83,6 +83,14 @@ let run_command ?(needs_node = true) ?(admin = false) ?node client command =
     (if admin then client.admin_path else client.path)
     (base_args ?node client @ command)
 
+let run_command' ?(needs_node = true) ?(admin = false) ?node client command =
+  if needs_node then check_node_is_specified ?node command client ;
+  Process.run_and_read_stdout
+    ~name:client.name
+    ~color:client.color
+    (if admin then client.admin_path else client.path)
+    (base_args ?node client @ command)
+
 let url_encode str =
   let buffer = Buffer.create (String.length str * 3) in
   for i = 0 to String.length str - 1 do
@@ -199,6 +207,10 @@ let bake_for ?node ?(key = Constant.bootstrap1.alias)
     ( "bake" :: "for" :: key
     :: (if minimal_timestamp then ["--minimal-timestamp"] else []) )
 
+let list_known_addresses ?node client =
+  run_command' client ?node
+    ["list"; "known"; "addresses"]
+
 let init ?path ?admin_path ?name ?color ?base_dir ?node () =
   let client = create ?path ?admin_path ?name ?color ?base_dir ?node () in
   let* () =
diff --git a/tezt/lib_tezos/client.mli b/tezt/lib_tezos/client.mli
index e1bdab746..41e5712b8 100644
--- a/tezt/lib_tezos/client.mli
+++ b/tezt/lib_tezos/client.mli
@@ -120,6 +120,13 @@ val activate_protocol :
 val bake_for :
   ?node:Node.t -> ?key:string -> ?minimal_timestamp:bool -> t -> unit Lwt.t
 
+val list_known_addresses:
+  ?node:Node.t -> t -> string Lwt.t
+
+val run_command' : ?needs_node:bool ->
+                  ?admin:bool -> ?node:Node.t -> t -> string list ->
+                  string Lwt.t
+
 (** {2 High-Level Functions} *)
 
 (** Create a client and import all secret keys listed in {!Constant.all_secret_keys}. *)
diff --git a/tezt/tests/dune b/tezt/tests/dune
index ba37bee14..d50bff721 100644
--- a/tezt/tests/dune
+++ b/tezt/tests/dune
@@ -1,4 +1,4 @@
 (executable
- (name main)
+ (name sample)
  (libraries tezt-tezos)
  (flags (:standard -open Tezt -open Tezt_tezos -open Tezt.Base)))

tezt/tests/sample.ml

let string_of_amount amount = Printf.sprintf "%.000f" amount

let list_known_addresses client =
  Client.list_known_addresses client
let get_balance account client =
  Client.run_command' client ["get"; "balance"; "for"; account]

let transfer client ~amount ~from ~to_ ~burn_cap =
  ["transfer"; string_of_amount amount; "from"; from; "to"; to_;
   "--burn-cap"; string_of_amount burn_cap;]
  |> Client.run_command' client

let originate_contract ~name ~amount ~from ?(init = "Unit") ~burn_cap tz_file client =
  Client.run_command' client ["originate"; "contract"; name;
                              "transferring"; string_of_amount amount;
                              "from"; from;
                              "running"; tz_file;
                              "--init"; init;
                              "--burn-cap"; string_of_amount burn_cap]


let f () =
  let _history_mode = Node.Full in
  let node =
    let data_dir = "/sandisk/tezos/tezos-carthagenet/" in
    let net_port = 9732 in
    let rpc_port = 8732 in
    Node.create ~name:"CARTHAGENET" ~data_dir ~net_port ~rpc_port ()
  in
  (*
  let* node =
    Node.init ~bootstrap_threshold:0 ~connections:1 ~history_mode ()
  in
   *)
  (*  let* _node_identity = Node.wait_for_identity node in*)
  let* client =
    let path = "/home/mube/tezos-carthagenet/tezos-client" in
    Client.init ~path ~node ()
  in
(*  let* () = Client.Admin.connect_address client ~peer:node in*)
  (*  let* () = Client.activate_protocol client in*)
  (*  Node.run ~bootstrap_threshold:0 ~connections:1 node;*)
(*  let* _ = Node.wait_for_ready node in*)
  let* json =
    Client.rpc Client.GET ["chains"; "main"; "blocks"; "head"] client
  in
  print_endline ("head: "^(JSON.encode json));
  let* out = Client.list_known_addresses client in
  print_endline ("addresses: "^out);
  let bootstrap1 = "bootstrap1" in
  let* out = get_balance bootstrap1 client in
  print_endline ("bootstrap1: "^out);
  let bootstrap2 = "bootstrap2" in
  let* out = get_balance bootstrap2 client in
  print_endline ("bootstrap2: "^out);
  let activator = "activator" in
  let* out = get_balance activator client in
  print_endline ("activator: "^out);


  let burn_cap = 1. in
  let* out = transfer ~amount:1. ~from:bootstrap1 ~to_:bootstrap2 ~burn_cap client in
  print_endline ("transfered: "^out);
    
  let* out = get_balance bootstrap1 client in
  print_endline ("--> bootstrap1: "^out);
  let* out = get_balance bootstrap2 client in
  print_endline ("--> bootstrap2: "^out);

  (*
  (* smart contract *)
  let burn_cap = 1. in
  let simplest = "simplest" in
  let* out =
    originate_contract ~name:simplest ~amount:0. ~from:bootstrap1 ~burn_cap "/home/mube/gitlab/nomadic-labs/tezos/tezt/tests/simplest.tz" client
  in
  print_endline ("originated: "^out);
 *)

  print_endline "hello";
  return ()

let () =
  Test.run
    ~title:"TITLETITLE"
    ~tags:[]
    f
dune exec tezt/tests/sample.exe -- --verbose

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment