Welche Funktionsteile werden extern und welche „on chain“ ausgeführt?

Ich bin immer noch ein Soliditäts-Noob, also entschuldige ich mich, wenn die Frage zu einfach ist.

Ich versuche, einen Vertrag zu schreiben, der den Hash einer (potenziell) großen Menge von Daten in der Kette speichert.

Aus diesem Grund möchte ich eine Funktion schreiben, die den Hash extern ausführt (dh auf der aufrufenden Maschine, so etwas wie eine Ansichtsfunktion) und das Ergebnis dann auf der Kette zurückspeichert. Ist es möglich? Ein Codebeispiel hier:

contract Test {
  bytes32[] hashes;

  function extCall(bytes _data) external view {
    bytes32 hash = keccak256(_data);
    _intCall(hash);
  }

  function _intCall(bytes32 _hash) private {
    hashes.push(_hash)
  }
}

Die Absicht war hier, die Möglichkeit auszuschließen, den Hash auf der Kette zu speichern, ohne die Originaldaten zu haben. Aus diesem Grund wäre die einzige Möglichkeit, die Funktion _intCall aufzurufen, der Aufruf über extCall. Aber es scheint, dass durch diesen Trick auch extCall in der Kette angerufen wird und Gas verbraucht. Insbesondere erhalte ich diese Warnung beim Testen auf Trüffel:

Warnung: Funktion als Ansicht deklariert, aber dieser Ausdruck modifiziert (möglicherweise) den Zustand und erfordert daher nicht zahlbar (Standard) oder zahlbar.

Ps. Es besteht eine (GROSSE) Chance, dass ich das Thema völlig falsch verstanden habe, also wird wirklich jede Hilfe angenommen!

Antworten (2)

Alles, was Sie im Rahmen einer Transaktion tun, geschieht in der Kette. Alles, was den Status eines Vertrags ändert, muss als Teil einer Transaktion erfolgen.

viewEs ist in Ordnung, eine Funktion als Helfer aufzurufen ; Dieser Code wird nur auf einem einzigen Knoten ausgeführt (demjenigen, mit dem Sie sprechen) und kann einen Wert zurückgeben. Dies würde also keine Kosten für alle Daten verursachen, die Sie hashen:

contract Test {
    bytes32[] hashes;

    function hash(bytes data) public pure {
        return keccak256(data);
    }

    function store(bytes32 hash) public {
        hashes.push(hash);
    }
}

Dies würde etwa so verwendet werden (web3.py-ish-Pseudocode):

hash = contract.call().hash("my document here")  # not a transaction
contract.transact().store(hash)  # a transaction

Aber dann können Sie das Hashing auch ganz außerhalb des Vertrags durchführen (z. B. hash = keccak256("my document here")).

Es gibt keine Möglichkeit, jemandem zu beweisen, dass Sie ein Dokument haben, das mit dem Hash übereinstimmt, es sei denn, Sie senden das gesamte Dokument als Teil einer Transaktion.

Ok danke, nur noch eine Frage: Ist es nur ein Soliditätsmerkmal oder ist es Ethereum inhärent? Ich meine, wird es Ihres Wissens nach eine Möglichkeit geben, eine Art "gemischten externen/internen Anruf" direkt in einen Versammlungsaufruf zu implementieren?
Es ist Ethereum inhärent.

pure -> Um mit Daten zu arbeiten (wörtliche) Beispiele:

Funktion helloo() öffentlich/extern rein {

a) return 4 + 5;

b) uint number = 6;
   return number;

c) string memory hello = "hi"; // 'memory' -> refers to the temporary memory of the virtual machine of ethereum.
   return hello;

}

Ansicht -> Vertragsdaten lesen

Beispiele:

Zeichenfolge Hallo = "Hallo"; -> GLOBAL IN THE CONTRACT (BLOCKCHAIN), wenn es außerhalb der Funktion deklariert wurde.

Funktion helloo() öffentliche/externe Ansicht {

a) return hello; 

b) string storage str = hello; -> Refers to the state variable 
(pointer).   
return str;

}

*Keiner dieser Modifikatoren verbraucht Gas, da diese Funktionen keine Daten in die Blockchain schreiben oder speichern.

Danke, was passiert, wenn ich eine öffentliche Pure/View-Funktion A in einer Nicht-Pure/View-Funktion B aufrufe? Wird A Gas verbrauchen, weil es in B „Scope“ genannt wird? Denn wenn ich die Funktion B in A aufrufe, beginnt A selbst Gas zu verbrauchen, auch wenn es als rein/sichtbar markiert ist.
In diesem Fall verbraucht „B“ Gas, wenn Sie „A“ anrufen, werden Sie Gas verbrauchen. Der Modifikator 'puer / view' von 'A' spielt keine Rolle. Als allgemeine Regel gilt: Wenn Sie eine andere Funktion als 'view / puere' aufrufen, kostet Sie das Gas.