constant "DaoVoteInput" { EcFixedPointShort VALUE_COMMIT_VALUE, EcFixedPoint VALUE_COMMIT_RANDOM, EcFixedPointBase NULLIFIER_K, } contract "DaoVoteInput" { Base secret, Base serial, Base spend_hook, Base user_data, Base value, Base gov_token_id, Base coin_blind, Scalar value_blind, Base gov_token_blind, Uint32 leaf_pos, MerklePath path, Base signature_secret, } circuit "DaoVoteInput" { # Poseidon hash of the nullifier nullifier = poseidon_hash(secret, serial); constrain_instance(nullifier); # Pedersen commitment for coin's value vcv = ec_mul_short(value, VALUE_COMMIT_VALUE); vcr = ec_mul(value_blind, VALUE_COMMIT_RANDOM); value_commit = ec_add(vcv, vcr); # Since value_commit is a curve point, we fetch its coordinates # and constrain them: value_commit_x = ec_get_x(value_commit); value_commit_y = ec_get_y(value_commit); constrain_instance(value_commit_x); constrain_instance(value_commit_y); # Commitment for coin's token ID token_commit = poseidon_hash(gov_token_id, gov_token_blind); constrain_instance(token_commit); # Coin hash pub = ec_mul_base(secret, NULLIFIER_K); pub_x = ec_get_x(pub); pub_y = ec_get_y(pub); C = poseidon_hash(pub_x, pub_y, value, gov_token_id, serial, spend_hook, user_data, coin_blind); # Merkle root root = merkle_root(leaf_pos, path, C); constrain_instance(root); # Finally, we derive a public key for the signature and # constrain its coordinates: signature_public = ec_mul_base(signature_secret, NULLIFIER_K); signature_x = ec_get_x(signature_public); signature_y = ec_get_y(signature_public); constrain_instance(signature_x); constrain_instance(signature_y); # At this point we've enforced all of our public inputs. }