Skip to main content

Ethernity Cloud logo

The Python implementation of the Ethernity CLOUD SDK protocol

Ethernity Cloud SDK PY

This project provides a set of tools and scripts to work with the Ethernity Cloud SDK in a python environment.

Table of Contents

Pre-requisites

Linux:

  • build-essentials
  • Python 3.10+
  • docker
  • docker-compose

Windows:

  • Python 3.13
  • Docker Desktop

Installation

To install the package and its dependencies, run:

python -m venv venv

source venv/bin/activate # for MacOS and Linux
venv\Scripts\activate # for Windows

pip install ethernity-cloud-sdk-py

Usage

After installation, you can use the provided scripts to build, publish, and initialize your project.

Operating System compatibility

The sdk has been tested on the following operating systems:

  • Windows 10
  • linux (Ubuntu 20.04)

Blockchain compatibility

  • Bloxberg:
    • Testnet - tested and working. CAS-attested: the securelock is provisioned by the ethernity-cas validator set exactly as on mainnet. ecld-publish registers the image in the ImageRegistry (ECImageRegistryV3, 0xa372a6e1...) before anything discloses its name, which makes the name the publishing wallet's; then registers the securelock session on-chain in the SessionRegistry (0x44442968...), which takes it only from that wallet, resolves a CAS from the ValidatorRegistry (0x0014aB10..., or ECLD_CAS_ADDR=host:port) for the compose and the certificate harvest, and links the session to the published image. ecld-build signs the securelock --production. The certificate is harvested on an SGX host or, without one, extracted by publickey.ethernity.cloud, which fetches the image from the publish's IPFS node and attests it through a CAS member it resolves from the ValidatorRegistry. tests/e2e_testnet_cas.sh runs the whole path -- init, build, publish, one task, and the CAS validators' verdict on it. The other testnets (Amoy, IoTeX, Sepolia, LiteForge) have no CAS deployment and self-sign from MR_ENCLAVE as before.
    • Mainnet - to be provided during the following updates
  • Polyhon:
    • Amoy Testnet - to be provided during the following updates
    • Mainnet - to be provided during the following updates

Scripts

  • Initialize: To initialize the project, run:

    ecld-init
    

    at this step, all the initial configurations will be set up and the project will be ready to be built, published and run.

  • Build: To build the project, run:

    ecld-build
    

    the project will be built and the docker repository output will be stored in the registry/ directory. This is the stage where the backend functions are added to the secure images.

  • Publish: To publish the project, run:

    ecld-publish
    

    Required after build, to build and integrate the secure certificates that will be used during executions and to register the project to the Ethernity Cloud Image Register. DEVELOPER_FEE in .config.json is your fee as the image's publisher, in percent of each task's base price (the node's price): the network adds it to what the dApp user pays and pays it to the image's reward address when the task is validated. Default 0; the registry accepts up to 15, and the fee is fixed once the image is registered. The reward address is the publishing wallet unless REWARD_ADDRESS names another one; the image's owner can change it later with the registry's changeImageRewardAddress.

    How the image reaches the network: unless .config.json names an IPFS API of your own (IPFS_ENDPOINT, or ECLD_IPFS_ENDPOINT in the environment), the publish runs its own IPFS node in docker (ipfs/kubo), adds the image and its compose there and peers it with the network's bootnode, which pins every registered image. An endpoint naming ipfs.ethernity.cloud counts as no endpoint (configs written by earlier versions of ecld-init): the publish runs its own node. For an API of your own that requires one, IPFS_TOKEN (or ECLD_IPFS_TOKEN) is sent verbatim as the Authorization header, on the image upload and on the session body's add alike; your own node needs none. On a network whose image registry records images before their certificate (the bloxberg testnet), the publish registers the image from your wallet first (registerImage, with your node's address), has the certificate extracted (on your SGX host, or by publickey.ethernity.cloud, which fetches the image from your node or the bootnode and reports its progress) and writes it from the same wallet (setImageCert). Keep the publish running until it prints the registration: your node is the image's first source. ECLD_KUBO_SWARM_PORT (default 4001) is the port your node listens on when it is free, ECLD_IPFS_PEERS (comma-separated multiaddrs, default the bootnode) the peers it keeps connected to, and ECLD_KUBO_IMAGE (default ipfs/kubo:release) the docker image it runs.

  • Test (local, no chain): To run your backend locally with the enclave's own executor — no SGX, no gas, instant — run:

    ecld-test 'hello("World")'
    ecld-test --file payload.py
    ecld-test --input data.json 'process(___etny_data_set___)'
    

    This validates the call (function names, arguments, result wiring) before a single on-chain request is paid for. If your dApp uses ESR (Enclave State Registry), state is emulated locally and on by default: StateRegistry get/commit, ownership/ACL, and task_caller() all work in-process against an in-memory registry, and persist between runs in .ecld-esr-local.*.json. The task caller defaults to your developer address; override it with --caller. ecld-test serve starts a local API so the runner's LOCAL mode drives your real integration end to end. Exit code 0 on SUCCESS, 1 otherwise.

  • Run (on the network): To submit a payload to the network and print the decrypted result, run:

    ecld-run 'hello("World")'
    ecld-run --file payload.py
    ecld-run --input data.json 'process(___etny_data_set___)'
    ecld-run --json 'esr_increment()'
    

    This is the network-side sibling of ecld-test: instead of executing locally it drives the runner end to end — encrypt → on-chain request → payload intake → wait for a node → download and decrypt the result. The task's artefacts go through the bootnode's payload intake; --ipfs <url> uploads and reads them through a Kubo RPC API of your own instead (e.g. http://127.0.0.1:5001; /api/v0 is appended when the URL does not end in it), with --ipfs-token (or ECLD_IPFS_TOKEN) sent verbatim as its Authorization header when that API requires one. It costs gas and needs a funded key. Network and enclaves come from .config.json (BLOCKCHAIN_NETWORK, PROJECT_NAME, TRUSTED_ZONE_IMAGE), overridable with --network/--securelock/--trustedzone; the signing key is ECLD_PRIVATE_KEY (plaintext) or the encrypted ENC_PRIVATE_KEY unlocked with ECLD_KEY_PASSWORD (or an interactive prompt). Resources are tunable with --task-price/--cpu/--memory/--storage/--bandwidth/--duration/--validators. Exit code 0 on a SUCCESS task result, 1 otherwise. (python src/ethernity_task.py remains available as a scriptable template if you prefer driving the runner yourself.) --unsafe runs the network's -unsafe variant (see below).

  • The testnets and their unsafe networks: Bloxberg Testnet (BLOXBERG_TESTNET) and LitVM LiteForge (LITVM_LITEFORGE) run your securelock in an enclave attested through that chain's Ethernity CAS validator set, on nodes whose platform the CAS can attest (DCAP). Each has an unsafe network beside it, Bloxberg Testnet unsafe (no CAS) (BLOXBERG_TESTNET_UNSAFE) and LitVM LiteForge unsafe (no CAS) (LITVM_LITEFORGE_UNSAFE): the same chain and contracts, for hardware SGX platforms the CAS cannot attest (EPID-only, SGX1). No CAS: enclaves are debug-signed and self-signed from their measurement, so a result proves which image ran but not that an enclave ran it. You choose an unsafe network by name, and the runner runs an -unsafe trustedzone on nothing else, so a dApp that runs without a CAS always says so in the network it names. A dApp publishes one securelock per network from two project directories with the same project name: the unsafe one is registered as <project>-unsafe and runs on the etny-pynithy-testnet-unsafe (ecld-pynithy-litvm-testnet-unsafe) trustedzone. Mainnet has no unsafe network.

  • Inspect (read-only): To read enclave and on-chain diagnostics — network, trustedzone/securelock registration, and ESR state — without spending gas, run:

    ecld-info
    ecld-info esr state <key>
    

Usage

To use the SDK:

  • after installation, run ecld-init to initialize the project
  • in you workspace, you will find the scr/serverless directory, this contains a backend.py file. This file will be imported in the dApp images to provide the backend functions for calling from the frontend of your application, eg.:
def hello(msg='World'):
    return "Hello "+msg

From your py application, using the ethernity cloud runner library, you will be calling the function as seen in the below example, where we pass hello("World") to be executed on the backend which will run in the Blockchain:

import os
from getpass import getpass
from dotenv import load_dotenv

load_dotenv()

from ethernity_cloud_runner_py.runner import EthernityCloudRunner  # type: ignore
from ethernity_cloud_sdk_py.commands.private_key import PrivateKeyManager


def execute_task() -> None:
    code = 'hello("Hello, Python World!")'

    # The funded 0x key that pays for the order. ecld-publish exports it to
    # src/.env as ENC_PRIVATE_KEY, encrypted with your key password (as a
    # plaintext PRIVATE_KEY only when told not to encrypt it).
    private_key = PrivateKeyManager(getpass("Private key password: ")).decrypt_private_key(
        os.getenv("ENC_PRIVATE_KEY")
    )

    runner = EthernityCloudRunner(os.getenv("NETWORK_NAME"), os.getenv("NETWORK_TYPE"))
    runner.set_private_key(private_key)
    # The task's artefacts go through the bootnode's payload intake; a Kubo RPC
    # API of your own goes in runner.set_storage_ipfs(url, token) instead.
    runner.set_public_intake()
    runner.connect()

    resources = {
        "taskPrice": 8,
        "cpu": 1,
        "memory": 1,
        "storage": 1,
        "bandwidth": 1,
        "duration": 1,
        "validators": 1,
    }
    # run(resources, securelock, protocol version, code, node, trustedzone):
    # the version is the protocol's, "v3", under which the image registry keys
    # the securelock; an empty node lets any node take the order.
    runner.run(
        resources,
        os.getenv("PROJECT_NAME"),
        "v3",
        code,
        "",
        os.getenv("TRUSTED_ZONE_IMAGE", ""),
    )


if __name__ == "__main__":
    execute_task()
  • you are able to define the functions needed to be used in the backend, while making sure that the function that is script is compilable and that it exports the function that will be called from the frontend, in the above example, the hello function.

Contributing

Contributions are welcome! Please open an issue or submit a pull request.

License

This project is licensed under the AGPL-3.0 License. See the LICENSE file for details.

Metadata

Release files for ethernity-cloud-sdk-py 0.9.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for ethernity-cloud-sdk-py 0.9.8
File Size Uploaded
ethernity_cloud_sdk_py-0.9.8.tar.gz 189.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for ethernity-cloud-sdk-py 0.9.8
File Interpreter ABI Platform
ethernity_cloud_sdk_py-0.9.8-py3-none-any.whl Python 3 none any Details

Total release size: 401.8 kB

Release files / ethernity_cloud_sdk_py-0.9.8.tar.gz

Download URL ethernity_cloud_sdk_py-0.9.8.tar.gz
Size 189.4 kB
Tags Source
SHA-256 checksum
How to use checksums
a42edf825706d7e72d3ed006a2af24490c10cef4f743abeaf1e492fa7a82682c
BLAKE2b-256 checksum
How to use checksums
4073c6444b235a70bfd1e2b9f154437c58c2d5e54a3010e3539436c8a5dc3f0a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.5

Release files / ethernity_cloud_sdk_py-0.9.8-py3-none-any.whl

Download URL ethernity_cloud_sdk_py-0.9.8-py3-none-any.whl
Size 212.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0c29c4b6c7abcf7b70589db32f421d6352cf8e586b0ba1a039ea360fe660fed8
BLAKE2b-256 checksum
How to use checksums
ee67dd431242f883d7ee826bd2c39220dedffb1e6f7f315e6c93c8f24485cf91
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.5

Release history Release notifications | RSS feed

0.9.13

2 release files

0.9.12

2 release files

0.9.11

2 release files

0.9.10

2 release files

0.9.9

2 release files

This release

0.9.8 This release

2 release files

0.9.7

2 release files

0.9.6

2 release files

0.9.5

2 release files

0.9.3

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.8.37

2 release files

0.8.36

2 release files

0.8.35

2 release files

0.8.34

2 release files

0.8.30

2 release files

0.8.29

2 release files

0.8.28

2 release files

0.8.27

2 release files

0.8.26

2 release files

0.8.25

2 release files

0.8.24

2 release files

0.8.23

2 release files

0.8.22

2 release files

0.8.21

2 release files

0.8.20

2 release files

0.8.19

2 release files

0.8.18

2 release files

0.8.17

2 release files

0.8.15

2 release files

0.8.14

2 release files

0.8.13

2 release files

0.8.12

2 release files

0.8.11

2 release files

0.8.10

2 release files

0.8.9

2 release files

0.8.8

2 release files

0.8.7

2 release files

0.8.6

2 release files

0.8.5

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.3.25

2 release files

0.3.24

2 release files

0.3.9

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.46

2 release files

0.2.45

2 release files

0.2.43

2 release files

0.2.42

2 release files

0.2.41

2 release files

0.2.40

2 release files

0.2.39

2 release files

0.2.38

2 release files

0.2.37

2 release files

0.2.36

2 release files

0.2.35

2 release files

0.2.34

2 release files

0.2.33

2 release files

0.2.32

2 release files

0.2.31

2 release files

0.2.30

2 release files

0.2.29

2 release files

0.2.28

2 release files

0.2.27

2 release files

0.2.26

2 release files

0.2.25

2 release files

0.2.24

2 release files

0.2.23

2 release files

0.2.22

2 release files

0.2.21

2 release files

0.2.20

2 release files

0.2.19

2 release files

0.2.18

2 release files

0.2.17

2 release files

0.2.16

2 release files

0.2.14

2 release files

0.2.13

2 release files

0.2.12

2 release files

0.2.11

2 release files

0.2.10

2 release files

0.2.9

2 release files

0.2.8

2 release files

0.2.7

2 release files

0.2.6

2 release files

0.2.5

2 release files

0.2.4

2 release files

0.2.3

2 release files

0.2.2

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.32

1 release file

0.1.31

2 release files

0.1.30

2 release files

0.1.29

2 release files

0.1.28

2 release files

0.1.14

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page