Перейти к основному содержимому

Изменение параметров

warning

Эта страница переведена сообществом на русский язык, но нуждается в улучшениях. Если вы хотите принять участие в переводе свяжитесь с @alexgton.

Цель этого документа — предоставить базовое объяснение параметров конфигурации блокчейна TON и пошаговые инструкции по изменению этих параметров по консенсусу большинства валидаторов.

Мы предполагаем, что читатель уже знаком с Fift и Lite Client, как описано в статье "Полный узел" (низкоуровневая) и статье "Валидатор" (низкоуровневая) в разделах, где описывается голосование валидаторов за предложения по конфигурации.

1. Параметры конфигурации

Параметры конфигурации — это определенные значения, которые влияют на поведение валидаторов и/или фундаментальных смарт-контрактов блокчейна TON. Текущие значения всех параметров конфигурации хранятся как особая часть состояния мастерчейна и извлекаются из текущего состояния мастерчейна при необходимости. Поэтому имеет смысл говорить о значениях параметров конфигурации относительно определенного блока мастерчейна. Каждый блок шардчейна содержит ссылку на последний известный блок мастерчейна; значения из соответствующего состояния мастерчейна считаются активными для этого блока шардчейна и используются во время его генерации и проверки. Для блоков мастерчейна состояние предыдущего блока мастерчейна используется для извлечения активных параметров конфигурации. Поэтому, даже если кто-то попытается изменить некоторые параметры конфигурации внутри блока мастерчейна, изменения станут активными только для следующего блока мастерчейна.

Каждый параметр конфигурации идентифицируется подписанным 32-битным целочисленным индексом, называемым индексом параметра конфигурации или просто индексом. Значением параметра конфигурации всегда является ячейка. Некоторые параметры конфигурации могут отсутствовать; тогда иногда предполагается, что значение этого параметра равно Null. Также существует список обязательных параметров конфигурации, которые должны присутствовать всегда; этот список хранится в параметре конфигурации #10.

Все параметры конфигурации объединены в словарь конфигурации - хэш-карту с подписанными 32-битными ключами (индексами параметров конфигурации) и значениями, состоящими ровно из одной ссылки на ячейку. Другими словами, словарь конфигурации - это значение типа TL-B (HashmapE 32 ^Cell). Фактически, коллекция всех параметров конфигурации хранится в состоянии мастерчейна как значение типа TL-B ConfigParams:

_ config_addr:bits256 config:^(Hashmap 32 ^Cell) = ConfigParams;

Мы видим, что, помимо словаря конфигурации, ConfigParams содержит config_addr - 256-битный адрес смарт-контракта конфигурации в мастерчейне. Более подробная информация о смарт-контракте конфигурации будет предоставлена ​​позже.

Словарь конфигурации, содержащий активные значения всех параметров конфигурации, доступен через специальный регистр TVM c7 для всех смарт-контрактов, когда их код выполняется в транзакции. Точнее, когда выполняется смарт-контракт, c7 инициализируется кортежем, единственным элементом которого является кортеж с несколькими "контекстными" значениями, полезными для выполнения смарт-контракта, такими как текущее время в Unix (как указано в заголовке блока). Десятая запись этого кортежа (т.е. запись с нулевым индексом 9) содержит ячейку, представляющую словарь конфигурации. Следовательно, к нему можно получить доступ с помощью команд TVM PUSH c7; FIRST; INDEX 9 или эквивалентной команды CONFIGROOT. Фактически, специальные инструкции TVM CONFIGPARAM и CONFIGOPTPARAM объединяют предыдущие действия с поиском по словарю, возвращая любой параметр конфигурации по его индексу. Мы обращаемся к документации TVM для получения более подробной информации об этих инструкциях. Здесь важно то, что все параметры конфигурации легко доступны из всех смарт-контрактов (мастерчейн или шардчейн), и смарт-контракты могут проверять их и использовать для выполнения определенных проверок. Например, смарт-контракт может извлекать цены на хранение данных воркчейна из параметра конфигурации, чтобы вычислить цену за хранение части предоставленных пользователем данных.

Значения параметров конфигурации не являются произвольными. Фактически, если индекс параметра конфигурации i неотрицателен, то значение этого параметра должно быть допустимым значением типа TL-B (ConfigParam i). Это ограничение вводится валидаторами, которые не будут принимать изменения параметров конфигурации с неотрицательными индексами, если только они не являются допустимыми значениями соответствующего типа TL-B.

Следовательно, структура таких параметров определяется в исходном файле crypto/block/block.tlb, где (ConfigParam i) определяется для разных значений i. Например,

_ config_addr:bits256 = ConfigParam 0;
_ elector_addr:bits256 = ConfigParam 1;
_ dns_root_addr:bits256 = ConfigParam 4; // root TON DNS resolver

capabilities#c4 version:uint32 capabilities:uint64 = GlobalVersion;
_ GlobalVersion = ConfigParam 8; // all zero if absent

Мы видим, что параметр конфигурации #8 содержит ячейку без ссылок и ровно 104 бита данных. Первые четыре бита должны быть 11000100, затем сохраняются 32 бита с включенной в данный момент "глобальной версией", а затем следует 64-разрядное целое число с флагами, соответствующими включенным в данный момент возможностям. Более подробное описание всех параметров конфигурации будет приведено в приложении к документации по блокчейну TON, а пока можно ознакомиться со схемой TL-B в crypto/block/block.tlb и проверить, как различные параметры используются в источниках валидатора.

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

2. Изменение параметров конфигурации

Мы уже объяснили, что текущие значения параметров конфигурации хранятся в специальной части состояния мастерчейна. Как они вообще могут быть изменены?

Фактически, в мастерчейне находится специальный смарт-контракт, называемый конфигурационным смарт-контрактом. Его адрес определяется полем config_addr в ConfigParams, которое мы описали ранее. Первая ссылка на ячейку в его данных должна содержать актуальную копию всех параметров конфигурации. Когда генерируется новый блок мастерчейна, смарт-контракт конфигурации ищет по его адресу, config_addr, и новый словарь конфигурации извлекается из первой ссылки в ячейку его данных. После некоторых проверок достоверности (например, проверки того, что любое значение с неотрицательным 32-битным индексом i действительно является допустимым значением типа TL-B (ConfigParam i)) валидатор копирует этот новый словарь конфигурации в часть мастерчейна, содержащую ConfigParams. Это выполняется после создания всех транзакций, поэтому проверяется только окончательная версия нового словаря конфигурации, хранящегося в смарт-контракте конфигурации. Если проверки на валидность не пройдены, то "истинный" словарь конфигурации остается неизменным. Таким образом, смарт-контракт конфигурации не может устанавливать недействительные значения параметров конфигурации. Если новый словарь конфигурации совпадает с текущим словарем конфигурации, то проверки не выполняются и изменения не вносятся.

Таким образом, все изменения параметров конфигурации выполняются смарт-контрактом конфигурации, и именно его код определяет правила изменения параметров конфигурации. В настоящее время смарт-контракт конфигурации поддерживает два режима изменения параметров конфигурации:

  1. Посредством внешнего сообщения, подписанного определенным закрытым ключом, который соответствует открытому ключу, хранящемуся в данных смарт-контракта конфигурации. Этот метод используется в общедоступной тестовой сети и, вероятно, в небольших частных тестовых сетях, контролируемых одним субъектом, поскольку он позволяет оператору легко изменять значения любых параметров конфигурации. Обратите внимание, что этот открытый ключ может быть изменен с помощью специального внешнего сообщения, подписанного старым ключом, и что если он будет изменен на ноль, то этот механизм будет отключен. Таким образом, можно было бы использовать его для точной настройки сразу после запуска, а затем отключить навсегда.
  2. Путем создания "предложений по настройке", за которые впоследствии голосуют валидаторы. Как правило, предложение по настройке должно собрать голоса более чем 3/4 всех проверяющих (по весу), и не только за один раунд, но и за несколько раундов (т.е. несколько последовательных наборов проверяющих должны подтвердить предлагаемое изменение параметра). Это механизм распределенного управления, который будет использоваться основной сетью блокчейна TON.

Мы хотели бы подробнее описать второй способ изменения параметров конфигурации.

3. Создание предложений по конфигурации

Новое предложение по конфигурации содержит следующие данные:

  • индекс параметра конфигурации, который необходимо изменить
  • новое значение параметра конфигурации (или Null, если его необходимо удалить)
  • время истечения срока действия предложения в Unix
  • флаг, указывающий, является ли предложение критическим или нет
  • необязательный хеш старого значения с хешем ячейки текущего значения (предложение может быть активировано только в том случае, если текущее значение имеет указанный хеш)

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

Обратите внимание, что существуют критические и обычные предложения конфигурации. Критическое предложение конфигурации может изменить любой параметр конфигурации, включая один из так называемых критических (список параметров критической конфигурации хранится в параметре конфигурации #10, который сам по себе является критическим). Однако создание предложений по критической конфигурации обходится дороже, и обычно для этого требуется собрать больше голосов валидаторов в большем количестве раундов (точные требования к голосованию для обычных и предложений критической конфигурации хранятся в параметре критической конфигурации #11). С другой стороны, обычные предложения конфигурации дешевле, но они не могут изменить критические параметры конфигурации.

Чтобы создать новое предложение конфигурации, сначала нужно сгенерировать файл BoC (bag-of-cells), содержащий предлагаемое новое значение. Точный способ сделать это зависит от изменяемого параметра конфигурации. Например, если мы хотим создать параметр -239, содержащий строку UTF-8 "TEST" (т. е. 0x54455354), мы могли бы создать config-param-239.boc следующим образом: вызвать Fift и затем ввести

<b "TEST" $, b> 2 boc+>B "config-param-239.boc" B>file
bye

В результате будет создан 21-байтовый файл config-param-239.boc, содержащий сериализацию требуемого значения.

Для более сложных случаев, и особенно для параметров конфигурации с неотрицательными индексами, этот простой подход не так легко применим. Мы рекомендуем использовать create-state (доступный как crypto/create-state в каталоге сборки) вместо fift и копировать и редактировать подходящие части исходных файлов crypto/smartcont/gen-zerostate.fif и crypto/smartcont/CreateState.fif, которые обычно используются для создания нулевого состояния (соответствующего "генезис блоку" других блокчейн архитектур) блокчейна TON.

Рассмотрим, например, параметр конфигурации #8, который содержит текущую включенную глобальную версию блокчейна и возможности:

capabilities#c4 version:uint32 capabilities:uint64 = GlobalVersion;
_ GlobalVersion = ConfigParam 8;

Мы можем проверить его текущее значение, запустив lite client и введя getconfig 8:

> getconfig 8
...
ConfigParam(8) = (
(capabilities version:1 capabilities:6))

x{C4000000010000000000000006}

Теперь предположим, что мы хотим включить функцию, представленную как bit #3 (+8), которая называется "capReportVersion" (при включении эта функция заставляет все средства сортировки сообщать о поддерживаемых версиях и возможностях в заголовках блоков, которые они генерируют). Поэтому мы хотим, чтобы у нас были version=1 и capabilities=14. В этом примере мы все еще можем угадать правильную сериализацию и создать BoC-файл напрямую, введя Fift.

x{C400000001000000000000000E} s>c 2 boc+>B "config-param8.boc" B>file

(В результате создается 30-байтовый файл config-param8.boc, содержащий желаемое значение.)

Однако в более сложных случаях это может оказаться невозможным, поэтому давайте рассмотрим этот пример по-другому. А именно, мы можем проверить исходные файлы crypto/smartcont/gen-zerostate.fif и crypto/smartcont/createState.fif для соответствующих частей.

// version capabilities --
{ <b x{c4} s, rot 32 u, swap 64 u, b> 8 config! } : config.version!
1 constant capIhr
2 constant capCreateStats
4 constant capBounceMsgBody
8 constant capReportVersion
16 constant capSplitMergeTransactions

и

// version capabilities
1 capCreateStats capBounceMsgBody or capReportVersion or config.version!

Мы видим, что config.version! без последнего 8 config! по сути, выполняет то, что нам нужно, поэтому мы можем создать временный скрипт Fift, например, create-param8.fif\`:

#!/usr/bin/fift -s
"TonUtil.fif" include

1 constant capIhr
2 constant capCreateStats
4 constant capBounceMsgBody
8 constant capReportVersion
16 constant capSplitMergeTransactions
{ <b x{c4} s, rot 32 u, swap 64 u, b> } : prepare-param8

// create new value for config param #8
1 capCreateStats capBounceMsgBody or capReportVersion or prepare-param8
// check the validity of this value
dup 8 is-valid-config? not abort"not a valid value for chosen configuration parameter"
// print
dup ."Serialized value = " <s csr.
// save into file provided as first command line argument
2 boc+>B $1 tuck B>file
."(Saved into file " type .")" cr

Теперь, если мы запустим fift -s create-param8.fif config-param8.boc или, что еще лучше, crypto/create-state -s create-param8.fif config-param8.boc (из каталога сборки), мы увидим следующий результат:

Serialized value = x{C400000001000000000000000E}
(Saved into file config-param8.boc)

и мы получим 30-байтовый файл config-param8.boc с тем же содержимым, что и раньше.

Как только у нас есть файл с нужным значением параметра конфигурации, мы вызываем скрипт create-config-proposal.fif, который можно найти в каталоге crypto/smartcont исходной ветки с подходящими аргументами. Опять же, мы рекомендуем использовать create-state (доступный как crypto/create-state из каталога сборки) вместо fift, поскольку это специальная расширенная версия Fift, которая может выполнять больше проверок валидности, связанных с блокчейном:

$ crypto/create-state -s create-config-proposal.fif 8 config-param8.boc -x 1100000


Loading new value of configuration parameter 8 from file config-param8.boc
x{C400000001000000000000000E}

Non-critical configuration proposal will expire at 1586779536 (in 1100000 seconds)
Query id is 6810441749056454664
resulting internal message body: x{6E5650525E838CB0000000085E9455904_}
x{F300000008A_}
x{C400000001000000000000000E}

B5EE9C7241010301002C0001216E5650525E838CB0000000085E9455904001010BF300000008A002001AC400000001000000000000000ECD441C3C
(a total of 104 data bits, 0 cell references -> 59 BoC data bytes)
(Saved to file config-msg-body.boc)

Мы получили тело внутреннего сообщения для отправки в смарт-контракт конфигурации с подходящим количеством Toncoin из любого смарт-контракта (кошелька), находящегося в мастерчейне. Адрес смарт-контракта конфигурации можно получить, введя getconfig 0 в lite client:

> getconfig 0
ConfigParam(0) = ( config_addr:x5555555555555555555555555555555555555555555555555555555555555555)
x{5555555555555555555555555555555555555555555555555555555555555555}

Мы видим, что адрес смарт-контракта конфигурации - -1:5555...5555. Запустив подходящие get-методы этого смарт-контракта, мы можем узнать требуемую оплату для создания этого предложения конфигурации:

> runmethod -1:5555555555555555555555555555555555555555555555555555555555555555 proposal_storage_price 0 1100000 104 0

arguments: [ 0 1100000 104 0 75077 ]
result: [ 2340800000 ]
remote result (not to be trusted): [ 2340800000 ]

Параметры get-метода proposal_storage_price — это критический флаг (в данном случае 0), временной интервал в течение в течение которого это предложение будет активно (1,1 мегасекунды), общее количество бит (104) и ссылки на ячейки (0) в данных. Последние две величины можно увидеть в выходных данных create-config-proposal.fif.

Мы видим, что для создания этого предложения нужно заплатить 2,3408 Toncoin. Лучше добавить в сообщение не менее 1,5 Tonoin для оплаты комиссий за обработку, поэтому мы отправим 4 Toncoin вместе с запросом (все лишние Toncoin будут возвращены). Теперь мы используем wallet.fif (или соответствующий скрипт Fift для используемого нами кошелька) для создания перевода из нашего кошелька в смарт-контракт конфигурации, содержащий 4 Toncoin и тело из config-msg-body.boc. Обычно это выглядит так:

$ fift -s wallet.fif my-wallet -1:5555555555555555555555555555555555555555555555555555555555555555 31 4. -B config-msg-body.boc

Transferring GR$4. to account kf9VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQft = -1:5555555555555555555555555555555555555555555555555555555555555555 seqno=0x1c bounce=-1
Body of transfer message is x{6E5650525E835154000000085E9293944_}
x{F300000008A_}
x{C400000001000000000000000E}

signing message: x{0000001C03}
x{627FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA773594000000000000000000000000000006E5650525E835154000000085E9293944_}
x{F300000008A_}
x{C400000001000000000000000E}

resulting external message: x{89FE000000000000000000000000000000000000000000000000000000000000000007F0BAA08B4161640FF1F5AA5A748E480AFD16871E0A089F0F017826CDC368C118653B6B0CEBF7D3FA610A798D66522AD0F756DAEECE37394617E876EFB64E9800000000E01C_}
x{627FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA773594000000000000000000000000000006E5650525E835154000000085E9293944_}
x{F300000008A_}
x{C400000001000000000000000E}

B5EE9C724101040100CB0001CF89FE000000000000000000000000000000000000000000000000000000000000000007F0BAA08B4161640FF1F5AA5A748E480AFD16871E0A089F0F017826CDC368C118653B6B0CEBF7D3FA610A798D66522AD0F756DAEECE37394617E876EFB64E9800000000E01C010189627FAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA773594000000000000000000000000000006E5650525E835154000000085E9293944002010BF300000008A003001AC400000001000000000000000EE1F80CD3
(Saved to file wallet-query.boc)

Теперь мы отправляем внешнее сообщение wallet-query.boc в блокчейн с помощью lite client.

> sendfile wallet-query.boc
....
external message status is 1

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

> runmethod -1:5555555555555555555555555555555555555555555555555555555555555555 list_proposals
...
arguments: [ 107394 ]
result: [ ([64654898543692093106630260209820256598623953458404398631153796624848083036321 [1586779536 0 [8 C{FDCD887EAF7ACB51DA592348E322BBC0BD3F40F9A801CB6792EFF655A7F43BBC} -1] 112474791597373109254579258586921297140142226044620228506108869216416853782998 () 864691128455135209 3 0 0]]) ]
remote result (not to be trusted): [ ([64654898543692093106630260209820256598623953458404398631153796624848083036321 [1586779536 0 [8 C{FDCD887EAF7ACB51DA592348E322BBC0BD3F40F9A801CB6792EFF655A7F43BBC} -1] 112474791597373109254579258586921297140142226044620228506108869216416853782998 () 864691128455135209 3 0 0]]) ]
... caching cell FDCD887EAF7ACB51DA592348E322BBC0BD3F40F9A801CB6792EFF655A7F43BBC

Мы видим, что список всех активных предложений конфигурации состоит ровно из одной записи, представленной парой.

[6465...6321 [1586779536 0 [8 C{FDCD...} -1] 1124...2998 () 8646...209 3 0 0]]

Первое число 6465..6321 - это уникальный идентификатор предложения конфигурации, равный его 256-битному хешу. Второй компонент этой пары - это кортеж, описывающий статус этого предложения конфигурации. Первый компонент этого кортежа - это время истечения срока действия Unix предложения конфигурации (1586779546). Второй компонент (0) - это флаг критичности. Далее следует само предложение конфигурации, описываемое тройкой [8 C{FDCD...} -1], где 8 - это индекс параметра конфигурации, который нужно изменить, C{FDCD...} - это ячейка с новым значением (представленная хешем этой ячейки), а -1 - это необязательный хеш старого значения этого параметра (-1 означает, что этот хеш не был указан). Далее мы видим большое число 1124...2998, представляющее идентификатор текущего набора валидаторов, затем пустой список (), представляющий набор всех активных на данный момент валидаторов, которые проголосовали за это предложение на данный момент, затем weight_remaining, равный 8646...209 — число, которое положительно, если предложение еще не собрало достаточно голосов валидаторов в этом раунде, и отрицательно в противном случае. Затем мы видим три числа: 3 0 0. Эти числа — rounds_remaining (это предложение выдержит не более трех раундов, т. е. изменения текущего набора валидаторов), wins (количество раундов, в которых предложение собрало голоса более 3/4 всех валидаторов по весу) и losses (количество раундов, в которых за него проголосовало более 3/4 всех голосов валидаторов).

Мы можем проверить предлагаемое значение для параметра конфигурации #8, попросив lite-client расширить ячейку C{FDCD...}, используя ее хэш FDCD... или достаточно длинный префикс этого хеша, чтобы однозначно идентифицировать рассматриваемую ячейку:

> dumpcell FDC
C{FDCD887EAF7ACB51DA592348E322BBC0BD3F40F9A801CB6792EFF655A7F43BBC} =
x{C400000001000000000000000E}

Мы видим, что значение равно x{C400000001000000000000000E}, что действительно является значением, которое мы встроили в наше предложение конфигурации. Мы даже можем попросить lite client отобразить эту ячейку как значение типа TL-B (ConfigParam 8).

> dumpcellas ConfigParam8 FDC
dumping cells as values of TLB type (ConfigParam 8)
C{FDCD887EAF7ACB51DA592348E322BBC0BD3F40F9A801CB6792EFF655A7F43BBC} =
x{C400000001000000000000000E}
(
(capabilities version:1 capabilities:14))

Это особенно полезно, когда мы рассматриваем предложения по конфигурации, созданные другими пользователями.

Обратите внимание, что предложение по конфигурации отныне идентифицируется его 256-битным хешем — огромным десятичным числом 6465...6321. Мы можем проверить текущий статус конкретного предложения конфигурации, запустив get-метод get_proposal с единственным аргументом, равным идентификатору предложения конфигурации:

> runmethod -1:5555555555555555555555555555555555555555555555555555555555555555 get_proposal 64654898543692093106630260209820256598623953458404398631153796624848083036321
...
arguments: [ 64654898543692093106630260209820256598623953458404398631153796624848083036321 94347 ]
result: [ [1586779536 0 [8 C{FDCD887EAF7ACB51DA592348E322BBC0BD3F40F9A801CB6792EFF655A7F43BBC} -1] 112474791597373109254579258586921297140142226044620228506108869216416853782998 () 864691128455135209 3 0 0] ]

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

4. Голосование за предложения конфигурации

После создания предложения по конфигурации предполагается, что оно наберет голоса более чем от 3/4 всех текущих валидаторов (по весу, т.е. по доле участия) в текущем раунде и, возможно, в нескольких последующих раундах (избранные наборы валидаторов). Таким образом, решение об изменении параметра конфигурации должно быть одобрено значительным большинством голосов не только текущего набора валидаторов, но и нескольких последующих наборов валидаторов.

Голосование за предложение конфигурации возможно только для текущих валидаторов, перечисленных (с их постоянными открытыми ключами) в параметре конфигурации #34. Процесс примерно следующий:

  • Оператор валидатора ищет val-idx, индекс (начиная с 0) своего валидатора в текущем наборе валидаторов, сохраненный в параметре конфигурации #34.
  • Оператор вызывает специальный скрипт Fift config-proposal-vote-req.fif, находящийся в каталоге crypto/smartcont исходной ветки, указывая val-idx и config-proposal-id в качестве аргументов:
    $ fift -s config-proposal-vote-req.fif -i 0 64654898543692093106630260209820256598623953458404398631153796624848083036321
Creating a request to vote for configuration proposal 0x8ef1603180dad5b599fa854806991a7aa9f280dbdb81d67ce1bedff9d66128a1 on behalf of validator with index 0
566F744500008EF1603180DAD5B599FA854806991A7AA9F280DBDB81D67CE1BEDFF9D66128A1
Vm90RQAAjvFgMYDa1bWZ-oVIBpkaeqnygNvbgdZ84b7f-dZhKKE=
Saved to file validator-to-sign.req
  • После этого запрос на голосование должен быть подписан закрытым ключом текущего валидатора, используя sign <validator-key-id> 566F744...28A1 в validator-engine-console, подключенном к валидатору. Этот процесс похож на тот, что описан в статье о валидаторах для участия в выборах валидатора, но на этот раз должен использоваться текущий активный ключ.
  • Затем должен быть вызван другой скрипт config-proposal-signed.fif. Он имеет аргументы, похожие на config-proposal-req.fif, но он ожидает два дополнительных аргумента: представление открытого ключа в формате base64, используемого для подписи запроса на голосование, и представление самой подписи в формате base64. Опять же, это очень похоже на процесс, описанный в статье о валидаторах.
  • Таким образом, создается файл vote-msg-body.boc, содержащий тело внутреннего сообщения, содержащего подписанный голос за это предложение конфигурации.
  • После этого vote-msg-body.boc должен быть передан во внутреннем сообщении из любого смарт-контракта, находящегося в мастерчейне (обычно будет использоваться контролирующий смарт-контракт валидатора) вместе с небольшим количеством Toncoin для обработки (обычно должно быть достаточно 1,5 Toncoin). Это снова полностью похоже на процедуру, используемую во время выборов валидатора. Обычно это достигается путем запуска:
$ fift -s wallet.fif my_wallet_id -1:5555555555555555555555555555555555555555555555555555555555555555 1 1.5 -B vote-msg-body.boc

(если для управления валидатором используется простой кошелек) и затем отправкой полученного файла wallet-query.boc из lite client:

> sendfile wallet-query.boc

Вы можете отслеживать ответные сообщения из смарт-контракта конфигурации в управляющий смарт-контракт, чтобы узнать статус ваших запросов на голосование. В качестве альтернативы вы можете проверить статус предложения конфигурации с помощью get-метода show_proposal смарт-контракта конфигурации:

> runmethod -1:5555555555555555555555555555555555555555555555555555555555555555 get_proposal 64654898543692093106630260209820256598623953458404398631153796624848083036321
...
arguments: [ 64654898543692093106630260209820256598623953458404398631153796624848083036321 94347 ]
result: [ [1586779536 0 [8 C{FDCD887EAF7ACB51DA592348E322BBC0BD3F40F9A801CB6792EFF655A7F43BBC} -1] 112474791597373109254579258586921297140142226044620228506108869216416853782998 (0) 864691128455135209 3 0 0] ]

На этот раз список индексов валидаторов, проголосовавших за это предложение конфигурации, должен быть непустым и должен содержать индекс вашего валидатора. В этом примере этот список равен (0), что означает, что проголосовал только валидатор с индексом 0 в параметре конфигурации #34. Если список станет достаточно большим, предпоследнее целое число (первый ноль в 3 0 0) в статусе предложения увеличится на единицу, что будет означать новую победу этого предложения. Если количество побед становится больше или равно значению, указанному в параметре конфигурации #11, то предложение конфигурации автоматически принимается, и предлагаемые изменения вступают в силу немедленно. С другой стороны, когда меняется набор валидаторов, то список валидаторов, которые уже проголосовали, становится пустым, значение rounds_remaining (три в 3 0 0) уменьшается на единицу, и если оно становится отрицательным, предложение конфигурации уничтожается. Если оно не уничтожается, и если оно не победило в этом раунде, то количество проигрышей (второй ноль в 3 0 0) увеличивается. Если оно становится больше значения, указанного в параметре конфигурации #11, то предложение конфигурации отбрасывается. В результате все валидаторы, которые не голосовали в раунде, неявно проголосовали против.

5. Автоматизированный способ голосования по предложениям конфигурации

Подобно автоматизации, предоставляемой командой createelectionbid из validator-engine-console для участия в выборах валидатора, validator-engine и validator-engine-console предлагают автоматизированный способ выполнения большинства шагов, описанных в предыдущем разделе, создавая vote-msg-body.boc, готовый к использованию с управляющим кошельком. Чтобы использовать этот метод, необходимо установить скрипты Fift config-proposal-vote-req.fif и config-proposal-vote-signed.fif в тот же каталог, который механизм проверки использует для поиска validator-elect-req.fif и validator-elect-signed.fif, как описано в разделе 5 статье о валидаторе. После этого вы просто запускаете

    createproposalvote 64654898543692093106630260209820256598623953458404398631153796624848083036321 vote-msg-body.boc

в validator-engine-console, чтобы создать vote-msg-body.boc с телом внутреннего сообщения, которое будет отправлено в смарт-контракт конфигурации.

6. Обновление кода смарт-контракта конфигурации и смарт-контракта выборщика

Может случиться так, что потребуется обновить код самого смарт-контракта конфигурации или код смарт-контракта выборщика. Для этого используется тот же механизм, что и описанный выше. Новый код должен быть сохранен в единственной ссылке на ячейку значений, и эта ячейка значений должна быть предложена в качестве нового значения параметра конфигурации -1000 (для обновления смарт-контракта конфигурации) или -1001 (для обновления смарт-контракта выборщика). Эти параметры претендуют на роль критических, поэтому для изменения конфигурации смарт-контракта требуется много голосов валидаторов (это сродни принятию новой конституции). Мы ожидаем, что такие изменения будут сначала протестированы в тестовой сети и будут обсуждаться предлагаемые изменения на публичных форумах, прежде чем каждый оператор валидатора решит проголосовать за или против предлагаемых изменений.

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

Для создания таких предложений конфигурации используются два вспомогательных скрипта для обновления кода смарт-контракта конфигурации или выборщика. А именно, create-config-upgrade-proposal.fif загружает исходный файл ассемблера Fift (auto/config-code.fif по умолчанию, соответствующий коду, автоматически сгенерированному компилятором FunC из crypto/smartcont/config-code.fc) и создает соответствующее предложение конфигурации (для параметра конфигурации -1000). Аналогично, create-elector-upgrade-proposal.fif загружает исходный файл ассемблера Fift (auto/elector-code.fif по умолчанию) и использует его для создания предложения конфигурации для параметра конфигурации -1001. Таким образом, создание предложений конфигурации для обновления одного из этих двух смарт-контрактов должно быть очень простым. Однако следует также опубликовать измененный исходный код FunC смарт-контракта, точную версию компилятора FunC, использованного для его компиляции, чтобы все валидаторы (или, скорее, их операторы) могли воспроизвести код в предложении конфигурации (и сравнить хэши), а также изучить и обсудить исходный код и изменения в этом коде, прежде чем принять решение о голосовании за или против предлагаемых изменений.