Zeth - Zerocash on Ethereum  0.8
Reference implementation of the Zeth protocol by Clearmatics
Public Member Functions | Static Public Member Functions | Public Attributes | List of all members
zeth.core.mixer_client.MixerClient Class Reference

Public Member Functions

def __init__ (self, Any web3, ProverConfiguration prover_config, Any mixer_instance)
 
str deposit (self, ProverClient prover_client, MerkleTree mk_tree, ZethAddress zeth_address, str sender_eth_address, Optional[bytes] sender_eth_private_key, EtherValue eth_amount, Optional[List[Tuple[ZethAddressPub, EtherValue]]] outputs=None, Optional[EtherValue] tx_value=None)
 
str joinsplit (self, ProverClient prover_client, MerkleTree mk_tree, OwnershipKeyPair sender_ownership_keypair, str sender_eth_address, Optional[bytes] sender_eth_private_key, List[Tuple[int, api.ZethNote]] inputs, List[Tuple[ZethAddressPub, EtherValue]] outputs, EtherValue v_in, EtherValue v_out, Optional[EtherValue] tx_value=None, Optional[ComputeHSigCB] compute_h_sig_cb=None)
 
str mix (self, MixParameters mix_params, str sender_eth_address, Optional[bytes] sender_eth_private_key, EtherValue tx_value, Optional[int] call_gas=None)
 
bool mix_call (self, MixParameters mix_params, str sender_eth_address, EtherValue tx_value, Optional[int] call_gas=None)
 
MixParameters create_mix_parameters_from_proof (self, MixCallDescription mix_call_desc, api.ProofInputs prover_inputs, signing.SigningKeyPair signing_keypair, ExtendedProof ext_proof, List[int] public_data, str sender_eth_address, bool for_dispatch_call=False)
 
Tuple[MixParameters, JoinsplitSigKeyPaircreate_mix_parameters_and_signing_key (self, ProverClient prover_client, MerkleTree mk_tree, OwnershipKeyPair sender_ownership_keypair, str sender_eth_address, List[Tuple[int, api.ZethNote]] inputs, List[Tuple[ZethAddressPub, EtherValue]] outputs, EtherValue v_in, EtherValue v_out, Optional[ComputeHSigCB] compute_h_sig_cb=None, bool for_dispatch_call=False)
 

Static Public Member Functions

Tuple[MixerClient, contracts.InstanceDescriptiondeploy (Any web3, ProverClient prover_client, str deployer_eth_address, Optional[bytes] deployer_eth_private_key, Optional[str] token_address=None, Optional[str] permitted_dispatcher=None, Optional[str] vk_hash=None, Optional[int] deploy_gas=None)
 
Tuple[api.ProofInputs, signing.SigningKeyPaircreate_prover_inputs (MixCallDescription mix_call_desc)
 

Public Attributes

 web3
 
 prover_config
 
 mixer_instance
 

Detailed Description

Interface to operations on the Mixer contract.

Definition at line 259 of file mixer_client.py.

Constructor & Destructor Documentation

◆ __init__()

def zeth.core.mixer_client.MixerClient.__init__ (   self,
Any  web3,
ProverConfiguration  prover_config,
Any  mixer_instance 
)

Definition at line 263 of file mixer_client.py.

263  def __init__(
264  self,
265  web3: Any,
266  prover_config: ProverConfiguration,
267  mixer_instance: Any):
268  self.web3 = web3
269  self.prover_config = prover_config
270  self.mixer_instance = mixer_instance
271 

Member Function Documentation

◆ create_mix_parameters_and_signing_key()

Tuple[MixParameters, JoinsplitSigKeyPair] zeth.core.mixer_client.MixerClient.create_mix_parameters_and_signing_key (   self,
ProverClient  prover_client,
MerkleTree  mk_tree,
OwnershipKeyPair  sender_ownership_keypair,
str  sender_eth_address,
List[Tuple[int, api.ZethNote]]  inputs,
List[Tuple[ZethAddressPub, EtherValue]]  outputs,
EtherValue  v_in,
EtherValue  v_out,
Optional[ComputeHSigCB]   compute_h_sig_cb = None,
bool   for_dispatch_call = False 
)
Convenience function around creation of MixCallDescription, ProofInputs,
Proof and MixParameters. If for_dispatch_call is set, the parameters
are to be passed to the Mixer's `dispatch` call in a later operation
(in which proof data is not available), hence proof is omitted from
the signature.

Definition at line 545 of file mixer_client.py.

545  def create_mix_parameters_and_signing_key(
546  self,
547  prover_client: ProverClient,
548  mk_tree: MerkleTree,
549  sender_ownership_keypair: OwnershipKeyPair,
550  sender_eth_address: str,
551  inputs: List[Tuple[int, api.ZethNote]],
552  outputs: List[Tuple[ZethAddressPub, EtherValue]],
553  v_in: EtherValue,
554  v_out: EtherValue,
555  compute_h_sig_cb: Optional[ComputeHSigCB] = None,
556  for_dispatch_call: bool = False
557  ) -> Tuple[MixParameters, JoinsplitSigKeyPair]:
558  """
559  Convenience function around creation of MixCallDescription, ProofInputs,
560  Proof and MixParameters. If for_dispatch_call is set, the parameters
561  are to be passed to the Mixer's `dispatch` call in a later operation
562  (in which proof data is not available), hence proof is omitted from
563  the signature.
564  """
565  # Generate prover inputs and signing key
566  mix_call_desc = MixCallDescription(
567  mk_tree,
568  sender_ownership_keypair,
569  inputs,
570  outputs,
571  v_in,
572  v_out,
573  compute_h_sig_cb)
574  assert len(mix_call_desc.inputs) == constants.JS_INPUTS
575  assert len(mix_call_desc.outputs) == constants.JS_OUTPUTS
576 
577  prover_inputs, signing_keypair = MixerClient.create_prover_inputs(
578  mix_call_desc)
579 
580  # pylint: disable=no-member
581  assert len(prover_inputs.js_inputs) == constants.JS_INPUTS
582  assert len(prover_inputs.js_outputs) == constants.JS_OUTPUTS
583  # pylint: enable=no-member
584 
585  # Query the prover-server for the related proof
586  ext_proof, public_data = prover_client.get_proof(prover_inputs)
587 
588  # Create the final MixParameters object
589  mix_params = self.create_mix_parameters_from_proof(
590  mix_call_desc,
591  prover_inputs,
592  signing_keypair,
593  ext_proof,
594  public_data,
595  sender_eth_address,
596  for_dispatch_call)
597 
598  return mix_params, signing_keypair
599 
600 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_mix_parameters_from_proof()

MixParameters zeth.core.mixer_client.MixerClient.create_mix_parameters_from_proof (   self,
MixCallDescription  mix_call_desc,
api.ProofInputs  prover_inputs,
signing.SigningKeyPair  signing_keypair,
ExtendedProof  ext_proof,
List[int]  public_data,
str  sender_eth_address,
bool   for_dispatch_call = False 
)
Create the MixParameters from MixCallDescription, signing keypair, sender
address and derived data (prover inputs and proof). This includes
creating and encrypting the plaintext messages, and generating the
one-time signature.

If for_dispatch_call is set, the parameters are to be passed to the
Mixer's `dispatch` call in a later operation (in which proof data is
not available), hence proof is omitted from the signature.

Definition at line 500 of file mixer_client.py.

500  def create_mix_parameters_from_proof(
501  self,
502  mix_call_desc: MixCallDescription,
503  prover_inputs: api.ProofInputs,
504  signing_keypair: signing.SigningKeyPair,
505  ext_proof: ExtendedProof,
506  public_data: List[int],
507  sender_eth_address: str,
508  for_dispatch_call: bool = False
509  ) -> MixParameters:
510  """
511  Create the MixParameters from MixCallDescription, signing keypair, sender
512  address and derived data (prover inputs and proof). This includes
513  creating and encrypting the plaintext messages, and generating the
514  one-time signature.
515 
516  If for_dispatch_call is set, the parameters are to be passed to the
517  Mixer's `dispatch` call in a later operation (in which proof data is
518  not available), hence proof is omitted from the signature.
519  """
520 
521  # Encrypt the notes
522  outputs_and_notes = zip(mix_call_desc.outputs, prover_inputs.js_outputs) \
523  # pylint: disable=no-member
524  output_notes_with_k_pk: List[Tuple[api.ZethNote, EncryptionPublicKey]] = \
525  [(note, zeth_addr.k_pk)
526  for ((zeth_addr, _), note) in outputs_and_notes]
527  ciphertexts = encrypt_notes(output_notes_with_k_pk)
528 
529  # Sign
530  zksnark = get_zksnark_provider(self.prover_config.zksnark_name)
531  signature = joinsplit_sign(
532  zksnark,
533  self.prover_config.pairing_parameters,
534  signing_keypair,
535  sender_eth_address,
536  ciphertexts,
537  ext_proof,
538  public_data,
539  for_dispatch_call)
540 
541  mix_params = MixParameters(
542  ext_proof, public_data, signing_keypair.vk, signature, ciphertexts)
543  return mix_params
544 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ create_prover_inputs()

Tuple[api.ProofInputs, signing.SigningKeyPair] zeth.core.mixer_client.MixerClient.create_prover_inputs ( MixCallDescription   mix_call_desc)
static
Given the basic parameters for a mix call, compute the input to the prover
server, and the signing key pair.

Definition at line 439 of file mixer_client.py.

439  def create_prover_inputs(
440  mix_call_desc: MixCallDescription
441  ) -> Tuple[api.ProofInputs, signing.SigningKeyPair]:
442  """
443  Given the basic parameters for a mix call, compute the input to the prover
444  server, and the signing key pair.
445  """
446 
447  # Compute Merkle paths
448  mk_tree = mix_call_desc.mk_tree
449  sender_ask = mix_call_desc.sender_ownership_keypair.a_sk
450 
451  def _create_api_input(
452  input_address: int,
453  input_note: api.ZethNote) -> api.JoinsplitInput:
454  mk_path = compute_merkle_path(input_address, mk_tree)
455  input_nullifier = compute_nullifier(input_note, sender_ask)
457  mk_path,
458  input_address,
459  input_note,
460  sender_ask,
461  input_nullifier)
462 
463  inputs = mix_call_desc.inputs
464  api_inputs = [_create_api_input(addr, note) for addr, note in inputs]
465 
466  mk_root = mk_tree.get_root()
467 
468  # Extract (<ownership-address>, <value>) tuples
469  outputs_with_a_pk = \
470  [(zeth_addr.a_pk, to_zeth_units(value))
471  for (zeth_addr, value) in mix_call_desc.outputs]
472 
473  # Public input and output values as Zeth units
474  public_in_value_zeth_units = to_zeth_units(mix_call_desc.v_in)
475  public_out_value_zeth_units = to_zeth_units(mix_call_desc.v_out)
476 
477  # Generate the signing key
478  signing_keypair = signing.gen_signing_keypair()
479 
480  # Use the specified or default h_sig computation
481  compute_h_sig_cb = mix_call_desc.compute_h_sig_cb or compute_h_sig
482  h_sig = compute_h_sig_cb(
483  [bytes.fromhex(input.nullifier) for input in api_inputs],
484  signing_keypair.vk)
485  phi = _phi_randomness()
486 
487  # Create the api.ZethNote objects
488  api_outputs = _create_api_zeth_notes(phi, h_sig, outputs_with_a_pk)
489 
490  proof_inputs = api.ProofInputs(
491  mk_root=mk_root.hex(),
492  js_inputs=api_inputs,
493  js_outputs=api_outputs,
494  pub_in_value=int64_to_hex(public_in_value_zeth_units),
495  pub_out_value=int64_to_hex(public_out_value_zeth_units),
496  h_sig=h_sig.hex(),
497  phi=phi.hex())
498  return (proof_inputs, signing_keypair)
499 
Here is the call graph for this function:

◆ deploy()

Tuple[MixerClient, contracts.InstanceDescription] zeth.core.mixer_client.MixerClient.deploy ( Any  web3,
ProverClient  prover_client,
str  deployer_eth_address,
Optional[bytes]  deployer_eth_private_key,
Optional[str]   token_address = None,
Optional[str]   permitted_dispatcher = None,
Optional[str]   vk_hash = None,
Optional[int]   deploy_gas = None 
)
static
Deploy Zeth contracts.

Definition at line 273 of file mixer_client.py.

273  def deploy(
274  web3: Any,
275  prover_client: ProverClient,
276  deployer_eth_address: str,
277  deployer_eth_private_key: Optional[bytes],
278  token_address: Optional[str] = None,
279  permitted_dispatcher: Optional[str] = None,
280  vk_hash: Optional[str] = None,
281  deploy_gas: Optional[int] = None
282  ) -> Tuple[MixerClient, contracts.InstanceDescription]:
283  """
284  Deploy Zeth contracts.
285  """
286  prover_config = prover_client.get_configuration()
287  vk = prover_client.get_verification_key()
288 
289  contracts_dir = get_contracts_dir()
290  zksnark = get_zksnark_provider(prover_config.zksnark_name)
291  pp = prover_config.pairing_parameters
292  mixer_name = zksnark.get_contract_name(pp)
293  mixer_src = os.path.join(contracts_dir, mixer_name + ".sol")
294  vk_hash_evm = list(hex_to_uint256_list(vk_hash)) if vk_hash else [0, 0]
295  assert len(vk_hash_evm) == 2
296 
297  # Constructor parameters have the form:
298  # uint256 mk_depth
299  # address token
300  # ... snark-specific key data ...
301  constructor_parameters: List[Any] = [
302  constants.ZETH_MERKLE_TREE_DEPTH, # mk_depth
303  token_address or ZERO_ADDRESS, # token
304  zksnark.verification_key_to_contract_parameters(vk, pp), # vk
305  permitted_dispatcher or ZERO_ADDRESS, # permitted_dispatcher
306  vk_hash_evm # vk_hash
307  ]
308  mixer_description = contracts.InstanceDescription.deploy(
309  web3,
310  mixer_src,
311  mixer_name,
312  deployer_eth_address,
313  deployer_eth_private_key,
314  deploy_gas,
315  compiler_flags={},
316  args=constructor_parameters)
317  mixer_instance = mixer_description.instantiate(web3)
318  client = MixerClient(web3, prover_config, mixer_instance)
319  return client, mixer_description
320 
Here is the call graph for this function:

◆ deposit()

str zeth.core.mixer_client.MixerClient.deposit (   self,
ProverClient  prover_client,
MerkleTree  mk_tree,
ZethAddress  zeth_address,
str  sender_eth_address,
Optional[bytes]  sender_eth_private_key,
EtherValue  eth_amount,
Optional[List[Tuple[ZethAddressPub, EtherValue]]]   outputs = None,
Optional[EtherValue]   tx_value = None 
)

Definition at line 321 of file mixer_client.py.

321  def deposit(
322  self,
323  prover_client: ProverClient,
324  mk_tree: MerkleTree,
325  zeth_address: ZethAddress,
326  sender_eth_address: str,
327  sender_eth_private_key: Optional[bytes],
328  eth_amount: EtherValue,
329  outputs: Optional[List[Tuple[ZethAddressPub, EtherValue]]] = None,
330  tx_value: Optional[EtherValue] = None
331  ) -> str:
332  if not outputs or len(outputs) == 0:
333  outputs = [(zeth_address.addr_pk, eth_amount)]
334  return self.joinsplit(
335  prover_client,
336  mk_tree,
337  sender_ownership_keypair=zeth_address.ownership_keypair(),
338  sender_eth_address=sender_eth_address,
339  sender_eth_private_key=sender_eth_private_key,
340  inputs=[],
341  outputs=outputs,
342  v_in=eth_amount,
343  v_out=EtherValue(0),
344  tx_value=tx_value)
345 
Here is the call graph for this function:

◆ joinsplit()

str zeth.core.mixer_client.MixerClient.joinsplit (   self,
ProverClient  prover_client,
MerkleTree  mk_tree,
OwnershipKeyPair  sender_ownership_keypair,
str  sender_eth_address,
Optional[bytes]  sender_eth_private_key,
List[Tuple[int, api.ZethNote]]  inputs,
List[Tuple[ZethAddressPub, EtherValue]]  outputs,
EtherValue  v_in,
EtherValue  v_out,
Optional[EtherValue]   tx_value = None,
Optional[ComputeHSigCB]   compute_h_sig_cb = None 
)
Create and broadcast a transactions that calls the mixer with the given
parameters. Requires a ProverClient for proof generation.

Definition at line 346 of file mixer_client.py.

346  def joinsplit(
347  self,
348  prover_client: ProverClient,
349  mk_tree: MerkleTree,
350  sender_ownership_keypair: OwnershipKeyPair,
351  sender_eth_address: str,
352  sender_eth_private_key: Optional[bytes],
353  inputs: List[Tuple[int, api.ZethNote]],
354  outputs: List[Tuple[ZethAddressPub, EtherValue]],
355  v_in: EtherValue,
356  v_out: EtherValue,
357  tx_value: Optional[EtherValue] = None,
358  compute_h_sig_cb: Optional[ComputeHSigCB] = None) -> str:
359  """
360  Create and broadcast a transactions that calls the mixer with the given
361  parameters. Requires a ProverClient for proof generation.
362  """
363  mix_params, _ = self.create_mix_parameters_and_signing_key(
364  prover_client,
365  mk_tree,
366  sender_ownership_keypair,
367  sender_eth_address,
368  inputs,
369  outputs,
370  v_in,
371  v_out,
372  compute_h_sig_cb)
373  return self.mix(
374  mix_params,
375  sender_eth_address,
376  sender_eth_private_key,
377  tx_value or v_in)
378 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mix()

str zeth.core.mixer_client.MixerClient.mix (   self,
MixParameters  mix_params,
str  sender_eth_address,
Optional[bytes]  sender_eth_private_key,
EtherValue  tx_value,
Optional[int]   call_gas = None 
)
Given a MixParameters object, create and broadcast a transaction
performing the appropriate mix call.

Definition at line 379 of file mixer_client.py.

379  def mix(
380  self,
381  mix_params: MixParameters,
382  sender_eth_address: str,
383  sender_eth_private_key: Optional[bytes],
384  tx_value: EtherValue,
385  call_gas: Optional[int] = None) -> str:
386  """
387  Given a MixParameters object, create and broadcast a transaction
388  performing the appropriate mix call.
389  """
390  mixer_call = self._create_mix_call(mix_params)
391  tx_hash = contracts.send_contract_call(
392  self.web3,
393  mixer_call,
394  sender_eth_address,
395  sender_eth_private_key,
396  tx_value,
397  call_gas)
398  return tx_hash.hex()
399 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ mix_call()

bool zeth.core.mixer_client.MixerClient.mix_call (   self,
MixParameters  mix_params,
str  sender_eth_address,
EtherValue  tx_value,
Optional[int]   call_gas = None 
)
Call the mix method (executes on the RPC host without creating a
transaction). Returns True if the call succeeds. False, otherwise.

Definition at line 400 of file mixer_client.py.

400  def mix_call(
401  self,
402  mix_params: MixParameters,
403  sender_eth_address: str,
404  tx_value: EtherValue,
405  call_gas: Optional[int] = None) -> bool:
406  """
407  Call the mix method (executes on the RPC host without creating a
408  transaction). Returns True if the call succeeds. False, otherwise.
409  """
410  mixer_call = self._create_mix_call(mix_params)
411  try:
412  contracts.local_contract_call(
413  mixer_call,
414  sender_eth_address,
415  tx_value,
416  call_gas)
417  return True
418 
419  except ValueError:
420  print("error executing mix call:")
421  traceback.print_exc()
422 
423  return False
424 
Here is the call graph for this function:

Member Data Documentation

◆ mixer_instance

zeth.core.mixer_client.MixerClient.mixer_instance

Definition at line 266 of file mixer_client.py.

◆ prover_config

zeth.core.mixer_client.MixerClient.prover_config

Definition at line 265 of file mixer_client.py.

◆ web3

zeth.core.mixer_client.MixerClient.web3

Definition at line 264 of file mixer_client.py.


The documentation for this class was generated from the following file:
zeth.core.mixer_client.create_api_joinsplit_input
api.JoinsplitInput create_api_joinsplit_input(List[str] merkle_path, int address, api.ZethNote note, OwnershipSecretKey a_sk, bytes nullifier)
Definition: mixer_client.py:227
zeth.core.mixer_client.encrypt_notes
List[bytes] encrypt_notes(List[Tuple[api.ZethNote, EncryptionPublicKey]] notes)
Definition: mixer_client.py:601
zeth.cli.zeth_deploy.deploy
None deploy(Context ctx, Optional[str] eth_addr, Optional[str] eth_private_key, str instance_out, Optional[str] token_address, Optional[str] permitted_dispatcher, Optional[str] vk_hash, Optional[int] deploy_gas)
Definition: zeth_deploy.py:29
zeth.core.merkle_tree.compute_merkle_path
List[str] compute_merkle_path(int address, MerkleTree mk_tree)
Definition: merkle_tree.py:188
zeth.core.mixer_client.joinsplit_sign
int joinsplit_sign(IZKSnarkProvider zksnark, PairingParameters pp, JoinsplitSigKeyPair signing_keypair, str sender_eth_address, List[bytes] ciphertexts, ExtendedProof extproof, List[int] public_data, bool for_dispatch_call=False)
Definition: mixer_client.py:657
zeth.core.utils.to_zeth_units
int to_zeth_units(EtherValue value)
Definition: utils.py:220
zeth.core.mixer_client.compute_nullifier
bytes compute_nullifier(api.ZethNote zeth_note, OwnershipSecretKey spending_authority_ask)
Definition: mixer_client.py:718
zeth.cli.zeth_mix.mix
None mix(Context ctx, str vin, str vout, List[str] input_notes, List[str] output_specs, Optional[str] eth_addr, Optional[str] eth_private_key, bool wait, bool for_dispatch_call, Optional[str] dump_parameters, Optional[str] dump_signing_keypair, bool dry_run)
Definition: zeth_mix.py:41
zeth.core.utils.get_contracts_dir
str get_contracts_dir()
Definition: utils.py:255
zeth.core.utils.int64_to_hex
str int64_to_hex(int number)
Definition: utils.py:158
zeth.core.utils.hex_to_uint256_list
Iterable[int] hex_to_uint256_list(str hex_str)
Definition: utils.py:172
zeth.core.zksnark.get_zksnark_provider
IZKSnarkProvider get_zksnark_provider(str zksnark_name)
Definition: zksnark.py:486