Erstens ist mir eine ähnliche Frage bekannt , aber diese Antwort ist nicht ausreichend.
Angenommen, ich habe einen Vertrag A bereitgestellt, dann stelle ich einige Zeit später einen weiteren Vertrag B bereit. Ich möchte sicherstellen, dass eine Funktion A.f1()
in A nur von Vertrag B aufgerufen werden kann. Dazu implementiere ich eine Funktion register(address trusted_contract)
, um B bei A zu registrieren, die im Grunde die Adresse von B in einem Array in A speichert. Da ich A besitze, I Bin der einzige, der es anrufen kann, um eine Adresse zu registrieren.
Wenn B jetzt anruft , überprüfe ich A.f1()
innerhalb von , ob es im Array enthalten ist, und entscheide, ob der Anruf bedient werden soll.f1()
msg.sender
Ist dies der richtige Weg?
Wenn ja, habe ich noch eine Frage. Was hindert einen anderen Vertrag C daran, eine Nachricht zu senden und behauptet, dass es B ist? Mein Verständnis ist, dass ein Vertrag im Gegensatz zu einem externen Konto keinen privaten Schlüssel hat und daher keine Nachricht signieren kann. Wenn ja, wie verifiziert Empfänger A, dass der Anrufer Vertragspartner B ist und nicht ein schlechter Schauspieler C?
Ist dies der richtige Weg?
Ja, außer dass Sie anstelle eines Arrays eine Karte für eine effiziente Suche verwenden sollten.
Wenn ja, wie verifiziert Empfänger A, dass der Anrufer Vertragspartner B ist und nicht ein schlechter Schauspieler C?
Es gibt zwei Möglichkeiten, wie ein "Angreifer" handeln kann:
Innerhalb des Vertrags A sind zwei Eigenschaften verfügbar:
tx.origin
- die externe Kontoadresse.msg.sender
- die externe Kontoadresse für Fall 1; Vertragsanschrift X für Fall 2.msg.sender
ist das, was Sie überprüfen werden, um sicherzustellen, dass der Anruf von Vertrag B erfolgt.
In beiden Fällen kann sich der „Angreifer“ nicht als Vertrag B ausgeben:
msg.sender
weil er von der EVM gehandhabt wird : Wenn ein Nachrichtenanruf von Vertrag X erfolgt, muss die EVM msg.sender
die Adresse von Vertrag X festlegen.Wenn also der „Angreifer“ die Transaktion nicht an Vertrag B sendet, kann er sich nicht als Vertrag B ausgeben.
Ja, das ist richtig. Was ein Konto daran hindert, eine Transaktion als Vertrag B zu senden, ist, dass das Konto das private/öffentliche Schlüsselpaar benötigen würde, um die Transaktion unter der Identität des Vertrags zu signieren.
Benutzer3839198