Я создаю файл , доступ к 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
метод открыт для обхода бизнес-логики, кажется серьезной проблемой безопасности.
Как я что-то пропустил?
Любая транзакция в реальном блокчейне Ethereum должна быть подписана закрытым ключом.
Чтобы приведенный выше код работал (просто предоставляя from
адрес), узел, к которому вы подключены, должен выполнять подпись за вас. Пока from
адрес «разблокирован» в этом узле (по умолчанию в тестовой сети, такой как ganache
или явно с использованием обычного узла, такого как geth или Parity), он может подписать транзакцию этим ключом и отправить ее.
В реальной ситуации пользователи вашего приложения не будут подключены к узлу, у которого есть ваш закрытый ключ, так что это не проблема.
Библиотека web3
создает транзакцию, которую необходимо подписать учетной записью, указанной в from
. Он подписывается либо путем разговора с локальным узлом, у которого есть закрытый ключ для этой учетной записи и в настоящее время он разблокирован, либо с помощью программного обеспечения, такого как Metamask, которое контролирует этот закрытый ключ и подписывает транзакцию, только если пользователь подтверждает.
Невозможно отправить действительную (подписанную) транзакцию без закрытого ключа учетной записи в from
поле.
Собственность msg.sender
не может быть подделана — по крайней мере, в той степени, в которой кто-то не может создать транзакцию с msg.sender
адресом, который не принадлежит ему.
Какие бы меры безопасности вы ни предусмотрели в своем договоре, вы можете полагаться на то, что msg.sender
адрес — это лицо, совершающее транзакцию.
хорошая вибрация
contract_owner_address
узел разблокирован на узле Ethereum, к которому вы подключены. Либо вы (неосознанно) разблокируете его в своем коде, либо узел (неосознанно) разблокирует его для вас.