2016-09-08 21:13:10 +04:00
|
|
|
(**************************************************************************)
|
|
|
|
(* *)
|
2018-02-06 00:17:03 +04:00
|
|
|
(* Copyright (c) 2014 - 2018. *)
|
2016-09-08 21:13:10 +04:00
|
|
|
(* Dynamic Ledger Solutions, Inc. <contact@tezos.com> *)
|
|
|
|
(* *)
|
|
|
|
(* All rights reserved. No warranty, explicit or implicit, provided. *)
|
|
|
|
(* *)
|
|
|
|
(**************************************************************************)
|
|
|
|
|
2018-01-29 04:06:47 +04:00
|
|
|
open Proto_alpha
|
2018-02-11 22:17:39 +04:00
|
|
|
open Alpha_context
|
2017-11-27 09:13:12 +04:00
|
|
|
open Tezos_micheline
|
2016-09-08 21:13:10 +04:00
|
|
|
open Client_proto_contracts
|
|
|
|
open Client_keys
|
|
|
|
|
2018-02-11 22:17:40 +04:00
|
|
|
let get_balance (rpc : #Proto_alpha.rpc_context) block contract =
|
2018-02-11 22:17:40 +04:00
|
|
|
Alpha_services.Contract.balance rpc block contract
|
2017-03-15 04:20:25 +04:00
|
|
|
|
2018-02-11 22:17:40 +04:00
|
|
|
let get_storage (rpc : #Proto_alpha.rpc_context) block contract =
|
2018-02-11 22:17:40 +04:00
|
|
|
Alpha_services.Contract.storage_opt rpc block contract
|
2017-07-24 17:57:03 +04:00
|
|
|
|
2017-11-04 03:16:05 +04:00
|
|
|
let parse_expression arg =
|
|
|
|
Lwt.return
|
|
|
|
(Micheline_parser.no_parsing_error
|
|
|
|
(Michelson_v1_parser.parse_expression arg))
|
|
|
|
|
2018-04-22 12:50:34 +04:00
|
|
|
let append_reveal
|
|
|
|
cctxt block
|
|
|
|
~source ~src_pk ops =
|
|
|
|
Alpha_services.Contract.manager_key cctxt block source >>=? fun (_pkh, pk) ->
|
|
|
|
let is_reveal = function
|
|
|
|
| Reveal _ -> true
|
|
|
|
| _ -> false in
|
|
|
|
match pk with
|
|
|
|
| None when not (List.exists is_reveal ops) ->
|
|
|
|
return (Reveal src_pk :: ops)
|
|
|
|
| _ -> return ops
|
2018-04-19 18:32:32 +04:00
|
|
|
|
2018-03-24 19:39:48 +04:00
|
|
|
let transfer (cctxt : #Proto_alpha.full)
|
2018-04-22 12:50:34 +04:00
|
|
|
block ?confirmations
|
|
|
|
?branch ~source ~src_pk ~src_sk ~destination ?arg
|
|
|
|
~amount ~fee ?(gas_limit = Z.minus_one) () =
|
2016-09-08 21:13:10 +04:00
|
|
|
begin match arg with
|
|
|
|
| Some arg ->
|
2017-11-04 03:16:05 +04:00
|
|
|
parse_expression arg >>=? fun { expanded = arg } ->
|
2017-11-02 21:57:17 +04:00
|
|
|
return (Some arg)
|
2017-04-05 12:22:41 +04:00
|
|
|
| None -> return None
|
|
|
|
end >>=? fun parameters ->
|
2018-02-11 22:17:40 +04:00
|
|
|
Alpha_services.Contract.counter
|
2018-02-08 22:00:01 +04:00
|
|
|
cctxt block source >>=? fun pcounter ->
|
2016-09-08 21:13:10 +04:00
|
|
|
let counter = Int32.succ pcounter in
|
2018-04-22 12:50:34 +04:00
|
|
|
let operations = [Transaction { amount ; parameters ; destination }] in
|
|
|
|
append_reveal cctxt block ~source ~src_pk operations >>=? fun operations ->
|
|
|
|
let contents =
|
2018-04-16 02:44:19 +04:00
|
|
|
Sourced_operation
|
2018-04-22 12:50:34 +04:00
|
|
|
(Manager_operations { source ; fee ; counter ;
|
|
|
|
gas_limit ; operations }) in
|
|
|
|
Injection.inject_operation cctxt block ?confirmations
|
|
|
|
?branch ~src_sk contents >>=? fun (_oph, _op, result as res) ->
|
|
|
|
Lwt.return (Injection.originated_contracts result) >>=? fun contracts ->
|
|
|
|
return (res, contracts)
|
2017-02-16 22:01:35 +04:00
|
|
|
|
2018-02-22 01:19:21 +04:00
|
|
|
let reveal cctxt
|
2018-04-22 12:50:34 +04:00
|
|
|
block ?confirmations
|
|
|
|
?branch ~source ~src_pk ~src_sk ~fee () =
|
2018-02-22 01:19:21 +04:00
|
|
|
Alpha_services.Contract.counter cctxt block source >>=? fun pcounter ->
|
|
|
|
let counter = Int32.succ pcounter in
|
2018-04-22 12:50:34 +04:00
|
|
|
append_reveal cctxt block ~source ~src_pk [] >>=? fun operations ->
|
|
|
|
match operations with
|
|
|
|
| [] ->
|
|
|
|
failwith "The manager key was previously revealed."
|
|
|
|
| _ :: _ ->
|
|
|
|
let gas_limit = Z.zero in
|
|
|
|
let contents =
|
2018-04-16 02:44:19 +04:00
|
|
|
Sourced_operation
|
2018-04-22 12:50:34 +04:00
|
|
|
(Manager_operations { source ; fee ; counter ;
|
|
|
|
gas_limit ; operations }) in
|
|
|
|
Injection.inject_operation cctxt block ?confirmations
|
|
|
|
?branch ~src_sk contents >>=? fun res ->
|
|
|
|
return res
|
|
|
|
|
|
|
|
let originate
|
|
|
|
cctxt block ?confirmations
|
|
|
|
?branch ~source ~src_pk ~src_sk ~fee ?(gas_limit = Z.minus_one) origination =
|
|
|
|
Alpha_services.Contract.counter cctxt block source >>=? fun pcounter ->
|
|
|
|
let counter = Int32.succ pcounter in
|
|
|
|
let operations = [origination] in
|
|
|
|
append_reveal
|
|
|
|
cctxt block ~source ~src_pk operations >>=? fun operations ->
|
|
|
|
let contents =
|
2018-04-16 02:44:19 +04:00
|
|
|
Sourced_operation
|
2018-04-22 12:50:34 +04:00
|
|
|
(Manager_operations { source ; fee ; counter ;
|
|
|
|
gas_limit ; operations }) in
|
|
|
|
Injection.inject_operation cctxt block ?confirmations
|
|
|
|
?branch ~src_sk contents >>=? fun (_oph, _op, result as res) ->
|
|
|
|
Lwt.return (Injection.originated_contracts result) >>=? function
|
|
|
|
| [ contract ] -> return (res, contract)
|
2018-04-19 18:32:32 +04:00
|
|
|
| contracts ->
|
2017-04-06 00:33:46 +04:00
|
|
|
failwith
|
|
|
|
"The origination introduced %d contracts instead of one."
|
|
|
|
(List.length contracts)
|
2016-09-08 21:13:10 +04:00
|
|
|
|
2018-04-22 12:50:34 +04:00
|
|
|
let originate_account
|
|
|
|
cctxt block ?confirmations
|
|
|
|
?branch ~source ~src_pk ~src_sk ~manager_pkh
|
|
|
|
?(delegatable = false) ?delegate ~balance ~fee () =
|
|
|
|
let origination =
|
|
|
|
Origination { manager = manager_pkh ;
|
|
|
|
delegate ;
|
|
|
|
script = None ;
|
|
|
|
spendable = true ;
|
|
|
|
delegatable ;
|
|
|
|
credit = balance ;
|
|
|
|
preorigination = None } in
|
|
|
|
originate
|
|
|
|
cctxt block ?confirmations
|
|
|
|
?branch ~source ~gas_limit:Z.zero~src_pk ~src_sk ~fee origination
|
2017-02-28 05:48:51 +04:00
|
|
|
|
2018-02-08 22:00:01 +04:00
|
|
|
let delegate_contract cctxt
|
2018-04-22 12:50:34 +04:00
|
|
|
block ?branch ?confirmations
|
|
|
|
~source ~src_pk ~src_sk
|
2017-03-21 18:19:35 +04:00
|
|
|
~fee delegate_opt =
|
2018-02-11 22:17:40 +04:00
|
|
|
Alpha_services.Contract.counter
|
2018-02-08 22:00:01 +04:00
|
|
|
cctxt block source >>=? fun pcounter ->
|
2017-03-21 18:19:35 +04:00
|
|
|
let counter = Int32.succ pcounter in
|
2018-04-22 12:50:34 +04:00
|
|
|
let operations = [Delegation delegate_opt] in
|
|
|
|
append_reveal
|
|
|
|
cctxt block ~source ~src_pk operations >>=? fun operations ->
|
|
|
|
let contents =
|
2018-04-16 02:44:19 +04:00
|
|
|
Sourced_operation
|
2018-04-22 12:50:34 +04:00
|
|
|
(Manager_operations { source ; fee ; counter ;
|
|
|
|
gas_limit = Z.zero ; operations }) in
|
|
|
|
Injection.inject_operation cctxt block ?confirmations
|
|
|
|
?branch ~src_sk contents >>=? fun res ->
|
|
|
|
return res
|
|
|
|
|
|
|
|
let list_contract_labels
|
|
|
|
(cctxt : #Proto_alpha.full)
|
|
|
|
block =
|
|
|
|
Alpha_services.Contract.list cctxt block >>=? fun contracts ->
|
2017-04-06 00:33:46 +04:00
|
|
|
map_s (fun h ->
|
2018-02-21 21:08:09 +04:00
|
|
|
begin match Contract.is_implicit h with
|
2017-04-06 00:33:46 +04:00
|
|
|
| Some m -> begin
|
|
|
|
Public_key_hash.rev_find cctxt m >>=? function
|
|
|
|
| None -> return ""
|
|
|
|
| Some nm ->
|
|
|
|
RawContractAlias.find_opt cctxt nm >>=? function
|
|
|
|
| None -> return (" (known as " ^ nm ^ ")")
|
|
|
|
| Some _ -> return (" (known as key:" ^ nm ^ ")")
|
|
|
|
end
|
|
|
|
| None -> begin
|
|
|
|
RawContractAlias.rev_find cctxt h >>=? function
|
|
|
|
| None -> return ""
|
|
|
|
| Some nm -> return (" (known as " ^ nm ^ ")")
|
|
|
|
end
|
|
|
|
end >>=? fun nm ->
|
2018-02-21 21:08:09 +04:00
|
|
|
let kind = match Contract.is_implicit h with
|
|
|
|
| Some _ -> " (implicit)"
|
2017-04-06 00:33:46 +04:00
|
|
|
| None -> "" in
|
|
|
|
let h_b58 = Contract.to_b58check h in
|
|
|
|
return (nm, h_b58, kind))
|
|
|
|
contracts
|
|
|
|
|
2018-02-16 21:10:18 +04:00
|
|
|
let message_added_contract (cctxt : #Proto_alpha.full) name =
|
2017-11-07 20:38:11 +04:00
|
|
|
cctxt#message "Contract memorized as %s." name
|
2017-04-06 00:33:46 +04:00
|
|
|
|
2018-04-22 12:50:34 +04:00
|
|
|
let get_manager
|
|
|
|
(cctxt : #Proto_alpha.full)
|
|
|
|
block source =
|
2017-04-06 00:33:46 +04:00
|
|
|
Client_proto_contracts.get_manager
|
2017-11-07 20:38:11 +04:00
|
|
|
cctxt block source >>=? fun src_pkh ->
|
2017-04-06 00:33:46 +04:00
|
|
|
Client_keys.get_key cctxt src_pkh >>=? fun (src_name, src_pk, src_sk) ->
|
|
|
|
return (src_name, src_pkh, src_pk, src_sk)
|
2017-02-27 21:24:26 +04:00
|
|
|
|
2018-04-22 12:50:34 +04:00
|
|
|
let dictate rpc_config block ?confirmations command src_sk =
|
2018-04-16 02:44:19 +04:00
|
|
|
let contents = Sourced_operation (Dictator_operation command) in
|
2018-04-22 12:50:34 +04:00
|
|
|
Injection.inject_operation
|
|
|
|
rpc_config block ?confirmations
|
|
|
|
~src_sk contents >>=? fun res ->
|
|
|
|
return res
|
2017-05-19 07:14:14 +04:00
|
|
|
|
2018-04-22 12:50:34 +04:00
|
|
|
let set_delegate cctxt block ?confirmations ~fee contract ~src_pk ~manager_sk opt_delegate =
|
2017-11-07 20:38:11 +04:00
|
|
|
delegate_contract
|
2018-04-22 12:50:34 +04:00
|
|
|
cctxt block ?confirmations ~source:contract ~src_pk ~src_sk:manager_sk ~fee opt_delegate
|
2017-11-07 20:38:11 +04:00
|
|
|
|
2018-04-22 12:50:34 +04:00
|
|
|
let register_as_delegate cctxt block ?confirmations ~fee ~manager_sk src_pk =
|
2018-04-05 19:35:35 +04:00
|
|
|
let source = Signature.Public_key.hash src_pk in
|
2018-02-22 01:36:36 +04:00
|
|
|
delegate_contract
|
2018-04-22 12:50:34 +04:00
|
|
|
cctxt block ?confirmations
|
|
|
|
~source:(Contract.implicit_contract source) ~src_pk ~src_sk:manager_sk ~fee
|
2018-02-22 01:36:36 +04:00
|
|
|
(Some source)
|
|
|
|
|
2018-02-16 21:10:18 +04:00
|
|
|
let source_to_keys (wallet : #Proto_alpha.full) block source =
|
2017-11-07 20:38:11 +04:00
|
|
|
get_manager wallet block source >>=? fun (_src_name, _src_pkh, src_pk, src_sk) ->
|
|
|
|
return (src_pk, src_sk)
|
|
|
|
|
|
|
|
let save_contract ~force cctxt alias_name contract =
|
|
|
|
RawContractAlias.add ~force cctxt alias_name contract >>=? fun () ->
|
|
|
|
message_added_contract cctxt alias_name >>= fun () ->
|
|
|
|
return ()
|
|
|
|
|
|
|
|
let originate_contract
|
2018-04-22 12:50:34 +04:00
|
|
|
(cctxt : #Proto_alpha.full)
|
|
|
|
block ?confirmations ?branch
|
2017-11-07 20:38:11 +04:00
|
|
|
~fee
|
2018-03-24 19:39:48 +04:00
|
|
|
?gas_limit
|
2017-11-07 20:38:11 +04:00
|
|
|
~delegate
|
|
|
|
?(delegatable=true)
|
|
|
|
?(spendable=false)
|
|
|
|
~initial_storage
|
|
|
|
~manager
|
|
|
|
~balance
|
|
|
|
~source
|
|
|
|
~src_pk
|
|
|
|
~src_sk
|
|
|
|
~code
|
2018-04-22 12:50:34 +04:00
|
|
|
() =
|
2017-11-07 20:38:11 +04:00
|
|
|
Lwt.return (Michelson_v1_parser.parse_expression initial_storage) >>= fun result ->
|
|
|
|
Lwt.return (Micheline_parser.no_parsing_error result) >>=?
|
|
|
|
fun { Michelson_v1_parser.expanded = storage } ->
|
2018-04-22 12:50:34 +04:00
|
|
|
let origination =
|
|
|
|
Origination { manager ;
|
|
|
|
delegate ;
|
|
|
|
script = Some { code ; storage } ;
|
|
|
|
spendable ;
|
|
|
|
delegatable ;
|
|
|
|
credit = balance ;
|
|
|
|
preorigination = None } in
|
|
|
|
originate cctxt block ?confirmations
|
|
|
|
?branch ~source ~src_pk ~src_sk ~fee ?gas_limit origination
|
2018-04-17 12:50:23 +04:00
|
|
|
|
|
|
|
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)
|
2018-05-26 15:38:07 +04:00
|
|
|
?(encrypted = false) ?confirmations ?force block key name =
|
2018-04-17 12:50:23 +04:00
|
|
|
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 () ->
|
2018-04-22 12:50:34 +04:00
|
|
|
let contents =
|
|
|
|
Anonymous_operations
|
|
|
|
[ Activation { id = key.pkh ; secret = key.secret } ] in
|
|
|
|
Injection.inject_operation cctxt ?confirmations block contents >>=? fun (_oph, _op, _result as res) ->
|
2018-05-26 15:22:47 +04:00
|
|
|
let pk_uri = Tezos_signer_backends.Unencrypted.make_pk pk in
|
2018-05-26 15:38:07 +04:00
|
|
|
begin
|
|
|
|
if encrypted then
|
|
|
|
Tezos_signer_backends.Encrypted.encrypt cctxt sk
|
|
|
|
else
|
|
|
|
return (Tezos_signer_backends.Unencrypted.make_sk sk)
|
|
|
|
end >>=? fun sk_uri ->
|
2018-04-22 12:50:34 +04:00
|
|
|
Client_keys.register_key cctxt ?force (pkh, pk_uri, sk_uri) name >>=? fun () ->
|
2018-04-17 12:50:23 +04:00
|
|
|
begin
|
|
|
|
match confirmations with
|
|
|
|
| None ->
|
|
|
|
return ()
|
2018-04-22 12:50:34 +04:00
|
|
|
| Some _confirmations ->
|
2018-04-17 12:50:23 +04:00
|
|
|
Alpha_services.Contract.balance
|
2018-04-22 12:50:34 +04:00
|
|
|
cctxt (`Head 0)
|
|
|
|
(Contract.implicit_contract pkh) >>=? fun balance ->
|
2018-04-17 12:50:23 +04:00
|
|
|
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 ()
|
2018-04-22 12:50:34 +04:00
|
|
|
end >>=? fun () ->
|
|
|
|
return res
|
2018-04-17 12:50:23 +04:00
|
|
|
|