Money Contract Source Code

BZHKGQ26bzmBithTQYTJtjo2QdCqpkR9tjSBopT4yf4o
proof/fee_v1.zk
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
k = 11;
field = "pallas";

constant "Fee_V1" {
    EcFixedPointShort VALUE_COMMIT_VALUE,
    EcFixedPoint VALUE_COMMIT_RANDOM,
    EcFixedPointBase NULLIFIER_K,
}

witness "Fee_V1" {
    # Secret key used to derive input's nullifier
    Base input_secret,
    # Input coin's leaf position in the Merkle tree of coins
    Uint32 input_leaf_pos,
    # Merkle path to the coin
    MerklePath input_path,
    # Secret key used to derive public key for the tx signature
    Base signature_secret,
    # Value of the input coin
    Base input_value,
    # Random blinding factor for the input value commitment
    Scalar input_value_blind,
    # Input coin's spend hook
    Base input_spend_hook,
    # Data passed from the input to the invoked contract
    Base input_user_data,
    # Unique coin blind corresponding to the input coin
    Base input_coin_blind,
    # Blinding factor for the encrypted user_data
    Base input_user_data_blind,
    # Value of the output coin
    Base output_value,
    # Output coin's spend hook
    Base output_spend_hook,
    # Data passed from the output coin to the invoked contract
    Base output_user_data,
    # Random blinding factor for the output value commitment
    Scalar output_value_blind,
    # Unique coin blind corresponding to the output coin
    Base output_coin_blind,
    # Token ID
    Base token,
    # Random blinding factor for the token ID
    Base token_blind,

}

circuit "Fee_V1" {
    # Derive the input coin
    pub = ec_mul_base(input_secret, NULLIFIER_K);
    pub_x = ec_get_x(pub);
    pub_y = ec_get_y(pub);
    input_coin = poseidon_hash(
        pub_x,
        pub_y,
        input_value,
        token,
        input_spend_hook,
        input_user_data,
        input_coin_blind,
    );

    nullifier = poseidon_hash(input_secret, input_coin);
    constrain_instance(nullifier);

    # Pedersen commitment for the input coin value
    input_vcv = ec_mul_short(input_value, VALUE_COMMIT_VALUE);
    input_vcr = ec_mul(input_value_blind, VALUE_COMMIT_RANDOM);
    input_value_commit = ec_add(input_vcv, input_vcr);
    constrain_instance(ec_get_x(input_value_commit));
    constrain_instance(ec_get_y(input_value_commit));

    # Commitment for the token ID
    token_commit = poseidon_hash(token, token_blind);
    constrain_instance(token_commit);

    # Merkle root
    root = merkle_root(input_leaf_pos, input_path, input_coin);
    constrain_instance(root);

    # Export user_data
    user_data_enc = poseidon_hash(input_user_data, input_user_data_blind);
    constrain_instance(user_data_enc);

    # Reveal spend_hook
    ZERO = witness_base(0);
    constrain_equal_base(input_spend_hook, ZERO);

    # Derive a public key for the signature and
    # constrain its coordinates
    signature_public = ec_mul_base(signature_secret, NULLIFIER_K);
    constrain_instance(ec_get_x(signature_public));
    constrain_instance(ec_get_y(signature_public));

    # Derive output coin
    output_coin = poseidon_hash(
        pub_x,
        pub_y,
        output_value,
        token,
        output_spend_hook,
        output_user_data,
        output_coin_blind,
    );
    constrain_instance(output_coin);

    # Pedersen commitment for the output coin value
    output_vcv = ec_mul_short(output_value, VALUE_COMMIT_VALUE);
    output_vcr = ec_mul(output_value_blind, VALUE_COMMIT_RANDOM);
    output_value_commit = ec_add(output_vcv, output_vcr);
    constrain_instance(ec_get_x(output_value_commit));
    constrain_instance(ec_get_y(output_value_commit));
}