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

witness "ConsensusBurn_V1" {
	# The value of this coin
	Base value,
	# The epoch this coin was minted on
	Base epoch,
	# Unique serial number corresponding to this coin
	Base serial,
	# Random blinding factor for value commitment
	Scalar value_blind,
	# Secret key used to derive nullifier and coins' public key
	Base secret,
	# Leaf position of the coin in the Merkle tree of coins
	Uint32 leaf_pos,
	# Merkle path to the coin
	MerklePath path,
}

circuit "ConsensusBurn_V1" {
	# Poseidon hash of the nullifier
	nullifier = poseidon_hash(secret, serial);
	constrain_instance(nullifier);

	# Constrain the epoch this coin was minted on
	constrain_instance(epoch);

	# We derive coins' public key for the signature and
	# constrain its coordinates:
	pub = ec_mul_base(secret, NULLIFIER_K);
	pub_x = ec_get_x(pub);
	pub_y = ec_get_y(pub);
	constrain_instance(pub_x);
	constrain_instance(pub_y);

	# Coin hash	
	C = poseidon_hash(
		pub_x,
		pub_y,
		value,
		epoch,
		serial,
	);

	# Merkle root
	root = merkle_root(leaf_pos, path, C);
	constrain_instance(root);
	
	# 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:
	constrain_instance(ec_get_x(value_commit));
	constrain_instance(ec_get_y(value_commit));

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