# Process Contract
A process is the building block around which governance is made in Vocdoni. Similarly to an Operating System, think of the Processes contract like a Kernel that receives syscalls to spawn a new governance process.
Governance processes span across three different components: the Ethereum smart contract, IPFS to ditribute the vote metadata and the Vochain.
Processes follow a declarative fashion. The expected behavior is declared on the smart contract for integrity and then the voting blockchain (called Vochain) reacts according to the current settings.
The instance of the Voting process contract is resolved from processes.vocdoni.eth on the ENS registry.
# Contract structs
// GLOBAL STRUCTS
struct Process {
    uint8 mode; // The selected process mode. See: https://docs.vocdoni.io/architecture/smart-contracts/process.html#flags
    uint8 envelopeType; // One of valid envelope types, see: https://docs.vocdoni.io/architecture/smart-contracts/process.html#flags
    CensusOrigin censusOrigin; // How the census proofs are computed (Off-chain vs EVM Merkle Tree)
    address entity; // The address of the Entity (or contract) holding the process
    uint32 startBlock; // Vochain block number on which the voting process starts
    uint32 blockCount; // Amount of Vochain blocks during which the voting process should be active
    string metadata; // Content Hashed URI of the JSON meta data (See Data Origins)
    string censusRoot; // Hex string with the Census Root. Depending on the census origin, it will be a Merkle Root or a public key.
    string censusUri; // Content Hashed URI of the exported Merkle Tree (not including the public keys)
    Status status; // One of 0 [ready], 1 [ended], 2 [canceled], 3 [paused], 4 [results]
    uint8 questionIndex; // The index of the currently active question (only assembly processes)
    // How many questions are available to vote
    // questionCount >= 1
    uint8 questionCount;
    // How many choices can be made for each question.
    // 1 <= maxCount <= 100
    uint8 maxCount;
    // Determines the acceptable value range.
    // N => valid votes will range from 0 to N (inclusive)
    uint8 maxValue;
    uint8 maxVoteOverwrites; // How many times a vote can be replaced (only the last one counts)
    // Limits up to how much cost, the values of a vote can add up to (if applicable).
    // 0 => No limit / Not applicable
    uint16 maxTotalCost;
    // Defines the exponent that will be used to compute the "cost" of the options voted and compare it against `maxTotalCost`.
    // totalCost = Σ (value[i] ** costExponent) <= maxTotalCost
    //
    // Exponent range:
    // - 0 => 0.0000
    // - 10000 => 1.0000
    // - 65535 => 6.5535
    uint16 costExponent;
    uint256 evmBlockHeight; // EVM block number to use as a snapshot for the on-chain census
    bytes32 paramsSignature; // entity.sign({...}) // fields that the oracle uses to authenticate process creation
}
# Process ID
Processes are uniquely identified by their processId
It is the result of combining and hashing these three values:
entityAddressprocessCountIndexnamespace
function getNextProcessId(address entityAddress) public view override returns (bytes32) {
    // From 0 to N-1, the next index is N
    uint256 processCount = getEntityProcessCount(entityAddress);
    return getProcessId(entityAddress, processCount, namespaceId, ethChainId);
}
function getProcessId(address entityAddress, uint256 processCountIndex, uint32 namespaceIdNum, uint32 ethereumChainId) public pure override returns (bytes32) {
    return keccak256(abi.encodePacked(entityAddress, processCountIndex, namespaceIdNum, ethereumChainId));
}
Where:
entityAddressis the Ethereum address that creates the process (or the token address)entityProcessCountis an incremental nonce perentityAddressethereumChainIdis the Ethereum chain Id where this contract has been deployed tonamespaceIdis a number that the process contract is assigned when it is deployed. See the Namespace contract
# Methods
newProcess()- Sets the parameters of a new process to be run on the Vochain
 - If 
processPriceis defined to prevent spam, the transaction must include avaluewith at least such amount. 
setStatus()- With the appropriate flags, the creator can set the process to be 
READY,ENDED,CANCELEDorPAUSED. - See process status below
 
- With the appropriate flags, the creator can set the process to be 
 incrementQuestionIndex()- With the appropriate flags, the creator can define the question that can be voted on
 
setCensus()- With the appropriate flags, the creator can update the census for long lasting polls
 
For more details, you can see the implementation here (opens new window)
# Getters
get()- Retrieves all the parameters and flags defined for the given process
 
getParamsSignature()- Retrieves the signature of the parameters above
 
getCreationInstance()- Returns the address of the process contract where the given process is hosted
 - Useful to determine where an update needs to be sent to (see Transparent upgrades next)
 
# Flags
When a process is created, the entity needs to define what options apply to it. The combination of them produces:
- The process 
mode- It determines the external behavior of the process, when it starts, what can be updated, etc.
 
 - The 
envelopeType- Determines the internal behavior of the votes sent by participants.
 
 - The 
censusOrigin- Determines the way to compute and validate the voter's census proofs
 
 
There is the case where the entity wants to start the process as soon as possible. Because of the nature
of a blockchain it is not possible to know at which block a transaction will be mined/sealed and selecting
an approximate block number in the future could not work if the block number selected is very close to the current
block number.
For these cases an entity can use a special block number startBlock = 1 if the process mode flag AUTO_START is
set to true. If a process is created with this flags the startBlock of the process will be changed by the Oracles
sending the transaction to the Vochain and will be set to the current Vochain block plus some delay to ensure the
that the startBlock is never less than the current Vochain block.
The process will be ready to receive votes as soon as the transaction sended by the Oracles is mined.
# Process Mode
The process mode affects both the Vochain, the contract itself and even the metadata. Its value is generated by combining the flags below.
0b00011111
     |||||
     ||||`- autoStart
     |||`-- interruptible
     ||`--- dynamicCensus
     |`---- encryptedMetadata
     `----- preRegister
# AUTO_START
false⇒ The process needs to be set toREADYby the creator before it can start. Processes startPAUSEDby default.true⇒ Votes will be processes starting at blockstartBlock.
newProcess() enforces startBlock > 0 accordingly
# INTERRUPTIBLE
false⇒ The Vochain willENDthe process when the blockstartBlock + blockCountis reachedtrue⇒ In addition to the above, the admin canEND,PAUSEandCANCELit- Pausing a process prevents votes from being received and 
blockCountstays unchanged by now 
- Pausing a process prevents votes from being received and 
 
# DYNAMIC_CENSUS
false⇒ The census is immutabletrue⇒ The census can be edited during the life-cycle of the process. Allowing to add, subtract new keys, or change the census entirely, to a process that has already started.- Intended for low stake, long-term polls only
 - Warning: The admin would have the opportunity to cheat by enabling keys and then removing them later on
 
# ENCRYPTED_METADATA
false⇒ The processMetadata should be in plain texttrue⇒ The questions and options of a process should be encrypted, so an observer of the network won't be able to see what the process is about unless he/she has the key.
It requires a prior process to share the encryption key with the users with the right to read the data. This will be likely be handled by the User Registry.
# PRE_REGISTER
false⇒ There is not registration phase, thus the census root used for validate votes is theCensusRootparameter defined by thenewProcessTxtransaction.true⇒ There is a registration phase, the census root parameter defined bynewProcessTxis used only during the registration (before the processstartBlockis reached). The votingCensusRootwill be built inside the Vochain when registerVoterKeyTx are send by the elegible voters.
# Envelope Type
The envelope type tells how the vote envelope is formatted and handled. Its value is generated by combining the flags below.
0b00011111
     |||||
     ||||`- serial
     |||`-- anonymous
     ||`--- encryptedVotes
     |`---- uniqueValues
      `---- costFromWeight 
# SERIAL
falseA single envelope is expected with all votes in ittrueAn envelope needs to be sent for each question, asquestionIndexis incremented
# ANONYMOUS
falseThe voter identity (public key) can be known and therefore, the vote is pseudonymous. If an observer can correlate the voter public key with personal data, the voter could be identified.trueThe voter public key can't be known. Instead, the voter will submit a ZK-snark proof, ensuring that:- He/she belongs to the census of the process
 - He/she has not already voted on the process
 
# ENCRYPTED_VOTE
falseVotes are sent in plain text. Results can be seen in real time.trueThe vote payload will be encrypted. The results will become available once the encryption key is published at the end of the process by the miners.
# UNIQUE_VALUES
falseThe same vote value can be chosen more than oncetrueChoices must be unique across a field
# COST_FROM_WEIGHT
trueOn EVM-based census processes (weighted), the user's balance will be used as themaxCost. This allows splitting the voting power among several choices, even including quadratic voting scenarios.falseThe max cost will be taken from the value on the smart contract, being the same for everyone.
# Census Origin
The census origin is an unsigned integer holding a value defined by the following enumeration:
OFF_CHAIN_TREE(1)- An exhaustive Merkle Tree contains the list of (hashed) keys allowed to vote and its root is stored on 
censusRoot. 
- An exhaustive Merkle Tree contains the list of (hashed) keys allowed to vote and its root is stored on 
 OFF_CHAIN_TREE_WEIGHTED(2)- An exhaustive Merkle Tree contains the list of (hashed) keys allowed to vote and their respective voting power. Its root is also stored on 
censusRoot. 
- An exhaustive Merkle Tree contains the list of (hashed) keys allowed to vote and their respective voting power. Its root is also stored on 
 OFF_CHAIN_CA(3)- A certification authority issues signatures for all eligible voters on a per-process basis. The public key of the CA is stored on 
censusRoot. 
- A certification authority issues signatures for all eligible voters on a per-process basis. The public key of the CA is stored on 
 ERC20(11)- All the token holders of an ERC20 token (under the contract at the address of 
entity) are eligible to vote.censusRootcontains the storage (Merkle) root of the token contract at theevmBlockHeight. 
- All the token holders of an ERC20 token (under the contract at the address of 
 ERC721(12)- Same as the ERC20 case, but for ERC721 contracts
 
ERC1155(13)- Same as the ERC20 case, but for ERC1155 contracts
 
ERC777(14)- Same as the ERC20 case, but for ERC777 contracts
 
MINI_ME(15)- Same as the ERC20 case, but for MiniMe (ERC20) contracts
 
# Process Status
The status of a process is a simple enum, defined as follows:
READY(0)- The process is marked as ready. It is intended as a passive authorization to open the process
 - Vochain nodes will accept incoming votes if 
AUTO_STARTis disabled - Otherwise, they will accept votes when the Vochain block number reaches 
startBlock 
ENDED(1)- Tells the Vochain to stop accepting votes and start computing the results (if not already available)
 - Only when 
INTERRUPTIBLEis set 
CANCELED(2)- Tells the Vochain to stop accepting votes and drop the existing data. No results will be published.
 - Only when 
INTERRUPTIBLEis set 
PAUSED(3)- Tells the Vochain to stop processing votes temporarily. The process might be resumed in the future.
 - Only when 
INTERRUPTIBLEis set, or after creation ifAUTO_STARTis not set 
RESULTS(4)- Set by the Oracle from the Results contract as soon as the tally of a process has become available
 
# Transparent upgrades
Even if there are tools to deploy upgradeable smart contracts, we believe that newer versions of a contract should not be able to alter any of processes stored in the past. Existing data should remain intact, independently of future contract versions. In order to enforce transparency and full auditability:
- Upcoming contract versions allow to keep historical data by forking and chaining new instances
 - A common interface is available between old and new instances, so that backwards compatibility is preserved
 - When a new instance is deployed, it can have a predecessor, which can 
activatethe new version as its successor - New processes can only be created on the last successor of the chain
 - From successors, clients can navigate back in time transparently and read processes stored on old instances
 
This behavior is encapsulated into the Chained (opens new window) base contract.
However:
- Due to security concerns (opens new window), updates on a process coming from a successor are not acceptable
 - Updates on legacy processes need to be sent directly to the original contract instance
 - Use 
getCreationInstance(processId)to retrieve the appropriate address