Можно ли установить состояние мира (бухгалтерскую книгу) в рутинной работе?

Я хочу запустить рутину, чтобы ежедневно проверять и изменять состояние мира после инициализации.

func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
    stub.PutState("xiaoming_wallet", []byte("50"))
    stub.PutState("xiaoming_toy", []byte("0"))
    go monthly_check(&stub)
    return nil, nil
}

функция такая

func monthly_check(stub *shim.ChaincodeStubInterface)  {
    tc:=time.Tick(24*time.Hour)
    for range tc{
          ...
          ...
          (*stub).PutState(..,..)
          ...
          ...   }}

но функция putstate возвращает

ошибка размещения состояния Невозможно поместить состояние в контекст запроса

Кажется, что все взаимодействия с леджером должны быть частью внешней транзакции, а это значит, что я не могу изменить заглушку в рутинной работе? Есть ли способ добиться этого?


person Gang Zhao    schedule 06.03.2017    source источник
comment
Зао, я только что заметил еще одну вещь. Вы написали свой код в Init. По моей информации, Init запускается только один раз в течение жизненного цикла чейнкода, то есть во время развертывания чейнкода. И ваше требование состояло в том, чтобы выполнять что-то ежедневно, без повторного развертывания чейнкода, тогда вы должны смотреть на Invoke как на свой хук.   -  person Ashishkel    schedule 08.03.2017


Ответы (3)


Смарт-контракт написан либо на Go, либо на Java и подключается к узлу через прокладку (прокси в узле, заглушка в контракте — обычно называемый чейнкодом). Цепной код работает в собственном док-контейнере, а подключение от прокси к заглушке и обратно использует gRPC и protobufs. Когда чейнкод какое-то время простаивает, его контейнер может закрыться и снова запуститься, когда поступит следующая транзакция или запрос.

По этой причине вы не можете хранить какое-либо состояние в памяти. Все состояние должно сохраняться в мировом состоянии в конце транзакции и извлекаться в следующей транзакции или запросе. (Примечание: в структуре v1 запросы фактически являются транзакциями, хотя они и не записывают состояние.) Очевидно, что это распространяется на периодическое пробуждение потока и опрос значения в мировом состоянии.

Вместо этого вы можете использовать два метода вместе:

1) Сделайте так, чтобы чейнкод генерировал событие от транзакций, чтобы кормить ваше приложение почти в реальном времени.

2) Установите интервал опроса в качестве резервной копии событий, чтобы время от времени опрашивать состояние, которое вы хотите отслеживать.

(2) должно существовать, потому что (1) еще не гарантирована доставка.

person Kim    schedule 06.03.2017

Не из рутинной работы. На аналогичный вопрос был дан ответ, подтверждающий это некоторое время назад. Пожалуйста, посмотрите. cannot-put-state-in-query-context

person Ashishkel    schedule 06.03.2017

Было бы невозможно запустить таймер из чейнкода, потому что тогда каждый узел должен был бы прийти к консенсусу относительно того, который сейчас час и т. д. Что можно сделать, так это то, что вы могли бы иметь внешний таймер с соответствующие разрешения, которые периодически вызывают функцию чейнкода.

person Clyde D'Cruz    schedule 06.03.2017