Wie kann man diese Soliditätsfunktion mit Web3js aufrufen, wenn der Vertrag ausgeführt wird?

Ich bin neu bei Ethereum.
Ich kämpfe definitiv mit den letzten 4 Parametern dieser Funktion, also frage ich das Problem direkt.

mapping(address => uint256) nonces;
/*
 * Proxy transfer token. When some users of the ethereum account has no ether,
 * he or she can authorize the agent for broadcast transactions, and agents may charge agency fees
 * @param _from
 * @param _to
 * @param _value
 * @param fee
 * @param _v
 * @param _r
 * @param _s
 */
function transferProxy(address _from, address _to, uint256 _value, uint256 _fee,
    uint8 _v,bytes32 _r, bytes32 _s) public transferAllowed(_from) returns (bool){

    if(balances[_from] < _fee + _value) revert();

    uint256 nonce = nonces[_from];
    bytes32 h = keccak256(_from,_to,_value,_fee,nonce);
    if(_from != ecrecover(h,_v,_r,_s)) revert(); // THE PROBLEM I’m STUCK ON SEVERAL HOURS IS HERE.

    if(balances[_to] + _value < balances[_to]
        || balances[msg.sender] + _fee < balances[msg.sender]) revert();
    balances[_to] += _value;
    Transfer(_from, _to, _value);

    balances[msg.sender] += _fee;
    Transfer(_from, msg.sender, _fee);

    balances[_from] -= _value + _fee;
    nonces[_from] = nonce + 1;
    return true;
}
  • Erstens nimmt keccak256 normalerweise nur ein Argument (die zu hashenden Daten). Ich habe keine Ahnung, was die Verwendung mehrerer Parameter bewirkt. Daten hinzufügen? Wenn ja wie? Die Hashes hashen? alles auf einmal oder nach jedem Ergebnis aufwärmen?
  • Zweitens denke ich, dass ich web3.eth.sign mit _vverwenden muss, um es zu bekommen . Aber wenn es nicht der Fall ist, weiß ich nicht, was ich verwenden mussweb3.eth.sign("0x395BE1C1Eb316f82781462C4C028893e51d8b2a5",keccak256("data"))
  • Drittens, keine Ahnung von _rungefähr.
  • Viertens denke ich, dass _ses um einen HTTP-Rückruf geht (durch Lesen der Dokumentation). Aber es scheint, dass ich es nicht einfach auf 0 belassen kann, da ich nicht weiß, was ich zurückrufen soll.
  • UND DAS HÄRTESTE. Wie werden die Nonce-Parameter in keccak256 genau bestimmt  ? (auch wenn ich keine Ahnung habe, wie ich es nennen soll), denn es fällt mir schwer zu verstehen, was mapping(address => uint256) nonces;ich uint256 nonce = nonces[_from];wirklich tue. Und natürlich muss ich den Wert kennen, um ihn einzustellen_v _r _s

Antworten (2)

Also hast du

Zuordnung (Adresse => uint256) Nonces , was bedeutet, dass ein uint256-Wert einer Adresse zugeordnet ist. Lassen Sie mich Ihnen ein Beispiel geben

Angenommen, Sie haben eine Adresse 0xa1bc und Sie möchten dieser Adresse einen Wert zuordnen, lassen Sie den Wert 1234 sein. So wird es gemacht

nonces["0xa1bc"] = 1234;

und um den der Adresse zugeordneten Wert zu erhalten

uint256 temp = nonces["0xa1bc"]

Hier habe ich temp den Wert zugewiesen, also ist temp 1234. Wenn die Zuordnung nicht vorhanden ist, ist der Wert 0 (Null).

Sie können genau diese Verhaltensweisen in der transferProxy- Funktion sehen ,

uint256 nonce = nonces[_from];

nonces[_from] = nonce + 1;

In der Funktion liest sie also zuerst Nonce, die mit einer Adresse _from verknüpft ist, erledigt etwas Arbeit und erhöht schließlich die Nonce um eins und speichert sie unter derselben Adresse _from.

Kommen wir nun zu Ihrem nächsten Problem mit _v, _r und _s,

Sie haben Recht mit dem web3.eth.sign . Sie können eine Nachricht mit web3.eth.sign(data, privatekey) und ihrer Variante signieren. Dadurch erhalten Sie ein Signaturobjekt. Diese Signatur kann in v, r und s zerlegt werden. Also, wie können Sie diese Werte erhalten? Passt auf.

var sign = web3.eth.sign(data,privatekey);

var v = sign.v;

var r = sign.r;

var s = sign.s;

Diese v, r und s sind die Werte, die Sie an die transferproxy-Funktion im Vertrag senden müssen.

Also, warum brauchen Sie diese Werte im Grunde? Dort sehen Sie eine Funktion ecrecover , die diese Werte als Parameter übernimmt. Dies ist eine eingebaute Funktion, die von Solidity bereitgestellt wird. Es gibt die Adresse des Benutzers an, der die Daten signiert hat. Hier ist h der Hash der Daten, die Sie signieren möchten.

Aber hier können wir sehen, dass Sie den Hash h nicht an den Vertrag gesendet haben. Warum? Denn Sie können die ursprüngliche Nachricht mit den im Vertrag selbst vorhandenen Daten konstruieren. Und diese ursprüngliche Nachricht ist _from,_to,_value,_fee,nonce . Das heißt, auf Ihrer Client-Seite haben Sie diese Werte im Voraus gespeichert oder kennen sie.

var sign = web3.eth.sign(_from+_to+_value+_fee+nonce, privatekeyOf_from);

So sieht der Vertragsfunktionsaufruf auf der Vorderseite aus

contractInstance.transferProxy.sendTransaction(from, to, value, fee, nonce, v, r, s, {from:.....});

if(_from != ecrecover(h,_v,_r,_s)) revert(); stellt sicher, dass der Benutzer mit der Adresse _from die Daten tatsächlich signiert hat oder nicht. Wenn nicht, machen Sie die Transaktion rückgängig (setzen Sie die Änderungen zurück).

Um zu Ihrer ersten Frage zu kommen, werden mehrere Parameter verkettet und dann gehasht.

Was wäre also der Wert von Nonce, wenn ich das erste Mal zum Senden und Empfangen mit derselben Adresse anrufe 0x395BE1C1Eb316f82781462C4C028893e51d8b2a5?
der Wert ist in diesem Fall 0. Standardwerte sind 0, false für int bzw. boolesche Typen.
Eine Sache noch. Wie konvertiere ich Parameter in den Typ, den solidity erwartet?
Senden Sie diese Werte einfach so, wie sie sind. Adresse und Bytewert sind hexadezimal. Wenn Sie fest codierte (nicht einigen Variablen zugewiesene) Werte senden, schließen Sie Adresse und Bytes mit Anführungszeichen ein.
Derzeit ist alles im String. Ich nehme an, ich kann nicht einfach Zeichenfolgenwerte für keccak256 verketten.
Sehen Sie sich die Funktionen web3.util.sha3 oder web3.util.soliditySha3 an
Beachten Sie auch, dass web3.js Text mit den zu hashenden Daten vorangestellt wird. Deshalb stimmen die Hashes im Frontend und im Vertrag nicht überein
etherscan.io/tx/… Ich habe offensichtlich etwas falsch gemacht. An dieser Adresse ist nichts (weniger als 10 $). Ich bin bereit, den privaten Schlüssel an diesem Punkt abzugeben.

Erstens nimmt keccak256 normalerweise nur ein Argument (die zu hashenden Daten). Ich habe keine Ahnung, was die Verwendung mehrerer Parameter bewirkt. Daten hinzufügen? Wenn ja wie? Die Hashes hashen? alles auf einmal oder nach jedem Ergebnis aufwärmen?

Aus den Dokumenten in Solidität:

keccak256(...) gibt (bytes32) zurück: berechnet den Ethereum-SHA-3 (Keccak-256) Hash der (dicht gepackten) Argumente

Daher sind die zu hashenden Daten die dicht gepackten Parameter, (_from,_to,_value,_fee,nonce)also keccak256(_from,_to,_value,_fee,nonce)wird der Hash des Bynary-Wortes berechnet, das durch Zusammenfügen all dieser fünf Parameter entsteht.

Zweitens denke ich, dass ich, um _v zu erhalten, web3.eth.sign mit web3.eth.sign ("0x395BE1C1Eb316f82781462C4C028893e51d8b2a5", keccak256 ("data")) verwenden muss. Aber wenn es nicht der Fall ist, weiß ich nicht, was ich verwenden muss. Drittens, keine Ahnung, worum es bei _r geht. Viertens denke ich, dass es bei _s um einen HTTP-Rückruf geht (durch Lesen der Dokumentation). Aber es scheint, dass ich es nicht einfach auf 0 belassen kann, da ich nicht weiß, was ich zurückrufen soll.

Diese Parameter werden aus der Signatur erhalten. In web3 stellt das Signieren einer Transaktion die Signatur und die Parameter r, s und v bereit. Diese Parameter können auch von der Signatur selbst abgeleitet werden, siehe web3- Dokumentation zum Abrufen von r, s und v und auch diese Antwort

UND DAS HÄRTESTE. Wie werden die Nonce-Parameter in keccak256 genau bestimmt? (Auch wenn ich keine Ahnung habe, wie ich es nennen soll), weil es mir schwer fällt, zu verstehen, was Mapping (Adresse => uint256) nonces; und uint256 nonce = nonces[_from]; wirklich tun. Und natürlich muss ich den Wert kennen, um _v _r _s zu setzen

Die Zuordnung nimmt als Eingabe eine Adresse und gibt eine Zahl zurück, diese Zahl ist die Nonce. nonce[_from]Fordert daher die Nonce für die Adresse an _from. Dieser Nonce-Wert ist im Grunde ein Zähler, der jedes Mal erhöht wird, wenn eine Transaktion von der Adresse ausgeführt wird _from.

Hoffe das hilft.

Meinen Sie mit dem Zusammenstellen von Parametern verketten keccak256? Wenn ja in Byte oder in String?
the mapping takes as input an address and returns a number, that number is the nonce. Therefore, nonce[_from] is requesting the nonce for the address _from. This nonce value is basically a counter that increments every time a transaction is executed from the address _from.Dies sagt nicht aus, wie ich die Nonce für das Hashing bekomme.
Ja, bedeutet, dass sie eng verkettet sind, was bedeutet, dass der Hex-Wert jeder Variablen entsprechend dem Typ verkettet ist.
Die Nonce-Variable wird auf der Miner-Seite berechnet. Wie berechne ich es mit Javascript? Oder muss ich mir wirklich die Mühe machen, es für Ecrecover-Parameter zu bekommen?
web3.eth.personal.ecRecoverwenn für die Berechnung des Hashs. Ist web3.eth.sign erforderlich, um das Gegenteil zu tun?
Sie können die aktuelle Nonce für Ihr Konto mit abrufen nonce = w3.eth.getTransactionCount('your account address'). Jetzt signiert sign die Nachricht und gibt Ihnen die r-, s- und v-Werte. ecrecover in solidity stellt die Adresse des Kontos wieder her, von dem die Transaktion stammt. In Ihrem Code ist diese Wiederherstellung der Adresse der Beweis dafür, dass die Signatur gültig ist. Hoffe das hilft.
Ich habe ein ähnliches Problem wie bei dieser Frage . Aber das Problem ist, dass ich den Smart Contract nicht ändern kann.