Как проверить, какой контракт выполняется для транзакции в потоке? - PullRequest
0 голосов
/ 23 января 2019

У меня есть состояние 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 в качестве примера.

Но проверка имени пакета в потоках и контрактах кажется немного небезопасной и хакерской.Я не совсем понимаю, как работают загрузчики классов и как будут обрабатываться два идентичных имени класса с одним и тем же именем пакета, и если есть способы, с помощью которых вредоносный узел может что-то делать.

Кроме того, я не оченьпонять, почему нас просят связать контракт с государством при построении транзакции?Почему контракты не могут быть связаны с состояниями внутри самого определения состояния?Может быть, государство может быть аннотировано связанным с ним контрактом?Было ли так, что разные контракты могут быть использованы с одним и тем же государством в разное время?Но разве это не то, для чего нужны команды?Чтобы один и тот же контракт мог вести себя по-разному в разное время?

Или все мои заботы о том, «как мне убедиться, что на транзакции выполняется правильный контракт», что-то упустили?Заранее спасибо за ответ.

1 Ответ

0 голосов
/ 29 января 2019

Чтобы предотвратить эту ситуацию, Corda 4 вводит аннотацию @BelongsToContract.Эта аннотация связывает состояние с данным контрактом и запрещает использование любого другого контракта с этим состоянием.

Пример использования:

@BelongsToContract(TemplateContract::class)
class TemplateState(override val participants: List<AbstractParty>) : ContractState
...