If a channel has been finalized on chain, the adjudicator contract knows about the final outcome. This tutorial section covers pushing that outcome to the asset holder contract(s), which is a necessary step to releasing the assets.
A finalized outcome is stored in two places on chain: first, as a single hash in the adjudicator contract; second, in multiple hashes across multiple asset holder contracts.
pushOutcome method on the
NitroAdjudicator allows one or more
assetOutcomes to be registered against a channel in a number of AssetHolder contracts (specified by the
outcome stored against a channel that has been finalized in the adjudicator).
In this example we will limit ourselves to an outcome that specifies ETH only, and therefore will only be pushing the outcome to a single contract (the
Let us begin with a conclude transaction, following the steps in the tutorial section above. When we finalize a channel this way, the chain stores the timestamp of the current blocknumber. We need to extract this information from the transaction receipt in order to be able to push the outcome successfully.
transferAll method is available on all asset holders, including the
ETHAssetHolder. It pays out assets according to outcomes that it knows about, if the channel is sufficiently funded.
If the destination specified in the outcome is external, the asset holder pays out the funds (as in the example above). Otherwise the destination is a channel id, and the contract updates its internal accounting such that this channel has its direct funding increased.
This method executes payouts that might benefit multiple participants. If multiple actors try and call this method, after the first transaction is confirmed the remaining ones may fail.
It may be desirable to payout to a subset of destinations (or even a single one). The
transfer method can be used to do this, and accepts a list of
indices to transfer from. See the contract API for more information. More information coming soon, including how to track the updated allocation after a
transfer is mined.
claimAll method will pay out the funds held against a guarantor channel, according to a target channel's outcome but with an preference order controlled by the guarantor channel.
If this process seems overly complicated to you: remember that guarantor channels are only required when virtually funding a channel. Also bear in mind that this process is unlinkely to actually play out on chain very often: it is in everyone's interest to administrate inter-channel funding off chain as much as possible, with the on chain administration such as this used as a last resort.
Instead of pushing the outcome from the adjudicator to the asset holder in one transaction, and then transferring the assets out of a channel according to that outcome, it is more convenient to use the adjudicator's
pushOutcomeAndTransferfAll method, which will do both in one go and save gas, to boot.
If we have a finalization proof, then we can call
condludePushOutcomeAndTransferAll to do the channel close, outcome push and payouts in one transaction.