This is a great question. So delegating a call is often misunderstood. There isn't much documentation out there on this topic. This article does exist:
However, the above article can be dense and hard to understand.
Basically when you are using ink! DelegateCall
you are "delegating" the call (ink! message) to another contract's code (by using that contract's on-chain code hash).
However, there are caveats.
First of all, as demonstrated in the example, if the delegated code intends to mutate the caller's storage, a developer needs to be mindful. If the delegated code modifies layout-full storage (i.e. it contains at least non-Lazy
, non-Mapping
field), the CallFlags::TAIL_CALL
flag needs to be specified and the storage layouts must match. This is due to the way ink! execution call stack is operated (see Stack Exchange Answer for more explanation).
I created a working example here:
You could try using DelegateCall
to use a message from another code hash that does a cross-contract call to another contract.
Another example can be found here:
Hopefully, this sheds some light on delegate calls.