Kann ein externes Konto einen Vertrag erstellen, der alles tun kann, was das externe Konto ihm sagt?

Kann ein externes Konto einen Vertrag erstellen, der alles tun kann, was das externe Konto ihm sagt, einschließlich des Aufrufens beliebiger Verträge und des Sendens von Ether?

Das heißt, der Vertrag definiert keine spezifischen Methoden, sondern kann alles tun, was ein externes Konto tun kann, also hat er vielleicht eine generische Methode, die nur die Eigentümeradresse verwenden kann und die als Argumente erhält, was der Eigentümer mit dem Vertrag tun soll ( Aufruf eines anderen Kontrakts, Senden von Ether usw.).

Ist es möglich, einen solchen Vertrag in Solidity umzusetzen?

Antworten (1)

Vitalik lieferte ein Beispiel (in Serpent), das jetzt auf Solidity portierbar sein sollte.

# We assume that data takes the following schema:
# bytes 0-31: v (ECDSA sig)
# bytes 32-63: r (ECDSA sig)
# bytes 64-95: s (ECDSA sig)
# bytes 96-127: sequence number (formerly called "nonce")
# bytes 128-159: gasprice
# bytes 172-191: to
# bytes 192-223: value
# bytes 224+: data

# Get the hash for transaction signing
~mstore(0, ~txexecgas())
~calldatacopy(32, 96, ~calldatasize() - 96)
~mstore(0, ~sha3(0, ~calldatasize() - 64))
~calldatacopy(32, 0, 96)
# Call ECRECOVER contract to get the sender
~call(5000, 1, 0, 0, 128, 0, 32)
# Check sender correctness; exception if not
if ~mload(0) != 0x82a978b3f5962a5b0957d9ee9eef472ee55b42f1:
    ~invalid()
# Sequence number operations
with minusone = ~sub(0, 1):
    with curseq = self.storage[minusone]:
        # Check sequence number correctness, exception if not
        if ~calldataload(96) != curseq:
            ~invalid()
        # Increment sequence number
        self.storage[minusone] = curseq + 1
# Make the sub-call and discard output
with x = ~msize():
    ~call(msg.gas - 50000, ~calldataload(160), ~calldataload(192), 160, ~calldatasize() - 224, x, 1000)
    # Pay for gas
    ~mstore(0, ~calldataload(128))
    ~mstore(32, (~txexecgas() - msg.gas + 50000))
    ~call(12000, ETHER, 0, 0, 64, 0, 0)
    ~return(x, ~msize() - x)

Dieser Code würde als Vertragscode des Benutzerkontos dienen; Wenn der Benutzer eine Transaktion senden möchte, würde er eine Transaktion (von der Nulladresse) an dieses Konto senden und die ECDSA-Signatur, die Sequenznummer, den Gaspreis, die Zieladresse, den Etherwert und die tatsächlichen Transaktionsdaten unter Verwendung der angegebenen Codierung codieren oben im Code. Der Code vergleicht die Signatur mit dem Transaktionsgaslimit und den bereitgestellten Daten und prüft dann die Sequenznummer, und wenn beide korrekt sind, erhöht er die Sequenznummer, sendet die gewünschte Nachricht und sendet am Ende eine zweite Nachricht zum Bezahlen für Gas (beachten Sie, dass Miner Konten statisch analysieren und Transaktionen ablehnen können, die an Konten gesendet werden, die am Ende keinen Gas-Zahlungscode haben).

Der sichtbare Teil (möglicherweise andere), der jetzt nicht portierbar ist ~txexecgas(), ist ein neuer Opcode (Punkt 8 von EIP 101 ), aber er sollte derzeit nicht benötigt werden, da Miner derzeit bezahlt werden.

Referenzen (neu zu alt):