Veo a menudo _
en modificadores
modifier onlyOwner() {
if (msg.sender != owner) throw;
_
}
¿Ejecuta algún código o está destinado a hacer que el código sea más fácil de leer?
A partir de la versión 0.4.0+ de Solidity, ahora debe agregar un punto y coma después de _
. Ver Solidez - Versión 0.4.0 :
- Cambiar
_
a_;
en modificadores.
Las siguientes pruebas solo funcionan en Solidity < v 0.4.0.
_
se coloca en el modificador._
s en el código modificador. Y el código de la función que se modifica se inserta en cada lugar donde _
se encuentra en el modificador. ver modifier checkThree
_ Esto puede evitarse con versiones posteriores del solc
compilador.checkOne checkTwo checkThree
) y al final de la función, se llaman a la inversa. Los modificadores parecen aplicarse como una pila. En este ejemplo de todos modos.De Solidity Features - Modificadores de función :
Los modificadores PT se pueden usar para cambiar fácilmente el comportamiento de las funciones, por ejemplo, para verificar automáticamente una condición antes de ejecutar la función. Son propiedades heredables de los contratos y pueden ser anuladas por contratos derivados.
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) _ } }
Aquí hay un ejemplo de EtherScan.io - The DAO - Código fuente .
El modificador onlyTokenholders
restringe que las funciones "modificadas" sean ejecutadas por personas que no poseen tokens.
modifier onlyTokenholders {
if (balanceOf(msg.sender) == 0) throw;
_
}
Aquí está la vote(...)
función con el onlyTokenHolders
modificador:
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;
}
El código dentro de la vote(...)
función solo se ejecuta si la verificación del modificador no arroja un error de la declaración if (balanceOf(msg.sender) == 0) throw;
. El _
representa el cuerpo de la vote(...)
función.
De Learn X in Y minutes - Where X=Solidity , aquí hay un ejemplo donde _
no está al final de la función modificadora:
// 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);
}
}
Aquí hay un código para probar _
:
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;
}
}
Aplanado el código
> 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
Contrato insertado en la cadena de bloques:
> 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]
Envió una transacción para llamar a la test()
función:
> testModifier.test(eth.accounts[0], {
from:web3.eth.accounts[0],
data: testModifierCompiled.TestModifier.code,
gas: 1000000
});
Comprueba los resultados:
> 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()
:Eliminé la declaración de devolución, por lo que el código fuente test
es:
function test() checkOne checkTwo checkThree returns (uint256) {
messages.push("test - 1");
testVariable = 345;
messages.push("test - 2");
// return testVariable;
}
Y volvió a ejecutar la prueba para producir los siguientes resultados:
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
insecto
Nicolás Massart
privacidadisahumanright.eth
@oIG
, algunos resultados de pruebas interesantes.@Nicolas Massart
, ¿cómo funciona el modificador en Swift?Cabra teletransportadora
{action 1; _; action2;}
, cuando lo llame, realizará la acción 1, luego la función, luego la acción 2. Si no lo especifica, asumo que el guión bajo se coloca implícitamente al final del modificador.Cabra teletransportadora
Jaynti Kanani
modifier
comodecorator
en python.Dipankar
guauarco
Maxareo
anderson