У меня есть состояние SomeBond
, которое я хочу выдать и совершить в сети Corda.Когда участник A передает состояние SomeBond
участнику B, ожидается, что либо A получило состояние от X, либо A было выдано SomeBond
(скажем, Y).
Чтобы проверить это, B выполняет контракты, связанные со всеми состояниями в транзакции.Ожидаемый контракт - SomeBondContract
, но Б не уверен, что он будет запущен.Чтобы быть уверенным, что состояния в этой транзакции будут запускаться SomeBondContract
, он должен будет на самом деле поставить проверку в потоке перед подписанием.
val outputsLegit = stx.tx.outputs.all { it.contract == "com.example.SomeBondContract" }
val inputsLegit = stx.tx.toLedgerTransaction(serviceHub).inputs.all { it.state.contract == "com.example.SomeBondContract" }
Но если он поставит чек только в потоке, он будет проверять только текущую транзакцию.Мы до сих пор не можем быть уверены, что в предыдущей транзакции, в которой C отправил состояние A, был такой же контракт, назначенный его состоянию ввода.Может быть, что-то вроде этого:
C создает транзакцию (101):
Ввод (пусто)
Выход: SomeBondState
, идентификатор контракта: com.example.EmptyContract
И затем создает транзакцию (102):
Ввод: 101 [0]
Выход: SomeBondState
, ID контракта: com.example.SomeBondContract
И использует выходные данные этой транзакции (то есть 102 [0]) в качестве входных данных для перевода в B. Проблема здесь в том, что C никогда не был законным эмитентом для SomeBondState
и транзакция никогда не должна была состояться, но, поскольку он назначил ошибочный контракт государству, он создал его без проблем.
Чтобы предотвратить это, можно поставить тот же чек в контракт, что иЧто ж.Таким образом, поток может проверить, имеет ли текущая транзакция контракты, назначенные ее состояниям, и сам контракт может проверить, что для состояния ввода назначен контракт.Таким образом, транзакция 102 никогда не будет успешной, поскольку она имеет входные данные типа SomeBondState
, но не имеет com.example.SomeBondState
в качестве контракта.Поскольку граф зависимостей рекурсивно проверяется до возникновения проблемы, даже неисправные узлы не смогут выдать ложное состояние за реальное.
Конечно, более простой способ состоит в том, чтобы гарантировать отсутствие EmptyContract
вбанку, но может быть более тонкое злоупотребление любым существующим контрактом, чтобы проскользнуть через нежелательные состояния.Я просто использую EmptyContract
в качестве примера.
Но проверка имени пакета в потоках и контрактах кажется немного небезопасной и хакерской.Я не совсем понимаю, как работают загрузчики классов и как будут обрабатываться два идентичных имени класса с одним и тем же именем пакета, и если есть способы, с помощью которых вредоносный узел может что-то делать.
Кроме того, я не оченьпонять, почему нас просят связать контракт с государством при построении транзакции?Почему контракты не могут быть связаны с состояниями внутри самого определения состояния?Может быть, государство может быть аннотировано связанным с ним контрактом?Было ли так, что разные контракты могут быть использованы с одним и тем же государством в разное время?Но разве это не то, для чего нужны команды?Чтобы один и тот же контракт мог вести себя по-разному в разное время?
Или все мои заботы о том, «как мне убедиться, что на транзакции выполняется правильный контракт», что-то упустили?Заранее спасибо за ответ.