use-ink / ink-examples

A set of examples for ink! smart contract language. Happy hacking!
https://use.ink
The Unlicense
99 stars 55 forks source link

Multisig example - invoke_transaction/eval_transaction does not work when calling Multisig functions #71

Open haydenyoung opened 1 month ago

haydenyoung commented 1 month ago

I have implemented the Multisig wallet and have successfully created an e2e test to check the functionality.

My e2e flow:

invoke_transaction does not error but requirement does not update either.

eval_transaction errors with:

Calling `eval_transaction` failed: CallExtrinsic(Module(ModuleError(<Contracts::ContractReverted>)))

This problem only occurs when calling functions on Multisig. Calling functions on external contracts works.

haydenyoung commented 1 month ago

Further to the above post, I was able to get the invoke_tx function to work on fn calls on multisig by setting the CallFlags::TAIL_CALL call flag.

I'm not entirely sure why this works but according to the Ink documentation:

it is advised to use &self receiver with a mutating delegate call, or .set_tail_call(true) to flag that any changes made by delegate call should be flushed into storage.

I don't understand what "&self receiver with a mutating delegate call means" but, if set_tail_call forces the storage to update on the delegate call (i.e. the inner call being invoked by invoke_tx), it would make sense why this solves the problem.

I can't think why an external fn would update storage but a call back into multisig would not (without set_tail_call). Is it because storage doesn't update on the multisig until invoke_tx completes, and, because the delegate call falls out of scope, its changes aren't stored?