The concept of Delegate Contract ID is touched upon in the documentation but I don't understand it.
I was not able to find examples or further explanations. Can someone point me to more details?
Delegate Contract ID was introduced with HIP-206: Hedera Token Service Precompiled Contract for Hedera SmartContract Service, and you can use it to be more permissive about the actual code you are delegating the control of specific features to (i.e., freezing, burning, wiping, etc.) to.
For example, if you set a contract as controller of the FreezeKey key using ContractId
, only the actual code owned by the specified contract can use the freeze function.
const transaction = new TokenCreateTransaction()
.setFreezeKey(ContractId.fromString(contractId))
If, on the contrary, you set a contract as controller of the FreezeKey using a DelegateContractId
, that contract can execute code it does not own (i.e., via delegateCall
). So, you have more flexibility, but it will not always be possible to determine the actual code your transaction will execute in advance.
const transaction = new TokenCreateTransaction()
.setFreezeKey(DelegateContractId.fromString(contractId))
Here is an excerpt from the HIP-206:
Contract Key
To support contracts controlling features like minting and burning the defined but up until now unused field contractID in the Key protobuf message will be utilised. When a token has a contract key as the admin key or one of the admin keys then that key is considered validated if the CALLER of the relevant method is the contract identified in the call. This is the effect of a CALL operation in the EVM.
Delegatable Contract Key
Some smart contracts may want to delegate control to a library contract. In order to allow this and preserve the default security of only permitting direct contract calls to the EVM a second contract key field delegatableContractKey will be added to the Key protobuf message. The requirement for authorization will be that only the CALLER of the call be the authorized contract ID. This will allow contracts to do a DELEGATECALL to the library and then the library (or any of the other sub-libraries it then DELEGATECALLs to) can CALL the precompile contract and have the authorization granted as though it was the origin of the current delegate call chain.
Using a contractKey is the safer options and is recommended as the default contract level security. delegatableContractKey should only be used when the library is fully known and audited ahead of time.