1
0
mirror of https://github.com/danog/toncontest.git synced 2024-12-02 09:27:47 +01:00
This commit is contained in:
Daniil Gentili 2019-10-15 00:23:58 +02:00
parent d902bc1ec3
commit 496cd2279d
Signed by: danog
GPG Key ID: 8C1BE3B34B230CA7
4 changed files with 79 additions and 76 deletions

View File

@ -18,7 +18,7 @@ This will automatically build the lite client, fift and func, and will also edit
## Contents ## Contents
* `toolchain` - Some automatic builder scripts and wrappers around the funC compiler and fift * `toolchain` - Some automatic builder scripts and wrappers around the funC compiler and fift, along with tweaked zerostate generator and testgiver scripts
* `wallet` - Advanced upgradable multisignature wallet * `wallet` - Advanced upgradable multisignature wallet
* `test` - A small bugreport about issues with fift exception traces * `test` - A small bugreport about issues with fift exception traces
* [GitHub issues and bugreports](https://github.com/ton-blockchain/ton/issues?utf8=%E2%9C%93&q=author%3Adanog+): * [GitHub issues and bugreports](https://github.com/ton-blockchain/ton/issues?utf8=%E2%9C%93&q=author%3Adanog+):

View File

@ -6,7 +6,7 @@ Upgradable multisignature wallet, with custom scripts to deserialize and inspect
All custom data structures used in the wallet can be viewed as a custom TL-B scheme in `proto/scheme.tlb` (some basic TON constructors are also included for reference). All custom data structures used in the wallet can be viewed as a custom TL-B scheme in `proto/scheme.tlb` (some basic TON constructors are also included for reference).
Most smart contact get-methods (except for the basic seqno and getPartials methods) return an integer, indicating whether the operation was successful and the requested data was found, followed by a cell/integer with the found data (or an empty cell/0 in case of failure). Most smart contact get-methods (except for the basic seqno and getPartials methods) return an integer, indicating whether the operation was successful and the requested data was found, followed by a cell/integer with the found data (or an empty cell/0 in case of failure).
I created a full testing platform with a collator emulator in FIFT that parses the generated external messages and runs the required logic (including code and data initialization from the StateInit of constructor messages, with support for multiple consecutive method calls and data persistence) in the TVM, partially emulating the logic of `Transaction::unpack_input_msg` and `Collator::create_ordinary_transaction`. I created a full testing platform with a collator emulator in FIFT that parses the generated external messages and runs the required logic (including code and data initialization from the StateInit of constructor messages, with support for multiple consecutive method calls and data persistence) in the TVM, partially emulating the logic of `Transaction::unpack_input_msg` and `Collator::create_ordinary_transaction`, also allowing us to run get-methods.
I've tested throughly the smart contract using my local collator emulator (`test.fif`), and the actual TON collator using a slightly tweaked [zerostate generator](https://github.com/ton-blockchain/ton/pull/145) and the custom `test-collator.sh` script. I've tested throughly the smart contract using my local collator emulator (`test.fif`), and the actual TON collator using a slightly tweaked [zerostate generator](https://github.com/ton-blockchain/ton/pull/145) and the custom `test-collator.sh` script.
@ -104,7 +104,7 @@ Scripts:
## Testing ## Testing
The `test.sh` script contains a full set of commands to test every fift script. The `test.sh` script contains a full set of commands to test every fift script.
You might want to run each command inside `test.sh` separately (there are also multiple comments explaining what each line does in detail), or run `./test.sh | less` to be able to better review the output of each command. You might want to run each command inside `test.sh` separately (there are also multiple comments explaining what each line does in detail).
What follows is a line-by-line description of the actions in `test.sh`. What follows is a line-by-line description of the actions in `test.sh`.

View File

@ -5,43 +5,44 @@ chr() { [ "$1" -lt 256 ] || return 1; printf "\\$(printf '%03o' "$1")"; }
ord() { LC_CTYPE=C printf '%d' "'$1"; } ord() { LC_CTYPE=C printf '%d' "'$1"; }
cd tests cd tests
{
# Sign previous simple wallet query (a, b) with key c (a, b, c)
fift -s ../sign.fif b abc c 2
# Sign previous simple wallet query (a, b) with key c (a, b, c) # Update the wallet using code from wallet-code-update.fif,
fift -s ../sign.fif b abc c 2 # also substituting the 10 keys with only 3 and setting k to 3
fift -s ../wallet-update.fif pony code-update-a 1 3 3 0 a b c
# Update the wallet using code from wallet-code-update.fif, # Sign the query using all keys separately, creating eight more boc files, each signed by two keys only (0 and 1..9)
# also substituting the 10 keys with only 3 and setting k to 3 for f in {1..9}; do fift -s ../sign.fif code-update-a code-update-$(chr $((97+f))) $(chr $((97+f))) $f;done
fift -s ../wallet-update.fif pony code-update-a 1 3 3 0 a b c
# Sign the query using all keys separately, creating eight more boc files, each signed by two keys only (0 and 1..9) # Merge all queries
for f in {1..9}; do fift -s ../sign.fif code-update-a code-update-$(chr $((97+f))) $(chr $((97+f))) $f;done fift -s ../merge.fif code-update-{a..j} code-update-merge
# Merge all queries # Inspect queries
fift -s ../merge.fif code-update-{a..j} code-update-merge fift -s ../inspect.fif merge
# Inspect queries # Finally run the generated files in the VM
fift -s ../inspect.fif merge #
# First init VM with constructor message
# Finally run the generated files in the VM # Then load first file with only two signatures by key a, b (0, 1)
# # Then load wallet code update (0)
# First init VM with constructor message # Run seqno get-method
# Then load first file with only two signatures by key a, b (0, 1) # Run getPartialsByKeyId get-method
# Then load wallet code update (0) # Load wallet code update with all signatures (and UPDATE CODE)
# Run seqno get-method # Run getPartialsByKeyId get-method
# Run getPartialsByKeyId get-method # Finally load file with three signatures by keys a, b, c (0, 1, 2)
# Load wallet code update with all signatures (and UPDATE CODE) #
# Run getPartialsByKeyId get-method # The latter will actually send the message, since now only three signatures are required to send a message (but the wallet code update was signed by all 10)
# Finally load file with three signatures by keys a, b, c (0, 1, 2) # This will not actually update the code, since there is no way (yet) to get a list of output actions generated by the TON VM from fift,
# # however the message **will be sent** since the minSig and keys fields in persistent storage will be updated.
# The latter will actually send the message, since now only three signatures are required to send a message (but the wallet code update was signed by all 10) #
# This will not actually update the code, since there is no way (yet) to get a list of output actions generated by the TON VM from fift, fift -s ../test.fif \
# however the message **will be sent** since the minSig and keys fields in persistent storage will be updated. pony-create \
# b -1 \
fift -s ../test.fif \ code-update-a -1 \
pony-create \ 0 85143 \
b -1 \ 0 113609 \
code-update-a -1 \ code-update-merge -1 \
0 85143 \ abc -1
0 113609 \ } 2>&1 | less -R
code-update-merge -1 \
abc -1

View File

@ -4,52 +4,54 @@
chr() { [ "$1" -lt 256 ] || return 1; printf "\\$(printf '%03o' "$1")"; } chr() { [ "$1" -lt 256 ] || return 1; printf "\\$(printf '%03o' "$1")"; }
ord() { LC_CTYPE=C printf '%d' "'$1"; } ord() { LC_CTYPE=C printf '%d' "'$1"; }
mkdir -p tests {
cd tests mkdir -p tests
# Create 10 public keys cd tests
for f in {a..j}; do fift -s ../gen-pub.fif $f;done # Create 10 public keys
for f in {a..j}; do fift -s ../gen-pub.fif $f;done
# Create wallet with those 10 public keys on workchain 0, requiring all 10 signatures to send a message # Create wallet with those 10 public keys on workchain 0, requiring all 10 signatures to send a message
fift -s ../wallet-create.fif 0 pony 10 10 {a..j} | tee log fift -s ../wallet-create.fif 0 pony 10 10 {a..j} | tee log
# Get wallet address # Get wallet address
sed '/Non-bounceable address [(]for init[)]: /!d;s/.* //g' log > naddr.addr sed '/Non-bounceable address [(]for init[)]: /!d;s/.* //g' log > naddr.addr
address=$(sed '/Bounceable address [(]for later access[)]: /!d;s/.* //g' log) address=$(sed '/Bounceable address [(]for later access[)]: /!d;s/.* //g' log)
rm log rm log
# Create a new wallet query signed with key a (ID 0), transferring 10 grams to the wallet itself # Create a new wallet query signed with key a (ID 0), transferring 10 grams to the wallet itself
fift -s ../create.fif pony a 0 $address 0 10 a fift -s ../create.fif pony a 0 $address 0 10 a
# Here, note the `a 0`: to save space, I have chosen to not use the entire ecdh key as key in the signature dictionary. # Here, note the `a 0`: to save space, I have chosen to not use the entire ecdh key as key in the signature dictionary.
# Instead, a **key ID** is used to distinguish signatures made by certain keys: this is a simple 4-bit value (instead of 256 bits!), equal to the position of the key in the `wallet-create` argument list. # Instead, a **key ID** is used to distinguish signatures made by certain keys: this is a simple 4-bit value (instead of 256 bits!), equal to the position of the key in the `wallet-create` argument list.
# In this case, the `a` key was the first key (`{a..j}` in Bash is shorthand for `a b c .. j`), so the ID is `0`. # In this case, the `a` key was the first key (`{a..j}` in Bash is shorthand for `a b c .. j`), so the ID is `0`.
# What follows is the address, the seqno, the amount of grams and the savefile (`a`) for the query. # What follows is the address, the seqno, the amount of grams and the savefile (`a`) for the query.
# Sign the query using all keys separately, creating eight more boc files, each signed by two keys only (0 and 1..9) # Sign the query using all keys separately, creating eight more boc files, each signed by two keys only (0 and 1..9)
for f in {1..9}; do fift -s ../sign.fif a $(chr $((97+f))) $(chr $((97+f))) $f;done for f in {1..9}; do fift -s ../sign.fif a $(chr $((97+f))) $(chr $((97+f))) $f;done
# Merge all queries # Merge all queries
fift -s ../merge.fif {a..j} merge fift -s ../merge.fif {a..j} merge
# Inspect queries # Inspect queries
fift -s ../inspect.fif merge fift -s ../inspect.fif merge
# Finally run the generated files in the VM # Finally run the generated files in the VM
# #
# First init VM with constructor message # First init VM with constructor message
# Then load first file with only one signature by key a (0) # Then load first file with only one signature by key a (0)
# Run seqno get-method # Run seqno get-method
# Run getPartialsByKeyId get-method # Run getPartialsByKeyId get-method
# Load file with all signatures (and send message) # Load file with all signatures (and send message)
# Run getPartialsByKeyId get-method # Run getPartialsByKeyId get-method
# #
fift -s ../test.fif \ fift -s ../test.fif \
pony-create \ pony-create \
a -1 \ a -1 \
0 85143 \ 0 85143 \
0 113609 \ 0 113609 \
merge -1 \ merge -1 \
0 113609 0 113609
} 2>&1 | less -R