Skip to content

Latest commit

 

History

History
325 lines (245 loc) · 8.96 KB

File metadata and controls

325 lines (245 loc) · 8.96 KB

Example Workflow

This document demonstrates a practical workflow using Ledgerator for document attestation between multiple parties.

Scenario

Three parties need to agree on a service contract:

  • Alice (Service Provider) - Registers the contract
  • Bob (Client) - Reviews and accepts the contract
  • Carol (Witness) - Acknowledges the agreement

Setup

Start Local Environment

# Terminal 1: Start Anvil (local Ethereum node)
anvil

# Terminal 2: Deploy contract
make deploy-local

Configure CLI

Each party configures their CLI with the deployed contract address.

Alice's config (~/.ledgerator/config.toml):

[network]
rpc_url = "http://localhost:8545"
chain_id = 31337
contract_address = "0x5FbDB2315678afecb367f032d93F642f64180aa3"

Private keys (Anvil test accounts):

# Alice (Anvil account #0)
export LEDGERATOR_PRIVATE_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"

# Bob (Anvil account #1)
export LEDGERATOR_PRIVATE_KEY="0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"

# Carol (Anvil account #2)
export LEDGERATOR_PRIVATE_KEY="0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"

Workflow Steps

1. Set Up Identities

First, let's configure identities for the participants to make output more readable:

# Alice sets up identities for all parties
ledge identity set 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 Alice
ledge identity set 0x70997970C51812dc3A010C7d01b50e0d17dc79C8 Bob
ledge identity set 0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC Carol

# View all identities
ledge identity list
# Output:
# Identities:
#   0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC: Carol
#   0x70997970C51812dc3A010C7d01b50e0d17dc79C8: Bob
#   0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266: Alice

2. Alice Creates and Registers the Contract

Create the contract document:

cat > service-contract.txt << EOF
Service Agreement

Provider: Alice (0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266)
Client: Bob (0x70997970C51812dc3A010C7d01b50e0d17dc79C8)
Witness: Carol (0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC)

Services: Web Development
Duration: 6 months
Payment: 50 ETH
Start Date: 2026-01-15

Terms:
1. Provider delivers working website
2. Client pays upon delivery
3. Witness validates completion
EOF

Register with Ledgerator:

ledge register service-contract.txt \
  --title "Service Agreement - Alice & Bob" \
  --description "6-month web development contract" \
  --location "s3://shared-contracts/2026-01-02/service-agreement.txt"

# Output:
# Computing file hash...
# Registering document on blockchain...
# Uploading metadata...
# Document registered successfully!
# Hash: 0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e
# Transaction hash: 0xabc123...

Alice attests to the contract:

ledge attest 0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e \
  --type ACCEPT

# Output:
# Attesting to document 0x7d3e...
# Transaction hash: 0xdef456...
# Attestation recorded: ACCEPT

Alice shares the hash with Bob and Carol via email or Slack.

2. Bob Reviews and Accepts

Bob receives the contract file and hash from Alice.

First, verify the file matches the hash:

# Switch to Bob's private key
export LEDGERATOR_PRIVATE_KEY="0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"

# Verify file hash
ledge verify service-contract.txt 0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e

# Output:
# Computing file hash...
# Expected hash:  0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e
# Computed hash:  0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e
#
# ✓ Hashes match!

Query the document to verify on-chain registration:

ledge query 0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e

# Output:
# Querying document 0x7d3e...
#
# Blockchain Information:
#   Hash: 0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e
#   Registrar: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (Alice)
#   Registered At: 1704240000 (Unix timestamp)
#
# Metadata:
#   Title: Service Agreement - Alice & Bob
#   Description: 6-month web development contract
#   Retrieved From: s3://shared-contracts/2026-01-02/service-agreement.txt
#
# Attestations:
#   0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (Alice) - ACCEPT (1704240123)

Bob adds his own metadata locally:

# Register the document locally with Bob's metadata
ledge register service-contract.txt \
  --title "Service Agreement - Alice & Bob" \
  --description "Web dev contract - reviewed and approved" \
  --location "s3://shared-contracts/2026-01-02/service-agreement.txt"

Bob attests acceptance:

ledge attest 0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e \
  --type ACCEPT

# Output:
# Attesting to document 0x7d3e...
# Transaction hash: 0x123abc...
# Attestation recorded: ACCEPT

3. Carol Witnesses the Agreement

Carol switches to her private key:

export LEDGERATOR_PRIVATE_KEY="0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"

Carol verifies file hash and on-chain registration:

# Verify file hash
ledge verify service-contract.txt 0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e
# ✓ Hashes match!

# Verify on-chain registration
ledge query 0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e

# Output shows Alice and Bob have both accepted
# Attestations:
#   0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (Alice) - ACCEPT (1704240123)
#   0x70997970C51812dc3A010C7d01b50e0d17dc79C8 (Bob) - ACCEPT (1704240456)

Carol adds her witness attestation:

# Store metadata locally
ledge register service-contract.txt \
  --title "Alice-Bob Service Agreement" \
  --description "Witnessed agreement between Alice and Bob" \
  --location "s3://shared-contracts/2026-01-02/service-agreement.txt"

# Witness the agreement
ledge attest 0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e \
  --type WITNESS

# Output:
# Attesting to document 0x7d3e...
# Transaction hash: 0x789def...
# Attestation recorded: WITNESS

4. Final Verification

Anyone can now query the complete attestation history:

ledge query 0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e

# Output:
# Querying document 0x7d3e...
#
# Blockchain Information:
#   Hash: 0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e
#   Registrar: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (Alice)
#   Registered At: 1704240000 (Unix timestamp)
#
# Attestations:
#   0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 (Alice) - ACCEPT (1704240123)
#   0x70997970C51812dc3A010C7d01b50e0d17dc79C8 (Bob) - ACCEPT (1704240456)
#   0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC (Carol) - WITNESS (1704240789)

The blockchain now contains immutable proof that:

  1. Alice registered the document on 2026-01-02
  2. Alice accepted it immediately
  3. Bob accepted it a few minutes later
  4. Carol witnessed the agreement shortly after

5. Sharing Metadata (Optional)

If Alice wants to share her local metadata with a team member:

# Alice exports metadata
ledge export my-contracts.json

# Metadata file can be shared via email, Slack, etc.

# Team member imports
ledge import my-contracts.json

# Now they can see Alice's local metadata
ledge list

List All Documents

Each party can list their locally tracked documents:

ledge list

# Output:
# Documents:
#
# Hash: 0x7d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e
#   Title: Service Agreement - Alice & Bob
#   Registrar: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
#   Local Path: /Users/alice/contracts/service-contract.txt
#   Retrieved From: emailed to all parties on 2026-01-02

Filter by registrar:

ledge list --registrar 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266

Key Takeaways

  1. Immutable Record: All attestations are permanently recorded on the blockchain
  2. Verification: Anyone can verify the document hash matches the file
  3. Timeline: Blockchain timestamps prove when each action occurred
  4. Trust: No central authority - cryptographic proof via blockchain
  5. Privacy: Metadata stays local unless explicitly shared
  6. Collaboration: Export/import enables selective metadata sharing

Production Workflow

For production use on mainnet:

  1. Deploy contract to Ethereum mainnet
  2. Update config.toml with mainnet RPC and contract address
  3. Use production private keys (not test accounts!)
  4. Share document hashes through existing communication channels
  5. Use export/import for team metadata sharing
  6. Query blockchain to verify attestations at any time

Security Considerations

  • Private Keys: Never share your private key
  • File Verification: Always verify hash before attesting
  • Blockchain Fees: Mainnet transactions cost gas
  • Metadata Privacy: Local storage means metadata stays private
  • Export Security: Exported JSON contains your metadata - share carefully