Buenos días.
Tengo una serie de estructuras como:
User[] public users;
struct User{
uint idNum;
string name;
address userAddress;
}
Y estoy tratando de obtener la matriz de usuarios con web3.js usando:
contract = web3.eth.contract([ABI]).at("0x0..");
var users = contract.users();
Hasta ahora todo funciona bien, pero cuando trato de obtener el tamaño de la matriz, siempre obtengo 3; supongo que solo cuenta cuántos campos tiene cada usuario, pero lo que quiero es contar cuántos usuarios hay.
Entiendo que la variable "usuarios" (en JS) es una función y no una matriz per se, pero no puedo encontrar ninguna forma de interactuar directamente con la matriz.
Prueba lo siguiente:
function getUsersCount() public constant returns(uint) {
return users.length;
}
function getUser(uint index) public constant returns(uint, string, address) {
return (users[index].idNum, users[index].name, users[index].userAddress);
}
Entonces debería poder usar las declaraciones:
> var numberOfUsers = contract.usersCount();
undefined
> numberOfUsers
5
> var user0 = contract.users(0)
[123, "User 123", "0xbeefee3ad17cd9aca6fd5343a53a513685c7e0ed"]
> var user1 = contract.getUser(1)
[234, "User 234", "0xbeefee3ad17cd9aca6fd5343a53a513685c7e0ed"]
> var lastUser = arrayStruct.users(numberOfUsers-1)
undefined
> lastUser
[567, "User 567", "0xbeefee3ad17cd9aca6fd5343a53a513685c7e0ed"]
Y respondiendo al comentario de Nikhil M
, la siguiente declaración siempre devuelve 0 para mí. No sé si es una característica de diseño o un error.
> var users = contract.users.length
undefined
> users
0
La llamada a contract.usersCount()
, contract.users(x)
y contract.getUser()
no cambie los datos de la cadena de bloques y no cueste gasolina. de saludador ,
Ejecute el Greeter Para llamar a su bot, simplemente escriba el siguiente comando en su terminal:
greeter.greet();
Dado que esta llamada no cambia nada en la cadena de bloques, regresa instantáneamente y sin costo de gasolina. Deberías ver que te devuelve el saludo:
Este es el código de contrato que utilicé:
contract ArrayStruct {
struct User {
uint idNum;
string name;
address userAddress;
}
User[] public users;
function addUser(uint _idNum, string _name, address _userAddress) public returns(uint) {
users.length++;
users[users.length-1].idNum = _idNum;
users[users.length-1].name = _name;
users[users.length-1].userAddress = _userAddress;
return users.length;
}
function getUsersCount() public constant returns(uint) {
return users.length;
}
function getUser(uint index) public constant returns(uint, string, address) {
return (users[index].idNum, users[index].name, users[index].userAddress);
}
}
Deberá pagar el gas por insertar el contrato en la cadena de bloques como se muestra en el gas: 1000000
campo en la siguiente declaración:
var contract = arrayStructContract.new({
from:web3.eth.accounts[0],
data: arrayStructCompiled.ArrayStruct.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);
}
}
})
Y tendrá que pagar la gasolina cuando cambie los datos de la cadena de bloques, como se muestra gas: 500000
en las siguientes declaraciones:
contract.addUser(123, "User 123", eth.accounts[0], {
from:web3.eth.accounts[0],
data: arrayStructCompiled.ArrayStruct.code,
gas: 500000
});
contract.addUser(234, "User 234", eth.accounts[0], {
from:web3.eth.accounts[0],
data: arrayStructCompiled.ArrayStruct.code,
gas: 500000
});
contract.usersCount()
, contract.users(x)
y contract.getUser()
no cambie los datos de la cadena de bloques y no cueste gasolina.Aquí está el código que uso... probablemente solo sea una solución, pero desde la consola de mi nodo uso:
var i = 4;
var j = 0;
while (i>3) {var x = contract.users.call(j);j++;var i = x.length}
j-1
Entonces ese último j-1 debería imprimir la longitud de su lista
niksmac
var users = contract.users.length
en tu.js
archivo,Shultz