Ich habe versucht, die Funktion "Anrufen" zu verwenden, wie hier beschrieben: Aufruffunktion aus bereitgestelltem Vertrag
Aber es scheint überhaupt nicht zu funktionieren.
Wie kann ich eine Funktion aus einem vorhandenen bereitgestellten Smart Contract aufrufen?
Ich versuche, eine einfache Funktion von einer vorhandenen Adresse aufzurufen, die eine Adresse als Parameter erhält.
Dies ist der Code, den ich verwende, um die externe Funktion aufzurufen:
Vertrag A:
function CallExternalFunction(address externalContractAddress)
{
externalContractAddress.call(bytes4(sha3("FunctionX(address)")),0xfffff);
//sends 0xfffff as input parameter to the external contract
}
Der Quellcode des bereits bereitgestellten Vertrags sieht folgendermaßen aus:
Vertrag B:
contract test {
mapping (address => uint256) public balanceOf;
function test() {
}
function FunctionX(address _address)
{
balanceOf[_address] = 50000;
}
}
Versuche dies. Stellen Sie den Aufrufer bereit, und er stellt den Testvertrag bereit, um die Dinge zu vereinfachen.
contract Caller {
test public t;
function Caller() {
t = new test();
}
function callIt(address theAddress)
public
returns(bool success)
{
t = test(t); <===== here the other contract address can be called t = test([OtherContractAddress]); example: test(0x12345);
bool result = t.FunctionX(theAddress);
return result;
}
}
contract test {
mapping (address => uint256) public balanceOf;
function FunctionX(address _address) public returns(bool success)
{
balanceOf[_address] = 50000;
return true;
}
}
In Remix, um zu zeigen, dass es funktioniert.
Sie können eine ähnliche Struktur für einen Vertrag verwenden, der bereits vorhanden ist, wenn Sie über den Quellcode verfügen, indem Sie einen Schnittstellenvertrag verwenden. Hier kann der "Caller"-Compiler gerade genug von test {} sehen, um die Schnittstelle zu verwalten.
contract Caller {
test public t;
// where test is deployed and the address is known
// Pass in the address for test {}.
function Caller(address tAddress) {
t = test(tAddress); // address of contract t
}
function callIt(address theAddress)
public
returns(uint bal)
{
return t.FunctionX(theAddress);
}
}
// This interface constant includes the function interfaces (exactly as in the "real" contract" with the fynctions undefined
// This tells the compiler how to communicate with the ABI in test{}.
contract test {
function FunctionX(address _address) public returns(uint balanceOf) {}
}
t = new test();
stellt eine neue Instanz von test bereit. Für bereits bereitgestellte Tests{} können Sie die Adresse übergeben oder die Adresse fest codieren. Der Anrufer muss sie kennen, um den Anruf tätigen zu können. Die einzelne Quelldatei gibt dem Compiler eine Ansicht des Testvertrags, damit er die Schnittstelle test{} versteht und über den Bytecode verfügt, den er zum Bereitstellen eines neuen Tests{} benötigt.
Rob Hitchens
Ausruhen
Garen Vartanian
call
gesamtes Gas (minus ~30.000) wird an den externen Vertrag weitergeleitet, um damit zu tun, was er will, was eine Schwachstelle darstellt, insbesondere wenn der Anruf fehlschlägt und standardmäßig auf die Fallback-Funktion zurückgreift.call
unterbricht auch die Typsicherheit für Funktionsargumente und überträgt weiterhin Ether, wenn bei der Ausführung eine Ausnahme ausgegeben wird. Stellen Sie also sicher, dass Sie den Aufruf in a platzierenrequire()
, um Transaktionen rückgängig zu machen, die sich nicht wie erwartet verhalten.