Der Aufruf der Vertragsfunktion über web3.eth.sendTransaction funktioniert nicht

Ich lerne, wie Blockchains funktionieren, und habe eine private Blockchain erstellt, um einige Dinge zu testen. Ich habe den folgenden Vertrag bereitgestellt:

contract Greeter         
{
    address creator;     
    string greeting;     

    function Greeter(string _greeting) public   
    {
        creator = msg.sender;
        greeting = _greeting;
    }

    function greet() constant returns (string)          
    {
        return greeting;
    }

    function getBlockNumber() constant returns (uint) 
    {                                                   
        return block.number;
    }

    function setGreeting(string _newgreeting) 
    {
        greeting = _newgreeting;
    }


    function kill()
    { 
        if (msg.sender == creator)  
            suicide(creator);       
    }

}

Jetzt habe ich verschiedene Methoden ausprobiert, um die Setter-Funktion aufzurufen. Ich habe die Instanz mit der Verwendung von Vertragsadresse und abi erhalten und aufgerufen

instance.setGreeting.sendTransaction(...)

Dieser hat funktioniert und mit instance.greet()bekam ich den neuen Gruß. Aber dann habe ich ein Beispiel von dieser Seite https://github.com/ethereumbook/ethereumbook/blob/develop/transactions.asciidoc#invocation ausprobiert und aufgerufen

web3.eth.sendTransaction({from: eth.coinbase, to: contract_address, data: "0x4136862e000000000000000000000000000000000000000000004d794e65774772656574"})

Dabei werden die Daten aus den ersten 4 Bytes des Keccak256-Hashes der Prototypfunktion und dem in Hex codierten und auf 32 Bytes aufgefüllten setGreeting(string)String erstellt. "MyNewGreet"Die Transaktion wird abgebaut, gibt aber instance.greet()immer noch die alte Begrüßung zurück

Antworten (1)

Anscheinend hast du den Funktionswähler falsch eingestellt. Es sollte sein 0xa4136862. (Dir fehlt das erste Zeichen und du hast stattdessen ein zusätzliches am Ende eingefügt.)

Die Zeichenfolge ist auch falsch codiert. Es sollte eine 32-Byte-Position der Daten (0x20) sein, gefolgt von einer 32-Byte-Länge (0x0a), gefolgt von den eigentlichen Daten, rechts aufgefüllt, um ein Vielfaches von 32 Bytes zu sein. Siehe https://solidity.readthedocs.io/en/v0.4.24/abi-spec.html#argument-encoding für die vollständigen Details.

Alles in allem ist dies die korrekte ABI-Codierung Ihres Funktionsaufrufs:

0xa41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a4d794e6577477265657400000000000000000000000000000000000000000000