Smart Actions

Atomic verifiable computation units composing into Smart Workflows. Each produces cryptographic attestations of execution correctness.

Smart Actions define computations with formal input/output specifications and produce cryptographic attestations. Composing Smart Actions maintains end-to-end verifiability guarantees.

Examples

w3-io/actions/storage/storj

v1

Decentralized S3-compatible object storage. Store workflow state, execution results, and artifacts with cryptographic proof of storage. Fully compatible with AWS S3 API.

Execution:🔒 TEE
Verification:Content Hash + Availability

Storj access grant is a secret credential. Must decrypt in TEE to prevent validator operator from accessing your storage.

Action Definition

action.yml (Published in w3-io/actions repo)
name: Storj Storage
description: Decentralized S3-compatible storage with TEE secret handling

inputs:
  bucket:
    description: S3 bucket name
    required: true
  key:
    description: Object key
    required: true
  operation:
    description: read or write
    required: true
  access_grant:
    description: Storj access grant (encrypted for TEE)
    required: true
    encrypted: true

outputs:
  content_hash:
    description: SHA256 of content
  size_bytes:
    description: Object size

runs:
  using: tee
  platform: intel_sgx
  main: dist/index.js
  secrets:
    - access_grant

Usage in Workflow

Workflow Step Declaration
- name: Example step
  uses: w3-io/actions/storage/storj@v1
  with:
    bucket: "w3-workflows-production"
    key: "workflows/0x4f3a7c9e.../run_1730485532.json"
    operation: "write"
    data: [object Object]
    access_grant: "${{ secrets.STORJ_ACCESS_GRANT }}"

Execution

Execution Code
// Storj S3-compatible storage
const s3 = new StorjS3({
  accessGrant: inputs.access_grant
});

if (inputs.operation === "write") {
  const content = JSON.stringify(inputs.data);
  const hash = sha256(content);

  await s3.putObject({
    Bucket: inputs.bucket,
    Key: inputs.key,
    Body: content,
    Metadata: {
      content_hash: hash,
      timestamp: Date.now()
    }
  });

  return {
    key: inputs.key,
    content_hash: hash,
    size_bytes: content.length,
    operation: "write"
  };
} else {
  const obj = await s3.getObject({
    Bucket: inputs.bucket,
    Key: inputs.key
  });

  const content = await obj.Body.text();
  return {
    key: inputs.key,
    content_hash: sha256(content),
    data: JSON.parse(content),
    operation: "read"
  };
}
Output
{
  "key": "workflows/0x4f3a7c9e.../run_1730485532.json",
  "content_hash": "0x8a3f9c2e5d7b1a4c6f9e2b8d5a7c3e9f1b4d7a0c3e6b9f2d5a8c1e4f7b0d3a6",
  "size_bytes": 234,
  "operation": "write"
}

Verification

Attestation
{
  "action": "w3-io/actions/storage/storj@v1",
  "operation": "write",
  "bucket": "w3-workflows-production",
  "key": "workflows/0x4f3a7c9e.../run_1730485532.json",
  "content_hash": "0x8a3f9c2e5d7b1a4c6f9e2b8d5a7c3e9f1b4d7a0c3e6b9f2d5a8c1e4f7b0d3a6",
  "size_bytes": 234,
  "timestamp": 1730485532000,
  "storj_metadata": {
    "pieces_stored": 80,
    "nodes_storing": 40,
    "erasure_code": "29/80"
  }
}
Verify Logic
// Verify storage operation
fn verify(attestation: Attestation) -> bool {
    // Challenge: retrieve content from Storj
    let retrieved = storj_client.get_object(
        attestation.bucket,
        attestation.key
    );

    // Verify content hash matches
    let actual_hash = sha256(&retrieved.content);
    if actual_hash != attestation.content_hash {
        return false;
    }

    // Verify availability (can retrieve)
    if retrieved.is_none() {
        return false;
    }

    // Verify metadata
    retrieved.size == attestation.size_bytes
        && storj_metadata_valid(attestation)
}