TGViewer
Из Solidity в AI и дальше Из Solidity в AI и дальше @solidityset · 2.49K subscribers
Post #1344 736
Работа с мультисиг кошельками. Часть 5

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

Я потихоньку буду разворачивать весь код, чтобы вы успевали следить за мыслью. Итак, начнем.

Давайте рассуждать, что нам вообще потребуется:

1. Во-первых, это некоторый набор владельцев кошелька, которые смогут одабривать транзакции.

2. Также нам потребуется наперёд знать, сколько человек будет одабривать действия, и проверка, что у пользователя действительно есть права на это.

За это, как раз, и будут отвечать эти переменные:

    address[] public owners;
mapping(address => bool) public isOwner;
uint256 public numConfirmationsRequired;


3. Теперь подумаем о форме транзакций. В больших проектах может потребоваться больше полей, но для самой базы будет достаточно этих: кто инициировал, на какую сумму, есть ли дополнительные данные, статус и количество подписей для одобрения. Создадим структуру и поместим ее в массив:

    struct Transaction {
address to;
uint256 value;
bytes data;
bool executed;
uint256 numConfirmations;
}

Transaction[] public transactions;


4. Ну, и само собой, некоторый набор модификаторов для быстрой валидации владельцев и статуса транзакций:

    modifier onlyOwner() {
require(isOwner[msg.sender], "not owner");
_;
}

modifier txExists(uint256 _txIndex) {
require(_txIndex < transactions.length, "tx does not exist");
_;
}

modifier notExecuted(uint256 _txIndex) {
require(!transactions[_txIndex].executed, "tx already executed");
_;
}

modifier notConfirmed(uint256 _txIndex) {
require(!isConfirmed[_txIndex][msg.sender], "tx already confirmed");
_;
}


5. И для того, чтобы можно было отслеживать, кто подписал транзакцию, а кто нет, мы введем маппинг:

mapping(uint256 => mapping(address => bool)) public isConfirmed;


6. И в конструкторе нам потребуется сделать несколько проверок и записать изначальные данные в переменные состояния:

    constructor(address[] memory _owners, uint256 _numConfirmationsRequired) {
require(_owners.length > 0, "owners required");
require(
_numConfirmationsRequired > 0
&& _numConfirmationsRequired <= _owners.length,
"invalid number of required confirmations"
);

for (uint256 i = 0; i < _owners.length; i++) {
address owner = _owners[i];

require(owner != address(0), "invalid owner");
require(!isOwner[owner], "owner not unique");

isOwner[owner] = true;
owners.push(owner);
}

numConfirmationsRequired = _numConfirmationsRequired;
}


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

В итоге мы получаем базовый набор контракта:
More from @solidityset
  1. Sep 22, 2026Какой язык программирования учить сейчас? На днях в Твиттере увидел небольшой пост о разви…
  2. Sep 18, 2026Интересная модель Jev Буквально пару дней назад в Твиттере многие начали обсуждение новой…
  3. Sep 14, 2026Графы повсюду Если вы также следите за новостями в мире ИИ, то наверняка уже все чаще встр…
  4. Sep 10, 2026GTA6, Cyberleek, блокчейн и безопасность Увидел несколько постов (тут и тут) про Cyberleek…
  5. Sep 9, 2026Работа с чистой энергией Дисклеймер Сегодня ава и название канала, наконец, поменялись. Я…
  6. Sep 9, 2026Channel name was changed to «Из Solidity в AI и дальше»
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →