Creating and Calling Contracts

When you pass a contract to techelson using techelson --contract <file> ..., the contract becomes a named contract in the techelson environment. The name of the contract is the name of the file

  • up to its first . character,
  • with the first letter capitalized.

So

techelson \
    --contract my_contract.tz \
    --contract myContract.tz  \
    --contract my.contract.tz \
    ...

defines three named contracts: My_contract, MyContract and My.

Note that the naming convention is the same for testcases, based on the testcase file. The name of a testcase might be used in techelson's output to provide information, but it has no practical use currently.

Named Contract Creation

Techelson extends the CREATE_CONTRACT michelson instruction with the following rule

instruction parameter stack
CREATE_CONTRACT <string> :: key_hash : option key_hash : bool : bool : mutez : 'g : 'S
-> operation : address : 'S

where <string> is the name of a contract with storage type 'g in the environment. The semantics of the stack parameters is the same as in michelson: manager, optional delegate, the two spendable and delegatable flags, and the balance and storage of the contract created.

NB: techelson also provides the SPAWN_CONTRACT extension which takes the name of the contract on the stack. See techelson's Extensions for more details.

Say we have the following contract in file simpleExample.tz.

storage nat;
parameter bool;
code {
    UNPAIR;        # Unpair parameter and storage.
    IF {           # Asked not to count: storage is unchanged, nothing to do.
    } {
        PUSH nat 1;
        ADD
    };
    NIL operation; # We don't want to perform any operations.
    PAIR           # Aggregate the operation list and the new storage.
};

We can craft a creation operation in file create1.techel as follows

{
    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 ;
    PRINT_STACK ;
    STEP "before creation" ;

    CREATE_CONTRACT "SimpleExample" ;
    PRINT_STACK ;
    STEP "after creation" ;
}

This produces the following output

$ techelson --contract rsc/simpleExample/contracts/simpleExample.tz -- rsc/simpleExample/okay/create1.techel
Running test `Create1`

running test script...
   timestamp: 1970-01-01 00:00:00 +00:00
stack:
|==================================================================================================|
|                                                                                         @storage |
| 0p                                                                                               |
| nat                                                                                              |
|--------------------------------------------------------------------------------------------------|
|                                                                                          @amount |
| 3utz                                                                                             |
| mutez                                                                                            |
|--------------------------------------------------------------------------------------------------|
|                                                                                     @delegatable |
| True                                                                                             |
| bool                                                                                             |
|--------------------------------------------------------------------------------------------------|
|                                                                                       @spendable |
| True                                                                                             |
| bool                                                                                             |
|--------------------------------------------------------------------------------------------------|
|                                                                                        @delegate |
| None                                                                                             |
| (option key_hash)                                                                                |
|--------------------------------------------------------------------------------------------------|
|                                                                                         @manager |
| "sha512:manager address"                                                                         |
| key_hash                                                                                         |
|==================================================================================================|

running test script...
   timestamp: 1970-01-01 00:00:00 +00:00
stopping [before creation] press `return` to continue


running test script...
   timestamp: 1970-01-01 00:00:00 +00:00
stack:
|==================================================================================================|
| address[1]                                                                                       |
| address                                                                                          |
|--------------------------------------------------------------------------------------------------|
| CREATE[uid:0] (@address[1], "sha512:manager address", None, true, true, 3utz) "SimpleExample"    |
| operation                                                                                        |
|==================================================================================================|

running test script...
   timestamp: 1970-01-01 00:00:00 +00:00
stopping [after creation] press `return` to continue


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

Done running test `Create1`

Applying Operations

Michelson operations (contract/account creation, transfers) cannot be applied directly in a michelson contract. Instead, a contract produces a list of operation which the tezos runtime applies after the contract is done running.

A techelson test case needs to be able to apply operations however, which is why the APPLY_OPERATIONS extension exists. This instruction suspends the execution of the testcase to apply the list of operations on the top of the stack. When all these operations are done running, techelson resumes the execution of the testcase.

Warning: this instruction is only legal in testcases, not in contracts.

Consider testcase create2.techel:

{
    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 ;
    PRINT_STACK ;
    STEP "operation is now in a list" ;

    APPLY_OPERATIONS ;

    PRINT_STACK ;
    STEP "testing that contract exists" ;
    # 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
    } {
        PUSH string "success" ;
        PRINT_STACK
    }
}

Running it yields

$ techelson --contract rsc/simpleExample/contracts/simpleExample.tz -- rsc/simpleExample/okay/create2.techel
Running test `Create2`

running test script...
   timestamp: 1970-01-01 00:00:00 +00:00
stack:
|==================================================================================================|
|                                                                                            @main |
| address[1]@main                                                                                  |
| address                                                                                          |
|--------------------------------------------------------------------------------------------------|
| [ CREATE[uid:0] (@address[1]@main, "sha512:manager address", None, true, true, 3utz) "SimpleExample" ] |
| (list operation)                                                                                 |
|==================================================================================================|

running test script...
   timestamp: 1970-01-01 00:00:00 +00:00
stopping [operation is now in a list] press `return` to continue


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:
|==================================================================================================|
|                                                                                            @main |
| address[1]@main                                                                                  |
| address                                                                                          |
|==================================================================================================|

running test script...
   timestamp: 1970-01-01 00:00:00 +00:00
stopping [testing that contract exists] press `return` to continue


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

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

Done running test `Create2`

Notice the line Applying operations.... We could increase techelson's verbosity to obtain more information as to which contracts are deployed, but let's see how to inspect the state of a live (deployed) contract instead.