{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Michelson kernel basics\n", "Welcome, friend! This an ultimate Michelson playground, and in this tutorial, you will learn how to make the most of all available functionality. \n", "If there are any questions, please ask in our telegram chat https://t.me/baking_bad_chat" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
\"Hello, world!\"
string
" ], "text/plain": [ "value type\n", "--------------- ------\n", "\"Hello, world!\" string" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PUSH string \"Hello, world!\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Michelson kernel is built on top of a custom interpreter which does not typecheck the whole script before execution but at runtime instead. Also, it allows developer to check the stack state at any time and for arbitrary depth. \n", "This enables a step-by-step coding approach which can save time while learning language or making a prototype or demo." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "DROP" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Context, stack, and notebook cells\n", "When you start a kernel, a new instance of context is initialized. It stores the Michelson stack, stub values for the blockchain-specific instructions (e.g. `BALANCE` or `SENDER`), big map pool, origination index, and some internal variables. \n", "This context is shared across all cells. Note, that the cell's position doesn't matter, only the execution order." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type name
257000000
mutez
@balance
" ], "text/plain": [ " value type name\n", "--------- ------ --------\n", "257000000 mutez @balance" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "BALANCE # balance is initialized with a default value" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When you execute a cell, messages can appear in the `stdout` and` stderr` streams, as well as the optional result at the end. \n", "Let's try to execute a sequence of commands:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PUSH: push 0;\n", "COMPARE: pop 0, 257000000; push -1;\n", "EQ: pop -1; push False;\n", "IF: pop False;\n", " PUSH: push We got money!;" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
\"We got money!\"
string
" ], "text/plain": [ "value type\n", "--------------- ------\n", "\"We got money!\" string" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PUSH mutez 0 ;\n", "IFCMPEQ { FAIL } { PUSH string \"We got money!\" }" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When there's more than one command a verbose logging is enabled. It can be disabled which will be shown a bit later. \n", "If the latest command in the sequences pushes an item onto the stack - it will be returned as a result." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Inspecting the stack" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "DEBUG False # we just have disabled the verbose output" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PRINT: ['a', 'b', 'c'] is on top of the stack, then goes We got money!;" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type name
\"abc\"
string
@abc
" ], "text/plain": [ "value type name\n", "------- ------ ------\n", "\"abc\" string @abc" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PUSH (list string) { \"a\" ; \"b\" ; \"c\" } ;\n", "PRINT \"{0} is on top of the stack, then goes {1}\" ; # still we can printf anything to stdout\n", "CONCAT @abc" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Time to inspect the stack, there is `DUMP` helper for that. You can use it with or without depth specified (all elements)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type name
\"abc\"
string
@abc
\"We got money!\"
string
" ], "text/plain": [ "value type name\n", "--------------- ------ ------\n", "\"abc\" string @abc\n", "\"We got money!\" string" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "DUMP 2" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "stack is empty" ], "text/plain": [ "stack is empty" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "DROP_ALL ; DUMP" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Errors\n", "if any instruction in a cell has failed the whole context is rolled back to the previous state. So you don't have to rerun everything from the beginning. Here are a few examples of possible errors:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "MichelsonRuntimeError: got 0 items, requested 2 \n", "at ADD" ] } ], "source": [ "ADD" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "MichelsonParserError: unknown primitive HELLO\n", "at line 1, pos 0" ] } ], "source": [ "HELLO" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "MichelsonRuntimeError: expected Int, got Mutez\n", "at EQ" ] } ], "source": [ "PUSH mutez 1 ; EQ" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "DEBUG True # and we continue to the next topic ^_^" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Blockchain-specific instructions\n", "First of all, there are several instructions that in a real environment push some value from the execution context, as `AMOUNT`, `SENDER`, `SOURCE`, `BALANCE`, etc. Here we are detached from any particular chain, but you have an opportunity to patch these values:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PATCH: set AMOUNT=100500;\n", "AMOUNT: push 100500;" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type name
100500
mutez
@amount
" ], "text/plain": [ " value type name\n", "------- ------ -------\n", " 100500 mutez @amount" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PATCH AMOUNT 100500 ; AMOUNT" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PATCH: unset AMOUNT;\n", "AMOUNT: push 0;" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type name
0
mutez
@amount
" ], "text/plain": [ " value type name\n", "------- ------ -------\n", " 0 mutez @amount" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PATCH AMOUNT ; AMOUNT # still have default value 0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Internal operations\n", "Despite internal operations will never apply, Michelson kernel tries to emulate the standard behavior as closely as possible." ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "UNIT: push Unit;\n", "AMOUNT: push 0;\n", "NONE: push None;\n", "CREATE_CONTRACT: pop None, 0, Unit; set BALANCE=257000000; push KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm; push ;" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
amount: '0'\n",
       "code: code { { UNIT ; FAILWITH } }\n",
       "kind: origination\n",
       "storage: Unit\n",
       "target: KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm
operation
" ], "text/plain": [ "value type\n", "-------------------------------------------- ---------\n", "amount: '0' operation\n", "code: code { { UNIT ; FAILWITH } }\n", "kind: origination\n", "storage: Unit\n", "target: KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "UNIT; # starting storage for contract\n", "AMOUNT; # Push the starting balance\n", "NONE key_hash; # No delegate\n", "CREATE_CONTRACT # Create the contract\n", "{ parameter unit ;\n", " storage unit ;\n", " code { FAIL } };" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Script sections\n", "`parameter`, `storage`, and `code` instructions are supported as well, what they do is basically store the argument in the context." ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "parameter unit\n", "storage string\n", "code { DROP ; PUSH string \"Hey!\" ; NIL operation ; PAIR }" ] } ], "source": [ "parameter unit ;\n", "storage string ;\n", "code { DROP ; PUSH string \"Hey!\"; NIL operation ; PAIR }" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In order to run this contract with particular parameters and initial storage you can use `RUN` helper:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RUN: use %default; drop all; push (Unit, 'hi');\n", " DROP: pop (Unit, 'hi');\n", " PUSH: push Hey!;\n", " NIL: push [];\n", " PAIR: pop [], Hey!; push ([], 'Hey!');" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
\"Hey!\"
string
" ], "text/plain": [ "value type\n", "------- ------\n", "\"Hey!\" string" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "RUN %default Unit \"hi\" # %default is entrypoint" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`RUN` returns storage, big map diff (if applicable), and list of internal operations. \n", "You can also load contract from file or chain via `INCLUDE` helper:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "INCLUDE: set STORAGE={'prim': 'Pair', 'args': [{'int': '4'}, {'prim': 'Unit'}]};\n", "parameter (or\n", " (or %fund\n", " (pair :initiate %initiate (address %participant)\n", " (pair %settings\n", " (pair (bytes %hashed_secret) (timestamp %refund_time))\n", " (mutez %payoff)))\n", " (bytes :hashed_secret %add))\n", " (or %withdraw (bytes :secret %redeem) (bytes :hashed_secret %refund)))\n", "storage (pair\n", " (big_map bytes\n", " (pair (pair %recipients (address %initiator) (address %participant))\n", " (pair %settings (pair (mutez %amount) (timestamp %refund_time))\n", " (mutez %payoff))))\n", " unit)\n", "code { NIL @operations operation ;\n", " SWAP ;\n", " { { DUP ; CAR @% ; DIP { CDR } } ; DIP { { DUP ; CAR @% ; DIP { CDR @% } } } } ;\n", " DIP { DUP } ;\n", " IF_LEFT\n", " { IF_LEFT\n", " { { { DUP ; CAR @% ; DIP { CDR @% } } } ;\n", " DUP ;\n", " CONTRACT @participant unit ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " DROP ;\n", " SWAP ;\n", " { { DUP ; CAR ; DIP { CDR @% } } ; { DUP ; CAR @% ; DIP { CDR @% } } } ;\n", " DUP ;\n", " SIZE ;\n", " PUSH nat 32 ;\n", " { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ;\n", " DIP { DIP { DUP } ;\n", " SWAP ;\n", " AMOUNT @amount ;\n", " SUB ;\n", " SENDER ;\n", " DUP ;\n", " CONTRACT @initiator unit ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " DROP ;\n", " DIP { { PAIR ; PAIR } ; SWAP } ;\n", " { PAIR ; PAIR } ;\n", " SOME @xcat ;\n", " SWAP } ;\n", " DUP ;\n", " DIP { MEM ; NOT ; { IF {} { { UNIT ; FAILWITH } } } } }\n", " { DUP ;\n", " DIP { GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { { DUP ; CAR @% ; DIP { CDR @% } } } ;\n", " DIP { { { DUP ; CAR ; DIP { CDR @% } } ; { DUP ; CAR @% ; DIP { CDR @% } } } ;\n", " SWAP ;\n", " DUP ;\n", " NOW ;\n", " { { COMPARE ; LT } ; IF {} { { UNIT ; FAILWITH } } } ;\n", " SWAP ;\n", " AMOUNT @amount ;\n", " ADD } ;\n", " { DIP { PAIR } ; DIP { PAIR } ; PAIR } ;\n", " SOME @xcat } } ;\n", " UPDATE ;\n", " PAIR @new_storage ;\n", " SWAP ;\n", " PAIR }\n", " { IF_LEFT\n", " { DUP ;\n", " SIZE ;\n", " PUSH nat 32 ;\n", " { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ;\n", " SHA256 ;\n", " SHA256 @hash ;\n", " DUP ;\n", " DIP { SWAP } ;\n", " { DIP { DIP { GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " DUP ;\n", " { { DUP ; CAR @% ; DIP { CDR @% } } } ;\n", " CDR @% ;\n", " CONTRACT @participant unit ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " SWAP ;\n", " { CAR ; CAR @% } ;\n", " { DIP { DIP { SENDER ;\n", " CONTRACT @sender unit ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " SWAP ;\n", " CDR @% ;\n", " { { DUP ; CAR ; DIP { CDR @% } } ;\n", " { DUP ; CAR @% ; DIP { CDR @% } } } ;\n", " DROP ;\n", " NOW ;\n", " { { COMPARE ; LT } ; IF {} { { UNIT ; FAILWITH } } } ;\n", " DUP ;\n", " PUSH mutez 0 ;\n", " { COMPARE ;\n", " LT ;\n", " IF\n", " { UNIT ; TRANSFER_TOKENS ; DIP { SWAP } ; CONS }\n", " { DROP ; DROP ; SWAP } } } } } ;\n", " UNIT ;\n", " TRANSFER_TOKENS } } } }\n", " { DUP ;\n", " DIP { GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " DUP ;\n", " { CAR ; CAR @% } ;\n", " CONTRACT @initiator unit ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " SWAP ;\n", " CDR ;\n", " { { DUP ; CAR ; DIP { CDR @% } } ; { DUP ; CAR @% ; DIP { CDR @% } } } ;\n", " SWAP ;\n", " NOW ;\n", " { { COMPARE ; GE } ; IF {} { { UNIT ; FAILWITH } } } ;\n", " ADD ;\n", " UNIT ;\n", " TRANSFER_TOKENS ;\n", " SWAP ;\n", " { DIP { DIP { SWAP } } } } } ;\n", " NONE @none (pair (pair address address) (pair (pair mutez timestamp) mutez)) ;\n", " SWAP ;\n", " UPDATE @cleared_map ;\n", " SWAP ;\n", " DIP { SWAP ; DIP { PAIR } } ;\n", " CONS ;\n", " PAIR } }" ] } ], "source": [ "INCLUDE \"mainnet:KT1VG2WtYdSWz5E7chTeAdDPZNy2MpP8pTfL\" # can also be a filename" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Step by step debugging\n", "In case you don't want to execute the whole `code`, you can mark the beginning of the contract by calling `BEGIN` (with the same arguments as `RUN`) and in the end call `COMMIT`:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
Pair 0xdeadbeef (Pair -1 Unit)
pair (bytes :hashed_secret %refund)\n",
       "      (pair\n",
       "        (big_map bytes\n",
       "                 (pair (pair %recipients (address %initiator) (address %participant))\n",
       "                       (pair %settings (pair (mutez %amount) (timestamp %refund_time))\n",
       "                                       (mutez %payoff))))\n",
       "        unit)
" ], "text/plain": [ "value type\n", "------------------------------ --------------------------------------------------------------------------------------\n", "Pair 0xdeadbeef (Pair -1 Unit) pair (bytes :hashed_secret %refund)\n", " (pair\n", " (big_map bytes\n", " (pair (pair %recipients (address %initiator) (address %participant))\n", " (pair %settings (pair (mutez %amount) (timestamp %refund_time))\n", " (mutez %payoff))))\n", " unit)" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "BEGIN %refund 0xdeadbeef (Pair {} Unit)" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CDR: pop (b'\\xde\\xad\\xbe\\xef', (-1, Unit)); push (-1, Unit);\n", "NIL: push [];\n", "PAIR: pop [], (-1, Unit); push ([], (-1, Unit));\n", "COMMIT:" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
Pair 0 Unit
pair\n",
       "  (big_map bytes\n",
       "           (pair (pair %recipients (address %initiator) (address %participant))\n",
       "                 (pair %settings (pair (mutez %amount) (timestamp %refund_time)) (mutez %payoff))))\n",
       "  unit

\n", "\n", "\n", "\n", "\n", "\n", "\n", "
big_map action key value
0
alloc
bytes
pair (pair %recipients (address %initiator) (address %participant))\n",
       "      (pair %settings (pair (mutez %amount) (timestamp %refund_time)) (mutez %payoff))
" ], "text/plain": [ "value type\n", "----------- ---------------------------------------------------------------------------------------------------\n", "Pair 0 Unit pair\n", " (big_map bytes\n", " (pair (pair %recipients (address %initiator) (address %participant))\n", " (pair %settings (pair (mutez %amount) (timestamp %refund_time)) (mutez %payoff))))\n", " unit\n", " big_map action key value\n", "--------- -------- ----- --------------------------------------------------------------------------------------\n", " 0 alloc bytes pair (pair %recipients (address %initiator) (address %participant))\n", " (pair %settings (pair (mutez %amount) (timestamp %refund_time)) (mutez %payoff))" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "CDR ; NIL operation ; PAIR ; COMMIT" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also break the current pseudo-exection by calling `RESET` - it will clear the stack and all the cached big maps:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [], "source": [ "RESET" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Big maps\n", "In the previous example, you might notice that we initialize the storage as an empty map, then it is displayed on the stack as -1, and as a result, it becomes 0. \n", "This is roughly how big map works in the real world: first, a temporary container is created, and if at the end of the contract execution it's still in use - a new big map is allocated. Basically big map is an integer pointer to a hashtable somewhere in the context. \n", "In our playground in order to check the big map state, you need to call `BIG_MAP_DIFF` helper." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
-1
big_map string string
" ], "text/plain": [ " value type\n", "------- ---------------------\n", " -1 big_map string string" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "EMPTY_BIG_MAP string string" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PUSH: push two;\n", "SOME: pop two; push ('two',);\n", "PUSH: push one;\n", "UPDATE: pop one, ('two',), -1; push -1;" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
-1
big_map string string
" ], "text/plain": [ " value type\n", "------- ---------------------\n", " -1 big_map string string" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PUSH string \"two\";\n", "SOME;\n", "PUSH string \"one\";\n", "UPDATE" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
big_map action key value
0
alloc
string
string
0
update
\"one\"
\"two\"
" ], "text/plain": [ " big_map action key value\n", "--------- -------- ------ -------\n", " 0 alloc string string\n", " 0 update \"one\" \"two\"" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "BIG_MAP_DIFF # works if the top item contains big maps" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Reusing big maps\n", "So far, we have come across `alloc` and` update` actions in big map., but there are also `copy` and `remove` actions. We will need to pass one of the allocated big map pointer to another pseudo-contract:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "parameter unit\n", "storage (big_map int int)\n", "code { CDR ; NIL operation ; PAIR }" ] } ], "source": [ "parameter unit;\n", "storage (big_map int int);\n", "code { CDR ; NIL operation ;PAIR }" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RUN: use %default; drop all; push (Unit, -2);\n", " CDR: pop (Unit, -2); push -2;\n", " NIL: push [];\n", " PAIR: pop [], -2; push ([], -2);" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
0
big_map int int

\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
big_map action key value
0
alloc
int
int
0
update
1
2
0
update
2
3
" ], "text/plain": [ " value type\n", "------- ---------------\n", " 0 big_map int int\n", " big_map action key value\n", "--------- -------- ----- -------\n", " 0 alloc int int\n", " 0 update 1 2\n", " 0 update 2 3" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "RUN Unit { Elt 1 2 ; Elt 2 3 }" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [], "source": [ "code { CDR ; PUSH int 5; SOME ; PUSH int 4; UPDATE ; NIL operation ; PAIR }" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "RUN: use %default; drop all; push (Unit, 0);\n", " CDR: pop (Unit, 0); push 0;\n", " PUSH: push 5;\n", " SOME: pop 5; push (5,);\n", " PUSH: push 4;\n", " UPDATE: pop 4, (5,), 0; push 0;\n", " NIL: push [];\n", " PAIR: pop [], 0; push ([], 0);" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
0
big_map int int

\n", "\n", "\n", "\n", "\n", "\n", "\n", "
big_map action key value
0
update
4
5
" ], "text/plain": [ " value type\n", "------- ---------------\n", " 0 big_map int int\n", " big_map action key value\n", "--------- -------- ----- -------\n", " 0 update 4 5" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "RUN Unit 0 # passing previously allocated big_map #0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Accessing on-chain data\n", "Sometimes it is convenient to access the blockchain data right from the notebook. The `RESET` helper has an extra parameter that allows to specify the network we shoudl bind to." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "RESET \"mainnet\"" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CHAIN_ID: push NetXdQprcVkpaWU;\n", "NOW: push 1583536716;" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type name
1583536716
timestamp
@now
\"NetXdQprcVkpaWU\"
chain_id
@mainnet
" ], "text/plain": [ "value type name\n", "----------------- --------- --------\n", "1583536716 timestamp @now\n", "\"NetXdQprcVkpaWU\" chain_id @mainnet" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "CHAIN_ID ; NOW ; DUMP 2 # Few blockchain-specific instruction will change the behavior" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "PUSH: push KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg;\n", "CONTRACT: pop KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg; entry type mismatch; push None;" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
None
option (contract unit)
" ], "text/plain": [ "value type\n", "------- ----------------------\n", "None option (contract unit)" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "PUSH address \"KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg\" ; CONTRACT unit # also, contract type checking is now working" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Real big maps\n", "The coolest thing is that now you can access real big maps by a pointer, right from your pseudo-contract. \n", "If you are loading the contract source from the network, a special variable `Current` is initialized with the current contract storage." ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "INCLUDE: set STORAGE={'prim': 'Pair', 'args': [{'int': '9'}, {'prim': 'Pair', 'args': [{'prim': 'Pair', 'args': [{'string': 'tz1M9CMEtsXm3QxA7FmMU2Qh7xzsuGXVbcDr'}, [{'prim': 'Elt', 'args': [{'string': 'By'}, {'string': 'https://SmartPy.io'}]}, {'prim': 'Elt', 'args': [{'string': 'Help'}, {'string': 'Use Build to define a new game board and Play to make moves'}]}, {'prim': 'Elt', 'args': [{'string': 'Play at'}, {'string': 'https://smartpy.io/demo/explore.html?address=KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg'}]}, {'prim': 'Elt', 'args': [{'string': 'SmartPy Template'}, {'string': 'https://smartpy.io/demo/index.html?template=tictactoeFactory.py'}]}]]}, {'prim': 'False'}]}]};\n", "parameter (or\n", " (or\n", " (or\n", " (or\n", " (or (pair %build (pair (string %game) (address %player1)) (address %player2))\n", " (string %game))\n", " (pair %play (pair (pair (string %game) (int %i)) (int %j)) (int %move)))\n", " (pair %setGameMetaData (pair (string %game) (string %name)) (string %value)))\n", " (pair %setMetaData (string %name) (string %value)))\n", " (bool %setPause))\n", "storage (pair\n", " (big_map string\n", " (pair\n", " (pair\n", " (pair\n", " (pair\n", " (pair\n", " (pair (pair (map %deck int (map int int)) (bool %draw))\n", " (map %metaData string string))\n", " (int %nbMoves))\n", " (int %nextPlayer))\n", " (address %player1))\n", " (address %player2))\n", " (int %winner)))\n", " (pair (pair (address %admin) (map %metaData string string)) (bool %paused)))\n", "code { DUP ;\n", " CDR ;\n", " SWAP ;\n", " CAR ;\n", " IF_LEFT\n", " { IF_LEFT\n", " { IF_LEFT\n", " { IF_LEFT\n", " { IF_LEFT\n", " { PAIR ;\n", " DUP ;\n", " { CDR ; CDR ; CDR } ;\n", " NOT ;\n", " IF\n", " { PUSH bool True }\n", " { DUP ; { CDR ; CDR ; CAR ; CAR } ; SENDER ; COMPARE ; EQ } ;\n", " IF\n", " {}\n", " { PUSH string \"WrongCondition: (~ self.data.paused) | (sp.sender == self.data.admin)\" ;\n", " FAILWITH } ;\n", " DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR } ;\n", " MEM ;\n", " NOT ;\n", " IF\n", " {}\n", " { PUSH string \"WrongCondition: ~ (params.game in self.data.boards)\" ;\n", " FAILWITH } ;\n", " DUP ;\n", " CDR ;\n", " DUP ;\n", " CAR ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR } ;\n", " { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ;\n", " CAR ;\n", " CDR ;\n", " PUSH int 0 ;\n", " SWAP ;\n", " { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " { CAR ; CAR ; CDR } ;\n", " PUSH int 1 ;\n", " PUSH int 0 ;\n", " EMPTY_MAP string string ;\n", " PUSH bool False ;\n", " PUSH (map int (map int int)) { Elt 0 { Elt 0 0 ; Elt 1 0 ; Elt 2 0 } ;\n", " Elt 1 { Elt 0 0 ; Elt 1 0 ; Elt 2 0 } ;\n", " Elt 2 { Elt 0 0 ; Elt 1 0 ; Elt 2 0 } } ;\n", " PAIR ;\n", " PAIR ;\n", " PAIR ;\n", " PAIR ;\n", " PAIR ;\n", " PAIR ;\n", " PAIR ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " CDR ;\n", " SWAP ;\n", " PAIR ;\n", " SWAP ;\n", " DROP ;\n", " NIL operation ;\n", " PAIR }\n", " { PAIR ;\n", " DUP ;\n", " { CDR ; CDR ; CAR ; CAR } ;\n", " SENDER ;\n", " COMPARE ;\n", " EQ ;\n", " IF\n", " {}\n", " { PUSH string \"WrongCondition: sp.sender == self.data.admin\" ; FAILWITH } ;\n", " DUP ;\n", " CDR ;\n", " DUP ;\n", " CAR ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " CAR ;\n", " NONE (pair\n", " (pair\n", " (pair\n", " (pair\n", " (pair\n", " (pair (pair (map %deck int (map int int)) (bool %draw))\n", " (map %metaData string string))\n", " (int %nbMoves))\n", " (int %nextPlayer))\n", " (address %player1))\n", " (address %player2))\n", " (int %winner)) ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " CDR ;\n", " SWAP ;\n", " PAIR ;\n", " SWAP ;\n", " DROP ;\n", " NIL operation ;\n", " PAIR } }\n", " { PAIR ;\n", " DUP ;\n", " { CDR ; CDR ; CDR } ;\n", " NOT ;\n", " IF {} { PUSH string \"WrongCondition: ~ self.data.paused\" ; FAILWITH } ;\n", " DUP ;\n", " CDR ;\n", " CAR ;\n", " PUSH int 0 ;\n", " SWAP ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " CDR ;\n", " COMPARE ;\n", " EQ ;\n", " IF\n", " { DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CDR } ;\n", " NOT }\n", " { PUSH bool False } ;\n", " IF\n", " {}\n", " { PUSH string \"WrongCondition: (self.data.boards[params.game].winner == 0) & (~ self.data.boards[params.game].draw)\" ;\n", " FAILWITH } ;\n", " DUP ;\n", " CAR ;\n", " { CAR ; CAR ; CDR } ;\n", " PUSH int 0 ;\n", " SWAP ;\n", " COMPARE ;\n", " GE ;\n", " IF\n", " { PUSH int 3 ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CDR } ; COMPARE ; LT }\n", " { PUSH bool False } ;\n", " IF\n", " {}\n", " { PUSH string \"WrongCondition: (params.i >= 0) & (params.i < 3)\" ; FAILWITH } ;\n", " DUP ;\n", " CAR ;\n", " { CAR ; CDR } ;\n", " PUSH int 0 ;\n", " SWAP ;\n", " COMPARE ;\n", " GE ;\n", " IF\n", " { PUSH int 3 ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CDR } ; COMPARE ; LT }\n", " { PUSH bool False } ;\n", " IF\n", " {}\n", " { PUSH string \"WrongCondition: (params.j >= 0) & (params.j < 3)\" ; FAILWITH } ;\n", " DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CDR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CDR } ;\n", " COMPARE ;\n", " EQ ;\n", " IF\n", " {}\n", " { PUSH string \"WrongCondition: params.move == self.data.boards[params.game].nextPlayer\" ;\n", " FAILWITH } ;\n", " DUP ;\n", " CDR ;\n", " CAR ;\n", " PUSH int 0 ;\n", " SWAP ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " EQ ;\n", " IF\n", " {}\n", " { PUSH string \"WrongCondition: self.data.boards[params.game].deck[params.i][params.j] == 0\" ;\n", " FAILWITH } ;\n", " DUP ;\n", " CAR ;\n", " CDR ;\n", " PUSH int 1 ;\n", " COMPARE ;\n", " EQ ;\n", " IF\n", " { DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CDR } ;\n", " SENDER ;\n", " COMPARE ;\n", " EQ ;\n", " IF\n", " {}\n", " { PUSH string \"WrongCondition: sp.sender == self.data.boards[params.game].player1\" ;\n", " FAILWITH } }\n", " { DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CDR } ;\n", " SENDER ;\n", " COMPARE ;\n", " EQ ;\n", " IF\n", " {}\n", " { PUSH string \"WrongCondition: sp.sender == self.data.boards[params.game].player2\" ;\n", " FAILWITH } } ;\n", " DUP ;\n", " CDR ;\n", " DUP ;\n", " CAR ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " PAIR ;\n", " DUP ;\n", " DIP { { { DUP ; CAR ; DIP { CDR } } } } ;\n", " { { DUP ; CAR ; DIP { CDR } } } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ;\n", " CAR ;\n", " { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CDR } ;\n", " PUSH int 3 ;\n", " SUB ;\n", " SWAP ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ; { CAR @%% ; PAIR %@ % } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " CDR ;\n", " SWAP ;\n", " PAIR ;\n", " SWAP ;\n", " CAR ;\n", " PAIR ;\n", " DUP ;\n", " CDR ;\n", " DUP ;\n", " CAR ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " PAIR ;\n", " DUP ;\n", " DIP { { { DUP ; CAR ; DIP { CDR } } } } ;\n", " { { DUP ; CAR ; DIP { CDR } } } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " DUP ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " { CAR ; CAR ; CAR ; CDR } ;\n", " PAIR ;\n", " DUP ;\n", " DIP { { { DUP ; CAR ; DIP { CDR } } } } ;\n", " { { DUP ; CAR ; DIP { CDR } } } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DIP { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " SWAP } ;\n", " SWAP } ;\n", " SWAP } ;\n", " { CAR ; CAR ; CDR } ;\n", " { DIP { DIP { DIP { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " SWAP } ;\n", " SWAP } ;\n", " SWAP } ;\n", " SWAP } ;\n", " SWAP } ;\n", " { CAR ; CDR } ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { CDR @%% ; SWAP ; PAIR % %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " CDR ;\n", " SWAP ;\n", " PAIR ;\n", " SWAP ;\n", " CAR ;\n", " PAIR ;\n", " DUP ;\n", " CDR ;\n", " DUP ;\n", " CAR ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " PAIR ;\n", " DUP ;\n", " DIP { { { DUP ; CAR ; DIP { CDR } } } } ;\n", " { { DUP ; CAR ; DIP { CDR } } } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ;\n", " CAR ;\n", " PUSH int 1 ;\n", " SWAP ;\n", " { DIP { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CDR } ;\n", " ADD ;\n", " SWAP ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ; { CAR @%% ; PAIR %@ % } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " CDR ;\n", " SWAP ;\n", " PAIR ;\n", " SWAP ;\n", " CAR ;\n", " PAIR ;\n", " DUP ;\n", " CDR ;\n", " CAR ;\n", " PUSH int 0 ;\n", " SWAP ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " NEQ ;\n", " IF\n", " { DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 1 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CDR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " EQ }\n", " { PUSH bool False } ;\n", " IF\n", " { DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 2 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CDR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " EQ }\n", " { PUSH bool False } ;\n", " IF\n", " { DUP ;\n", " CDR ;\n", " DUP ;\n", " CAR ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " PAIR ;\n", " DUP ;\n", " DIP { { { DUP ; CAR ; DIP { CDR } } } } ;\n", " { { DUP ; CAR ; DIP { CDR } } } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ;\n", " CAR ;\n", " { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " { CAR ; CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " SWAP ;\n", " CAR ;\n", " PAIR ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " CDR ;\n", " SWAP ;\n", " PAIR ;\n", " SWAP ;\n", " CAR ;\n", " PAIR }\n", " {} ;\n", " DUP ;\n", " CDR ;\n", " CAR ;\n", " PUSH int 0 ;\n", " SWAP ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " NEQ ;\n", " IF\n", " { DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 1 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CDR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " EQ }\n", " { PUSH bool False } ;\n", " IF\n", " { DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 2 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CDR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " EQ }\n", " { PUSH bool False } ;\n", " IF\n", " { DUP ;\n", " CDR ;\n", " DUP ;\n", " CAR ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " PAIR ;\n", " DUP ;\n", " DIP { { { DUP ; CAR ; DIP { CDR } } } } ;\n", " { { DUP ; CAR ; DIP { CDR } } } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ;\n", " CAR ;\n", " { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " { CAR ; CAR ; CDR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " SWAP ;\n", " CAR ;\n", " PAIR ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " CDR ;\n", " SWAP ;\n", " PAIR ;\n", " SWAP ;\n", " CAR ;\n", " PAIR }\n", " {} ;\n", " DUP ;\n", " CDR ;\n", " CAR ;\n", " PUSH int 0 ;\n", " SWAP ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " NEQ ;\n", " IF\n", " { DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 1 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 1 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CDR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " EQ }\n", " { PUSH bool False } ;\n", " IF\n", " { DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 2 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 2 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CDR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " EQ }\n", " { PUSH bool False } ;\n", " IF\n", " { DUP ;\n", " CDR ;\n", " DUP ;\n", " CAR ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " PAIR ;\n", " DUP ;\n", " DIP { { { DUP ; CAR ; DIP { CDR } } } } ;\n", " { { DUP ; CAR ; DIP { CDR } } } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ;\n", " CAR ;\n", " { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " SWAP ;\n", " CAR ;\n", " PAIR ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " CDR ;\n", " SWAP ;\n", " PAIR ;\n", " SWAP ;\n", " CAR ;\n", " PAIR }\n", " {} ;\n", " DUP ;\n", " CDR ;\n", " CAR ;\n", " PUSH int 0 ;\n", " SWAP ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 2 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " NEQ ;\n", " IF\n", " { DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 1 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 1 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CDR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 2 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " EQ }\n", " { PUSH bool False } ;\n", " IF\n", " { DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 2 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CDR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 2 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " COMPARE ;\n", " EQ }\n", " { PUSH bool False } ;\n", " IF\n", " { DUP ;\n", " CDR ;\n", " DUP ;\n", " CAR ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " PAIR ;\n", " DUP ;\n", " DIP { { { DUP ; CAR ; DIP { CDR } } } } ;\n", " { { DUP ; CAR ; DIP { CDR } } } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ;\n", " CAR ;\n", " { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ;\n", " PUSH int 0 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH int 2 ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " SWAP ;\n", " CAR ;\n", " PAIR ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " CDR ;\n", " SWAP ;\n", " PAIR ;\n", " SWAP ;\n", " CAR ;\n", " PAIR }\n", " {} ;\n", " DUP ;\n", " CDR ;\n", " CAR ;\n", " PUSH int 9 ;\n", " SWAP ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CAR ; CAR ; CDR } ;\n", " COMPARE ;\n", " EQ ;\n", " IF\n", " { PUSH int 0 ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CDR ; CAR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " CDR ;\n", " COMPARE ;\n", " EQ }\n", " { PUSH bool False } ;\n", " IF\n", " { DUP ;\n", " CDR ;\n", " DUP ;\n", " CAR ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR ; CAR } ;\n", " PAIR ;\n", " DUP ;\n", " DIP { { { DUP ; CAR ; DIP { CDR } } } } ;\n", " { { DUP ; CAR ; DIP { CDR } } } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " PUSH bool True ;\n", " SWAP ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { CAR @%% ; PAIR %@ % } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " CDR ;\n", " SWAP ;\n", " PAIR ;\n", " SWAP ;\n", " CAR ;\n", " PAIR }\n", " {} ;\n", " CDR ;\n", " NIL operation ;\n", " PAIR } }\n", " { PAIR ;\n", " DUP ;\n", " { CDR ; CDR ; CAR ; CAR } ;\n", " SENDER ;\n", " COMPARE ;\n", " EQ ;\n", " IF\n", " { PUSH bool True }\n", " { DUP ;\n", " { CDR ; CAR } ;\n", " { DIP { DUP } ; SWAP } ;\n", " { CAR ; CAR ; CAR } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " { CAR ; CAR ; CDR } ;\n", " SENDER ;\n", " COMPARE ;\n", " EQ } ;\n", " IF\n", " {}\n", " { PUSH string \"WrongCondition: (sp.sender == self.data.admin) | (sp.sender == self.data.boards[params.game].player1)\" ;\n", " FAILWITH } ;\n", " DUP ;\n", " CDR ;\n", " DUP ;\n", " CAR ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CAR } ;\n", " PAIR ;\n", " DUP ;\n", " DIP { { { DUP ; CAR ; DIP { CDR } } } } ;\n", " { { DUP ; CAR ; DIP { CDR } } } ;\n", " GET ;\n", " { IF_NONE { { UNIT ; FAILWITH } } {} } ;\n", " DUP ;\n", " { CAR ; CAR ; CAR ; CAR ; CAR ; CDR } ;\n", " { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR ; CDR } ;\n", " { DIP { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ;\n", " SWAP } ;\n", " SWAP } ;\n", " { CAR ; CDR } ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ;\n", " { DUP ;\n", " DIP { CAR @%% ; { CAR @%% ; PAIR %@ % } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } } ;\n", " CDR @%% ;\n", " SWAP ;\n", " PAIR %@ %@ } ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " CDR ;\n", " SWAP ;\n", " PAIR ;\n", " SWAP ;\n", " DROP ;\n", " NIL operation ;\n", " PAIR } }\n", " { PAIR ;\n", " DUP ;\n", " { CDR ; CDR ; CAR ; CAR } ;\n", " SENDER ;\n", " COMPARE ;\n", " EQ ;\n", " IF {} { PUSH string \"WrongCondition: sp.sender == self.data.admin\" ; FAILWITH } ;\n", " DUP ;\n", " CDR ;\n", " DUP ;\n", " { CDR ; CAR ; CDR } ;\n", " { DIP { DIP { DUP } ; SWAP } ; SWAP } ;\n", " { CAR ; CAR } ;\n", " { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ;\n", " { CAR ; CDR } ;\n", " SOME ;\n", " SWAP ;\n", " UPDATE ;\n", " SWAP ;\n", " { DUP ;\n", " DIP { CDR @%% ;\n", " { DUP ; DIP { CAR @%% ; { CAR @%% ; PAIR %@ % } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ;\n", " CAR @%% ;\n", " PAIR %@ %@ } ;\n", " SWAP ;\n", " DROP ;\n", " NIL operation ;\n", " PAIR } }\n", " { PAIR ;\n", " DUP ;\n", " { CDR ; CDR ; CAR ; CAR } ;\n", " SENDER ;\n", " COMPARE ;\n", " EQ ;\n", " IF {} { PUSH string \"WrongCondition: sp.sender == self.data.admin\" ; FAILWITH } ;\n", " DUP ;\n", " CDR ;\n", " { DIP { DUP } ; SWAP } ;\n", " CAR ;\n", " SWAP ;\n", " { DUP ; DIP { CDR @%% ; { CAR @%% ; PAIR %@ % } } ; CAR @%% ; PAIR %@ %@ } ;\n", " SWAP ;\n", " DROP ;\n", " NIL operation ;\n", " PAIR } }" ] } ], "source": [ "INCLUDE \"KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg\"" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
Pair True\n",
       "      (Pair 9\n",
       "            (Pair\n",
       "              (Pair \"tz1M9CMEtsXm3QxA7FmMU2Qh7xzsuGXVbcDr\"\n",
       "                    { Elt \"By\" \"https://SmartPy.io\" ;\n",
       "                      Elt \"Help\" \"Use Build to define a new game board and Play to make moves\" ;\n",
       "                      Elt \"Play at\"\n",
       "                           \"https://smartpy.io/demo/explore.html?address=KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg\" ;\n",
       "                      Elt \"SmartPy Template\"\n",
       "                           \"https://smartpy.io/demo/index.html?template=tictactoeFactory.py\" })\n",
       "              False))
pair (bool %setPause)\n",
       "      (pair\n",
       "        (big_map string\n",
       "                 (pair\n",
       "                   (pair\n",
       "                     (pair\n",
       "                       (pair\n",
       "                         (pair\n",
       "                           (pair (pair (map %deck int (map int int)) (bool %draw))\n",
       "                                 (map %metaData string string))\n",
       "                           (int %nbMoves))\n",
       "                         (int %nextPlayer))\n",
       "                       (address %player1))\n",
       "                     (address %player2))\n",
       "                   (int %winner)))\n",
       "        (pair (pair (address %admin) (map %metaData string string)) (bool %paused)))
" ], "text/plain": [ "value type\n", "---------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------\n", "Pair True pair (bool %setPause)\n", " (Pair 9 (pair\n", " (Pair (big_map string\n", " (Pair \"tz1M9CMEtsXm3QxA7FmMU2Qh7xzsuGXVbcDr\" (pair\n", " { Elt \"By\" \"https://SmartPy.io\" ; (pair\n", " Elt \"Help\" \"Use Build to define a new game board and Play to make moves\" ; (pair\n", " Elt \"Play at\" (pair\n", " \"https://smartpy.io/demo/explore.html?address=KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg\" ; (pair\n", " Elt \"SmartPy Template\" (pair (pair (map %deck int (map int int)) (bool %draw))\n", " \"https://smartpy.io/demo/index.html?template=tictactoeFactory.py\" }) (map %metaData string string))\n", " False)) (int %nbMoves))\n", " (int %nextPlayer))\n", " (address %player1))\n", " (address %player2))\n", " (int %winner)))\n", " (pair (pair (address %admin) (map %metaData string string)) (bool %paused)))" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "BEGIN %setPause True STORAGE" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "CDR: pop (True, (9, (('tz1M9CMEtsXm3QxA7FmMU2Qh7xzsuGXVbcDr', {'By': 'https://SmartPy.io', 'Help': 'Use Build to define a new game board and Play to make moves', 'Play at': 'https://smartpy.io/demo/explore.html?address=KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg', 'SmartPy Template': 'https://smartpy.io/demo/index.html?template=tictactoeFactory.py'}), False))); push (9, (('tz1M9CMEtsXm3QxA7FmMU2Qh7xzsuGXVbcDr', {'By': 'https://SmartPy.io', 'Help': 'Use Build to define a new game board and Play to make moves', 'Play at': 'https://smartpy.io/demo/explore.html?address=KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg', 'SmartPy Template': 'https://smartpy.io/demo/index.html?template=tictactoeFactory.py'}), False));\n", "CAR: pop (9, (('tz1M9CMEtsXm3QxA7FmMU2Qh7xzsuGXVbcDr', {'By': 'https://SmartPy.io', 'Help': 'Use Build to define a new game board and Play to make moves', 'Play at': 'https://smartpy.io/demo/explore.html?address=KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg', 'SmartPy Template': 'https://smartpy.io/demo/index.html?template=tictactoeFactory.py'}), False)); push 9;\n", "PUSH: push MeuJogo;\n", "GET: pop MeuJogo, 9; push (((((((({0: {0: 0, 1: 0, 2: 0}, 1: {0: 0, 1: 1, 2: 0}, 2: {0: 0, 1: 0, 2: 0}}, False), {}), 1), 2), 'tz1S37hEZnNrAXfzuRYSjG9Qxq8VrwpWaukB'), 'tz1YNRy5f4vWVWTY8nqhA9Q9P1CjTb8oby6g'), 0),);" ] }, { "data": { "text/html": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
value type
Some (Pair\n",
       "       (Pair\n",
       "         (Pair\n",
       "           (Pair\n",
       "             (Pair\n",
       "               (Pair\n",
       "                 (Pair\n",
       "                   { Elt 0 { Elt 0 0 ; Elt 1 0 ; Elt 2 0 } ;\n",
       "                     Elt 1 { Elt 0 0 ; Elt 1 1 ; Elt 2 0 } ;\n",
       "                     Elt 2 { Elt 0 0 ; Elt 1 0 ; Elt 2 0 } }\n",
       "                   False)\n",
       "                 {})\n",
       "               1)\n",
       "             2)\n",
       "           \"tz1S37hEZnNrAXfzuRYSjG9Qxq8VrwpWaukB\")\n",
       "         \"tz1YNRy5f4vWVWTY8nqhA9Q9P1CjTb8oby6g\")\n",
       "       0)
option (pair\n",
       "         (pair\n",
       "           (pair\n",
       "             (pair\n",
       "               (pair\n",
       "                 (pair (pair (map %deck int (map int int)) (bool %draw))\n",
       "                       (map %metaData string string))\n",
       "                 (int %nbMoves))\n",
       "               (int %nextPlayer))\n",
       "             (address %player1))\n",
       "           (address %player2))\n",
       "         (int %winner))
" ], "text/plain": [ "value type\n", "------------------------------------------------------------ ------------------------------------------------------------------------\n", "Some (Pair option (pair\n", " (Pair (pair\n", " (Pair (pair\n", " (Pair (pair\n", " (Pair (pair\n", " (Pair (pair (pair (map %deck int (map int int)) (bool %draw))\n", " (Pair (map %metaData string string))\n", " { Elt 0 { Elt 0 0 ; Elt 1 0 ; Elt 2 0 } ; (int %nbMoves))\n", " Elt 1 { Elt 0 0 ; Elt 1 1 ; Elt 2 0 } ; (int %nextPlayer))\n", " Elt 2 { Elt 0 0 ; Elt 1 0 ; Elt 2 0 } } (address %player1))\n", " False) (address %player2))\n", " {}) (int %winner))\n", " 1)\n", " 2)\n", " \"tz1S37hEZnNrAXfzuRYSjG9Qxq8VrwpWaukB\")\n", " \"tz1YNRy5f4vWVWTY8nqhA9Q9P1CjTb8oby6g\")\n", " 0)" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "CDR ; CAR ; PUSH string \"MeuJogo\" ; GET" ] } ], "metadata": { "kernelspec": { "display_name": "Michelson", "language": "michelson", "name": "michelson" }, "language_info": { "codemirror_mode": "michelson", "file_extension": ".tz", "mimetype": "text/x-michelson", "name": "Michelson" } }, "nbformat": 4, "nbformat_minor": 2 }