¿Qué estaría en su lista para advertir a otros desarrolladores?
¿Qué funciona en la mayoría de los otros idiomas que no funciona o no se comporta como se esperaba en Solidity?
Solo por ejemplo: ¿qué parámetros se pueden pasar a las funciones, qué se puede devolver de las funciones?
Declarar una matriz local (u otro tipo de referencia ) y asumir que se creará en la memoria pero que en realidad sobrescribirá el almacenamiento :
/// THIS CONTRACT CONTAINS AN ERROR
contract C {
uint someVariable;
uint[] data;
function f() {
uint[] x;
x.push(2);
data = x;
}
}
El tipo de la variable local x es almacenamiento uint[], pero dado que el almacenamiento no se asigna dinámicamente, debe asignarse desde una variable de estado antes de poder usarse. Por lo tanto, no se asignará espacio en el almacenamiento para x, sino que funcionará solo como un alias para una variable preexistente en el almacenamiento.
Lo que sucederá es que el compilador interpreta x como un puntero de almacenamiento y hará que apunte a la ranura de almacenamiento 0 de forma predeterminada. Esto tiene el efecto de que someVariable (que reside en la ranura de almacenamiento 0) es modificada por x.push(2).
La forma correcta de hacerlo es la siguiente:
contract C {
uint someVariable;
uint[] data;
function f() {
uint[] x = data;
x.push(2);
}
}
OR
contract C {
uint someVariable;
uint[] data;
function f() {
uint[] memory x = new uint[](1);
x[0] = 2;
data = x;
}
}
de los documentos
En for (var i = 0; i < arrayName.length; i++) { ... }, el tipo de i será uint8, porque este es el tipo más pequeño que se requiere para contener el valor 0. Si la matriz tiene más de 255 elementos, el ciclo no terminará.
además
Todavía no es posible utilizar matrices de matrices en funciones externas. ... Solo puede usar un nivel de matrices dinámicas [en cualquier lugar].
y
Debido a las limitaciones de EVM, no es posible devolver contenido dinámico desde llamadas a funciones externas. La función f en contrato C { función f() devuelve (uint[]) { ... } } devolverá algo si se llama desde web3.js, pero no si se llama desde Solidity. La única solución por ahora es usar arreglos grandes de tamaño estático.
string[] no están permitidos en parámetros de función o retornos.
consulte la discusión aquí:
¿Es imposible usar una matriz de cadenas como argumento para la función de solidez?
returns
con parámetros de salida con nombre introduce una nueva variable local.
Por ejemplo, de esta pregunta :
contract Test {
address owner;
function Test(){
owner = msg.sender;
}
function getOwner() returns (address owner) {
return owner;
}
}
Aquí en getOwner
new variable owner
se introduce y se inicializa a cero. Coincidentemente, anula la variable de estado, owner
lo que conduce a un resultado inesperado.
Las asignaciones solo se permiten para variables de estado (o como tipos de referencia de almacenamiento en funciones internas).
Por ejemplo, de esta pregunta :
function getBalance(address addr) returns (uint, uint) {
mapping(address => uint) balancers;
balancers[msg.sender] = 500;
return (balancesA[addr], balancesB[addr]);
}
Aquí mapping(address => uint) balances
no asigna una nueva asignación, sino que introduce una variable no inicializada. Por lo tanto, el acceso balancers[msg.sender]
no es válido.
El uso delete
en una matriz deja un espacio, por lo que debe cambiar los elementos manualmente y actualizar la propiedad de longitud.
string
es lo mismo que bytes
pero no permite el acceso a la longitud ni al índice.
bytes
es lo mismo byte[]
pero empaquetado herméticamente (más caro).
Los sufijos de fecha no se pueden aplicar a las variables.
Solidity hereda las reglas de alcance de JavaScript; no hay alcance de bloque.
Para obtener más trucos de solidez, consulte https://github.com/miguelmota/solidity-idiosyncrasies
ryepdx