1
0
mirror of https://github.com/danog/toncontest.git synced 2024-11-29 20:19:11 +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
* `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
* `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+):

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).
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.
@ -104,7 +104,7 @@ Scripts:
## Testing
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`.

View File

@ -5,43 +5,44 @@ chr() { [ "$1" -lt 256 ] || return 1; printf "\\$(printf '%03o' "$1")"; }
ord() { LC_CTYPE=C printf '%d' "'$1"; }
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)
fift -s ../sign.fif b abc c 2
# Update the wallet using code from wallet-code-update.fif,
# 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,
# 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
# 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 code-update-a code-update-$(chr $((97+f))) $(chr $((97+f))) $f;done
# 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 code-update-a code-update-$(chr $((97+f))) $(chr $((97+f))) $f;done
# Merge all queries
fift -s ../merge.fif code-update-{a..j} code-update-merge
# Merge all queries
fift -s ../merge.fif code-update-{a..j} code-update-merge
# Inspect queries
fift -s ../inspect.fif merge
# Inspect queries
fift -s ../inspect.fif merge
# Finally run the generated files in the VM
#
# First init VM with constructor message
# Then load first file with only two signatures by key a, b (0, 1)
# Then load wallet code update (0)
# Run seqno get-method
# Run getPartialsByKeyId get-method
# Load wallet code update with all signatures (and UPDATE CODE)
# Run getPartialsByKeyId get-method
# Finally load file with three signatures by keys a, b, c (0, 1, 2)
#
# 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,
# however the message **will be sent** since the minSig and keys fields in persistent storage will be updated.
#
fift -s ../test.fif \
pony-create \
b -1 \
code-update-a -1 \
0 85143 \
0 113609 \
code-update-merge -1 \
abc -1
# Finally run the generated files in the VM
#
# First init VM with constructor message
# Then load first file with only two signatures by key a, b (0, 1)
# Then load wallet code update (0)
# Run seqno get-method
# Run getPartialsByKeyId get-method
# Load wallet code update with all signatures (and UPDATE CODE)
# Run getPartialsByKeyId get-method
# Finally load file with three signatures by keys a, b, c (0, 1, 2)
#
# 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,
# however the message **will be sent** since the minSig and keys fields in persistent storage will be updated.
#
fift -s ../test.fif \
pony-create \
b -1 \
code-update-a -1 \
0 85143 \
0 113609 \
code-update-merge -1 \
abc -1
} 2>&1 | less -R

View File

@ -4,52 +4,54 @@
chr() { [ "$1" -lt 256 ] || return 1; printf "\\$(printf '%03o' "$1")"; }
ord() { LC_CTYPE=C printf '%d' "'$1"; }
mkdir -p tests
cd tests
# Create 10 public keys
for f in {a..j}; do fift -s ../gen-pub.fif $f;done
{
mkdir -p tests
cd tests
# 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
fift -s ../wallet-create.fif 0 pony 10 10 {a..j} | tee log
# 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
# Get wallet address
sed '/Non-bounceable address [(]for init[)]: /!d;s/.* //g' log > naddr.addr
# Get wallet address
sed '/Non-bounceable address [(]for init[)]: /!d;s/.* //g' log > naddr.addr
address=$(sed '/Bounceable address [(]for later access[)]: /!d;s/.* //g' log)
rm log
address=$(sed '/Bounceable address [(]for later access[)]: /!d;s/.* //g' log)
rm log
# 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
# 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
# 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.
# 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.
# 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.
# 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.
# 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
# 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
# Merge all queries
fift -s ../merge.fif {a..j} merge
# Merge all queries
fift -s ../merge.fif {a..j} merge
# Inspect queries
fift -s ../inspect.fif merge
# Inspect queries
fift -s ../inspect.fif merge
# Finally run the generated files in the VM
#
# First init VM with constructor message
# Then load first file with only one signature by key a (0)
# Run seqno get-method
# Run getPartialsByKeyId get-method
# Load file with all signatures (and send message)
# Run getPartialsByKeyId get-method
#
fift -s ../test.fif \
pony-create \
a -1 \
0 85143 \
0 113609 \
merge -1 \
0 113609
# Finally run the generated files in the VM
#
# First init VM with constructor message
# Then load first file with only one signature by key a (0)
# Run seqno get-method
# Run getPartialsByKeyId get-method
# Load file with all signatures (and send message)
# Run getPartialsByKeyId get-method
#
fift -s ../test.fif \
pony-create \
a -1 \
0 85143 \
0 113609 \
merge -1 \
0 113609
} 2>&1 | less -R