Was ich zu erreichen versuche, ist wie, ich sollte in der Lage sein, eine Reihe von Solidity-Funktionen dynamisch basierend auf einigen Kriterien aufzurufen. Ich verwende die call () -Methode, um dasselbe zu erreichen.
(bool success, bytes memory result) =APContract.call(abi.encodeWithSignature(string(data), "hello"));
data
Variable enthält den Funktionsaufruf-String "testCall(string)". Anstatt aus dem Vertrag zu codieren, sollte ich in der Lage sein, dasselbe mit Javascript zu codieren (wegen einer Logik zur Argumentgenerierung). damit ich die Funktion wie aufrufen kann APContract.call(data)
. Gibt es eine Methode, die hilft, dasselbe zu erreichen?
Ich bin mir nicht sicher, ob ich Ihre Frage vollständig verstanden habe, aber Sie können sich die ABI-Spezifikation des Solidity Documentation Contract ansehen: https://docs.soliditylang.org/en/latest/abi-spec.html#examples
Um zu sehen, wie Sie die Parameter selbst codieren können. Es ist im Grunde ein großer Satz verketteter Zeichenfolgen aus Funktionsnamen-Hash und Funktionsargumenten.
Sie können sich auch diese Bibliothek ansehen, die "kundenspezifische Vertragsaufrufe" durchführt (also sich nicht auf ABI verlässt): https://github.com/ERC725Alliance/erc725.js/blob/main/src/lib/utils.ts
import Web3 from 'web3';
const web3 = new Web3();
const methodId = web3.utils.keccak256('testCall(string)').substr(0, 10); //0xc7cee1b7
// In this function call, the first and only parameter uses a dynamic type: string
// https://docs.soliditylang.org/en/latest/abi-spec.html#use-of-dynamic-types
// we use the offset in bytes to the start of their data area, measured from the start of the value encoding
// offset to start of data part of second parameter, 1*32 bytes, exactly the size of the head part
const stringArgument = web3.utils.padLeft(web3.utils.toHex(1*32), 64).replace('0x', '');
// 0000000000000000000000000000000000000000000000000000000000000020
const stringValue = 'TODO' // This one is a bit tricky, the docs explain it well: https://docs.soliditylang.org/en/latest/abi-spec.html#use-of-dynamic-types
const call = methodId + stringArgument + stringValue;
Sie können jederzeit Ihr eigenes ABI-Diktat erstellen, dann übernimmt web3 die obige Konvertierung für Sie:
const contract = new web3.eth.Contract(
[
{
name: 'testCall',
inputs: [
{ type: 'bytes32', name: '_hash', internalType: 'bytes32' },
],
},
],
contractAddress,
);
const answer = await contract.methods
.testCall(messageHash)
.call();
Verwenden Sie die Hilfsfunktionen von: https://web3js.readthedocs.io/en/v1.3.0/web3-eth-abi.html, um das zu erstellen, was Sie benötigen.
web3.eth.abi.encodeParameter('string', 'Hello')
Bearbeiten: Sie können auch den Quellcode von web3 überprüfen
abi.encodeWithSignature("testCall(string)", "hello")
. und die codierten Bytes werden an einen Parameter einer Solidity-Funktion übergeben (wird ein Web3-Aufruf sein). diese spezielle Funktion wird like aufrufen aPContract.call(data)
. data
sind die kodierten Bytes als Argument der aufgerufenen Funktion gekommen. Es wird eine große Hilfe sein, wenn Sie auf diese Weise führenHier ist, was ich verwendet habe, um das Ethernaut Puzzle Wallet-Level zu knacken . Ich glaube encodeFunctionCall
genau das was du suchst:
let deposit = web3.eth.abi.encodeFunctionCall(contract.abi[2], [])
let multicall = web3.eth.abi.encodeFunctionCall(contract.abi[6], [[deposit]])
let calldata = web3.eth.abi.encodeFunctionCall(contract.abi[6], [[deposit, multicall]])
await sendTransaction({
from: player,
to: instance,
value: web3.utils.toWei('0.001', "ether"),
data: calldata
})
Rashiq Kodakkad
abi.encodeWithSignature("testCall(string)", "hello")