Я работаю через руководство, где написано, как создать контракт.
Вот их код:
function createFirstPing() {
const request = {
commands: {
applicationId: 'PingPongApp',
workflowId: `Ping-${sender}`,
commandId: uuidv4(),
ledgerEffectiveTime: { seconds: 0, nanoseconds: 0 },
maximumRecordTime: { seconds: 5, nanoseconds: 0 },
party: sender,
list: [
{
create: {
templateId: PING,
arguments: {
fields: {
sender: { party: sender },
receiver: { party: receiver },
count: { int64: 0 }
}
}
}
}
]
}
};
client.commandClient.submitAndWait(request, (error, _) => {
if (error) throw error;
console.info(`Created Ping contract from ${sender} to ${receiver}.`);
});
}
Я хочу создать аналогичный запрос в своем проекте, который отправляет поле с именем «datetime_added». В моем коде DAML это тип time. Я не могу понять правильный синтаксис для этого запроса. Например:
arguments: {
fields: {
sender: { party: sender },
receiver: { party: receiver },
count: { int64: 0 },
datetime_added: { time: '2019 Feb 19 00 00 00' }
}
}
Формат, в котором я выражаю время, не является причиной проблемы (хотя я признаю, что это также, вероятно, неправильно). Ошибка, которую я вижу, следующая:
Error: ! Validation error
▸ commands
▸ list
▸ 0
▸ create
▸ arguments
▸ fields
▸ datetime_added
✗ Unexpected key time found
at CommandClient.exports.SimpleReporter [as reporter] (/home/vantage/damlprojects/loaner_car/node_modules/@da/daml-ledger/lib/data/reporting/simple_reporter.js:36:12)
at Immediate.<anonymous> (/home/vantage/damlprojects/loaner_car/node_modules/@da/daml-ledger/lib/data/client/command_client.js:52:62)
at runCallback (timers.js:705:18)
at tryOnImmediate (timers.js:676:5)
at processImmediate (timers.js:658:5)
Я не понимаю, time не является допустимым типом данных DAML?
Я попытался переключить time на timestamp следующим образом.
datetime_added: {timestamp: { seconds: 0, nanoseconds: 0 }}
вызывает следующую ошибку:
/home/......../damlprojects/car/node_modules/google-protobuf/google-protobuf.js:98
goog.string.splitLimit=function(a,b,c){a=a.split(b);for(var d=[];0<c&&a.length;)d.push(a.shift()),c--;a.length&&d.push(a.join(b));return d};goog.string.editDistance=function(a,b){var c=[],d=[];if (a==b)return 0;if (!a.length||!b.length)return Math.max(a.length,b.length);for(var e=0;e<b.length+1;e++)c[e]=e;for(e=0;e<a.length;e++){d[0]=e+1;for(var f=0;f<b.length;f++)d[f+1]=Math.min(d[f]+1,c[f+1]+1,c[f]+Number(a[e]!=b[f]));for(f=0;f<c.length;f++)c[f]=d[f]}return d[b.length]};goog.asserts = {};goog.asserts.ENABLE_ASSERTS=goog.DEBUG;goog.asserts.AssertionError=function(a,b){b.unshift(a);goog.debug.Error.call(this,goog.string.subs.apply(null,b));b.shift();this.messagePattern=a};goog.inherits(goog.asserts.AssertionError,goog.debug.Error);goog.asserts.AssertionError.prototype.name = "AssertionError";goog.asserts.DEFAULT_ERROR_HANDLER=function(a){throw a;};goog.asserts.errorHandler_=goog.asserts.DEFAULT_ERROR_HANDLER;
AssertionError: Assertion failed
at new goog.asserts.AssertionError (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:98:603)
at Object.goog.asserts.doAssertFailure_ (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:99:126)
at Object.goog.asserts.assert (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:99:385)
at jspb.BinaryWriter.writeSfixed64 (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:338:80)
at proto.com.digitalasset.ledger.api.v1.Value.serializeBinaryToWriter (/home/vantage/damlprojects/loaner_car/node_modules/@da/daml-ledger/lib/grpc/generated/com/digitalasset/ledger/api/v1/value_pb.js:289:12)
at jspb.BinaryWriter.writeMessage (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:341:342)
at proto.com.digitalasset.ledger.api.v1.RecordField.serializeBinaryToWriter (/home/vantage/damlprojects/loaner_car/node_modules/@da/daml-ledger/lib/grpc/generated/com/digitalasset/ledger/api/v1/value_pb.js:1024:12)
at jspb.BinaryWriter.writeRepeatedMessage (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:350:385)
at proto.com.digitalasset.ledger.api.v1.Record.serializeBinaryToWriter (/home/vantage/damlprojects/loaner_car/node_modules/@da/daml-ledger/lib/grpc/generated/com/digitalasset/ledger/api/v1/value_pb.js:822:12)
at jspb.BinaryWriter.writeMessage (/home/vantage/damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:341:342)
Короче говоря, мне нужно знать, какой тип использовать в моем клиенте Node.js для значения DAML типа time и как его выразить.
Думаю точное совпадение.





Я бы рекомендовал использовать справочная документация для привязок (хотя, начиная с версии 0.4.0, просматривая его, чтобы ответить на ваш вопрос, я заметил две ошибки). В верхней панели навигации страницы вы можете начать с Классы > data.CommandClient и продвигаться вниз по его единственному аргументу (ОтправитьАндВаитрекуест), пока, следуя ссылкам на разные поля, не дойдете до документации для поля timestamp, которое, как предполагает ошибка ( несмотря на ошибку в документации), должно быть Отметка времени, где секунды выражены во времени эпохи (секунды с 1970 года).
Следовательно, чтобы сделать вызов, который вы хотели, это будет форма объекта, который вы должны отправить:
arguments: {
fields: {
sender: { party: sender },
receiver: { party: receiver },
count: { int64: 0 }
datetime_added: { timestamp: { seconds: 0, nanoseconds: 0 } }
}
}
В частности, для вашего случая я бы, вероятно, сделал небольшой помощник, который использует функцию Date.parse.
function parseTimestamp(string) {
return { seconds: Date.parse(string) / 1000, nanoseconds: 0 };
}
Затем вы можете использовать его, чтобы передать время, которое вы упомянули в примере, который вы сделали:
arguments: {
fields: {
sender: { party: sender },
receiver: { party: receiver },
count: { int64: 0 }
datetime_added: { timestamp: parseTimestamp('2019-02-19') }
}
}
В заключение я хотел бы добавить, что привязки Node.js поставляются с файлами ввода, которые обеспечивают автозаполнение и контекстную справку в совместимых редакторах (например, Visual Studio Code). Использование их, вероятно, поможет вам. Поскольку привязки написаны на TypeScript, типизация гарантированно всегда будет соответствовать API. Обратите внимание, что на данный момент автозаполнение работает для самого Ledger API, но не поможет вам с произвольными записями, нацеленными на вашу модель DAML (в данном случае объект fields).
Я попробовал это, и возникла следующая ошибка: home/...../damlprojects/loaner_car/node_modules/google-protobuf/google-protobuf.js:98 goog.string.splitLimit=function(a,b,c){a=a.split(b);for(var d=[];0<c&&a.le............goog.asserts.DEFAULT_ERROR_HANDLER=function(a){throw a;};goog.asserts.errorHandler_=goog.asserts.DEFAULT_ERROR_HANDLER;
Ссылки на data.CommandClient , SubmitAndWaitRequest) и Timestamp недействительны.
Вы можете отредактировать исходный вопрос с новыми деталями или создать новый вопрос, довольно сложно интерпретировать ограниченную часть ошибки в комментариях.
Вы соответствующим образом изменили модель DAML и загрузили новую модель с новым полем в песочнице?
Модель DAML включает переменную datetime_added с типом time. На нем работает песочница. Потом я побежал npm run fetch-template-ids. Эта ошибка возникает при запуске node index.js
Я смог полностью воспроизвести проблему, это похоже на ошибку. Попробую понять в чем дело.
Из трассировки стека видно, что это утверждение не работает, когда он пытается записать число (возможно, любое из значений в отметке времени): github.com/protocolbuffers/protobuf/blob/v3.6.1/js/binary/… Если код, которым вы поделились, точно совпадает с тем, который вы используете, я бы не понимаю, почему это утверждение потерпит неудачу.