Welcome, friend! This an ultimate Michelson playground, and in this tutorial, you will learn how to make the most of all available functionality.
If there are any questions, please ask in our telegram chat https://t.me/baking_bad_chat
PUSH string "Hello, world!"
value | type |
---|---|
"Hello, world!" | string |
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.
This enables a step-by-step coding approach which can save time while learning language or making a prototype or demo.
DROP
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.
This context is shared across all cells. Note, that the cell's position doesn't matter, only the execution order.
BALANCE # balance is initialized with a default value
value | type | name |
---|---|---|
257000000 | mutez | @balance |
When you execute a cell, messages can appear in the stdout
andstderr
streams, as well as the optional result at the end.
Let's try to execute a sequence of commands:
PUSH mutez 0 ;
IFCMPEQ { FAIL } { PUSH string "We got money!" }
PUSH: push 0; COMPARE: pop 0, 257000000; push -1; EQ: pop -1; push False; IF: pop False; PUSH: push We got money!;
value | type |
---|---|
"We got money!" | string |
When there's more than one command a verbose logging is enabled. It can be disabled which will be shown a bit later.
If the latest command in the sequences pushes an item onto the stack - it will be returned as a result.
DEBUG False # we just have disabled the verbose output
PUSH (list string) { "a" ; "b" ; "c" } ;
PRINT "{0} is on top of the stack, then goes {1}" ; # still we can printf anything to stdout
CONCAT @abc
PRINT: ['a', 'b', 'c'] is on top of the stack, then goes We got money!;
value | type | name |
---|---|---|
"abc" | string | @abc |
Time to inspect the stack, there is DUMP
helper for that. You can use it with or without depth specified (all elements)
DUMP 2
value | type | name |
---|---|---|
"abc" | string | @abc |
"We got money!" | string |
DROP_ALL ; DUMP
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:
ADD
MichelsonRuntimeError: got 0 items, requested 2 at ADD
HELLO
MichelsonParserError: unknown primitive HELLO at line 1, pos 0
PUSH mutez 1 ; EQ
MichelsonRuntimeError: expected Int, got Mutez at EQ
DEBUG True # and we continue to the next topic ^_^
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:
PATCH AMOUNT 100500 ; AMOUNT
PATCH: set AMOUNT=100500; AMOUNT: push 100500;
value | type | name |
---|---|---|
100500 | mutez | @amount |
PATCH AMOUNT ; AMOUNT # still have default value 0
PATCH: unset AMOUNT; AMOUNT: push 0;
value | type | name |
---|---|---|
0 | mutez | @amount |
Despite internal operations will never apply, Michelson kernel tries to emulate the standard behavior as closely as possible.
UNIT; # starting storage for contract
AMOUNT; # Push the starting balance
NONE key_hash; # No delegate
CREATE_CONTRACT # Create the contract
{ parameter unit ;
storage unit ;
code { FAIL } };
UNIT: push Unit; AMOUNT: push 0; NONE: push None; CREATE_CONTRACT: pop None, 0, Unit; set BALANCE=257000000; push KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm; push <originate KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm>;
value | type |
---|---|
amount: '0' code: code { { UNIT ; FAILWITH } } kind: origination storage: Unit target: KT1Mjjcb6tmSsLm7Cb3DSQszePjfchPM4Uxm | operation |
parameter
, storage
, and code
instructions are supported as well, what they do is basically store the argument in the context.
parameter unit ;
storage string ;
code { DROP ; PUSH string "Hey!"; NIL operation ; PAIR }
parameter unit storage string code { DROP ; PUSH string "Hey!" ; NIL operation ; PAIR }
In order to run this contract with particular parameters and initial storage you can use RUN
helper:
RUN %default Unit "hi" # %default is entrypoint
RUN: use %default; drop all; push (Unit, 'hi'); DROP: pop (Unit, 'hi'); PUSH: push Hey!; NIL: push []; PAIR: pop [], Hey!; push ([], 'Hey!');
value | type |
---|---|
"Hey!" | string |
RUN
returns storage, big map diff (if applicable), and list of internal operations.
You can also load contract from file or chain via INCLUDE
helper:
INCLUDE "mainnet:KT1VG2WtYdSWz5E7chTeAdDPZNy2MpP8pTfL" # can also be a filename
INCLUDE: set STORAGE={'prim': 'Pair', 'args': [{'int': '4'}, {'prim': 'Unit'}]}; parameter (or (or %fund (pair :initiate %initiate (address %participant) (pair %settings (pair (bytes %hashed_secret) (timestamp %refund_time)) (mutez %payoff))) (bytes :hashed_secret %add)) (or %withdraw (bytes :secret %redeem) (bytes :hashed_secret %refund))) storage (pair (big_map bytes (pair (pair %recipients (address %initiator) (address %participant)) (pair %settings (pair (mutez %amount) (timestamp %refund_time)) (mutez %payoff)))) unit) code { NIL @operations operation ; SWAP ; { { DUP ; CAR @% ; DIP { CDR } } ; DIP { { DUP ; CAR @% ; DIP { CDR @% } } } } ; DIP { DUP } ; IF_LEFT { IF_LEFT { { { DUP ; CAR @% ; DIP { CDR @% } } } ; DUP ; CONTRACT @participant unit ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; DROP ; SWAP ; { { DUP ; CAR ; DIP { CDR @% } } ; { DUP ; CAR @% ; DIP { CDR @% } } } ; DUP ; SIZE ; PUSH nat 32 ; { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; DIP { DIP { DUP } ; SWAP ; AMOUNT @amount ; SUB ; SENDER ; DUP ; CONTRACT @initiator unit ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; DROP ; DIP { { PAIR ; PAIR } ; SWAP } ; { PAIR ; PAIR } ; SOME @xcat ; SWAP } ; DUP ; DIP { MEM ; NOT ; { IF {} { { UNIT ; FAILWITH } } } } } { DUP ; DIP { GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { { DUP ; CAR @% ; DIP { CDR @% } } } ; DIP { { { DUP ; CAR ; DIP { CDR @% } } ; { DUP ; CAR @% ; DIP { CDR @% } } } ; SWAP ; DUP ; NOW ; { { COMPARE ; LT } ; IF {} { { UNIT ; FAILWITH } } } ; SWAP ; AMOUNT @amount ; ADD } ; { DIP { PAIR } ; DIP { PAIR } ; PAIR } ; SOME @xcat } } ; UPDATE ; PAIR @new_storage ; SWAP ; PAIR } { IF_LEFT { DUP ; SIZE ; PUSH nat 32 ; { { COMPARE ; EQ } ; IF {} { { UNIT ; FAILWITH } } } ; SHA256 ; SHA256 @hash ; DUP ; DIP { SWAP } ; { DIP { DIP { GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; DUP ; { { DUP ; CAR @% ; DIP { CDR @% } } } ; CDR @% ; CONTRACT @participant unit ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; SWAP ; { CAR ; CAR @% } ; { DIP { DIP { SENDER ; CONTRACT @sender unit ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; SWAP ; CDR @% ; { { DUP ; CAR ; DIP { CDR @% } } ; { DUP ; CAR @% ; DIP { CDR @% } } } ; DROP ; NOW ; { { COMPARE ; LT } ; IF {} { { UNIT ; FAILWITH } } } ; DUP ; PUSH mutez 0 ; { COMPARE ; LT ; IF { UNIT ; TRANSFER_TOKENS ; DIP { SWAP } ; CONS } { DROP ; DROP ; SWAP } } } } } ; UNIT ; TRANSFER_TOKENS } } } } { DUP ; DIP { GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; DUP ; { CAR ; CAR @% } ; CONTRACT @initiator unit ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; SWAP ; CDR ; { { DUP ; CAR ; DIP { CDR @% } } ; { DUP ; CAR @% ; DIP { CDR @% } } } ; SWAP ; NOW ; { { COMPARE ; GE } ; IF {} { { UNIT ; FAILWITH } } } ; ADD ; UNIT ; TRANSFER_TOKENS ; SWAP ; { DIP { DIP { SWAP } } } } } ; NONE @none (pair (pair address address) (pair (pair mutez timestamp) mutez)) ; SWAP ; UPDATE @cleared_map ; SWAP ; DIP { SWAP ; DIP { PAIR } } ; CONS ; PAIR } }
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
:
BEGIN %refund 0xdeadbeef (Pair {} Unit)
value | type |
---|---|
Pair 0xdeadbeef (Pair -1 Unit) | pair (bytes :hashed_secret %refund) (pair (big_map bytes (pair (pair %recipients (address %initiator) (address %participant)) (pair %settings (pair (mutez %amount) (timestamp %refund_time)) (mutez %payoff)))) unit) |
CDR ; NIL operation ; PAIR ; COMMIT
CDR: pop (b'\xde\xad\xbe\xef', (-1, Unit)); push (-1, Unit); NIL: push []; PAIR: pop [], (-1, Unit); push ([], (-1, Unit)); COMMIT:
value | type |
---|---|
Pair 0 Unit | pair (big_map bytes (pair (pair %recipients (address %initiator) (address %participant)) (pair %settings (pair (mutez %amount) (timestamp %refund_time)) (mutez %payoff)))) unit |
big_map | action | key | value |
---|---|---|---|
0 | alloc | bytes | pair (pair %recipients (address %initiator) (address %participant)) (pair %settings (pair (mutez %amount) (timestamp %refund_time)) (mutez %payoff)) |
You can also break the current pseudo-exection by calling RESET
- it will clear the stack and all the cached big maps:
RESET
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.
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.
In our playground in order to check the big map state, you need to call BIG_MAP_DIFF
helper.
EMPTY_BIG_MAP string string
value | type |
---|---|
-1 | big_map string string |
PUSH string "two";
SOME;
PUSH string "one";
UPDATE
PUSH: push two; SOME: pop two; push ('two',); PUSH: push one; UPDATE: pop one, ('two',), -1; push -1;
value | type |
---|---|
-1 | big_map string string |
BIG_MAP_DIFF # works if the top item contains big maps
big_map | action | key | value |
---|---|---|---|
0 | alloc | string | string |
0 | update | "one" | "two" |
So far, we have come across alloc
andupdate
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:
parameter unit;
storage (big_map int int);
code { CDR ; NIL operation ;PAIR }
parameter unit storage (big_map int int) code { CDR ; NIL operation ; PAIR }
RUN Unit { Elt 1 2 ; Elt 2 3 }
RUN: use %default; drop all; push (Unit, -2); CDR: pop (Unit, -2); push -2; NIL: push []; PAIR: pop [], -2; push ([], -2);
value | type |
---|---|
0 | big_map int int |
big_map | action | key | value |
---|---|---|---|
0 | alloc | int | int |
0 | update | 1 | 2 |
0 | update | 2 | 3 |
code { CDR ; PUSH int 5; SOME ; PUSH int 4; UPDATE ; NIL operation ; PAIR }
RUN Unit 0 # passing previously allocated big_map #0
RUN: use %default; drop all; push (Unit, 0); CDR: pop (Unit, 0); push 0; PUSH: push 5; SOME: pop 5; push (5,); PUSH: push 4; UPDATE: pop 4, (5,), 0; push 0; NIL: push []; PAIR: pop [], 0; push ([], 0);
value | type |
---|---|
0 | big_map int int |
big_map | action | key | value |
---|---|---|---|
0 | update | 4 | 5 |
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.
RESET "mainnet"
CHAIN_ID ; NOW ; DUMP 2 # Few blockchain-specific instruction will change the behavior
CHAIN_ID: push NetXdQprcVkpaWU; NOW: push 1583536716;
value | type | name |
---|---|---|
1583536716 | timestamp | @now |
"NetXdQprcVkpaWU" | chain_id | @mainnet |
PUSH address "KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg" ; CONTRACT unit # also, contract type checking is now working
PUSH: push KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg; CONTRACT: pop KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg; entry type mismatch; push None;
value | type |
---|---|
None | option (contract unit) |
The coolest thing is that now you can access real big maps by a pointer, right from your pseudo-contract.
If you are loading the contract source from the network, a special variable Current
is initialized with the current contract storage.
INCLUDE "KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg"
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'}]}]}; parameter (or (or (or (or (or (pair %build (pair (string %game) (address %player1)) (address %player2)) (string %game)) (pair %play (pair (pair (string %game) (int %i)) (int %j)) (int %move))) (pair %setGameMetaData (pair (string %game) (string %name)) (string %value))) (pair %setMetaData (string %name) (string %value))) (bool %setPause)) storage (pair (big_map string (pair (pair (pair (pair (pair (pair (pair (map %deck int (map int int)) (bool %draw)) (map %metaData string string)) (int %nbMoves)) (int %nextPlayer)) (address %player1)) (address %player2)) (int %winner))) (pair (pair (address %admin) (map %metaData string string)) (bool %paused))) code { DUP ; CDR ; SWAP ; CAR ; IF_LEFT { IF_LEFT { IF_LEFT { IF_LEFT { IF_LEFT { PAIR ; DUP ; { CDR ; CDR ; CDR } ; NOT ; IF { PUSH bool True } { DUP ; { CDR ; CDR ; CAR ; CAR } ; SENDER ; COMPARE ; EQ } ; IF {} { PUSH string "WrongCondition: (~ self.data.paused) | (sp.sender == self.data.admin)" ; FAILWITH } ; DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR } ; MEM ; NOT ; IF {} { PUSH string "WrongCondition: ~ (params.game in self.data.boards)" ; FAILWITH } ; DUP ; CDR ; DUP ; CAR ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR } ; { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; CAR ; CDR ; PUSH int 0 ; SWAP ; { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CDR } ; PUSH int 1 ; PUSH int 0 ; EMPTY_MAP string string ; PUSH bool False ; PUSH (map int (map int int)) { Elt 0 { Elt 0 0 ; Elt 1 0 ; Elt 2 0 } ; Elt 1 { Elt 0 0 ; Elt 1 0 ; Elt 2 0 } ; Elt 2 { Elt 0 0 ; Elt 1 0 ; Elt 2 0 } } ; PAIR ; PAIR ; PAIR ; PAIR ; PAIR ; PAIR ; PAIR ; SOME ; SWAP ; UPDATE ; SWAP ; CDR ; SWAP ; PAIR ; SWAP ; DROP ; NIL operation ; PAIR } { PAIR ; DUP ; { CDR ; CDR ; CAR ; CAR } ; SENDER ; COMPARE ; EQ ; IF {} { PUSH string "WrongCondition: sp.sender == self.data.admin" ; FAILWITH } ; DUP ; CDR ; DUP ; CAR ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; CAR ; NONE (pair (pair (pair (pair (pair (pair (pair (map %deck int (map int int)) (bool %draw)) (map %metaData string string)) (int %nbMoves)) (int %nextPlayer)) (address %player1)) (address %player2)) (int %winner)) ; SWAP ; UPDATE ; SWAP ; CDR ; SWAP ; PAIR ; SWAP ; DROP ; NIL operation ; PAIR } } { PAIR ; DUP ; { CDR ; CDR ; CDR } ; NOT ; IF {} { PUSH string "WrongCondition: ~ self.data.paused" ; FAILWITH } ; DUP ; CDR ; CAR ; PUSH int 0 ; SWAP ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; CDR ; COMPARE ; EQ ; IF { DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CDR } ; NOT } { PUSH bool False } ; IF {} { PUSH string "WrongCondition: (self.data.boards[params.game].winner == 0) & (~ self.data.boards[params.game].draw)" ; FAILWITH } ; DUP ; CAR ; { CAR ; CAR ; CDR } ; PUSH int 0 ; SWAP ; COMPARE ; GE ; IF { PUSH int 3 ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CDR } ; COMPARE ; LT } { PUSH bool False } ; IF {} { PUSH string "WrongCondition: (params.i >= 0) & (params.i < 3)" ; FAILWITH } ; DUP ; CAR ; { CAR ; CDR } ; PUSH int 0 ; SWAP ; COMPARE ; GE ; IF { PUSH int 3 ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CDR } ; COMPARE ; LT } { PUSH bool False } ; IF {} { PUSH string "WrongCondition: (params.j >= 0) & (params.j < 3)" ; FAILWITH } ; DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CDR } ; { DIP { DUP } ; SWAP } ; { CAR ; CDR } ; COMPARE ; EQ ; IF {} { PUSH string "WrongCondition: params.move == self.data.boards[params.game].nextPlayer" ; FAILWITH } ; DUP ; CDR ; CAR ; PUSH int 0 ; SWAP ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; EQ ; IF {} { PUSH string "WrongCondition: self.data.boards[params.game].deck[params.i][params.j] == 0" ; FAILWITH } ; DUP ; CAR ; CDR ; PUSH int 1 ; COMPARE ; EQ ; IF { DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CDR } ; SENDER ; COMPARE ; EQ ; IF {} { PUSH string "WrongCondition: sp.sender == self.data.boards[params.game].player1" ; FAILWITH } } { DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CDR } ; SENDER ; COMPARE ; EQ ; IF {} { PUSH string "WrongCondition: sp.sender == self.data.boards[params.game].player2" ; FAILWITH } } ; DUP ; CDR ; DUP ; CAR ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; PAIR ; DUP ; DIP { { { DUP ; CAR ; DIP { CDR } } } } ; { { DUP ; CAR ; DIP { CDR } } } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; CAR ; { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CDR } ; PUSH int 3 ; SUB ; SWAP ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { CAR @%% ; PAIR %@ % } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } ; SOME ; SWAP ; UPDATE ; SWAP ; CDR ; SWAP ; PAIR ; SWAP ; CAR ; PAIR ; DUP ; CDR ; DUP ; CAR ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; PAIR ; DUP ; DIP { { { DUP ; CAR ; DIP { CDR } } } } ; { { DUP ; CAR ; DIP { CDR } } } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; DUP ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CDR } ; PAIR ; DUP ; DIP { { { DUP ; CAR ; DIP { CDR } } } } ; { { DUP ; CAR ; DIP { CDR } } } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DIP { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CDR } ; { DIP { DIP { DIP { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CDR } ; SOME ; SWAP ; UPDATE ; SOME ; SWAP ; UPDATE ; SWAP ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { CDR @%% ; SWAP ; PAIR % %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } ; SOME ; SWAP ; UPDATE ; SWAP ; CDR ; SWAP ; PAIR ; SWAP ; CAR ; PAIR ; DUP ; CDR ; DUP ; CAR ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; PAIR ; DUP ; DIP { { { DUP ; CAR ; DIP { CDR } } } } ; { { DUP ; CAR ; DIP { CDR } } } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; CAR ; PUSH int 1 ; SWAP ; { DIP { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CDR } ; ADD ; SWAP ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { CAR @%% ; PAIR %@ % } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } ; SOME ; SWAP ; UPDATE ; SWAP ; CDR ; SWAP ; PAIR ; SWAP ; CAR ; PAIR ; DUP ; CDR ; CAR ; PUSH int 0 ; SWAP ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; NEQ ; IF { DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 1 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DUP } ; SWAP } ; { CDR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; EQ } { PUSH bool False } ; IF { DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 2 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DUP } ; SWAP } ; { CDR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; EQ } { PUSH bool False } ; IF { DUP ; CDR ; DUP ; CAR ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; PAIR ; DUP ; DIP { { { DUP ; CAR ; DIP { CDR } } } } ; { { DUP ; CAR ; DIP { CDR } } } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; CAR ; { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; SWAP ; CAR ; PAIR ; SOME ; SWAP ; UPDATE ; SWAP ; CDR ; SWAP ; PAIR ; SWAP ; CAR ; PAIR } {} ; DUP ; CDR ; CAR ; PUSH int 0 ; SWAP ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; NEQ ; IF { DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 1 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DUP } ; SWAP } ; { CDR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; EQ } { PUSH bool False } ; IF { DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 2 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DUP } ; SWAP } ; { CDR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; EQ } { PUSH bool False } ; IF { DUP ; CDR ; DUP ; CAR ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; PAIR ; DUP ; DIP { { { DUP ; CAR ; DIP { CDR } } } } ; { { DUP ; CAR ; DIP { CDR } } } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; CAR ; { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CDR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; SWAP ; CAR ; PAIR ; SOME ; SWAP ; UPDATE ; SWAP ; CDR ; SWAP ; PAIR ; SWAP ; CAR ; PAIR } {} ; DUP ; CDR ; CAR ; PUSH int 0 ; SWAP ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; NEQ ; IF { DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 1 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 1 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DUP } ; SWAP } ; { CDR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; EQ } { PUSH bool False } ; IF { DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 2 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 2 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DUP } ; SWAP } ; { CDR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; EQ } { PUSH bool False } ; IF { DUP ; CDR ; DUP ; CAR ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; PAIR ; DUP ; DIP { { { DUP ; CAR ; DIP { CDR } } } } ; { { DUP ; CAR ; DIP { CDR } } } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; CAR ; { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; SWAP ; CAR ; PAIR ; SOME ; SWAP ; UPDATE ; SWAP ; CDR ; SWAP ; PAIR ; SWAP ; CAR ; PAIR } {} ; DUP ; CDR ; CAR ; PUSH int 0 ; SWAP ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 2 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; NEQ ; IF { DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 1 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 1 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DUP } ; SWAP } ; { CDR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 2 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; EQ } { PUSH bool False } ; IF { DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 2 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DUP } ; SWAP } ; { CDR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 2 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; COMPARE ; EQ } { PUSH bool False } ; IF { DUP ; CDR ; DUP ; CAR ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; PAIR ; DUP ; DIP { { { DUP ; CAR ; DIP { CDR } } } } ; { { DUP ; CAR ; DIP { CDR } } } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; CAR ; { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CAR ; CAR ; CAR } ; PUSH int 0 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH int 2 ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; SWAP ; CAR ; PAIR ; SOME ; SWAP ; UPDATE ; SWAP ; CDR ; SWAP ; PAIR ; SWAP ; CAR ; PAIR } {} ; DUP ; CDR ; CAR ; PUSH int 9 ; SWAP ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CAR ; CAR ; CDR } ; COMPARE ; EQ ; IF { PUSH int 0 ; { DIP { DUP } ; SWAP } ; { CDR ; CAR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; CDR ; COMPARE ; EQ } { PUSH bool False } ; IF { DUP ; CDR ; DUP ; CAR ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR ; CAR } ; PAIR ; DUP ; DIP { { { DUP ; CAR ; DIP { CDR } } } } ; { { DUP ; CAR ; DIP { CDR } } } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; PUSH bool True ; SWAP ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { CAR @%% ; PAIR %@ % } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } ; SOME ; SWAP ; UPDATE ; SWAP ; CDR ; SWAP ; PAIR ; SWAP ; CAR ; PAIR } {} ; CDR ; NIL operation ; PAIR } } { PAIR ; DUP ; { CDR ; CDR ; CAR ; CAR } ; SENDER ; COMPARE ; EQ ; IF { PUSH bool True } { DUP ; { CDR ; CAR } ; { DIP { DUP } ; SWAP } ; { CAR ; CAR ; CAR } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; { CAR ; CAR ; CDR } ; SENDER ; COMPARE ; EQ } ; IF {} { PUSH string "WrongCondition: (sp.sender == self.data.admin) | (sp.sender == self.data.boards[params.game].player1)" ; FAILWITH } ; DUP ; CDR ; DUP ; CAR ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CAR } ; PAIR ; DUP ; DIP { { { DUP ; CAR ; DIP { CDR } } } } ; { { DUP ; CAR ; DIP { CDR } } } ; GET ; { IF_NONE { { UNIT ; FAILWITH } } {} } ; DUP ; { CAR ; CAR ; CAR ; CAR ; CAR ; CDR } ; { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CAR ; CDR } ; { DIP { DIP { DIP { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CDR } ; SOME ; SWAP ; UPDATE ; SWAP ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { DUP ; DIP { CAR @%% ; { CAR @%% ; PAIR %@ % } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CDR @%% ; SWAP ; PAIR %@ %@ } ; SOME ; SWAP ; UPDATE ; SWAP ; CDR ; SWAP ; PAIR ; SWAP ; DROP ; NIL operation ; PAIR } } { PAIR ; DUP ; { CDR ; CDR ; CAR ; CAR } ; SENDER ; COMPARE ; EQ ; IF {} { PUSH string "WrongCondition: sp.sender == self.data.admin" ; FAILWITH } ; DUP ; CDR ; DUP ; { CDR ; CAR ; CDR } ; { DIP { DIP { DUP } ; SWAP } ; SWAP } ; { CAR ; CAR } ; { DIP { DIP { DIP { DUP } ; SWAP } ; SWAP } ; SWAP } ; { CAR ; CDR } ; SOME ; SWAP ; UPDATE ; SWAP ; { DUP ; DIP { CDR @%% ; { DUP ; DIP { CAR @%% ; { CAR @%% ; PAIR %@ % } } ; CDR @%% ; SWAP ; PAIR %@ %@ } } ; CAR @%% ; PAIR %@ %@ } ; SWAP ; DROP ; NIL operation ; PAIR } } { PAIR ; DUP ; { CDR ; CDR ; CAR ; CAR } ; SENDER ; COMPARE ; EQ ; IF {} { PUSH string "WrongCondition: sp.sender == self.data.admin" ; FAILWITH } ; DUP ; CDR ; { DIP { DUP } ; SWAP } ; CAR ; SWAP ; { DUP ; DIP { CDR @%% ; { CAR @%% ; PAIR %@ % } } ; CAR @%% ; PAIR %@ %@ } ; SWAP ; DROP ; NIL operation ; PAIR } }
BEGIN %setPause True STORAGE
value | type |
---|---|
Pair True (Pair 9 (Pair (Pair "tz1M9CMEtsXm3QxA7FmMU2Qh7xzsuGXVbcDr" { Elt "By" "https://SmartPy.io" ; Elt "Help" "Use Build to define a new game board and Play to make moves" ; Elt "Play at" "https://smartpy.io/demo/explore.html?address=KT1UvfyLytrt71jh63YV4Yex5SmbNXpWHxtg" ; Elt "SmartPy Template" "https://smartpy.io/demo/index.html?template=tictactoeFactory.py" }) False)) | pair (bool %setPause) (pair (big_map string (pair (pair (pair (pair (pair (pair (pair (map %deck int (map int int)) (bool %draw)) (map %metaData string string)) (int %nbMoves)) (int %nextPlayer)) (address %player1)) (address %player2)) (int %winner))) (pair (pair (address %admin) (map %metaData string string)) (bool %paused))) |
CDR ; CAR ; PUSH string "MeuJogo" ; GET
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)); 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; PUSH: push MeuJogo; 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),);
value | type |
---|---|
Some (Pair (Pair (Pair (Pair (Pair (Pair (Pair { Elt 0 { Elt 0 0 ; Elt 1 0 ; Elt 2 0 } ; Elt 1 { Elt 0 0 ; Elt 1 1 ; Elt 2 0 } ; Elt 2 { Elt 0 0 ; Elt 1 0 ; Elt 2 0 } } False) {}) 1) 2) "tz1S37hEZnNrAXfzuRYSjG9Qxq8VrwpWaukB") "tz1YNRy5f4vWVWTY8nqhA9Q9P1CjTb8oby6g") 0) | option (pair (pair (pair (pair (pair (pair (pair (map %deck int (map int int)) (bool %draw)) (map %metaData string string)) (int %nbMoves)) (int %nextPlayer)) (address %player1)) (address %player2)) (int %winner)) |