Synchroner Aufruf der externen Vertragsfunktion in Solidity

Ich habe zwei Solidity-Verträge, wobei der Vertrag Callervon einem zweiten Vertrag abhängt Callee. Contract Calleebietet eine öffentliche Ansichtsfunktion, die die Gültigkeit einer Zeichenfolge (z. B. eines Passworts) gemäß einigen internen Regeln überprüft. Callermuss einen String in seiner eigenen Funktion durch Aufrufen prüfen Callee, bevor er weiterverarbeiten kann. Außerdem Callermuss die Funktion von Calleemit aufgerufen werden delegatecall, da die interne Gültigkeitsprüfung die aufrufende Adresse berücksichtigt.

contract Caller {

  function doSomething(string _text, address _callee) public {
     bool valid = bool(_callee.delegatecall(
                          bytes4(keccak256("check(string _text)")), _text)
                  );

     require(valid == true);
     /* further process if text is valid */
  }
}

contract Callee {

  function check(string _text) public view returns(bool){
    /* validity check */
    return true;
  }
}

Das Problem mit diesem Code ist, dass der Aufruf der Funktion checkasynchron zu sein scheint und daher die requireAnweisung in der Funktion doSomethingimmer fehlschlägt. Ist das ein Problem von delegatecall? Gibt es eine Möglichkeit, die externe Funktion synchron aufzurufen?

Antworten (1)

Ich habe endlich die Antwort auf mein Problem gefunden: Leider kann man keine Werte von Funktionsaufrufen von Delegatecall empfangen.

Nun, die virtuelle Maschine unterstützt Rückgabewerte im DELEGATECALLOpcode:func opDelegateCall(pc *uint64, evm *EVM, contract *Contract, memory *Memory, stack *Stack) ([]byte, error)
Wirklich? Lese ich den Opcode richtig: Er kann ein Byte-Array zurückgeben?
Ich bin nicht wirklich Experte im Schreiben von Verträgen, aber DELGATECALL-Opcode funktioniert genauso wie CALL-Opcode. Ich weiß es, weil ich die VM für eine benutzerdefinierte Blockchain-Verarbeitung modifiziert habe. Es ist absolut identisch, öffnen Sie core/vm/instructions.go und überzeugen Sie sich selbst. Die retVariable enthält das []bytevon DELEGATECALL zurückgegebene Array. Vielleicht können Sie einen kleinen Teil Ihres Vertrages in Assembler schreiben, also rufen Sie DELEGATECALL auf und fangen diesen Rückgabewert ab. Dieser Rückgabewert wird an outOffsetPosition in den Speicher gestellt.
Ich denke, diese retVariable zeigt an, ob die Verarbeitung der aufgerufenen Funktion erfolgreich war.
Nein, retist die Ausgabe, die von der EVM zurückgegeben wird. Wenn ein Fehler aufgetreten ist, wird die error. Diese Ausgabe ist gemäß ABI codiert. Wenn Sie abi.Unpack() aufrufen, reterhalten Sie den Wert entsprechend seinem Typ. Zum Beispiel werden alle Ganzzahlen in 32-Byte-Arrays gespeichert, alle Zeichenfolgen haben zuerst die Zeichenfolgenlänge und dann folgen Zeichenfolgendaten und so weiter ...