Client: add a claim operation that activate a commitment account
This commit is contained in:
parent
aeaf2a240c
commit
020ef19460
@ -4,6 +4,8 @@
|
|||||||
((name runtest_basic.sh)
|
((name runtest_basic.sh)
|
||||||
(deps (sandbox.json
|
(deps (sandbox.json
|
||||||
protocol_parameters.json
|
protocol_parameters.json
|
||||||
|
king_commitment.json
|
||||||
|
queen_commitment.json
|
||||||
test_lib.inc.sh
|
test_lib.inc.sh
|
||||||
(glob_files contracts/*)
|
(glob_files contracts/*)
|
||||||
))
|
))
|
||||||
|
8
src/bin_client/test/king_commitment.json
Normal file
8
src/bin_client/test/king_commitment.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"mnemonic": ["envelope", "hospital", "mind", "sunset", "cancel", "muscle", "leisure", "thumb", "wine", "market", "exit", "lucky", "style", "picnic", "success"],
|
||||||
|
"secret": "0f39ed0b656509c2ecec4771712d9cddefe2afac",
|
||||||
|
"amount": "23932454669343",
|
||||||
|
"pkh": "tz1MawerETND6bqJqx8GV3YHUrvMBCDasRBF",
|
||||||
|
"password": "z0eZHQQGKt",
|
||||||
|
"email": "cjgfoqmk.wpxnvnup@tezos.example.org"
|
||||||
|
}
|
8
src/bin_client/test/queen_commitment.json
Normal file
8
src/bin_client/test/queen_commitment.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"mnemonic": ["flag", "quote", "will", "valley", "mouse", "chat", "hold", "prosper", "silk", "tent", "cruel", "cause", "demise", "bottom", "practice"],
|
||||||
|
"secret": "41f98b15efc63fa893d61d7d6eee4a2ce9427ac4",
|
||||||
|
"amount": "72954577464032",
|
||||||
|
"pkh": "tz1X4maqF9tC1Yn4jULjHRAyzjAtc25Z68TX",
|
||||||
|
"password": "MHErskWPE6",
|
||||||
|
"email": "oklmcktr.ztljnpzc@tezos.example.org"
|
||||||
|
}
|
@ -26,6 +26,8 @@ sleep 1
|
|||||||
key1=foo
|
key1=foo
|
||||||
key2=bar
|
key2=bar
|
||||||
key3=boo
|
key3=boo
|
||||||
|
key4=king
|
||||||
|
key5=queen
|
||||||
|
|
||||||
$client gen keys $key1
|
$client gen keys $key1
|
||||||
$client gen keys $key2 --sig secp256k1
|
$client gen keys $key2 --sig secp256k1
|
||||||
@ -106,6 +108,20 @@ $client transfer 400,000 from bootstrap1 to bootstrap5 -fee 0
|
|||||||
sleep 1
|
sleep 1
|
||||||
$client bake for bootstrap1 -max-priority 512
|
$client bake for bootstrap1 -max-priority 512
|
||||||
$client get balance for bootstrap5 | assert "4,000,000 ꜩ"
|
$client get balance for bootstrap5 | assert "4,000,000 ꜩ"
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
|
||||||
|
$client activate account $key4 with king_commitment.json --no-confirmation
|
||||||
|
$client activate account $key5 with queen_commitment.json --no-confirmation
|
||||||
|
$client bake for bootstrap1 -max-priority 512
|
||||||
|
sleep 1
|
||||||
|
|
||||||
|
$client get balance for $key4 | assert "23,932,454.669,343 ꜩ"
|
||||||
|
$client get balance for $key5 | assert "72,954,577.464,032 ꜩ"
|
||||||
|
|
||||||
|
$client transfer 10 from $key4 to $key5
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
echo
|
echo
|
||||||
echo End of test
|
echo End of test
|
||||||
|
@ -159,9 +159,8 @@ let append cctxt loc buf =
|
|||||||
sign cctxt loc buf >>|? fun signature ->
|
sign cctxt loc buf >>|? fun signature ->
|
||||||
Signature.concat buf signature
|
Signature.concat buf signature
|
||||||
|
|
||||||
let gen_keys ?(force=false) ?algo ?seed (cctxt : #Client_context.io_wallet) name =
|
let register_key cctxt ?(force=false)
|
||||||
let public_key_hash, public_key, secret_key =
|
(public_key_hash, public_key, secret_key) name =
|
||||||
Signature.generate_key ?algo ?seed () in
|
|
||||||
Secret_key.add ~force cctxt name
|
Secret_key.add ~force cctxt name
|
||||||
(Secret_key_locator.of_unencrypted secret_key) >>=? fun () ->
|
(Secret_key_locator.of_unencrypted secret_key) >>=? fun () ->
|
||||||
Public_key.add ~force cctxt name
|
Public_key.add ~force cctxt name
|
||||||
@ -170,6 +169,9 @@ let gen_keys ?(force=false) ?algo ?seed (cctxt : #Client_context.io_wallet) name
|
|||||||
cctxt name public_key_hash >>=? fun () ->
|
cctxt name public_key_hash >>=? fun () ->
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
|
let gen_keys ?(force=false) ?algo ?seed (cctxt : #Client_context.io_wallet) name =
|
||||||
|
let key = Signature.generate_key ?algo ?seed () in
|
||||||
|
register_key cctxt ~force key name
|
||||||
|
|
||||||
let gen_keys_containing ?(prefix=false) ?(force=false) ~containing ~name (cctxt : #Client_context.full) =
|
let gen_keys_containing ?(prefix=false) ?(force=false) ~containing ~name (cctxt : #Client_context.full) =
|
||||||
let unrepresentable =
|
let unrepresentable =
|
||||||
|
@ -116,6 +116,13 @@ val gen_keys :
|
|||||||
?seed:Ed25519.Seed.t ->
|
?seed:Ed25519.Seed.t ->
|
||||||
#Client_context.io_wallet -> string -> unit tzresult Lwt.t
|
#Client_context.io_wallet -> string -> unit tzresult Lwt.t
|
||||||
|
|
||||||
|
val register_key :
|
||||||
|
#Client_context.wallet ->
|
||||||
|
?force:bool ->
|
||||||
|
(Signature.Public_key_hash.t *
|
||||||
|
Signature.Public_key.t *
|
||||||
|
Signature.Secret_key.t) -> string -> unit tzresult Lwt.t
|
||||||
|
|
||||||
val gen_keys_containing :
|
val gen_keys_containing :
|
||||||
?prefix:bool ->
|
?prefix:bool ->
|
||||||
?force:bool ->
|
?force:bool ->
|
||||||
|
@ -180,6 +180,12 @@ let no_print_source_flag =
|
|||||||
This option disables this behaviour."
|
This option disables this behaviour."
|
||||||
()
|
()
|
||||||
|
|
||||||
|
let no_confirmation =
|
||||||
|
switch
|
||||||
|
~long:"no-confirmation"
|
||||||
|
~doc:"don't print wait for the operation to be confirmed."
|
||||||
|
()
|
||||||
|
|
||||||
module Daemon = struct
|
module Daemon = struct
|
||||||
let baking_switch =
|
let baking_switch =
|
||||||
switch
|
switch
|
||||||
|
@ -26,6 +26,7 @@ val force_switch: (bool, Proto_alpha.full) Clic.arg
|
|||||||
val endorsement_delay_arg: (int, Proto_alpha.full) Clic.arg
|
val endorsement_delay_arg: (int, Proto_alpha.full) Clic.arg
|
||||||
|
|
||||||
val no_print_source_flag: (bool, Proto_alpha.full) Clic.arg
|
val no_print_source_flag: (bool, Proto_alpha.full) Clic.arg
|
||||||
|
val no_confirmation: (bool, Proto_alpha.full) Clic.arg
|
||||||
|
|
||||||
val tez_arg :
|
val tez_arg :
|
||||||
default:string ->
|
default:string ->
|
||||||
|
@ -285,3 +285,77 @@ let wait_for_operation_inclusion
|
|||||||
end stream >>= fun _ ->
|
end stream >>= fun _ ->
|
||||||
stop () ;
|
stop () ;
|
||||||
return ()
|
return ()
|
||||||
|
|
||||||
|
type activation_key =
|
||||||
|
{ pkh : Ed25519.Public_key_hash.t ;
|
||||||
|
amount : Tez.t ;
|
||||||
|
secret : Blinded_public_key_hash.secret ;
|
||||||
|
mnemonic : string list ;
|
||||||
|
password : string ;
|
||||||
|
email : string ;
|
||||||
|
}
|
||||||
|
|
||||||
|
let activation_key_encoding =
|
||||||
|
let open Data_encoding in
|
||||||
|
conv
|
||||||
|
(fun { pkh ; amount ; secret ; mnemonic ; password ; email } ->
|
||||||
|
( pkh, amount, secret, mnemonic, password, email ))
|
||||||
|
(fun ( pkh, amount, secret, mnemonic, password, email ) ->
|
||||||
|
{ pkh ; amount ; secret ; mnemonic ; password ; email })
|
||||||
|
(obj6
|
||||||
|
(req "pkh" Ed25519.Public_key_hash.encoding)
|
||||||
|
(req "amount" Tez.encoding)
|
||||||
|
(req "secret" Blinded_public_key_hash.secret_encoding)
|
||||||
|
(req "mnemonic" (list string))
|
||||||
|
(req "password" string)
|
||||||
|
(req "email" string))
|
||||||
|
|
||||||
|
let read_key key =
|
||||||
|
match Bip39.of_words key.mnemonic with
|
||||||
|
| None ->
|
||||||
|
failwith ""
|
||||||
|
| Some t ->
|
||||||
|
(* TODO: unicode normalization (NFKD)... *)
|
||||||
|
let sk = Bip39.to_seed ~passphrase:(key.email ^ key.password) t in
|
||||||
|
let sk = Cstruct.(to_bigarray (sub sk 0 32)) in
|
||||||
|
let sk : Signature.Secret_key.t =
|
||||||
|
Ed25519 (Data_encoding.Binary.of_bytes_exn Ed25519.Secret_key.encoding sk) in
|
||||||
|
let pk = Signature.Secret_key.to_public_key sk in
|
||||||
|
let pkh = Signature.Public_key.hash pk in
|
||||||
|
return (pkh, pk, sk)
|
||||||
|
|
||||||
|
let claim_commitment (cctxt : #Proto_alpha.full)
|
||||||
|
?confirmations ?force block key name =
|
||||||
|
read_key key >>=? fun (pkh, pk, sk) ->
|
||||||
|
fail_unless (Signature.Public_key_hash.equal pkh (Ed25519 key.pkh))
|
||||||
|
(failure "@[<v 2>Inconsistent activation key:@ \
|
||||||
|
Computed pkh: %a@ \
|
||||||
|
Embedded pkh: %a @]"
|
||||||
|
Signature.Public_key_hash.pp pkh
|
||||||
|
Ed25519.Public_key_hash.pp key.pkh) >>=? fun () ->
|
||||||
|
let op = [ Activation { id = key.pkh ; secret = key.secret } ] in
|
||||||
|
Block_services.info cctxt block >>=? fun bi ->
|
||||||
|
Alpha_services.Forge.Anonymous.operations
|
||||||
|
cctxt block ~branch:bi.hash op >>=? fun bytes ->
|
||||||
|
Shell_services.inject_operation
|
||||||
|
cctxt ~chain_id:bi.chain_id bytes >>=? fun oph ->
|
||||||
|
operation_submitted_message cctxt oph >>=? fun () ->
|
||||||
|
begin
|
||||||
|
match confirmations with
|
||||||
|
| None ->
|
||||||
|
Client_keys.register_key cctxt ?force (pkh, pk, sk) name >>=? fun () ->
|
||||||
|
return ()
|
||||||
|
| Some confirmations ->
|
||||||
|
cctxt#message "Waiting for the operation to be included..." >>= fun () ->
|
||||||
|
wait_for_operation_inclusion ~confirmations cctxt oph >>=? fun () ->
|
||||||
|
Client_keys.register_key cctxt ?force (pkh, pk, sk) name >>=? fun () ->
|
||||||
|
Alpha_services.Contract.balance
|
||||||
|
cctxt (`Head 0) (Contract.implicit_contract pkh) >>=? fun balance ->
|
||||||
|
cctxt#message "Account %s (%a) created with %s%a."
|
||||||
|
name
|
||||||
|
Signature.Public_key_hash.pp pkh
|
||||||
|
Client_proto_args.tez_sym
|
||||||
|
Tez.pp balance >>= fun () ->
|
||||||
|
return ()
|
||||||
|
end
|
||||||
|
|
||||||
|
@ -141,3 +141,24 @@ val wait_for_operation_inclusion:
|
|||||||
?confirmations:int ->
|
?confirmations:int ->
|
||||||
Operation_hash.t ->
|
Operation_hash.t ->
|
||||||
unit tzresult Lwt.t
|
unit tzresult Lwt.t
|
||||||
|
|
||||||
|
type activation_key =
|
||||||
|
{ pkh : Ed25519.Public_key_hash.t ;
|
||||||
|
amount : Tez.t ;
|
||||||
|
secret : Blinded_public_key_hash.secret ;
|
||||||
|
mnemonic : string list ;
|
||||||
|
password : string ;
|
||||||
|
email : string ;
|
||||||
|
}
|
||||||
|
|
||||||
|
val activation_key_encoding: activation_key Data_encoding.t
|
||||||
|
|
||||||
|
val claim_commitment:
|
||||||
|
#Proto_alpha.full ->
|
||||||
|
?confirmations:int ->
|
||||||
|
?force:bool ->
|
||||||
|
Block_services.block ->
|
||||||
|
activation_key ->
|
||||||
|
string ->
|
||||||
|
unit tzresult Lwt.t
|
||||||
|
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
tezos-protocol-environment
|
tezos-protocol-environment
|
||||||
tezos-shell-services
|
tezos-shell-services
|
||||||
tezos-client-base
|
tezos-client-base
|
||||||
tezos-rpc))
|
tezos-rpc
|
||||||
|
bip39))
|
||||||
(library_flags (:standard -linkall))
|
(library_flags (:standard -linkall))
|
||||||
(flags (:standard -w -9+27-30-32-40@8
|
(flags (:standard -w -9+27-30-32-40@8
|
||||||
-safe-string
|
-safe-string
|
||||||
|
@ -28,6 +28,13 @@ let report_michelson_errors ?(no_print_source=false) ~msg (cctxt : #Client_conte
|
|||||||
| Ok data ->
|
| Ok data ->
|
||||||
Lwt.return (Some data)
|
Lwt.return (Some data)
|
||||||
|
|
||||||
|
let file_parameter =
|
||||||
|
Clic.parameter (fun _ p ->
|
||||||
|
if not (Sys.file_exists p) then
|
||||||
|
failwith "File doesn't exist: '%s'" p
|
||||||
|
else
|
||||||
|
return p)
|
||||||
|
|
||||||
let group =
|
let group =
|
||||||
{ Clic.name = "context" ;
|
{ Clic.name = "context" ;
|
||||||
title = "Block contextual commands (see option -block)" }
|
title = "Block contextual commands (see option -block)" }
|
||||||
@ -253,6 +260,32 @@ let commands () =
|
|||||||
operation_submitted_message cctxt oph
|
operation_submitted_message cctxt oph
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
command ~group ~desc:"Register and activate a predefined account using the provided activation key."
|
||||||
|
(args2 (Secret_key.force_switch ()) (Client_proto_args.no_confirmation))
|
||||||
|
(prefixes [ "activate" ; "account" ]
|
||||||
|
@@ Secret_key.fresh_alias_param
|
||||||
|
@@ prefixes [ "with" ]
|
||||||
|
@@ param ~name:"activation_key"
|
||||||
|
~desc:"Activation key (as JSON file) obtained from the Tezos foundation (or the Alphanet faucet)."
|
||||||
|
file_parameter
|
||||||
|
@@ stop)
|
||||||
|
(fun (force, no_confirmation) name activation_key_file cctxt ->
|
||||||
|
Secret_key.of_fresh cctxt force name >>=? fun name ->
|
||||||
|
Lwt_utils_unix.Json.read_file activation_key_file >>=? fun json ->
|
||||||
|
match Data_encoding.Json.destruct
|
||||||
|
Client_proto_context.activation_key_encoding
|
||||||
|
json with
|
||||||
|
| exception (Data_encoding.Json.Cannot_destruct _ as exn) ->
|
||||||
|
Format.kasprintf (fun s -> failwith "%s" s)
|
||||||
|
"Invalid activation file: %a %a"
|
||||||
|
(fun ppf -> Data_encoding.Json.print_error ppf) exn
|
||||||
|
Data_encoding.Json.pp json
|
||||||
|
| key ->
|
||||||
|
let confirmations =
|
||||||
|
if no_confirmation then None else Some 0 in
|
||||||
|
claim_commitment cctxt cctxt#block ?confirmations ~force key name
|
||||||
|
);
|
||||||
|
|
||||||
command ~group:alphanet ~desc: "Activate a protocol (Alphanet dictator only)."
|
command ~group:alphanet ~desc: "Activate a protocol (Alphanet dictator only)."
|
||||||
no_options
|
no_options
|
||||||
(prefixes [ "activate" ; "protocol" ]
|
(prefixes [ "activate" ; "protocol" ]
|
||||||
@ -306,6 +339,7 @@ let commands () =
|
|||||||
wait_for_operation_inclusion ctxt
|
wait_for_operation_inclusion ctxt
|
||||||
~confirmations ~predecessors operation_hash
|
~confirmations ~predecessors operation_hash
|
||||||
end ;
|
end ;
|
||||||
|
|
||||||
command ~group:alphanet ~desc: "Fork a test protocol (Alphanet dictator only)."
|
command ~group:alphanet ~desc: "Fork a test protocol (Alphanet dictator only)."
|
||||||
no_options
|
no_options
|
||||||
(prefixes [ "fork" ; "test" ; "protocol" ]
|
(prefixes [ "fork" ; "test" ; "protocol" ]
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
((name tezos_client_alpha_commands)
|
((name tezos_client_alpha_commands)
|
||||||
(public_name tezos-client-alpha-commands)
|
(public_name tezos-client-alpha-commands)
|
||||||
(libraries (tezos-base
|
(libraries (tezos-base
|
||||||
|
tezos-stdlib-unix
|
||||||
tezos-protocol-alpha
|
tezos-protocol-alpha
|
||||||
tezos-protocol-environment
|
tezos-protocol-environment
|
||||||
tezos-shell-services
|
tezos-shell-services
|
||||||
@ -16,6 +17,7 @@
|
|||||||
(flags (:standard -w -9+27-30-32-40@8
|
(flags (:standard -w -9+27-30-32-40@8
|
||||||
-safe-string
|
-safe-string
|
||||||
-open Tezos_base__TzPervasives
|
-open Tezos_base__TzPervasives
|
||||||
|
-open Tezos_stdlib_unix
|
||||||
-open Tezos_shell_services
|
-open Tezos_shell_services
|
||||||
-open Tezos_client_base
|
-open Tezos_client_base
|
||||||
-open Tezos_client_alpha
|
-open Tezos_client_alpha
|
||||||
|
@ -36,7 +36,7 @@ type error += Too_early_double_baking_evidence
|
|||||||
of { level: Raw_level.t ; current: Raw_level.t } (* `Temporary *)
|
of { level: Raw_level.t ; current: Raw_level.t } (* `Temporary *)
|
||||||
type error += Outdated_double_baking_evidence
|
type error += Outdated_double_baking_evidence
|
||||||
of { level: Raw_level.t ; last: Raw_level.t } (* `Permanent *)
|
of { level: Raw_level.t ; last: Raw_level.t } (* `Permanent *)
|
||||||
type error += Invalid_activation
|
type error += Invalid_activation of { pkh : Ed25519.Public_key_hash.t }
|
||||||
type error += Wrong_activation_secret
|
type error += Wrong_activation_secret
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
@ -295,11 +295,14 @@ let () =
|
|||||||
~title:"Invalid activation"
|
~title:"Invalid activation"
|
||||||
~description:"The given key has already been activated or the given \
|
~description:"The given key has already been activated or the given \
|
||||||
key does not correspond to any preallocated contract"
|
key does not correspond to any preallocated contract"
|
||||||
~pp:(fun ppf () ->
|
~pp:(fun ppf pkh ->
|
||||||
Format.fprintf ppf "Invalid activation.")
|
Format.fprintf ppf "Invalid activation. The public key %a does \
|
||||||
Data_encoding.unit
|
not match any commitment."
|
||||||
(function Invalid_activation -> Some () | _ -> None)
|
Ed25519.Public_key_hash.pp pkh
|
||||||
(fun () -> Invalid_activation) ;
|
)
|
||||||
|
Data_encoding.(obj1 (req "pkh" Ed25519.Public_key_hash.encoding))
|
||||||
|
(function Invalid_activation { pkh } -> Some pkh | _ -> None)
|
||||||
|
(fun pkh -> Invalid_activation { pkh } ) ;
|
||||||
register_error_kind
|
register_error_kind
|
||||||
`Permanent
|
`Permanent
|
||||||
~id:"operation.wrong_activation_secret"
|
~id:"operation.wrong_activation_secret"
|
||||||
@ -579,9 +582,9 @@ let apply_anonymous_operation ctxt _delegate origination_nonce kind =
|
|||||||
| Activation { id = pkh ; secret } ->
|
| Activation { id = pkh ; secret } ->
|
||||||
let h_pkh = Unclaimed_public_key_hash.of_ed25519_pkh pkh in
|
let h_pkh = Unclaimed_public_key_hash.of_ed25519_pkh pkh in
|
||||||
Commitment.get_opt ctxt h_pkh >>=? function
|
Commitment.get_opt ctxt h_pkh >>=? function
|
||||||
| None -> fail Invalid_activation
|
| None -> fail (Invalid_activation { pkh })
|
||||||
| Some { blinded_public_key_hash = submitted_bpkh ; amount } ->
|
| Some { blinded_public_key_hash = blinded_pkh ; amount } ->
|
||||||
let blinded_pkh = Blinded_public_key_hash.of_ed25519_pkh secret pkh in
|
let submitted_bpkh = Blinded_public_key_hash.of_ed25519_pkh secret pkh in
|
||||||
fail_unless
|
fail_unless
|
||||||
Blinded_public_key_hash.(blinded_pkh = submitted_bpkh)
|
Blinded_public_key_hash.(blinded_pkh = submitted_bpkh)
|
||||||
Wrong_activation_secret >>=? fun () ->
|
Wrong_activation_secret >>=? fun () ->
|
||||||
|
Loading…
Reference in New Issue
Block a user