Condition prefixes and filtering
When performing an operation on the protocol, it is usually necessary to spend multiple protocol coins at once, and for these coins to communicate with each other to ensure that each of them is being spent in a specific way. The mechanism that Chia uses for this are conditions.
In addition, protocol coins may also want to communicate with the off-chain world, for example with the driver code that is used to construct coin spends. This can be achieved via driver hints, which also use conditions.
Inter-coin communication
Inter-coin communication is facilitated by announcement and message conditions.
condition | prefixable |
---|---|
SEND_MESSAGE | ✅ |
RECEIVE_MESSAGE | ✅ |
CREATE_COIN_ANNOUNCEMENT | ✅ |
ASSERT_COIN_ANNOUNCEMENT | |
CREATE_PUZZLE_ANNOUNCEMENT | ✅ |
ASSERT_PUZZLE_ANNOUNCEMENT |
For the protocol to be secure, it is crucial that the conditions marked as prefixable in the table above cannot be faked.
For example, if a user secures a vault with an inner puzzle, the inner puzzle must not output a SEND_MESSAGE condition that looks like an SEND_MESSAGE condition the outer puzzle could have generated, as this could be used to falsely signal to other coins that the vault is being spent in a certain way or has a certain state.
To prevent conditions from being faked, the protocol uses the same trick as CATs, and prepends the protocol prefix to the condition message:
PROTOCOL_PREFIX = "C"
The outer puzzle of any protocol coin can then filter all conditions generated by the inner puzzle or passed in via the solution, and fail the spend if a prefixable condition is encountered.
Assert conditions are not prefixable as these can only restrict the spend of the coin that outputs them, but have no effect on other coins.
For a diagram showing how protocol coins communicate with each other, see the Inter-Coin Communication section.
Driver hints
It can be difficult for drivers to tell the state of an unspent coin. The driver code would effectively need to reimplement the coin spend logic of the coin's parent puzzle, so that the state of the unspent coin can be derived from parent puzzle reveal and solution. However, this can be challenging, especially as there are no transpilers for Chialisp available yet, making driver code trying to accurately replicate Chialisp code prone to errors.
As a workaround, puzzles can communicate with the driver via remark conditions. If every spend path of a puzzle includes a remark condition that publishes the state of the child coin created, it is straightforward for the driver to construct the state of the child coin.
condition | prefixable |
---|---|
REMARK | ✅ |
As with conditions use for inter-coin communication, the protocol makes sure that remark conditions used for driver hints cannot be faked by making the protocol prefix the first element following the condition code.
(list REMARK PROTOCOL_PREFIX ...)
The outer puzzle of any protocol coin can then filter all remark conditions generated by the inner puzzle or passed in via the solution, and fail the spend if a prefixed one is encountered.
Collateral vaults use a prefixed remark condition from the inner puzzle to determine which vault operation is being performed. This means that vault owners need to be careful to only use inner puzzles that allows them to generate the required remark conditions if needed. This has the advantage that complex custody arrangements can be put into place (such as custom rules for how individual vault operations must be authorised), but comes with the risk that an error in the inner puzzle logic results in the collateral deposited in a vault becoming inaccessible.
Coin creation
The CREATE_COIN condition deserves special attention. Where there is an inner puzzle or the ability to pass in conditions via the solution, it would be possible for additional child coins to be created. This is problematic for protocol coins that are singletons.
Although it would be possible to prefix CREATE_COIN conditions using the memo field, protocol condition filters ensure that no arbitrary CREATE_COINs can be generated from inner puzzles or solutions. CREATE_COIN conditions are either suitably processed or modified, or cause the spend to fail. If users want to tie the creation of a new coin to protocol coin spends, they can achieve this by using non-prefixed inter-coin communication conditions and protocol-external parent coins.