kadena-io / pact

The Pact Smart Contract Language
https://docs.kadena.io/build/pact
BSD 3-Clause "New" or "Revised" License
579 stars 100 forks source link

#2 Modrefs refSpec: storage in tables AND typed variable binding #1308

Open CryptoPascal31 opened 11 months ago

CryptoPascal31 commented 11 months ago

Issue description

Re-file the previous issue by changing the examples... btw: @jmcardon @emilypi If not already done please can you read my last comment on the previous one. I want to be sure that the case is closed without misunderstanding.

When storing a modref into a typed variable or a table, the interfaces (refSpec) list should be "sanitized".

I mean: redact unused interfaces, and reorder them following the target type specification.

From the previous issue I removed the last part, as it is confusing and anyway it's not my use case.

As always, the better is to provide an example:

Steps to reproduce

; Two simple interface
(interface character
  (defconst SOMETHING:bool true)
)

(interface mouse
  (defconst SOMETHING:bool true)
)

; Let's create a character repository
; Allows to store and get characters.
(module character-collection G
  (defcap G () true)

  (defschema entry
    person:module{character}
  )
  (deftable tbl:{entry})

  (defun add:string (name:string x:module{character})
    (insert tbl name {'person:x}))

  (defun get:module{character} (name:string)
    (with-read tbl name {'person:=x}
      x))
)
(create-table tbl)

; Let's create mickey
(module mickey G
  (implements character)
  (implements mouse)
  (defcap G () true)
)
(character-collection.add "mickey-A" mickey)
(character-collection.add "mickey-B" mickey)

; Sanity check => OK
(expect "Both mickey modrefs are the same" true (= (character-collection.get "mickey-A")
                                                   (character-collection.get "mickey-B")))

; Redeploy mickey but invert interfaces
(module mickey G
  (implements mouse)
  (implements character)
  (defcap G () true)
)
(character-collection.add "mickey-C" mickey)

; !!! THIS DOESN'T WORK AND SHOULD !!!!
(expect "Both mickey modrefs are the same" true (= (character-collection.get "mickey-A")
                                                   (character-collection.get "mickey-C")))

; Redeploy mickey but forget the mouse property
(module mickey G
  (implements character)
  (defcap G () true)
)
(character-collection.add "mickey-NOT-mouse" mickey)

; !!! THIS DOESN'T WORK AND SHOULD => In my opinion from a character point of view: modrefs are
;                                     still the same
(expect "Both mickey modrefs are the same" true (= (character-collection.get "mickey-A")
                                                   (character-collection.get "mickey-NOT-mouse")))

Just tried to do a simple minimal non working example (that you can easily reproduce with the REPL).

But to help, let me give some details about the real use case. I try to load a modref to coin or another fungible using (read-msg) and store it in DB as a {fungible-v2}:

But the coin contract can be expressed in 3 different ways in JSON:

 {"refSpec":
    [{"namespace":null,"name":"fungible-xchain-v1"},
     {"namespace":null,"name":"fungible-v2"}],
   "refName":{"namespace":null,"name":"coin"}
}

or

 {"refSpec":
    [{"namespace":null,"name":"fungible-v2"},
     {"namespace":null,"name":"fungible-xchain-v1"}],
   "refName":{"namespace":null,"name":"coin"}
}

or

 {"refSpec":
    [{"namespace":null,"name":"fungible-v2"}],
   "refName":{"namespace":null,"name":"coin"}
}

The first one is the real deployed on chain.

But in the context of a fungible-v2 I expect the three to be =, as they point exactly to the same module.

From: https://github.com/kadena-io/marmalade/blob/db1c34a7a1450a75fcc6ff030c96f06bf2d3c66e/pact/concrete-policies/royalty-policy/royalty-policy-v1.pact#L67

https://github.com/kadena-io/marmalade/blob/db1c34a7a1450a75fcc6ff030c96f06bf2d3c66e/pact/concrete-policies/royalty-policy/royalty-policy-v1.pact#L115