Blockchain Anchoring
Anchoring creates an immutable audit trail for important events or payloads by writing a compact reference to a blockchain. TrustWeave standardises the experience so you can leverage tamper evidence without becoming a chain expert.
1
2
3
4
dependencies {
implementation("com.trustweave:trustweave-anchor:1.0.0-SNAPSHOT")
implementation("com.trustweave:trustweave-json:1.0.0-SNAPSHOT")
}
Result: Adds the anchoring registry and clients to your project so the examples below compile.
Why anchor data?
- Integrity – recompute a digest and compare it to the anchor; any change breaks the link.
- Provenance – the anchor’s block height or timestamp proves when the information existed.
- Portability –
AnchorRefstructures capture chain ID, transaction hash, optional contract/app ID, and metadata that verifiers can consume.
Anchoring complements verifiable credentials: you can notarise VC digests, presentation receipts, workflow checkpoints—anything that needs an immutable trail.
How TrustWeave anchors payloads
| Step | Implementation |
|---|---|
| 1. Choose a chain | Register a BlockchainAnchorClient (in-memory, Algorand, Polygon, Ethereum, Base, Arbitrum, Indy, or your own adapter). Chains use CAIP-2 IDs such as algorand:testnet. |
| 2. Canonicalise payload | Kotlinx Serialization + JSON Canonicalization Scheme ensure deterministic bytes. |
| 3. Submit | writePayload stores the digest on chain and returns AnchorResult with an AnchorRef. |
| 4. Verify | readPayload rehydrates the JSON, or recompute the digest locally and compare to the stored reference. |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import com.trustweave.TrustWeave
import com.trustweave.core.*
import kotlinx.serialization.json.Json
// Using TrustWeave facade (recommended)
import com.trustweave.trust.TrustWeave
val trustWeave = TrustWeave.build { ... }
val anchorResult = trustWeave.blockchains.anchor(
data = credential,
serializer = VerifiableCredential.serializer(),
chainId = "algorand:testnet"
)
println("Anchored tx: ${anchorResult.ref.txHash}")
// With error handling (wrap in try-catch)
try {
val anchor = trustWeave.blockchains.anchor(data, serializer, chainId)
result.fold(
onSuccess = { anchor -> println("Anchored tx: ${anchor.ref.txHash}") },
onFailure = { error ->
when (error) {
is TrustWeaveError.ChainNotRegistered -> {
println("Chain not registered: ${error.chainId}")
}
else -> println("Anchoring error: ${error.message}")
}
}
)
Configuring clients
- In-memory – perfect for tutorials and unit tests.
- Algorand – use
AlgorandBlockchainAnchorClientOptions(algodUrl,algodToken, optional private key). - Polygon / Ganache – specify RPC endpoints, signer keys, and (optionally) contract addresses.
- Indy – configure pool parameters and wallet credentials for permissioned ledgers.
- Custom – implement
BlockchainAnchorClientorBlockchainAnchorClientProvider(discovered via SPI).
Reading and verifying
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import com.trustweave.trust.TrustWeave
import com.trustweave.core.*
// Using TrustWeave facade (recommended)
val trustWeave = TrustWeave.build { ... }
val data = trustWeave.blockchains.read<VerifiableCredential>(
ref = anchorRef,
serializer = VerifiableCredential.serializer()
)
println("Read credential: ${data.id}")
// With error handling (wrap in try-catch)
try {
val data = trustWeave.blockchains.read<VerifiableCredential>(ref, serializer)
result.fold(
onSuccess = { data -> println("Read: ${data.id}") },
onFailure = { error ->
when (error) {
is TrustWeaveError.ChainNotRegistered -> {
println("Chain not registered: ${error.chainId}")
}
else -> println("Read error: ${error.message}")
}
}
)
readAnchorreturnsResult<T>with the deserialized data.- For higher assurance, recompute the digest from the canonical payload and compare it to the data stored on chain.
- Keep connection credentials (RPC tokens, private keys) in a secret store for production deployments.
- All anchoring operations return
Result<T>for consistent error handling.
Practical usage tips
- Persist AnchorRefs with credentials so verifiers can revalidate without bespoke lookups.
- Retry-friendly anchoring – public chains may require exponential back-off; design idempotent submissions.
- Integrate with revocation – anchor revocation lists or proofs to create audit trails for credential status changes.
- Testing – use the in-memory client or spin up Ganache/Testnet clients for end-to-end tests.
- Error handling – all anchoring operations return
Result<T>with structuredTrustWeaveErrortypes. See Error Handling. - Input validation – TrustWeave automatically validates chain ID format and registration before anchoring.
See also
- Blockchain Anchor Integration Guides – Implementation guides for Algorand, Ethereum, Base, Arbitrum, Polygon, and Ganache
- Quick Start – Step 5 for an end-to-end example.
- Wallet API Reference – Anchoring helpers for wallet-integrated flows.
- Architecture Overview for the DID ➜ credential ➜ anchor flow.
- Verifiable Credentials to understand what you may want to anchor.
- Blockchain-Anchored Revocation for anchoring credential revocation status lists.
Blockchain Anchoring
Anchoring creates an immutable audit trail for important events or payloads by writing a compact reference to a blockchain. TrustWeave standardizes the experience so you can take advantage of tamper evidence without having to become a chain expert.
Why Anchor?
- Integrity – prove a payload was not modified after anchoring by recomputing its digest and comparing it to the on-chain reference.
- Provenance – demonstrate when information existed by referencing the block height or timestamp of the anchor transaction.
- Portability – exchangeable
AnchorRefmodels capture chain, transaction hash, optional contract, and any custom metadata.
Anchoring is complementary to verifiable credentials: you can anchor raw JSON, credential digests, presentation receipts, or any other data you want to notarize.
How TrustWeave Anchoring Works
- Choose a chain – TrustWeave ships with in-memory clients for testing and adapters for Algorand, Polygon, Ethereum, Base, Arbitrum, Indy, and community providers. Chains are identified using CAIP-2 strings (for example
algorand:testnet). - Serialize the payload – the SDK serializes your Kotlin data using Kotlinx Serialization before hashing.
- Submit – the registered
BlockchainAnchorClientstores the digest on-chain and returns anAnchorResultcontaining theAnchorRef(transaction hash, contract/app ID, chain). - Verify – later you can
readPayloador independently recompute the digest to confirm the payload matches the anchor reference.
1
2
3
val anchorClient = anchorRegistry.get("algorand:testnet")
val result = anchorClient?.writePayload(jsonPayload)
println("Anchored tx: ${result?.ref?.txHash}")
Configuring Clients
- In-memory – great for tests. Register with
BlockchainAnchorRegistry().register("inmemory:anchor", InMemoryBlockchainAnchorClient("inmemory:anchor")). - Algorand – configure
AlgorandBlockchainAnchorClientOptions(algodUrl,algodToken, optional private key for signing). See Algorand Integration Guide. - Polygon / Ganache – supply RPC URLs, contract addresses, and private keys via typed options. See Integration Modules.
- Indy – connect to Hyperledger Indy pools using pool endpoints, wallet names, and DIDs.
All clients share a common template (AbstractBlockchainAnchorClient) for fallbacks, metadata, and error handling. You can implement your own by extending the base class or providing an SPI adapter discovered via META-INF/services.
Reading and Verifying
1
2
3
val anchorRef: AnchorRef = result.ref
val stored = anchorClient?.readPayload(anchorRef)
println("Stored mediaType=${stored?.mediaType} payload=${stored?.payload}")
- The payload is returned as a
JsonElement; you can re-hydrate it using your serializer. - Anchoring with in-memory fallbacks works without private keys, which makes it ideal for unit tests and demos.
- For production you should secure credentials (RPC URLs, tokens, private keys) using your secrets management system.
When to Use Anchoring
- Credential issuance receipts or revocation records.
- Supply-chain checkpoints or sensor readings.
- Publication timestamps for news or research.
- Any workflow where you need evidence that “this existed in this exact form at this time.”
Next Steps
Ready to use Blockchain Anchoring?
- Quick Start – Step 5 - Anchor your first credential
- Core API Reference – Blockchain Operations - Complete API documentation
- TrustWeave Anchor Module - Implementation details
Want to learn more?
- Verifiable Credentials - Issue and verify credentials
- Blockchain-Anchored Revocation - Revocation with blockchain anchoring
- Smart Contracts - Executable agreements with anchoring
Related How-To Guides
- Anchor to Blockchain - Step-by-step guide for anchoring data to blockchains
Explore integrations:
- Blockchain Integrations - Algorand, Polygon, Ethereum, and more
- Use Case Scenarios - Real-world anchoring examples