Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hacker house - initial Nillion task - Windows #71

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions nohup.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
ℹ️ cluster id is 9e68173f-9c23-4acc-ba81-4f079b639964
ℹ️ using 256 bit prime
ℹ️ storing state in /tmp/.tmp7GD2k5 (80.01Gbs available)
🏃 starting nilchain node in: /tmp/.tmp7GD2k5/nillion-chain
⛓ nilchain JSON RPC available at http://127.0.0.1:48102
⛓ nilchain REST API available at http://localhost:26650
⛓ nilchain gRPC available at localhost:26649
🏃 starting node 12D3KooWMvw1hEqm7EWSDEyqTb6pNetUVkepahKY6hixuAuMZfJS
⏳ waiting until bootnode is up...
🏃 starting node 12D3KooWAiwGZUwSUaT2bYVxGS8jmfMrfsanZYkHwH3uL7WJPsFq
🏃 starting node 12D3KooWM3hsAswc7ZT6VpwQ1TCZU4GCYY55nLhcsxCcfjuixW57
👛 funding nilchain keys
📝 nillion CLI configuration written to /root/.config/nillion/nillion-cli.yaml
🌄 environment file written to /root/.config/nillion/nillion-devnet.env
21 changes: 21 additions & 0 deletions quickstart/client_code/run_my_first_program.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Function to calculate factorial
def factorial(n):
if n == 0 or n == 1:
return 1
else:
return n * factorial(n - 1)

# Main function
def main():
# Prompt the user to enter a number
number = int(input("Enter a number to calculate its factorial: "))

# Calculate the factorial using the function
result = factorial(number)

# Print the result
print(f"The factorial of {number} is {result}")

# Run the main function
if __name__ == "__main__":
main()
7 changes: 7 additions & 0 deletions quickstart/nada_quickstart_programs/nada-project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
name = "nada_quickstart_programs"
version = "0.1.0"
authors = [""]

[[programs]]
path = "src/main.py"
prime_size = 128
12 changes: 12 additions & 0 deletions quickstart/nada_quickstart_programs/src/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from nada_dsl import *

def nada_main():
party1 = Party(name="Party1")
party2 = Party(name="Party2")
party3 = Party(name="Party3")
a = SecretInteger(Input(name="A", party=party1))
b = SecretInteger(Input(name="B", party=party2))

result = a + b

return [Output(result, "my_output", party3)]
Binary file not shown.
150 changes: 12 additions & 138 deletions quickstart_complete/client_code/secret_addition_complete.py
Original file line number Diff line number Diff line change
@@ -1,142 +1,16 @@
"""
In this example, we:
1. connect to the local nillion-devnet
2. store the secret addition program
3. store a secret to be used in the computation
4. compute the secret addition program with the stored secret and another computation time secret
"""
from nillion import Client # Assuming `nillion` is the module being used

import asyncio
import py_nillion_client as nillion
import os

from py_nillion_client import NodeKey, UserKey
from dotenv import load_dotenv
from nillion_python_helpers import get_quote_and_pay, create_nillion_client, create_payments_config

from cosmpy.aerial.client import LedgerClient
from cosmpy.aerial.wallet import LocalWallet
from cosmpy.crypto.keypairs import PrivateKey

home = os.getenv("HOME")
load_dotenv(f"{home}/.config/nillion/nillion-devnet.env")

async def main():
# 1. Initial setup
# 1.1. Get cluster_id, grpc_endpoint, & chain_id from the .env file
cluster_id = os.getenv("NILLION_CLUSTER_ID")
grpc_endpoint = os.getenv("NILLION_NILCHAIN_GRPC")
chain_id = os.getenv("NILLION_NILCHAIN_CHAIN_ID")
# 1.2 pick a seed and generate user and node keys
seed = "my_seed"
userkey = UserKey.from_seed(seed)
nodekey = NodeKey.from_seed(seed)

# 2. Initialize NillionClient against nillion-devnet
# Create Nillion Client for user
client = create_nillion_client(userkey, nodekey)

party_id = client.party_id
user_id = client.user_id

# 3. Pay for and store the program
# Set the program name and path to the compiled program
program_name = "secret_addition_complete"
program_mir_path = f"../nada_quickstart_programs/target/{program_name}.nada.bin"

# Create payments config, client and wallet
payments_config = create_payments_config(chain_id, grpc_endpoint)
payments_client = LedgerClient(payments_config)
payments_wallet = LocalWallet(
PrivateKey(bytes.fromhex(os.getenv("NILLION_NILCHAIN_PRIVATE_KEY_0"))),
prefix="nillion",
)

# Pay to store the program and obtain a receipt of the payment
receipt_store_program = await get_quote_and_pay(
client,
nillion.Operation.store_program(program_mir_path),
payments_wallet,
payments_client,
cluster_id,
)

# Store the program
action_id = await client.store_program(
cluster_id, program_name, program_mir_path, receipt_store_program
)

# Create a variable for the program_id, which is the {user_id}/{program_name}. We will need this later
program_id = f"{user_id}/{program_name}"
print("Stored program. action_id:", action_id)
print("Stored program_id:", program_id)

# 4. Create the 1st secret, add permissions, pay for and store it in the network
# Create a secret named "my_int1" with any value, ex: 500
new_secret = nillion.NadaValues(
{
"my_int1": nillion.SecretInteger(500),
}
)

# Set the input party for the secret
# The party name needs to match the party name that is storing "my_int1" in the program
party_name = "Party1"

# Set permissions for the client to compute on the program
permissions = nillion.Permissions.default_for_user(client.user_id)
permissions.add_compute_permissions({client.user_id: {program_id}})

# Pay for and store the secret in the network and print the returned store_id
receipt_store = await get_quote_and_pay(
client,
nillion.Operation.store_values(new_secret, ttl_days=5),
payments_wallet,
payments_client,
cluster_id,
)
# Store a secret
store_id = await client.store_values(
cluster_id, new_secret, permissions, receipt_store
)
print(f"Computing using program {program_id}")
print(f"Use secret store_id: {store_id}")

# 5. Create compute bindings to set input and output parties, add a computation time secret and pay for & run the computation
compute_bindings = nillion.ProgramBindings(program_id)
compute_bindings.add_input_party(party_name, party_id)
compute_bindings.add_output_party(party_name, party_id)

# Add my_int2, the 2nd secret at computation time
computation_time_secrets = nillion.NadaValues({"my_int2": nillion.SecretInteger(10)})

# Pay for the compute
receipt_compute = await get_quote_and_pay(
client,
nillion.Operation.compute(program_id, computation_time_secrets),
payments_wallet,
payments_client,
cluster_id,
)

# Compute on the secret
compute_id = await client.compute(
cluster_id,
compute_bindings,
[store_id],
computation_time_secrets,
receipt_compute,
)

# 8. Return the computation result
print(f"The computation was sent to the network. compute_id: {compute_id}")
while True:
compute_event = await client.next_compute_event()
if isinstance(compute_event, nillion.ComputeFinishedEvent):
print(f"✅ Compute complete for compute_id {compute_event.uuid}")
print(f"🖥️ The result is {compute_event.result.value}")
return compute_event.result.value
def main():
# Initialize the client
client = Client()

# Your program's specific functionality
# For example, if your program calculates factorial:
number = 5 # Example number
result = client.factorial(number) # Call your program's function

# Print the result
print(f"The factorial of {number} is {result}")

if __name__ == "__main__":
asyncio.run(main())
main()
Binary file not shown.