Skip to main content

Python Developer Quickstart

Start building on Nillion. The quickstart walks you through

  1. Installing the Nillion SDK
  2. Setting up a developer environment
  3. Running and connecting to nillion-devnet, a local Nillion network
  4. Writing your first Nada program, tiny_secret_addition.py
  5. Connecting to the network with the NillionClient to store programs, store secrets, and compute on programs with stored secrets.

Install the Nillion SDK tools

  1. Install nilup the Nillion SDK tool installer and version manager. Binaries are available for Linux and macOS platforms

    For the security-conscious, please download the install.sh script, so that you can inspect how it works, before piping it to bash.

    curl https://nilup.nilogy.xyz/install.sh | bash

    Confirm global nilup tool installation

    nilup -V
  2. Use nilup to install the latest version of the Nillion SDK.

    nilup install latest
    nilup use latest
    nilup init

    Optionally enable nilup telemetry, providing your Ethereum wallet address. We collect this data to understand how the software is used, and to better assist you in case of issues.In doing this, you consent to the collection of telemetry data by the Nillion Network. While we will not collect any personal information, we still recommend using a new wallet address that cannot be linked to your identity by any third party. For more information, check out our privacy policy.

    nilup instrumentation enable --wallet <your-eth-wallet-address>

    Confirm global Nillion tool installation

    nillion -V

Clone the Nillion python starter repo

The Nillion Python Starter repo has everything you need to start building. Clone the repo:

git clone https://github.com/NillionNetwork/nillion-python-starter.git
cd nillion-python-starter

Install script dependencies

There are a few pre-reqs for using the python starter repo: make sure you have python3 (version >=3.11) and pip, foundry, pidof, and grep installed on your machine.

  • python3 version >=3.11 version 3.11 or higher with a working pip installed

    tip

    Use these commands to confirm that you have python3 (version >=3.11) and pip installed:

    python3 --version
    python3 -m pip --version
  • anvil tool from foundry, which can be installed with:

    # install Foundryup, the Foundry toolchain installer
    curl -L https://foundry.paradigm.xyz | bash

    # after installation, use the foundryup commmand to install the binaries including Anvil
    foundryup
  • pidof

  • grep

Create a .env file by copying the sample

cp .env.sample .env

Activate the virtual environment

These scripts activate a python virtual environment at .venv and install py_nillion_client and nada_dsl packages + dependencies listed in the requirements.txt file

bash ./create_venv.sh && source .venv/bin/activate

Bootstrap your local environment and run the nillion-devnet

The bootstrap-local-environment script installs Nada DSL and Nillion Client, then uses the nillion-devnet Nillion SDK tool to spin up a local test Nillion cluster that is completely isolated within your computer. The script also populates your .env file with keys, bootnodes, cluster, and payment info that will allow you to connect to the local cluster network.

./bootstrap-local-environment.sh
tip

You can stop the local cluster at any time by running

killall nillion-devnet

Write a Nada program

The Nillion Network uses Nada, our MPC language, to define MPC programs. The first implementation of Nada is a Python DSL (Domain Specific Language), called Nada. Let's write a tiny Nada program that adds two secret numbers. Here's the code for the finished program we'll write line by line:

programs/tiny_secret_addition_complete.py
loading...

Create a python file called tiny_secret_addition.py in the programs folder. This is where you will write your Nada program code.

cd programs
touch tiny_secret_addition.py

Open the file and import nada_dsl

from nada_dsl import *

Create a function called nada_main() that will contain the code you want to run

from nada_dsl import *
def nada_main():

Add a party

In Nada you have to declare the parties involved in the computation through the Party type. A Party is defined with a name.

info

Here's an example of a Party

Party(name="Steph")

Create party1, a Party named "Party1"

from nada_dsl import *
def nada_main():

party1 = Party(name="Party1")

Learn about inputs

Nada programs have inputs. An Input is defined with a name and a party, which is the Party providing the input.

info

Here's an example of an Input:

Input(name="numberOfDogs", party=Party(name="Steph"))

Nada program inputs are typed. There are a few categories of types

Secrecy level

  • Public: visible to all nodes
  • Secret: secret values to be handled by the computing nodes as shares or particles

Scalar

  • Integer
  • String

These categories are combined into types like SecretInteger, which are used to type an Input. See all types

info

Here's an example of a SecretInteger Input provided by Steph

steph = Party(name="Steph")
stephs_secret_int = SecretInteger(Input(name="numberOfDogs", party=steph))

Create 2 secret integers inputs

  • my_int1, a SecretInteger named "my_int1" owned by Party1
  • my_int2, a SecretInteger named "my_int2" owned by Party1
from nada_dsl import *

def nada_main():
party1 = Party(name="Party1")
my_int1 = SecretInteger(Input(name="my_int1", party=party1))
my_int2 = SecretInteger(Input(name="my_int2", party=party1))

Add the integers by creating a new variable called new_int and setting it equal to my_int1 + my_int2

from nada_dsl import *

def nada_main():
party1 = Party(name="Party1")
my_int1 = SecretInteger(Input(name="my_int1", party=party1))
my_int2 = SecretInteger(Input(name="my_int2", party=party1))

new_int = my_int1 + my_int2

Finally, Nada programs return an output. The Output type is used to declare a named output that will be revealed to a concrete Party. The Output has a name and a party as parameters.

Return the output

Nada programs return an array of outputs.

info

Here's an example of an output. The output is named total_score, its value is score_int, and it can be read by the party named Steph.

Output(score_int, "total_score", Party(name="Steph"))

Complete your Nada program by adding a final line that returns an array with one output. The output is named "my_output", its value is new_int, and it can be ready by party1.

Resulting Nada program

programs/tiny_secret_addition_complete.py
loading...

🎉 You just wrote your first Nada program! Next, let's compile the program.

Compile the Nada program

Nada programs need to be compiled ahead of being stored. Navigate back to the root of the repo, and compile all programs in the programs folder, including tiny_secret_addition.py, with the compile script. The compile_programs.sh script runs the pynadac SDK tool on all files in the programs folder.

cd ..
sh compile_programs.sh

This results in programs-compiled, a folder of compiled programs. Check programs-compiled for your compiled output, called tiny_secret_addition.nada.bin

Write a Python script to interact with nillion-devnet

Let's write a Python script that will interact with nillion-devnet. This Python script will:

  1. Initialize NillionClient, connecting to nillion-devnet
  2. Get the user id and party id from NillionClient
  3. Store a compiled Nada program in the network
  4. Create the 1st secret with bindings to the program
  5. Store the secret in the network
  6. Create compute bindings to set input and output parties
  7. Compute on the program with 1st secret from the network, and the 2nd secret, provided at compute time
  8. Print the computation result

Check out the completed Python script here

Complete the python script 🎯 TODOs

Open the core_concept_single_party_compute/tiny_secret_addition.py file and let's work through the 🎯 TODOs.

tip

Open the Nillion Python Client Reference doc in another tab to search for available classes while completing the 🎯 TODOs.

1. Initialize NillionClient, connecting to nillion-devnet

The first step was completed for you. The script uses a create_nillion_client helper file to create the instance of nillion.NillionClient used throughout the script

examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition.py
loading...

2. Get the user id and party id from NillionClient

examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition.py
loading...

3. Store a compiled Nada program in the network

examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition.py
loading...

4. Create the 1st secret with bindings to the program

examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition.py
loading...

5. Store the secret in the network

When we wrote our Nada program, we created 2 secret integers that are inputs to the program. We'll store one of these secrets in the network using the Python Client, and provide the other secret at compute time. Let's store the first secret.

examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition.py
loading...

6. Create compute bindings to set input and output parties

examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition.py
loading...

7. Compute on the program with 1st secret from the network, and the 2nd secret, provided at compute time

examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition.py
loading...

8. Print the computation result

examples_and_tutorials/core_concept_single_party_compute/tiny_secret_addition.py
loading...

Run the completed python script

Run the script to store the program, store secrets and compute on the program.

cd core_concept_single_party_compute
python3 tiny_secret_addition.py

Check out the network result on tiny_secret_addition. Update the SecretInteger input values and run the program again.

Keep exploring

You've successfully written your first single party Nada program, stored the program on the network, stored secrets on the network, and run compute against secrets. Keep exploring by

Solve the millionaires problem