Ich sehe oft _
in Modifikatoren
modifier onlyOwner() {
if (msg.sender != owner) throw;
_
}
Führt es irgendeinen Code aus oder soll es den Code leichter lesbar machen?
Ab Solidity-Version 0.4.0+ müssen Sie jetzt ein Semikolon nach hinzufügen _
. Siehe Solidity - Version 0.4.0 :
- Wechseln Sie
_
zu_;
in Modifikatoren.
Die folgenden Tests funktionieren nur in Solidity < v 0.4.0.
_
im Modifikator steht._
Sie können dem Modifikatorcode mehr als ein s hinzufügen . Und der Code der zu ändernden Funktion wird an jeder Stelle eingefügt, an _
der sich der Modifikator befindet. Siehe modifier checkThree
. Dies kann durch spätere Versionen des solc
Compilers verhindert werden.checkOne checkTwo checkThree
) und am Ende der Funktion werden sie umgekehrt aufgerufen. Die Modifikatoren scheinen wie ein Stapel angewendet zu werden. In diesem Beispiel sowieso.Aus Solidity Features - Funktionsmodifikatoren :
PT-Modifikatoren können verwendet werden, um das Verhalten von Funktionen einfach zu ändern, beispielsweise um eine Bedingung vor dem Ausführen der Funktion automatisch zu überprüfen. Sie sind vererbbare Eigenschaften von Verträgen und können durch abgeleitete Verträge außer Kraft gesetzt werden.
contract owned { function owned() { owner = msg.sender; } address owner; // This contract only defines a modifier but does not use it - it will // be used in derived contracts. // The function body is inserted where the special symbol "_" in the // definition of a modifier appears. modifier onlyowner { if (msg.sender == owner) _ } }
Hier ist ein Beispiel von EtherScan.io - The DAO - Source Code .
Der Modifikator onlyTokenholders
verhindert, dass "modifizierte" Funktionen von Nicht-Token-Inhabern ausgeführt werden.
modifier onlyTokenholders {
if (balanceOf(msg.sender) == 0) throw;
_
}
Hier ist die vote(...)
Funktion mit dem onlyTokenHolders
Modifikator:
function vote(
uint _proposalID,
bool _supportsProposal
) onlyTokenholders noEther returns (uint _voteID) {
Proposal p = proposals[_proposalID];
if (p.votedYes[msg.sender]
|| p.votedNo[msg.sender]
|| now >= p.votingDeadline) {
throw;
}
Der Code innerhalb der vote(...)
Funktion wird nur ausgeführt, wenn die Modifikatorprüfung keinen Fehler aus der Anweisung auswirft if (balanceOf(msg.sender) == 0) throw;
. Das _
repräsentiert den Hauptteil der vote(...)
Funktion.
Aus Learn X in Y minutes - Where X=Solidity , hier ist ein Beispiel, in dem _
das nicht am Ende der Modifikatorfunktion steht:
// underscore can be included before end of body,
// but explicitly returning will skip, so use carefully
modifier checkValue(uint amount) {
_
if (msg.value > amount) {
msg.sender.send(amount - msg.value);
}
}
Hier ist ein Code zum Testen _
:
contract TestModifier {
string[] public messages;
uint256 testVariable;
function numberOfMessages() constant returns (uint256) {
return messages.length;
}
modifier checkOne {
messages.push("checkOne - 1");
if (testVariable == 123)
throw;
_
messages.push("checkOne - 2");
if (testVariable == 123)
throw;
}
modifier checkTwo {
messages.push("checkTwo - 1");
if (testVariable == 123)
throw;
_
messages.push("checkTwo - 2");
if (testVariable == 123)
throw;
}
modifier checkThree {
messages.push("checkThree - 1");
if (testVariable == 123)
throw;
_
messages.push("checkThree - 2");
if (testVariable == 123)
throw;
_
messages.push("checkThree - 3");
if (testVariable == 123)
throw;
}
function test() checkOne checkTwo checkThree returns (uint256) {
messages.push("test - 1");
testVariable = 345;
messages.push("test - 2");
return testVariable;
}
}
Code abgeflacht
> var testModifierSource='contract TestModifier { string[] public messages; uint256 testVariable; function numberOfMessages() constant returns (uint256) { return messages.length; } modifier checkOne { messages.push("checkOne - 1"); if (testVariable == 123) throw; _ messages.push("checkOne - 2"); if (testVariable == 123) throw; } modifier checkTwo { messages.push("checkTwo - 1"); if (testVariable == 123) throw; _ messages.push("checkTwo - 2"); if (testVariable == 123) throw; } modifier checkThree { messages.push("checkThree - 1"); if (testVariable == 123) throw; _ messages.push("checkThree - 2"); if (testVariable == 123) throw; _ messages.push("checkThree - 3"); if (testVariable == 123) throw; } function test() checkOne checkTwo checkThree returns (uint256) { messages.push("test - 1"); testVariable = 345; messages.push("test - 2"); return testVariable; }}'
undefined
Vertrag in die Blockchain eingefügt:
> var testModifierCompiled = web3.eth.compile.solidity(testModifierSource);
undefined
> var testModifierContract = web3.eth.contract(testModifierCompiled.TestModifier.info.abiDefinition);
var testModifier = testModifierContract.new({
from:web3.eth.accounts[0],
data: testModifierCompiled.TestModifier.code, gas: 1000000},
function(e, contract) {
if (!e) {
if (!contract.address) {
console.log("Contract transaction send: TransactionHash: " + contract.transactionHash + " waiting to be mined...");
} else {
console.log("Contract mined! Address: " + contract.address);
console.log(contract);
}
}
})
...
Contract mined! Address: 0xd2ca2d34da6e50d28407f78ded3a07962b56181c
[object Object]
Transaktion zum Aufrufen der test()
Funktion gesendet:
> testModifier.test(eth.accounts[0], {
from:web3.eth.accounts[0],
data: testModifierCompiled.TestModifier.code,
gas: 1000000
});
Ergebnisse überprüft:
> var i;
> for (i = 0; i < testModifier.numberOfMessages(); i++) {
console.log(testModifier.messages(i));
}
checkOne - 1
checkTwo - 1
checkThree - 1
test - 1
test - 2
test()
:Ich habe die return-Anweisung entfernt, sodass der Quellcode für Folgendes test
lautet:
function test() checkOne checkTwo checkThree returns (uint256) {
messages.push("test - 1");
testVariable = 345;
messages.push("test - 2");
// return testVariable;
}
Führen Sie den Test erneut aus, um die folgenden Ergebnisse zu erzielen:
var i;
undefined
> for (i = 0; i < testModifier.numberOfMessages(); i++) {
.. console.log(testModifier.messages(i));
.. }
checkOne - 1
checkTwo - 1
checkThree - 1
test - 1
test - 2
checkThree - 2
test - 1
test - 2
checkThree - 3
checkTwo - 2
checkOne - 2
undefined
dor
Nicolas Massart
Datenschutz ist ein Menschenrecht.eth
@oIG
, einige interessante Testergebnisse.@Nicolas Massart
, wie funktioniert der Modifikator in Swift?Teleportierende Ziege
{action 1; _; action2;}
, führt er beim Aufrufen Aktion 1 aus, dann die Funktion, dann Aktion 2. Wenn Sie ihn nicht angeben, gehe ich davon aus, dass der Unterstrich implizit am Ende des Modifikators platziert wird.Teleportierende Ziege
Jaynti Kanani
modifier
wiedecorator
in Python.Dipankar
WowBow
Maxareo
Anderson