Гаманці та облікові записи з кількома підписами (multi-sig) дозволяють кільком людям отримувати доступ до своїх активів на основі певних параметрів. Гаманець з кількома підписами може містити, наприклад, комунальну скарбницю децентралізованої автономної організації (DAO) або іншої групи. Гаманець може вимагати від 25 відсотків учасників підписати транзакцію, перш ніж будь-які активи можна буде перемістити.

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

Смарт-контракт із кількома підписами, написаний на Move, є основним будівельним блоком для цього типу додатків на Sui. Смарт-контракт з кількома підписами, представлений у цій статті, перевіряє адреси з кількома підписами та підтримує різні комбінації ключів, наприклад 2-з-3 або M-з-N, де M і N є параметрами, визначеними користувачем.

Створення та використання контракту перевірки кількох підписів у Move

Адреса з кількома підписами — це особливий тип адреси, який потребує кількох підписів для авторизації транзакції. Смарт-контракт із перевіркою кількох підписів отримує адресу з кількома підписами з набору відкритих ключів, вагових коефіцієнтів і порогового значення та порівнює її з очікуваною адресою.

Адреси з кількома підписами вимагають кількох підписів для авторизації транзакції. Вони часто використовуються для підвищення безпеки коштів шляхом розподілу контролю між кількома сторонами. Наприклад, адреса з декількома підписами 2 із 3 потребує принаймні двох із трьох підписувачів, щоб схвалити транзакцію. Адреси з декількома підписами також можна використовувати для управління, депонування або резервного копіювання.

Розумний контракт з кількома підписами виконує три функції. Він отримує багатопідписні адреси, перевіряє їх і може перевіряти багатопідписні адреси відправника.

Отримайте багатознакові адреси

Модуль multisig визначає

derive_multisig_address_quiet

який приймає три параметри: pks, ваги та поріг.

The

шт

Параметр - це вектор векторів байтів, що представляють відкриті ключі підписантів.

The

ваги

Параметр — це вектор байтів, що представляє ваги кожного підписувача.

The

поріг

Параметр — це 16-розрядне ціле число без знаку, що представляє мінімальну суму ваг, необхідних для виконання транзакції з адреси з кількома підписами.

Функція повертає адресу, яка є похідною адресою мультипідпису.

public fun derive_multisig_address_quiet(         pks: vector<vector<u8>>,         weights: vector<u8>,         threshold: u16,     ): адреса {

Функція виконує такі дії:

Він визначає змінну,

multiSigFlag

, має тип 8-розрядного цілого числа без знаку та присвоює йому значення 0x03, яке є прапором для адрес із кількома підписами.

нехай multiSigFlag = 0x03;

Він створює порожній вектор байтів, що викликається

хеш-дані

, який зберігатиме дані для хешування.

let hash_data = vector<u8>[];

Він отримує довжину

шт

і зважує вектори та перевіряє їхню рівність. Якщо ні, він перериває виконання з кодом помилки: ELengthsOfPksAndWeightsAreNotEqual.

нехай pks_len = pgs.length(); нехай weights_len = weights.length(); assert!(pks_len == weights_len, ELengthsOfPksAndWeightsAreNotEqual);

Він ініціалізує змінну,

сума

, типу 16-розрядного цілого числа без знаку та присвоює йому значення 0. Потім він проходить через вектор ваг і додає значення кожного елемента до суми. Потім він перевіряє, чи порогове значення є додатним і не перевищує суму. Якщо ні, він перериває виконання з кодом помилки: EThresholdIsPositiveAndNotGreaterThanTheSumOfWeights.

нехай mut sum = 0; нехай mut i = 0; while (i < weights_len) {             нехай w = ваги[i] як u16; сума = сума + w; i = i + 1; }; assert!(поріг > 0 && поріг <= сума, EThresholdIsPositiveAndNotGreaterThanTheSumOfWeights);

Це штовхає

multiSigFlag

до вектора hash_data. Потім він серіалізує порогове значення за допомогою функції bcs::to_bytes і додає результат до вектора hash_data.

hash_data.push_back(multiSigFlag); нехай threshold_bytes: vector<u8> = bcs::to_bytes(&threshold); hash_data.append(threshold_bytes);

Це петля через

шт

і зважує вектори та додає елементи кожної пари до вектора hash_data.

нехай mut i = 0; while (i < pks_len) { hash_data.append(pks[i]); hash_data.push_back(weights[i]); i = i + 1; };

Він хешує

хеш-дані

вектор за допомогою функції blake2b256 і перетворює результат на адресу за допомогою функції address::from_bytes. Потім він призначає адресу змінній ms_address і повертає її.

нехай ms_address = адреса::from_bytes(blake2b256(&hash_data)); ms_address     }

Він отримує адресу з кількома знаками та повертає адресу з кількома знаками.

Перевірка мультипідписних адрес

The

мультисиг

Модуль також визначає check_multisig_address_eq, який перевіряє, чи збігається створена адреса з кількома підписами очікуваній адресі. Як ми згадували вище, адреса з кількома підписами — це особливий тип адреси, який потребує кількох підписів для авторизації транзакції. Адреса з кількома знаками визначається набором відкритих ключів, вагових коефіцієнтів і порогового значення.

Функція

check_multisig_address_eq

приймає чотири параметри: pks, ваги, поріг і очікувану_адресу. Перші три параметри такі самі, як ті, що ми використовували в попередній функції, derive_multisig_address_quiet. Останній параметр, очікувана_адреса, — це значення адреси, яке ми хочемо порівняти з адресою з кількома знаками.

public entry fun check_multisig_address_eq(         pks: vector<vector<u8>>,         weights: vector<u8>,         threshold: u16,         expected_address: address,     ): bool {

Функція спочатку викликає функцію,

derive_multisig_address_quiet

, який створює адресу з кількома підписами із заданих відкритих ключів, вагових коефіцієнтів і порогового значення. Ця функція використовує алгоритм на основі хешу для об’єднання відкритих ключів і порогового значення в 16-байтове значення, яке потім перетворюється на адресу.

let ms_address = derive_multisig_address_quiet(pks, weights, threshold);

Потім функція порівнює багатосигнальну адресу з очікуваною адресою та повертає true, якщо адреси рівні, і false в іншому випадку.

повернення (ms_address == очікувана_адреса)

Функція

check_multisig_address_eq

може використовуватися для перевірки правильності адреси з кількома знаками та відповідності очікуваному значенню. Це може бути корисно для цілей тестування, налагодження або аудиту. Наприклад, цю функцію можна використовувати для перевірки того, що адреса з декількома підписами відповідає відкритим ключам і пороговому значенню, узгодженим підписантами.

Перевірка мультипідписної адреси відправника

Нарешті,

мультисиг

Модуль також визначає check_if_sender_is_multisig_address, який перевіряє, чи є відправник тією самою адресою з кількома підписами, отриманою з наданих пакетів, ваги та порогу.

The

check_if_sender_is_multisig_address

приймає чотири параметри: pks, ваги, поріг і ctx. Перші три параметри визначають схему адреси з кількома підписами, а останній параметр надає контекст транзакції.

The

шт

Параметр — це вектор векторів байтів, що представляють відкриті ключі підписантів.

The

ваги

Параметр — це вектор байтів, що представляє ваги кожного підписувача.

The

поріг

Параметр — це 16-розрядне ціле число без знаку, що представляє мінімальну суму ваг, необхідних для виконання транзакції з адреси з кількома знаками.

Нарешті,

ctx

є змінним посиланням на TxContext, який містить інформацію про поточну транзакцію, наприклад відправника.

public fun check_if_sender_is_multisig_address(         pks: vector<vector<u8>>,         weights: vector<u8>,         threshold: u16,         ctx: &mut TxContext     ): bool {

The

check_if_sender_is_multisig_address

викликає функцію check_multisig_address_eq, яка порівнює адресу з кількома знаками та адресою відправника.

check_multisig_address_eq(pks, weights, threshold, ctx.sender())             }

Функція

check_multisig_address_eq

повертає true, якщо адреса відправника відповідає схемі адреси з кількома підписами, і false в іншому випадку.

Почніть роботу з мультипідписом

Адреси з декількома підписами корисні для сценаріїв, коли є потреба в підвищеній безпеці, підзвітності або співпраці між кількома сторонами. Враховуючи цінні цифрові активи, що зберігаються на Sui, адреса з кількома підписами може допомогти зберегти ці активи в безпеці.

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