He definido un contrato que me gustaría usar para almacenar los detalles del usuario, es decir, un campo para almacenar el hash de su documento y un campo para almacenar la dirección de un bloque que tiene otra información del usuario. Utilicé la siguiente estructura para lo mismo:
pragma solidity ^0.4.17;
contract UserDetails {
struct User {
string fileHash;
address addr;
}
User[] userArr;
function addUserDetail(string hash,address blockAddress) public returns (bool) {
User memory usr;
usr = User({fileHash:hash, addr:blockAddress});
userArr.push(usr);
}
}
1) ¿Es esta la estructura de datos correcta para este propósito?
2) ¿Cómo pasar los argumentos a la función addUserDetail al implementar el contrato usando web3?
Lo modificaría un poco.
Lo primero que salta a la vista es que tiene la dirección de usuario dentro de la estructura. Eso será redundante porque querrá realizar un seguimiento de las claves de alguna otra manera. Querrá buscar por clave, por ejemplo. En eso, ya sabrás la clave que quieres buscar, ¿verdad? No es necesario almacenarlo nuevamente dentro de cada estructura.
Me di cuenta de que está almacenando hashes, así que asumo que habrá algo de almacenamiento de metadatos fuera de la cadena. Aun así, es posible que (generalmente) tenga algunos campos adicionales en la cadena. ¿Cómo saber la diferencia? Si el contrato necesita acceso a un campo para realizar alguna lógica dentro del contrato, entonces el campo pertenece a la estructura.
Hice pública la lista de claves para que un cliente pueda enumerar las claves y agregué una función para obtener un conteo rápido, porque generar un error es una forma desagradable de descubrir la longitud de la lista, en mi opinión .
pragma solidity ^0.4.17;
contract UserDetails {
struct UserStruct {
string fileHash;
uint userListPointer;
// you may continue with other non-key fields that are needed for contract logic
}
// unique identifiers
address[] public userList;
mapping(address=>UserStruct) public userStructs;
function isUser(address userAddress) public view returns(bool isIndeed) {
if(userList.length ==0) return false;
return userList[userStructs[userAddress].userListPointer] == userAddress;
}
function addUserDetail(string hash,address userAddress) public returns (bool) {
require(!isUser(userAddress));
UserStruct memory usr;
usr.fileHash = hash;
usr.userListPointer = userList.push(userAddress) - 1;
userStructs[userAddress] = usr;
}
function getUserCount() public view returns(uint count) {
return userList.length;
}
}
Puede encontrar algunos patrones relacionados aquí: ¿ Existen patrones de almacenamiento simples y bien resueltos para Solidity?
Y una explicación completa que casualmente usa Usuarios para el ejemplo aquí: https://medium.com/@robhitchens/solidity-crud-part-1-824ffa69509a
Espero eso ayude.
Anubhav Gupta
Anubhav Gupta
Anubhav Gupta
Rob Hitchens
Anubhav Gupta
Rob Hitchens
address of a block
es difícil de entender. Si quiere decirURI of an object
almacenado en otro lugar, entonces sí, este es un buen enfoque.Anubhav Gupta