Skip to content

Debugging ErgoScript#

Since ErgoScript is usually encapsulated within string literals, it is not feasible to directly set breakpoints within the script text itself for debugging purposes.

Scala-Based Debugging Approach#

ErgoScript is a deliberate subset of Scala, and a robust test suite, SigmaDslSpecification, exists to verify the equivalence between ErgoScript and Scala. As such, you can utilize Scala's debugging capabilities to debug ErgoScript.

Practical Debugging Example#

An example of a debugging scenario is provided in the sigmastate-interpreter repository, specifically within AssetsAtomicExchange.scala#L29.

// Debugging example from AssetsAtomicExchange
lazy val buyerProp = proposition("buyer", { ctx: Context =>
  import ctx._
  (HEIGHT > deadline && pkA) || {
    val tokenData = OUTPUTS(0).R2[Coll[(Coll[Byte], Long)]].get(0)
    val knownId = OUTPUTS(0).R4[Coll[Byte]].get == SELF.id
    allOf(Coll(
      tokenData._1 == tokenId,
      tokenData._2 >= 60L,
      OUTPUTS(0).propositionBytes == pkA.propBytes,
      knownId
    ))
  }
},

Debugging Process#

In this instance, a breakpoint can be set at the specified line above. Following this, a debug run can be executed for the corresponding test:

// Test method for atomic exchange
property("atomic exchange spec") {
  // Test implementation details
}

Debugging Technique#

During this execution, the debugger should halt at the pre-set breakpoint, enabling you to: - Inspect variable states - Understand code behavior step-by-step - Validate contract logic in a controlled environment

Key Debugging Strategies#

  1. Use Scala Debugging Tools
  2. Leverage IntelliJ IDEA or other Scala IDEs
  3. Set breakpoints in test cases
  4. Step through contract logic

  5. Comprehensive Testing

  6. Create detailed test scenarios
  7. Cover multiple execution paths
  8. Simulate different blockchain states

  9. Context Validation

  10. Carefully examine context variables
  11. Verify box selection and properties
  12. Check sigma proposition construction

Best Practices#

  • Break complex contracts into smaller, testable components
  • Use property-based testing
  • Understand the nuances of the UTXO model
  • Leverage Scala's type system for compile-time checks