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

contract "Mint_V1" {
	# X coordinate for public key
	Base pub_x,
	# Y coordinate for public key
	Base pub_y,
	# The value of this coin
	Base value,
	# The token ID
	Base token,
	# Unique serial number corresponding to this coin
	Base serial,
	# Random blinding factor for coin
	Base coin_blind,
	# Allows composing this ZK proof to invoke other contracts
	Base spend_hook,
	# Data passed from this coin to the invoked contract
	Base user_data,
	# Random blinding factor for the value commitment
	Scalar value_blind,
	# Random blinding factor for the token ID
	Scalar token_blind,
}

circuit "Mint_V1" {
	# Poseidon hash of the coin
	C = poseidon_hash(
		pub_x,
		pub_y,
		value,
		token,
		serial,
		spend_hook,
		user_data,
		coin_blind,
	);
	constrain_instance(C);

	# 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 the value commit is a curve point, we fetch its coordinates
	# and constrain them:
	constrain_instance(ec_get_x(value_commit));
	constrain_instance(ec_get_y(value_commit));

	# Pedersen commitment for coin's token ID
	tcv = ec_mul_base(token, NULLIFIER_K);
	tcr = ec_mul(token_blind, VALUE_COMMIT_RANDOM);
	token_commit = ec_add(tcv, tcr);
	# Since token_commit is also a curve point, we'll do the same
	# coordinate dance:
	constrain_instance(ec_get_x(token_commit));
	constrain_instance(ec_get_y(token_commit));

	# At this point we've enforced all of our public inputs.
}
