почему для отправки web3 не требуется закрытый ключ или подпись

Я создаю файл , доступ к ERC20 smart contractкоторому будет осуществляться через node.jsбиблиотеку web3. Я вижу, что web3.eth.Contractесть sendфункция, которая принимает параметр from, который сопоставляется с msg.senderв смарт-контракте. Насколько я понимаю (и моя отладка поддерживает это), я могу изменить fromполе практически на любой адрес и тем самым обойти бизнес-логику контракта, например

token.methods.method_only_owner_can_activate(<some_data>).send({ from: <contract_owner_address>, <gas> });

или даже установить владельца:

token.methods.setOwner(<my_not_owner_address>).send({ from: <contract_owner_address>, <gas> });

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

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

Как я что-то пропустил?

Вы упускаете тот факт, что ваш contract_owner_addressузел разблокирован на узле Ethereum, к которому вы подключены. Либо вы (неосознанно) разблокируете его в своем коде, либо узел (неосознанно) разблокирует его для вас.

Ответы (3)

Любая транзакция в реальном блокчейне Ethereum должна быть подписана закрытым ключом.

Чтобы приведенный выше код работал (просто предоставляя fromадрес), узел, к которому вы подключены, должен выполнять подпись за вас. Пока fromадрес «разблокирован» в этом узле (по умолчанию в тестовой сети, такой как ganacheили явно с использованием обычного узла, такого как geth или Parity), он может подписать транзакцию этим ключом и отправить ее.

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

Библиотека web3создает транзакцию, которую необходимо подписать учетной записью, указанной в from. Он подписывается либо путем разговора с локальным узлом, у которого есть закрытый ключ для этой учетной записи и в настоящее время он разблокирован, либо с помощью программного обеспечения, такого как Metamask, которое контролирует этот закрытый ключ и подписывает транзакцию, только если пользователь подтверждает.

Невозможно отправить действительную (подписанную) транзакцию без закрытого ключа учетной записи в fromполе.

Собственность msg.senderне может быть подделана — по крайней мере, в той степени, в которой кто-то не может создать транзакцию с msg.senderадресом, который не принадлежит ему.

Какие бы меры безопасности вы ни предусмотрели в своем договоре, вы можете полагаться на то, что msg.senderадрес — это лицо, совершающее транзакцию.