# Implementation Instructions

*Authors: BlockScience and SDF, July 2023*

The implementation of NG relies on two main premises - refactoring existing Neurons and creating new ones.&#x20;

A PoC implementation in Rust for Soroban by Alejo Mendoza, Karol Bisztyga and Mateusz Kowalski is located in the [`voting-poc`](https://github.com/alejomendoza/voting-poc/tree/main) GitHub repository. It implements the Neural Governance, Quorum Delegation and the Trust Graph Bonus governance modules.

A technical summary for learnings when implementing an MVP version of Neural Quorum Governance on SCF can be found on a post by [Karol Bisztyga](https://medium.com/@karol.bisztyga?source=post_page-----da746343c6f5--------------------------------): [SCF Voting Mechanism Implementation](https://medium.com/@karol.bisztyga/da746343c6f5).

#### 1) Decide on Neurons to be included

*pub fn add\_neuron(*\
*\&mut self,* \
*layer\_id: u32, // specifies the layer* \
*neuron: NeuronType // specifies the neuron*\
*)*

* The example implementations provide various Neurons as examples, among them:
  * Reputation through badges
  * Past Voting History
  * Trust Bonus
  * Additionally, new Neurons can be created (expanded on below).&#x20;

#### 2) Decide on aggregators to be included

*pub fn set\_layer\_aggregator(* \
*\&mut self,* \
*layer\_id: u32, // specifies a layer ID*\
*aggregator: LayerAggregator, // specifies the aggregator to use*\
*)*

* Each layer of Neurons has their own aggregator and can be arbitrarly set per layer. Standard aggregators include Sum, Product and Mean.&#x20;

#### 3) Decide on the Neural Layering (CHECK ordering)&#x20;

*pub fn add\_layer(*\
*\&mut self,* \
*env: Env*\
*)*

*pub fn remove\_layer(*\
*\&mut self,* \
*layer\_id: u32*\
*)*

* Adding and removing layers allows to set aggregators and neurons correctly.&#x20;
* While Neurons within a layer are independent of ordering, deciding the order of layers changes the input a layer starts with, with it changing the outputs.&#x20;

#### 4) Decide on the Neuron weights & parameters (if applicable)

*pub fn set\_neuron\_weight(* \
*\&mut self,* \
*layer\_id: u32, // specifies the layer*\
*neuron: NeuronType, // specifies the Neuron*\
*weight: DecimalNumber, // sets the weight*\
*)*

* Each Neuron can be weighted independently through their respective weight function. \
  Some Neurons might also include parameters to adjust, such as Quorum Sizes and tresholds for Quorum Delegation.&#x20;

#### 5) Implement oracle functions if needed

* Some Neurons require as input outside data, such as badges collected or past voting history.&#x20;

#### 6) Implement base module

* Neural Governance requires structure *around the layering and Neurons. Receiving the votes, feeding them through the m*echanism and then tallying the votes needs to be set up correctly. An example for instructions to set this up can be found [here](https://github.com/alejomendoza/voting-poc/tree/main#setting-up).&#x20;

#### 7) Implement new neurons

Additionally, any new Neurons can be developed and included (example instructions from [here](https://github.com/alejomendoza/voting-poc/tree/main#custom-neurons)):

* Add a new file to [the neurons folder](https://github.com/alejomendoza/voting-poc/blob/main/src/voting_system/src/neurons) - the new Neuron has to have `oracle_function`, the easiest way to go is to just copy the contents of the [dummy neuron](https://github.com/alejomendoza/voting-poc/blob/main/src/voting_system/src/neurons/dummy_neuron.rs)
* fill the `oracle_function` of the new neuron with your custom logic
* add your Neuron module to the [mod file](https://github.com/alejomendoza/voting-poc/blob/main/src/voting_system/src/neurons/mod.rs)
* in [types](https://github.com/alejomendoza/voting-poc/blob/main/src/voting_system/src/types.rs)
  * add a field of your Neuron to the `NeuronType` enum
  * add a case of your Neuron to the `neuron_type_from_str` function
* add a case for your Neuron in the `execute_layer` function in [the layer file](https://github.com/alejomendoza/voting-poc/blob/main/src/voting_system/src/layer.rs)

#### 8) Execute Neural Governance:

*pub fn execute\_neural\_governance(* \
*\&self,* \
*env: Env,* \
*voter\_id: String, // specifies the voter\_id for which NG is executed* \
*submission\_id: String, // specifies the project for which NG is executed*\
*)*
