Download ZIP (468.8 KB)

Pull request

Testing and Issues

You can test this entry and submit issues during the testing period of the Blockchain Contest contest.

Entries with serious issues will not be able to win the contest, but even minor issues might be important for overall results.




Haste free multi-signature wallet. Main advantages: orders are signed without seqno in them, which means they can be confirmed and launched in any order. (When something more important come into attention, or some members are slow to confirm previous one).

Each step has user friendly explanation on whats exactly happening right now. (Like - you signing order X, which valid within next N hours, it was signed by those participants etc. etc)
There some examples on how to extend the contract. How to update public keys list online or change number of required signatures before operation is approved. But because of constrained time of contest, I hadn't chance to finish them. Feel free to contact me if you need that in your applications (my GitHub profile in the link).

Notice, that you cannot send same order twice. If you want to send same amount to same destination again, you should consider making different "expires" value. Because upon sending message to contract it becomes public, anyone could re-send full list of signatures again. But they wont be accepted.
Any order hash that being sent are stored in history vault, and every message is compared, if it's found in history. (Both pending and history orders are being cleared once they expired automatically, or you can execute clear_space with some grams in message)

Stay tuned for better user-friendly scripts and updates!
While testing please notice, that seqno should be updated after each message being sent. Place valid seqno at enveloping step.
You have not added any comments yet...
by rating


Magic Python Oct 23, 2019 at 10:56
Tried to send one order with 10 signatures (n = 16, k=10)
Failed with exit_code=100. Also, this transaction was repeated multiple times, so now the account is almost empty
Bright Peacock Nov 11, 2019 at 08:26
Oh my goodness!

I've been testing things before submit, and there method call at the end of recv_external:

var yay = export_pending_by_pos(0), that shouldn't be there. And the throws. 100 means debug output. That's why transaction was repeated several times - seqno didn't update.

Thanks for pointing out >_>
Magic Python Nov 4, 2019 at 10:49
All required features are implemented.
It is possible to add a signature to order without modifying seqno.

Failed with exit_code=100.
Hash does not protect seqno.
The same signature repeated multiple times would be enough to execute an order.
accept_message() is called before any signature is verified.
The code is split into several files. This is fine, but in the current case, this makes it a bit hard to follow workflow.
For example, set_data is called multiple times during execution but this is hard to notice and there is no simple
way to fix it without refactoring
Bright Peacock Nov 11, 2019 at 08:25
Throw 100 mean debug. woops.

"The same signature repeated multiple times would be enough to execute an order." There protection against that, and that's not the case.
orders.fc, line 73-89. If user_id has been found - do nothing. contract_utils.fc, line 107-123, if key-ID proving signature - proceed. So by the time of calling add_confirmation_to_order each ID proven to be correct and trusted. Only first ID going to be added.

Thoughts: set_data its merely update of single register, and should be inexpensive. If we group methods by their hi-level purpose. The code going to be more flexible without any major tradeoff's. If my code going to be used by other people, this way is much easier to maintain.

We can reduce set_data calls to just 2, without refactoring (one for seqno update, and second for order processing). Because of assumptions above, I decided pass on that so far. Rule of thumb: each impure method will update set_data.

Trying to squeeze reply.
You accept the message before actually checking the signatures. Accepting message drains wallet funds for executing the code.
Bright Peacock Oct 17, 2019 at 07:56
Yes, I am. My concern was this: the message shouldn't be accepted before every single signature is confirmed. Because then anyone could add random bits at the end, and make contract drain all the funds. That's why I had the logic - if signature valid - throw exception. In my intuition that should lead to message being aborted. Instead I saw exactly opposite - endless retries.

I've learned it hard way: no throws after accept.

So, either there is not enough credit for validation, or it doesn't matter when exactly you accept it. It still vulnerable.

Now I know that the best way is to add one extra sign that validate message with pack of signatures. Then we can check it within credit. But I had no time to add that.
Nobody added any issues yet...