Gibt es eine bequemere Möglichkeit, den Wert data
für einen eth_call
JSON-RPC-API-Aufruf zu erstellen, als die "normale" Methode der ersten 4 Bytes web3.sha3
der kanonischen Funktionssignatur, gefolgt von codierten und aufgefüllten Argumenten? Ich weiß, dass die web3-JavaScript- getData
Methode verwendet werden kann, aber wenn der Zugriff über web3 verfügbar ist, könnte man die Funktion genauso gut direkt aufrufen, anstatt nur die data
JSON-RPC-API abzurufen und zu verwenden. Angenommen, in einigen Situationen ist nur JSON-RPC-API-Zugriff verfügbar. Ist das Konstruieren data
von Hand für einen Vertragsfunktionsaufruf die einzige Option?
BEARBEITEN (21.06.2017): Mir ist aufgefallen, dass Browser-Solidity möglicherweise das data
for an eth_call
oder eth_sendTransaction
anzeigt, da es den kompilierten Vertrags-Bytecode und die Schnittstelle anzeigt. Das hätte man kopieren können. Ich habe jedoch überprüft und sehe nicht, dass das data
für einen Funktionsaufruf erforderliche angezeigt wird, wenn ich eine Funktion im rechten Bereich aufrufe.
BEARBEITUNG Nr. 2 (21.06.2017): Vielleicht war meine Frage nicht so klar wie oben gepostet. Ich werde versuchen, es anders auszudrücken. Angenommen, wir haben den folgenden Solidity-Vertrag (mit dem Namen simple
) an einer Adresse bereitgestellt, z. B. at0xfbb5fa2ea8c5fc6f492c0795564352f262f49f50
pragma solidity ^0.4.9;
contract owned {
address owner;
function owned() {
owner = msg.sender;
}
function getOwner() constant returns(address) {
return owner;
}
}
contract simple is owned {
function twice(int a) constant returns(int) {
return 2*a;
}
}
Die Funktion twice
kann web3.js
wie folgt aus dem Javascript-Code aufgerufen werden:
var simple = eth.contract(<ABI>).at(0xfbb5fa2ea8c5fc6f492c0795564352f262f49f50);
var result = simple.twice(7);
Um diese Funktion jedoch mit JSON-RPC aufzurufen, muss eine HTTP-Post-Anforderung mit dem folgenden Text an den RPC-Port eines Knotens gesendet werden:
{
"jsonrpc": "2.0",
"method": "eth_call",
"params": [
{
"from": "0xccf9d7d2f8be1f821cb8d9ec9553ffa92aa8fc4d",
"to": "0xfbb5fa2ea8c5fc6f492c0795564352f262f49f50",
"data": "0x6ffa1caa0000000000000000000000000000000000000000000000000000000000000007"
},
"latest"
],
"id": 1
}
Der Wert von data
element wird berechnet als die ersten 4 Bytes von { dem Keccak-Hash von [ der ASCII-Codierung von ( einer kanonischen Form der Funktionssignatur ) ] } gefolgt von den Argumenten, die auf eine bestimmte Weise codiert sind, wie unter https://github angegeben .com/ethereum/wiki/wiki/Ethereum-Contract-ABI . HINWEIS: 3 Arten von Klammern hinzugefügt, um Mehrdeutigkeiten zu beseitigen :-) (Dies ist eine sehr einfache Funktion mit nur 1 int-Argument, aber dies kann bei komplexeren Argumenten schnell sehr unangenehm und fehleranfällig werden.
Es gibt eine Möglichkeit, den entsprechenden Wert data
für einen Funktionsaufruf mithilfe einer web3.js
Funktion wie folgt zu erhalten:
var callData = simple.twice.getData(7);
Angenommen, die Funktion soll von einem Remote-Computer aufgerufen werden und Javascript ist keine Option. Gibt es eine bequeme Möglichkeit (dh nicht manuell gemäß den komplexen Regeln im oben verlinkten Wiki), den korrekten Wert des data
Elements der JSON-RPC-API-Anforderung zu berechnen?
Ich habe genau das Tool gefunden, nach dem ich gesucht habe - Ethabi von Parity.
Ich habe jedoch überprüft und sehe nicht, dass die für einen Funktionsaufruf erforderlichen Daten angezeigt werden, wenn ich eine Funktion im rechten Bereich aufrufe.
Entfernen Sie einfach die constant
Deklaration in Ihrer Funktion, die nur Daten zurückgibt, und führen Sie eine Scheintransaktion mit Browsersolidity durch. Im Bytecode finden Sie die Funktionssignatur, die Sie leider genau so verwenden müssen, wie Sie es beschrieben haben. Es gab zwar eine Web3-Funktion zum Reeding von Speicher direkt aus einem Vertrag, soweit ich mich erinnern kann, aber das erschien mir komplizierter als die von Ihnen beschriebene Oldschool-Methode.
data
. Ich habe versucht, es in EDIT #2 klarer zu machen. Außerdem habe ich die Funktionssignatur nicht gefunden, nachdem ich die constant
Deklaration aus einer Funktion entfernt hatte, die nur Daten zurückgibt und sie in Browser-Solidity aufruft.data
Wert lokal zu generieren. Schließlich hängt es nur von der Funktionssignatur und den Argumenttypen und -werten ab. Keines davon erfordert eine Verbindung zu einem Knoten.
Ajoy Bhatia
Ajoy Bhatia
solc
aber jede andere Möglichkeit, diese Funktionalität in einem lokal ausgeführten Tool bereitzustellen, ist gut für mich. github.com/ethereum/ethereumj/issues/904