Migration Guide
This guide helps developers migrate from the USC testnet v1 to the latest USC testnet v2.
Overview
The latest version, v2, introduces significant architectural improvements over version v1.
V1 Architecture
Prover Contracts - Smart contracts acting as oracle interfaces (e.g.,
IPublicProver)STARK Proving - Cryptographic proofs generated using Cairo programs and Stakeware's stone prover
Prover Services - Separate off-chain services that generated proofs
Escrow/Payment System - Payment held in escrow until proof verification
Query Submission Flow - Users submit queries → provers generate STARK proofs → proofs verified on-chain
V2 Architecture
Significantly simplified:
Native Query Verification Precompile - Direct on-chain verification at
0x0FD2No STARK Proofs Required - Native verification without separate cryptographic proofs
No Prover Contracts - Direct precompile calls, no need to deploy oracle interface contracts
No Escrow System - Direct verification without payment escrow
Simplified Flow - Direct verification calls with immediate results
For architecture details, see USC Architecture Overview.
Breaking Changes
1. From Prover Contracts to Native Precompile
V1 had:
Prover contracts with escrow/payment system
Off-chain STARK proof generation
Query submission → wait → read results workflow
V2 has:
Direct precompile calls to
0x0FD2Native verification (no STARK proofs)
Immediate verification results
2. New Precompile Addresses added
V1 had:
0x0FD1(4049) - SubstrateTransferPrecompile0x13B9(5049) - SignatureVerifierPrecompile
V2 has:
0x0FD1(4049) - SubstrateTransferPrecompile (unchanged)0x13B9(5049) - SignatureVerifierPrecompile (unchanged)0x0FD2(4050) - BlockProverPrecompile (New - Native Query Verifier)0x0FD3(4051) - ChainInfoPrecompile (New)
3. Interface Function Changes
V2 Functions:
verifyAndEmit()- State-changing function that emitsTransactionVerifiedeventsverify()- View function for read-only verificationBatch verification overloads for both functions
New Event (optional; emitted with verifyAndEmit()):
verifyAndEmit()):For more details on new interface see: Universal Smart Contracts
Network Endpoints
See Quickstart for network endpoints and configuration.
Smart Contract Migration
In this section, we provide a brief overview of what all changes you will notice moving from v1 to v2.
V1 Approach:
V1 uses prover contracts that store query results. The complete flow involves multiple steps across different files and toolchains:
Step 1: Submit query with payment
Off-chain code submits a query to the prover contract with payment (snippet from submit_query.ts):
Step 2: Wait for prover to generate STARK proof and submit
The prover contract emits QuerySubmitted event. Off-chain provers listen to this event, generate STARK proofs, and submit them back to the contract. This step happens asynchronously off-chain.
Step 3: Listen for QueryProofVerified event
Off-chain code listens for the QueryProofVerified event indicating the proof was verified and results are stored (snippet from submit_query.ts):
Step 4: Read results from contract storage
Contracts inherit from UniversalSmartContract_Core and read ResultSegment[] from prover contract storage (snippet from MintableUSCBridge.sol):
The _processUSCQuery function reads from prover contract storage (snippet from UniversalSmartContract_Core.sol):
V2 Approach:
In v2 this process is really simplified by direct precompile calls with full transaction data (snippet from SimpleMinterUSC.sol):
Code Migration Examples
To better understand how to use version v2, see Universal Smart Contracts for in-depth explanation. Details example contracts are also available in the examples repository.
Troubleshooting
Common Issues
1. "Proof not found" / 404 from Proof API Server
Problem: Proof generation API server cannot find the transaction or block
Solutions:
Check if proof server is running via:
/api/v1/healthVerify transaction hash/index is correct
Check if block height exists on source chain and attestation block has been created
2. "Attestation not found" / "Block not ready"
Problem: Block hasn't been attested yet by the attestor network
Solutions:
Wait for attestors to attest the block
Verify attestor network is running and check attestation status on Creditcoin node
3. "Attestations missing for chain {chain_key}"
Problem: No attestations exist for the specified chainKey
Solutions:
Verify attestor network is running and configured for this chain
Check if attestations exist on-chain and verify
chainKeymatches source chain configuration
4. "Proof server down" / Connection refused
Problem: Proof generation API server is not running or unreachable
Solutions:
Check if proof server is running:
curl <http://localhost:3100/api/v1/health>Check server logs and verify RPC connections for issues
5. "No attestation or checkpoint found after block {height}"
Problem: Continuity proof requires an attestation/checkpoint after the query block, but it doesn't exist yet
Solutions:
Wait for next attestation to be created (check attestation interval, e.g., every 10 blocks)
6. "Transaction hash not found"
Problem: Proof API cannot find transaction by hash
Solutions:
Try using block height and transaction index instead:
/api/v1/proof/{chainKey}/{height}/{txIndex}
7. "Query height out of range"
Problem: Requested block height is invalid
Solutions:
Verify height is between lower and upper attestation bounds (not at or outside them)
Check if query height matches an attestation/checkpoint block (may need to adjust)
Ensure attestations exist for the chain and query height is within attested range
8. "Proof generation server returns 500 error for transactions"
Problem: Proof generation API server returns HTTP 500 (Internal Server Error) when requesting proofs
Solutions:
Check proof server logs for specific error details (database errors, RPC failures, Merkle proof generation issues)
Verify the transaction block has been attested (see issue #2 above)
Ensure source chain RPC is accessible and responding correctly
Check database connectivity if proof server uses caching
Verify the transaction exists on the source chain and is finalized
Wait for attestation before requesting proof (see Worker Flow below)
9. Worker Flow: Understanding targetHeight
Problem: Confusion about when workers should request proofs and what height to wait for
Clarification:
targetHeightis not the current source chain headtargetHeight = transactionBlockNumber + 1Workers should wait until
latestAttestation >= targetHeightThis guarantees the transaction block itself is attested before proof generation
This matters because if a transaction is in block N, waiting for block N+1 to be attested ensures block N is attested. Requesting proofs before the block is attested will result in "Block not ready" or 500 errors. This is related to issue #8 above - premature proof requests cause server errors
10. "Gas estimation failed: execution reverted"
Problem: Gas estimation fails because it simulates the transaction execution, and during simulation the precompile may revert. This is a known issue with pallet-evm. Note that the gas estimation failure does not necessarily mean the transaction will fail.
Workaround: Catch gas estimation failures and calculate gas based on continuity proof size instead:
This workaround is already implemented in the computeGasLimit() function in the examples repository.
Debugging Tips
Check proof server logs for detailed error messages
Verify all services are running: Creditcoin node, attestor network, proof server, database
Use proof API health endpoint:
/api/v1/healthCheck attestation status via Creditcoin RPC or
Polkadot.jsEnable verbose logging in proof server for more details
Support
If you encounter issues during migration:
Check the troubleshooting section above
Read the docs carefully once, especially the DApp builder section
Checkout the example code in examples repository
Check the Creditcoin repositories and public channels for latest updates
Last updated