Live Contract Inspection

Michelson smart contracts cannot access each other's storage. They can only interact through transfers, during which the client of the contract provides a parameter that the contract runs its code on.

As a test framework, techelson provides inspection instructions which give access to the balance and the storage of a live (deployed) contract. Both consume a contract from the top of the stack.

instruction parameter stack
GET_STORAGE 'storage :: contract _ : 'S or :: address : 'S
-> (option 'storage) : 'S
GET_BALANCE none :: contract _ : 'S or :: address : 'S
-> mutez : 'S

Let's extend the previous example to inspection.techel which checks that the balance and storage of the contract deployed are correct.

{
    PUSH @storage nat 0 ;
    PUSH @amount mutez 3 ;
    PUSH @delegatable bool True ;
    PUSH @spendable bool True ;
    NONE @delegate key_hash ;
    PUSH key "manager address" ;
    SHA512 @manager ;

    CREATE_CONTRACT @main @main_op "SimpleExample" ;

    DIP { NIL operation } ;
    CONS ;

    APPLY_OPERATIONS ;

    # Takes the address on the top of the stack, retrieves a contract of parameter `bool`.
    CONTRACT bool ;
    IF_NONE { # There is no hope, failing.
        PUSH @err_msg string "failed to retrieve contract" ;
        FAILWITH
    } {} ;

    DUP ;

    GET_BALANCE ;
    PRINT_STACK ;
    STEP "retrieved the balance of the contract" ;

    PUSH mutez 3 ;
    IFCMPNEQ {
        PUSH string "balance should be 3utz" ;
        FAILWITH
    } {} ;

    GET_STORAGE nat ;

    IF_NONE {
        PUSH string "unable to retrieve storage of contract" ;
        FAILWITH
    } {
        PRINT_STACK ;
        STEP "retrieved the storage of the contract" ;
        PUSH nat 0 ;
        IFCMPNEQ {
            PUSH string "storage should be 0 (nat)" ;
            FAILWITH
        } {} ;
    }
}

The testcase does not fail and produces the output

$ techelson --contract rsc/simpleExample/contracts/simpleExample.tz -- rsc/simpleExample/okay/inspection.techel
Running test `Inspection`

running test script...
   timestamp: 1970-01-01 00:00:00 +00:00

applying operation CREATE[uid:0] (@address[1]@main, "sha512:manager address", None, true, true, 3utz) "SimpleExample"
   timestamp: 1970-01-01 00:00:00 +00:00
   live contracts: none
=> live contracts: SimpleExample (3utz) address[1]@main

running test script...
   timestamp: 1970-01-01 00:00:00 +00:00
stack:
|==================================================================================================|
| address[1]@main                                                                                  |
| (contract bool)                                                                                  |
|--------------------------------------------------------------------------------------------------|
| 3utz                                                                                             |
| mutez                                                                                            |
|==================================================================================================|

running test script...
   timestamp: 1970-01-01 00:00:00 +00:00
stopping [retrieved the balance of the contract] press `return` to continue


running test script...
   timestamp: 1970-01-01 00:00:00 +00:00
stack:
|==================================================================================================|
| 0p                                                                                               |
| nat                                                                                              |
|==================================================================================================|

running test script...
   timestamp: 1970-01-01 00:00:00 +00:00
stopping [retrieved the storage of the contract] press `return` to continue


running test script...
   timestamp: 1970-01-01 00:00:00 +00:00

Done running test `Inspection`