Use self-type in contract keys

I know the following is technically possible. Are there any strange consequences, performance impacts maybe to use the template type in the contract key?

template Example
  with
    owner : Party
    value : Int
  where
    signatory owner
    key this : Example
    maintainer key.owner

example_test : Script ()
example_test = do
  owner <- allocateParty "John Doe"
  let example = Example owner 42

  owner `submit` createCmd example

  Some (_, foundExample) <- queryContractKey @Example owner example

  example === foundExample
3 Likes

There shouldn’t be any technical issues with this. I guess you can argue it might be slightly confusing to mix up the key type and the template type but from a technical pov that doesn’t matter.

1 Like

I do this quite frequently. It tends to make sense if you have hierarchical relationships between contracts. eg

template Parent
  with
    p : Party
    id : Text
  where
    signatory p
    key this : Parent
    maintainer key.p

template Child
  with
    parent : Parent
    childId : Text
  where
    signatory parent.p
    key this : Child
    maintainer parent.p
2 Likes

Thanks, appreciate the answers. I think I have found a perfectly good use case for this. So, if it’s not considered some anti-pattern, I will go with this approach.

I use it for “marker contracts”. These contracts are quite simple and I wanted to prevent duplication of them. Using keys seemed like an easy solution.

For the key I have to use all properties of the template, and that’s why I started to think of reusing what I had already.

1 Like