Build success, but excercise error
daml
module Currency where
template Publisher
with
name: Party
value: Decimal
where
signatory name
key name: Party
maintainer key
nonconsuming choice Publish: ()
with
amount : Decimal
owner : Party
controller
name
do
create Owner with
name = owner
cash = Currency with publisher = name, amount
return ()
nonconsuming choice Transfer: ()
with
transferAmount : Decimal
giver: Owner
receiver: Owner
controller
giver.name
do
let delta = giver.cash.amount - transferAmount
assertMsg "not enough cash" (delta < 0.0)
create giver with cash = giver.cash with amount = giver.cash.amount - transferAmount
create receiver with cash = receiver.cash with amount = receiver.cash.amount + transferAmount
return ()
template Owner
with
name: Party
cash: Currency
where
signatory cash.publisher
key name: Party
maintainer key
template Currency
with
publisher : Party
amount : Decimal
where
signatory publisher
tsx
const publish = async (owner: Party, amount: Decimal): Promise<boolean> => {
try {
await ledger.exerciseByKey(Currency.Publisher.Publish, name, {owner, amount});
return true;
} catch (error) {
alert(`Unknown error:\n${error}`);
return false;
}
}
result:
io.grpc.StatusRuntimeException: INVALID_ARGUMENT: Command interpretation error in LF-DAMLe: Interpretation error: Error: node NodeId(1) (dcccd8fecddd546a7e56fd59c5e2943e1926b411da42e385be2dbadb4c0071ef:Currency:Owner) has maintainers TreeSet(user1) which are not a subset of the signatories TreeSet(Bank). Details: Last location: [DA.Internal.Prelude:381], partial transaction: root node NodeId(1): NodeCreate(ContractId(00b7e041f9ebbb2c9d088428417352c0302209e3c2a8b19984d3ba9445a5414f2a),ContractInst(dcccd8fecddd546a7e56fd59c5e2943e1926b411da42e385be2dbadb4c0071ef:Currency:Owner,ValueRecord(Some(dcccd8fecddd546a7e56fd59c5e2943e1926b411da42e385be2dbadb4c0071ef:Currency:Owner),ImmArray((Some(name),ValueParty(user1)),(Some(cash),ValueRecord(Some(dcccd8fecddd546a7e56fd59c5e2943e1926b411da42e385be2dbadb4c0071ef:Currency:Currency),ImmArray((Some(publisher),ValueParty(Bank)),(Some(amount),ValueNumeric(0E-10))))))),),Some(Location(7109c6bec5e868575d0732faf86ff6e6c3986fdf6e22ee51d59bd7b828f3df0d,DA.Internal.Prelude,$u002b$u002b,(380,25),(380,27))),TreeSet(Bank),TreeSet(Bank),Some(KeyWithMaintainers(ValueParty(user1),TreeSet(user1))))
How can I resolve this problem?
Hi @Xuyx, welcome to the DAML forums!
The key error message is slightly buried in the result:
(dcccd8fecddd546a7e56fd59c5e2943e1926b411da42e385be2dbadb4c0071ef:Currency:Owner) has maintainers TreeSet(user1) which are not a subset of the signatories TreeSet(Bank).
You can see from the first segment in brackets that the error concerns a contract of type Owner. The first segment is the package hash, the second one the module Currency, and the third one the template, Owner.
It goes on to say that the set of maintainers user1 is not a subset of the signatories Bank. Looking at the Owner template that indeed appears to the issue. You have signatory cash.publisher, but maintainer key, where key == name. Maintainers must always be signatories as well.
Your Owner contract specifies an owner of an amount of currency. Using just name as a key will get you into trouble as DAML ensures a uniqueness constraint on keys. In that case contract keys should really be thought of in analogy with primary keys in RDBs. To have a good primary key on a position like your Owner contract, you have three options:
- You either ensure that a given user only ever has one contract of type
Ownerper publisher, in which case you can use use the pair(name, cash.publisher)as the key andkey._2as the maintainer or - You give each position a reference that you use as a key (like an ID column in an RDB) or
- You don’t use contract keys on the
Ownertemplate.
Thanks for your detailed answer to my question in such a short time.
I will try it immediately.
type OwnerKey = (Party, Party)
template Owner
with
name: Party
cash: Currency
where
signatory cash.publisher
key (name, cash.publisher): OwnerKey
maintainer key._1
After I update my code like this and build and run codegen, I find that a new dependency is required but none in node_modules.
var pkg40f452260bef3f29dede136108fc08a88d5a5250310281067087da6f0baddff7 = require('@daml.js/40f452260bef3f29dede136108fc08a88d5a5250310281067087da6f0baddff7');
In this case, what should I do?
Hi Xuyx,
This error message seems to suggest you may need to regenerate your JS bindings. In fact, you need to rerun the code generator every time you change your DAML code. The easiest way to achieve that depends on the version of the SDK you’re using (we’ve worked hard on improving that experience over the past couple months).
For SDK 1.5 and earlier, you should kill the yarn start and daml start processes and run (starting from the root of your project):
daml build
daml codegen js .daml/dist/*.dar -o daml.js
cd ui
yarn install --force --frozen-lockfile
then you can restart the daml start and yarn start processes.
If you are using SDK 1.6, you should kill the daml start and npm start processes, then run (starting from the root of the project):
daml build
daml codegen js .daml/dist/*.dar -o daml.js
and then restart the daml start and npm start processes.
Finally, for completeness: if you’re working with a recent 1.7 snapshot, or once you upgrade to 1.7 after it’s published, to process will be to select the terminal running the daml start command, and simply press the r key (r followed by Enter on Windows).
Hi, @Gary_Verhaegen .
I’m using SDK1.6.And I have run
daml codegen js .daml/dist/Currency-1.0.0.dar -o UI/daml.js
And it upates the file automatically in
UI\daml.js\Currency-1.0.0\lib\Currency\module.js
, adding following code:
var pkg40f452260bef3f29dede136108fc08a88d5a5250310281067087da6f0baddff7 = require('@daml.js/40f452260bef3f29dede136108fc08a88d5a5250310281067087da6f0baddff7');
var pkgd14e08374fc7197d6a0de468c968ae8ba3aadbf9315476fd39071831f5923662 = require('@daml.js/d14e08374fc7197d6a0de468c968ae8ba3aadbf9315476fd39071831f5923662');
However, the path
UI\node_modules\@daml.js\
only has folder
d14e08374fc7197d6a0de468c968ae8ba3aadbf9315476fd39071831f5923662
no
40f452260bef3f29dede136108fc08a88d5a5250310281067087da6f0baddff7
I have tried to run:
npm i @daml.js/40f452260bef3f29dede136108fc08a88d5a5250310281067087da6f0baddff7
But it doesn’t work.
Maybe try removing the node_modules and run npm install again just to make sure that the installation of the packages is complete.
Hi, drsk:
Thank you for your kind help.
I tried npm i again just now, but it didn’t work.
The package I’m using is copied from the one created by dam new create-daml-app --template create-daml-app, in SDK 1.6.
All the dependencies is the same except “@daml.js/Currency”: “file:daml.js/Currency-1.0.0” and puppeteer wait-on @types/jest @types/node @types/puppeteer @types/wait-on.
The attachment is my project which I refer to dam new create-daml-app --template create-daml-app.
(Attachment Currency.zip is missing)
Hi, drsk:
Thank you for your kind help.
I tried npm i again just now, but it didn’t work. The result is the same.
The package I’m using is copied from the one created by dam new create-daml-app --template create-daml-app, in SDK 1.6.
All the dependencies is the same except “@daml.js/Currency”: “file:daml.js/Currency-1.0.0” and puppeteer wait-on @types/jest @types/node @types/puppeteer @types/wait-on.
I tried to attach my project by zip but I’m not authorized.
Hi @Xuyx, I believe you should be able to share your example via a a private message. Then we can take a look and see if there’s anything off
Hi @cocreature, I’m willing to upload my project but I only can upload files of these formats:
jpg, jpeg, png, gif, daml, yaml, mp4, mov, mp3, webp
no zip or other formats.
I think email may be a good choice, but I don’t know the address of you.
My email address is xuyx@bayconnect.com.cn.
Hi @Xuyx,
The issue is caused by the outdated package-lock.json file. It looks like you generated that before you had a dependency on the Tuple2 (that’s what pulls in 40f452260bef3f29dede136108fc08a88d5a5250310281067087da6f0baddff7) and NPM doesn’t appear to update it automatically. If you remove package-lock.json and node_modules and rerun npm install, it should be generated correctly. This is definitely something we need to make clearer in our documentation.
ftr, this is @Xuyx’s projects which reproduces the issue.
It works!
Thank you very much.