1. 引言

前序博客见:

  • Mina中的Scan State
(* prover/prover.ml中有: *)
module Extend_blockchain_input = struct[%%versionedmodule Stable = struct[@@@no_toplevel_latest_type]module V2 = structtype t ={ chain : Blockchain.Stable.V2.t; next_state : Protocol_state.Value.Stable.V2.t; block : Snark_transition.Value.Stable.V2.t; ledger_proof : Ledger_proof.Stable.V2.t option; prover_state : Consensus.Data.Prover_state.Stable.V2.t; pending_coinbase : Pending_coinbase_witness.Stable.V2.t}
(* ledger_proof/ledger_proof.ml中有: *)
module Prod : Ledger_proof_intf.S with type t = Transaction_snark.t = struct[%%versionedmodule Stable = structmodule V2 = structtype t = Transaction_snark.Stable.V2.t
(* transaction_snark/transaction_snark.ml中有: *)
module Stable = structmodule V2 = structtype t ={ statement : Statement.With_sok.Stable.V2.t; proof : Proof.Stable.V2.t }module With_sok = struct[%%versionedmodule Stable = structmodule V2 = structtype t =( Frozen_ledger_hash.Stable.V1.t, Currency.Amount.Stable.V1.t, Pending_coinbase.Stack_versioned.Stable.V1.t, Fee_excess.Stable.V1.t, Sok_message.Digest.Stable.V1.t (* 为string类型 *), Local_state.Stable.V1.t )module Proof = struct[%%versionedmodule Stable = structmodule V2 = structtype t = Pickles.Proof.Branching_2.Stable.V2.t

Verifier端验证transaction_snark的输入为 [ledger_proof, sok_message] 数组:【其中sok_digest=BLAKE2_HASH(sok_message)】

val verify_transaction_snarks :t-> (ledger_proof * Mina_base.Sok_message.t) list-> bool Or_error.t Deferred.t
(* Mina_base.Sok_message.t结构定义为: *)
module Stable = structmodule V1 = structtype t ={ fee : Currency.Fee.Stable.V1.t; prover : Public_key.Compressed.Stable.V1.t}
(* verify_transaction_snarks函数实际实现为: *)let verify_transaction_snarks ts =match Or_error.try_with (fun () -> T.verify ts) with| Ok result ->result| Error e ->[%log error]~metadata:[ ("error", Error_json.error_to_yojson e) ]"Verifier threw an exception while verifying transaction \snark" ;failwith "Verifier crashed"let verify ts =ifList.for_all ts ~f:(fun (p, m) -> (* 【其中sok_digest=BLAKE2_HASH(sok_message)】 *)Sok_message.Digest.equal (Sok_message.digest m) p.statement.sok_digest)thenProof.verify(List.map ts ~f:(fun ({ statement; proof }, _) -> (statement, proof)))else Async.return false
(* Pickles Proof中的verify为: *)
let verify (type a n) (max_branching : (module Nat.Intf with type n = n))(a_value : (module Intf.Statement_value with type t = a))(key : Verification_key.t) (ts : (a * (n, n) Proof.t) list) =verify_heterogenous(List.map ts ~f:(fun (x, p) ->Instance.T (max_branching, a_value, key, x, p)))let verify_heterogenous (ts : Instance.t list) =let module Plonk = Types.Wrap.Proof_state.Deferred_values.Plonk inlet module Tick_field = Backend.Tick.Field inlet tick_field : _ Plonk_checks.field = (module Tick_field) inlet check, result =let r = ref [] inlet result () =match !r with| [] ->Ok ()| _ ->Error(String.concat ~sep:"\n"(List.map !r ~f:(fun lab -> Lazy.force lab)))in((fun (lab, b) -> if not b then r := lab :: !r), result)inlet in_circuit_plonks =List.map ts~f:(fun(T( _max_branching, _statement, key, app_state, T{ statement(* TODO; prev_x_hat = (x_hat1, _) as prev_x_hat*); prev_evals = evals} ))->Timer.start __LOC__ ;let statement ={ statement withpass_through = { statement.pass_through with app_state }}inlet open Types.Wrap.Proof_state inlet sc =SC.to_field_constant tick_field ~endo:Endo.Wrap_inner_curve.scalarinTimer.clock __LOC__ ;let { Deferred_values.xi; plonk = plonk0; combined_inner_product; which_branch; bulletproof_challenges} =Deferred_values.map_challenges ~f:Challenge.Constant.to_tick_field~scalar:sc statement.proof_state.deferred_valuesinlet zeta = sc plonk0.zeta inlet alpha = sc plonk0.alpha inlet step_domains = key.step_domains.(Index.to_int which_branch) inlet w =Tick.Field.domain_generator~log2_size:(Domain.log2_size step_domains.h)inlet zetaw = Tick.Field.mul zeta w inlet tick_plonk_minimal :_ Composition_types.Wrap.Proof_state.Deferred_values.Plonk.Minimal.t=let chal = Challenge.Constant.to_tick_field in{ zeta; alpha; beta = chal plonk0.beta; gamma = chal plonk0.gamma }inlet tick_combined_evals =Plonk_checks.evals_of_split_evals(module Tick.Field)(Double.map evals.evals ~f:(fun e -> e.evals))~rounds:(Nat.to_int Tick.Rounds.n) ~zeta ~zetawinlet tick_domain =Plonk_checks.domain(module Tick.Field)step_domains.h ~shifts:Common.tick_shifts~domain_generator:Backend.Tick.Field.domain_generatorinlet tick_env =Plonk_checks.scalars_env(module Tick.Field)~endo:Endo.Step_inner_curve.base ~mds:Tick_field_sponge.params.mds~srs_length_log2:Common.Max_degree.step_log2~field_of_hex:(fun s ->Kimchi_pasta.Pasta.Bigint256.of_hex_string s|> Kimchi_pasta.Pasta.Fp.of_bigint)~domain:tick_domain tick_plonk_minimal tick_combined_evalsinlet plonk =let p =Plonk_checks.Type1.derive_plonk(module Tick.Field)~shift:Shifts.tick1 ~env:tick_env tick_plonk_minimaltick_combined_evalsin{ p withzeta = plonk0.zeta; alpha = plonk0.alpha; beta = plonk0.beta; gamma = plonk0.gamma}inTimer.clock __LOC__ ;let absorb, squeeze =let open Tick_field_sponge.Bits inlet sponge =let s = create Tick_field_sponge.params inabsorb s(Digest.Constant.to_tick_fieldstatement.proof_state.sponge_digest_before_evaluations) ;sinlet squeeze () =let underlying =Challenge.Constant.of_bits(squeeze sponge ~length:Challenge.Constant.length)insc (Scalar_challenge.create underlying)in(absorb sponge, squeeze)inlet absorb_evals{ Plonk_types.All_evals.With_public_input.public_input = x_hat; evals = e} =let xs, ys = Plonk_types.Evals.to_vectors e inList.iterVector.([| x_hat |] :: (to_list xs @ to_list ys))~f:(Array.iter ~f:absorb)inDouble.(iter ~f:absorb_evals evals.evals) ;absorb evals.ft_eval1 ;let xi_actual = squeeze () inlet r_actual = squeeze () inTimer.clock __LOC__ ;(* TODO: The deferred values "bulletproof_challenges" should get routedinto a "batch dlog Tick acc verifier" *)let actual_branching =Vector.length statement.pass_through.old_bulletproof_challengesinTimer.clock __LOC__ ;let combined_inner_product_actual =Wrap.combined_inner_product ~env:tick_env ~plonk:tick_plonk_minimal~domain:tick_domain ~ft_eval1:evals.ft_eval1~actual_branching:(Nat.Add.create actual_branching)(Double.map evals.evals ~f:(fun e -> e.evals))~x_hat:(Double.map evals.evals ~f:(fun e -> e.public_input))~old_bulletproof_challenges:(Vector.map ~f:Ipa.Step.compute_challengesstatement.pass_through.old_bulletproof_challenges)~r:r_actual ~xi ~zeta ~zetaw ~step_branch_domains:step_domainsinlet check_eq lab x y =check( lazy(sprintf!"%s: %{sexp:Tick_field.t} != %{sexp:Tick_field.t}"lab x y), Tick_field.equal x y )inTimer.clock __LOC__ ;Timer.clock __LOC__ ;List.iter~f:(fun (s, x, y) -> check_eq s x y)(* Both these values can actually be omitted from the proof on the wire since we recompute themanyway. *)[ ("xi", xi, xi_actual); ( "combined_inner_product", Shifted_value.Type1.to_field(module Tick.Field)combined_inner_product ~shift:Shifts.tick1, combined_inner_product_actual )] ;plonk)inlet open Backend.Tock.Proof inlet open Promise.Let_syntax inlet%bind accumulator_check =Ipa.Step.accumulator_check(List.map ts ~f:(fun (T (_, _, _, _, T t)) ->( t.statement.proof_state.me_only.sg, Ipa.Step.compute_challengest.statement.proof_state.deferred_values.bulletproof_challenges )))inCommon.time "batch_step_dlog_check" (fun () ->check (lazy "batch_step_dlog_check", accumulator_check)) ;let%map dlog_check =batch_verify(List.map2_exn ts in_circuit_plonks~f:(fun(T((module Max_branching), (module A_value), key, app_state, T t))plonk->let prepared_statement : _ Types.Wrap.Statement.In_circuit.t ={ pass_through =Common.hash_step_me_only ~app_state:A_value.to_field_elements(Reduced_me_only.Step.prepare~dlog_plonk_index:key.commitments{ t.statement.pass_through with app_state }); proof_state ={ t.statement.proof_state withdeferred_values ={ t.statement.proof_state.deferred_values with plonk }; me_only =Common.hash_dlog_me_only Max_branching.n(Reduced_me_only.Wrap.preparet.statement.proof_state.me_only)}}inlet input =tock_unpadded_public_input_of_statement prepared_statementin( key.index, t.proof, input, Some(Vector.to_list(Vector.map2~f:(fun g cs ->{ Challenge_polynomial.challenges =Vector.to_array (Ipa.Wrap.compute_challenges cs); commitment = g})(Vector.extend_exn t.statement.pass_through.sgMax_branching.n(Lazy.force Dummy.Ipa.Wrap.sg))t.statement.proof_state.me_only.old_bulletproof_challenges)))))inCommon.time "dlog_check" (fun () -> check (lazy "dlog_check", dlog_check)) ;match result () with| Ok () ->true| Error e ->eprintf !"bad verify: %s\n%!" e ;false

1.1 Mina交易结构

当前Mina中支持的交易类型有:

let to_preunion (t : Transaction.t) =match t with| Command (Signed_command x) ->`Transaction (Transaction.Command x)| Fee_transfer x ->`Transaction (Fee_transfer x)| Coinbase x ->`Transaction (Coinbase x)| Command (Parties x) ->`Parties x

Mina中的交易失败类型有:

module Failure = struct[%%versionedmodule Stable = structmodule V2 = structtype t =| Predicate [@value 1]| Source_not_present| Receiver_not_present| Amount_insufficient_to_create_account| Cannot_pay_creation_fee_in_token| Source_insufficient_balance| Source_minimum_balance_violation| Receiver_already_exists| Not_token_owner| Mismatched_token_permissions| Overflow| Signed_command_on_zkapp_account| Zkapp_account_not_present| Update_not_permitted_balance| Update_not_permitted_timing_existing_account| Update_not_permitted_delegate| Update_not_permitted_app_state| Update_not_permitted_verification_key| Update_not_permitted_sequence_state| Update_not_permitted_zkapp_uri| Update_not_permitted_token_symbol| Update_not_permitted_permissions| Update_not_permitted_nonce| Update_not_permitted_voting_for| Parties_replay_check_failed| Fee_payer_nonce_must_increase| Account_precondition_unsatisfied| Protocol_state_precondition_unsatisfied| Incorrect_nonce| Invalid_fee_excess

transaction结构为:

(* transaction结构为: *)
module Stable = structmodule V2 = structtype t = User_command.Stable.V2.t Poly.Stable.V2.t module Poly = struct[%%versionedmodule Stable = structmodule V2 = structtype 'command t = (* 分为:普通的用户签名交易、Fee transfer、coinbase *)| Command of 'command| Fee_transfer of Fee_transfer.Stable.V2.t| Coinbase of Coinbase.Stable.V1.t(* User_command结构为: *)
module Stable = structmodule V2 = structtype t = (Signed_command.Stable.V2.t, Parties.Stable.V1.t) Poly.Stable.V2.t(* Signed_command结构为: *)
module Stable = structmodule V2 = structtype t =( Payload.Stable.V2.t, Public_key.Stable.V1.t, Signature.Stable.V1.t )Poly.Stable.V1.t(* Payload结构为: *)
module Stable = structmodule V2 = structtype t = (Common.Stable.V2.t, Body.Stable.V2.t) Poly.Stable.V1.t
(* Public_key结构为: *)
module Stable = structmodule V1 = structtype t = Field.t * Field.t
(* Signature结构为: *)
module Stable = structmodule V1 = structtype t = (Field.t, Inner_curve.Scalar.t) Signature_poly.Stable.V1.t(* Common结构为: *)
type t =( Currency.Fee.Stable.V1.t, Public_key.Compressed.Stable.V1.t, Account_nonce.Stable.V1.t, Global_slot.Stable.V1.t, Memo.Stable.V1.t ) (* 为string *)Poly.Stable.V2.t
(* Body结构为:根据是普通支付还是质押委托交易,body有所不同 *)
module Stable = structmodule V2 = structtype t = Binable_arg.Stable.V2.t =| Payment of Payment_payload.Stable.V2.t| Stake_delegation of Stake_delegation.Stable.V1.t

transaction_witness结构为:

(* transaction_witness为: *)
module Stable = structmodule V2 = structtype t ={ transaction : Mina_transaction.Transaction.Stable.V2.t; ledger : Mina_ledger.Sparse_ledger.Stable.V2.t; protocol_state_body : Mina_state.Protocol_state.Body.Value.Stable.V2.t; init_stack : Mina_base.Pending_coinbase.Stack_versioned.Stable.V1.t; status : Mina_base.Transaction_status.Stable.V2.t}(* Mina_ledger.Sparse_ledger结构为: *)
module Stable = structmodule V2 = structtype t =( Ledger_hash.Stable.V1.t (* 为Field.t,Tick曲线的 *), Account_id.Stable.V2.t, Account.Stable.V2.t )Sparse_ledger_lib.Sparse_ledger.T.Stable.V2.t
(* account_id结构为: *)
module Stable = structmodule V2 = struct (* 为压缩公钥 和 Pickles.Backend.Tick.Field.Stable.V1.t *)type t = Public_key.Compressed.Stable.V1.t * Digest.Stable.V1.t
(* account结构为: *)
type t =( Public_key.Compressed.Stable.V1.t, Token_id.Stable.V1.t, Token_permissions.Stable.V1.t, Token_symbol.Stable.V1.t, Balance.Stable.V1.t, Nonce.Stable.V1.t, Receipt.Chain_hash.Stable.V1.t, Public_key.Compressed.Stable.V1.t option, State_hash.Stable.V1.t, Timing.Stable.V1.t, Permissions.Stable.V2.t, Zkapp_account.Stable.V2.t option, string )(* TODO: Cache the digest of this? *)Poly.Stable.V2.t
(* Sparse_ledger_lib.Sparse_ledger结构为: *)
type ('hash, 'key, 'account) t ={ indexes : ('key * int) list; depth : int; tree : ('hash, 'account) Tree.Stable.V1.t}
(* Sparse_ledger中的Tree为account tree,其结构为: *)
type ('hash, 'key, 'account) t ={ indexes : ('key * int) list; depth : int; tree : ('hash, 'account) Tree.Stable.V1.t}

2. ledger_proof由snark worker生成

snark worker启动时,其选择的proof_level有3种状态:

  • full
  • check
  • none
module Proof_level = structtype t = Full | Check | None
module Single = structmodule Spec = struct[%%versionedmodule Stable = struct[@@@no_toplevel_latest_type]module V2 = structtype ('witness, 'ledger_proof) t =| Transition of Transaction_snark.Statement.Stable.V2.t * 'witness| Merge ofTransaction_snark.Statement.Stable.V2.t* 'ledger_proof* 'ledger_proof(* bin_io is for uptime service SNARK worker *)type single_spec =( Transaction_witness.Stable.Latest.t, Transaction_snark.Stable.Latest.t )Snark_work_lib.Work.Single.Spec.Stable.Latest.t

ledger_proof由snark worker生成,scan state中的tree中有base snark和merge snark,根据交易类型的不同,采取不同的生成snark proof和ledger proof方案:

(* snark_worker/prod.ml中生成ledger proof和snark proof的流程为: *)
let perform_single ({ m; cache; proof_level } : Worker_state.t) ~message =.......match proof_level with| Genesis_constants.Proof_level.Full -> (........match Cache.find cache statement with| Some proof ->Deferred.Or_error.return (proof, Time.Span.zero)| None -> (match single with| Work.Single.Spec.Transition (input, (w : Transaction_witness.t))->...........match w.transaction with| Command (Parties parties) -> (.........let log_base_snark f ~statement ~spec ~all_inputs =match%map.DeferredDeferred.Or_error.try_with (fun () ->f ~statement ~spec)let log_merge_snark ~sok_digest prev curr ~all_inputs=match%map.DeferredM.merge ~sok_digest prev curr........| _ ->let%bind t =Deferred.return@@(* Validate the received transaction *)match w.transaction with| Command (Signed_command cmd) -> (match Signed_command.check cmd with| Some cmd ->( Ok (Command (Signed_command cmd)): Transaction.Valid.t Or_error.t )| None ->Or_error.errorf"Command has an invalid signature" )| Command (Parties _) ->assert false| Fee_transfer ft ->Ok (Fee_transfer ft)| Coinbase cb ->Ok (Coinbase cb)inDeferred.Or_error.try_with ~here:[%here] (fun () ->M.of_non_parties_transaction~statement:{ input with sok_digest }{ Transaction_protocol_state.Poly.transaction =t; block_data = w.protocol_state_body}~init_stack:w.init_stack(unstage(Mina_ledger.Sparse_ledger.handler w.ledger))))..........)| Merge (_, proof1, proof2) ->process (fun () -> M.merge ~sok_digest proof1 proof2) )........)| Check | None ->(* Use a dummy proof. *)let stmt =match single with| Work.Single.Spec.Transition (stmt, _) ->stmt| Merge (stmt, _, _) ->stmtinDeferred.Or_error.return@@ ( Transaction_snark.create ~statement:{ stmt with sok_digest }~proof:Proof.transaction_dummy, Time.Span.zero )
  • snark worker: main->perform->perform_single,会将base snark或merge snark proof放入Snark_work_lib.Work.Result.proofs中,并提交到snark pool中?
  • 产块者:generate_next_state->Staged_ledger.apply_diff_unchecked->apply_diff->fill_work_and_enqueue_transactions->fill_in_transaction_snark_work->completed_work_to_scanable_work来将snark proof添加到区块内。
    |> Deferred.Or_error.map ~f:(function| `One (proof1, metrics1) ->{ Snark_work_lib.Work.Result.proofs = `One proof1; metrics = `One metrics1; spec; prover = public_key}| `Two ((proof1, metrics1), (proof2, metrics2)) ->{ Snark_work_lib.Work.Result.proofs = `Two (proof1, proof2); metrics = `Two (metrics1, metrics2); spec; prover = public_key})

2.1 Parties交易proof生成

所谓Parties交易,是指为支持zkApps智能合约创建的交易类型。
对于Parties交易类型,生成proof的方案为:【分为log_base_snarklog_merge_snark

                       match witnesses_specs_stmts with| [] ->Deferred.Or_error.error_string"no witnesses generated"| (witness, spec, stmt, snapp_statement) :: rest asinputs ->let%bind (p1 : Ledger_proof.t) =log_base_snark~statement:{ stmt with sok_digest } ~spec~all_inputs:inputs(M.of_parties_segment_exn ~snapp_statement~witness)inlet%map (p : Ledger_proof.t) =Deferred.List.fold ~init:(Ok p1) rest~f:(funacc(witness, spec, stmt, snapp_statement)->let%bind (prev : Ledger_proof.t) =Deferred.return accinlet%bind (curr : Ledger_proof.t) =log_base_snark~statement:{ stmt with sok_digest }~spec ~all_inputs:inputs(M.of_parties_segment_exn~snapp_statement ~witness)inlog_merge_snark ~sok_digest prev curr~all_inputs:inputs)

对于Parties交易,会调用Pickles proof system相关证明接口:

let of_parties_segment_exn ~statement ~snapp_statement ~witness~(spec : Parties_segment.Basic.t) : t Async.Deferred.t =Base.Parties_snark.witness := Some witness ;let res =match spec with| Opt_signed ->opt_signed [] statement| Opt_signed_unsigned ->opt_signed_unsigned [] statement| Opt_signed_opt_signed ->opt_signed_opt_signed [] statement| Proved -> (match snapp_proof_data ~snapp_statement ~witness with| None ->failwith "of_parties_segment: Expected exactly one proof"| Some (s, p, v, tag) ->(* TODO: We should not have to pass the statement in here. *)proved( Pickles.Side_loaded.in_prover (Base.side_loaded tag) v.data ;[ (s, p) ] )statement )inlet open Async inlet%map proof = res inBase.Parties_snark.witness := None ;{ proof; statement }

2.2 非Parties交易proof生成

非Parties交易是指用户签名交易、给snark worker的fee交易 以及 给产块者奖励的coinbase交易。

                         match w.transaction with| Command (Signed_command cmd) -> (match Signed_command.check cmd with| Some cmd ->( Ok (Command (Signed_command cmd)): Transaction.Valid.t Or_error.t )| None ->Or_error.errorf"Command has an invalid signature" )| Command (Parties _) ->assert false| Fee_transfer ft ->Ok (Fee_transfer ft)| Coinbase cb ->Ok (Coinbase cb)inDeferred.Or_error.try_with ~here:[%here] (fun () ->M.of_non_parties_transaction~statement:{ input with sok_digest }{ Transaction_protocol_state.Poly.transaction =t; block_data = w.protocol_state_body}~init_stack:w.init_stack(unstage(Mina_ledger.Sparse_ledger.handler w.ledger)))

非Parties交易生成proof方案为:

let of_non_parties_transaction ~statement ~init_stack transaction_in_blockhandler =let transaction : Transaction.t =Transaction.forget(Transaction_protocol_state.transaction transaction_in_block)inlet state_body =Transaction_protocol_state.block_data transaction_in_blockinmatch to_preunion transaction with| `Parties _ ->failwith "Called Non-parties transaction with parties transaction"| `Transaction t ->of_transaction_union ~statement ~init_stack(Transaction_union.of_transaction t)state_body handlerlet of_transaction_union ~statement ~init_stack transaction state_body handler=let open Async inlet%map proof =base []~handler:(Base.transaction_union_handler handler transaction state_bodyinit_stack)statementin{ statement; proof }let transaction_union_handler handler (transaction : Transaction_union.t)(state_body : Mina_state.Protocol_state.Body.Value.t)(init_stack : Pending_coinbase.Stack.t) :Snarky_backendless.Request.request -> _ =fun (With { request; respond } as r) ->match request with| Transaction ->respond (Provide transaction)| State_body ->respond (Provide state_body)| Init_stack ->respond (Provide init_stack)| _ ->handler r

of_transaction_union函数中的base会调用Pickles proof system相关证明接口:

let system ~proof_level ~constraint_constants =time "Transaction_snark.system" (fun () ->Pickles.compile ~cache:Cache_dir.cache(module Statement.With_sok.Checked)(module Statement.With_sok)~typ:Statement.With_sok.typ~branches:(module Nat.N6)~max_branching:(module Nat.N2)~name:"transaction-snark"~constraint_constants:(Genesis_constants.Constraint_constants.to_snark_keys_headerconstraint_constants)~choices:(fun ~self ->let parties x =Base.Parties_snark.rule ~constraint_constants ~proof_level xin[ Base.rule ~constraint_constants; Merge.rule ~proof_level self; parties Opt_signed_unsigned; parties Opt_signed_opt_signed; parties Opt_signed; parties Proved]))let compile ?self ?cache ?disk_keys a_var a_value ~typ ~branches ~max_branching~name ~constraint_constants ~choices =let self, cache_handle, proof_module, provers =compile_promise ?self ?cache ?disk_keys a_var a_value ~typ ~branches~max_branching ~name ~constraint_constants ~choicesinlet rec adjust_provers :type a1 a2 a3 s1 s2_inner.(a1, a2, a3, s1, s2_inner Promise.t) H3_2.T(Prover).t-> (a1, a2, a3, s1, s2_inner Deferred.t) H3_2.T(Prover).t = function| [] ->[]| prover :: tl ->(fun ?handler stmt_with_proof public_input ->Promise.to_deferred (prover ?handler stmt_with_proof public_input)):: adjust_provers tlin(self, cache_handle, proof_module, adjust_provers provers)

附录1. Mina系列博客

Mina系列博客有:

  • Mina概览
  • Mina的支付流程
  • Mina的zkApp
  • Mina中的Pasta(Pallas和Vesta)曲线
  • Mina中的Schnorr signature
  • Mina中的Pickles SNARK
  • Mina中的Kimchi SNARK
  • Mina Kimchi SNARK 代码解析
  • Mina Berkeley QANet测试网zkApp初体验
  • Mina中的Poseidon hash
  • Mina中的多项式承诺方案
  • Recursive SNARKs总览
  • Mina技术白皮书
  • Mina代码解析
  • Mina中的Snark Worker
  • Mina中的Scan State
  • Mina中的VRF
  • Mina中的delta_transition_chain_proof/delta_block_chain_proof
  • Mina中的stake delegation
  • Mina如何实现22KB?
  • Mina中的stake_proof
  • Mina中的genesis_proof
  • Mina中的交易及经济白皮书

Mina中的ledger proof相关推荐

  1. Mina中的zkApp交易snark

    1. 引言 前序博客有: Mina中的支付交易snark(针对Payment交易) Mina的zkApp Mina中的树结构 --账号树 Mina中的user_command交易目前有: 1)Sign ...

  2. Mina中的支付交易snark

    1. 引言 前序博客有: Mina的支付流程 Mina中目前的交易类型主要有: Coinbase交易:给产块者激励和手续费的交易,为内部交易. Fee_transfer交易:给snark worker ...

  3. Mina中的wrap snark

    1. 引言 前序博客有: Mina技术白皮书 所谓wrap snark,是将Tick snark(Mina代码中称为step proof)包裹为Tock snark(Mina代码中称为wrap pro ...

  4. Mina中的区块证明

    1. 引言 Mina的Pickles支持2种类型的tag: Side_loaded Compiled type ('var, 'value, 'n1, 'n2) t ={ kind : kind; i ...

  5. Mina中的Snark Worker

    1. 引言 Mina系列博客有: Mina概览 Mina的支付流程 Mina的zkApp Mina中的Pasta(Pallas和Vesta)曲线 Mina中的Schnorr signature Min ...

  6. Mina中的Kimchi SNARK

    1. 引言 Mina系列博客有: Mina概览 Mina的支付流程 Mina的zkApp Mina中的Pasta(Pallas和Vesta)曲线 Mina中的Schnorr signature Min ...

  7. Mina中的Pickles SNARK

    1. 引言 Mina系列博客有: Mina概览 Mina的支付流程 Mina的zkApp Mina中的Pasta(Pallas和Vesta)曲线 Mina中的Schnorr signature 视频可 ...

  8. mina 中的IoBufer(一)

    为什么80%的码农都做不了架构师?>>>    IoBuffer 是 MINA 中的独有接口,主要继承实现的是 java NIO 中的 ByteBuffer ,所以从使用方法上来看二 ...

  9. 从Jetty、Tomcat和Mina中提炼NIO构架网络服务器的经典模式(三)

    2019独角兽企业重金招聘Python工程师标准>>> 从Jetty.Tomcat和Mina中提炼NIO构架网络服务器的经典模式(三) 博客分类: java 最后我们再看看NIO方面 ...

  10. Mina中的Pasta(Pallas和Vesta)曲线

    1. 引言 Mina系列博客有: Mina概览 Mina的支付流程 Mina的zkApp Mina采用Zcash团队发明的Pallas curve和Vesta curve(统称为Pasta曲线).其中 ...

最新文章

  1. matlab导入txt数据_如何正确的将txt文本数据导入到Word中使用?
  2. vbs画动态爱心代码_前端必看之如何用CSS3画一个八卦和爱心
  3. angular中的依赖注入
  4. C++学习成长的四个层次
  5. ​凌云KTV点歌系统功能简介
  6. php 接口安全解决方案,php接口数据安全解决方案(一)
  7. JVM学习-垃圾回收调优
  8. 谈现代企业中(一)菜鸟和大牛
  9. phpStorm 2017.3.1,WebStorm 2017.3.4 最新版本免费注册激活方法
  10. configure: error: C compiler cannot create executables
  11. 项目操作案例丨西门子PLC通过网关连接ACS800变频器
  12. C#实现百度地图附近搜索调用JavaScript函数
  13. 机器学习基本 之 名词解释
  14. 基于springboot+vue的戒毒所人员管理系统 毕业设计-附源码251514
  15. VUE学习(一)、创建一个Vue应用。
  16. 每日一句:day04——From Zero To Hero
  17. FPGA在AI时代的角色
  18. 删除你的所有计算机文件的英文,删除Download和DataStore文件夹中的所有文件
  19. 计算机软件里的字体,软件里面的字体大小
  20. 创新数据库技术 成就IOD愿景携DB2 25载创新 IBM推新“信息议程”

热门文章

  1. android实现推箱子代码,android开发--推箱子小游戏(二)
  2. IllegalArgumentException异常
  3. NYOJ - 小柯的编译器
  4. 计算机数字键盘无法输入数字,键盘无法输入,键盘数字键打不出来
  5. win7桌面图标箭头怎么去掉
  6. 10 款新鲜出炉的jQuery UI插件
  7. NOIP2015 口胡题解
  8. Puppeteer开发过程中遇到的问题及解决方案
  9. 健脾和胃,养生食疗——山药枸杞鲫鱼汤了解一下
  10. 如何利用Python开发App?