En mi contrato tengo un mapeo como estemapping(uint => myStruct)
Tengo una check
función donde doy un uint id
y quiero obtener toda la información en la estructura (hay cadenas, direcciones, uints, ...) con una call
función en mi truffle app.js
.
¿Cuál es la mejor manera de hacer eso? ¿Puedo convertir cada campo en una cadena y enviar una matriz de cadenas? ¿Debo hacer un getter separado para cada campo y usar tantas call
funciones?
Por ahora solo devuelvo struct y obtengoinvalid solidity type!: tuple
No necesita una función de solidez adicional para obtener la información de una estructura. Puede llamar a la estructura directamente usando web3.
Ayuda si tiene una función en el contrato para obtener la cantidad de tokens; de lo contrario, podría quedarse atrapado usando while en lugar de for. Supongamos que tiene una función para darle struct.length
var OwnableList = [];
//to get one struct entry you do this.
function getStructData(tokenId) {
myContract.Ownables(tokenId, function(error, details) {
if(details == undefined) {
return false;
} else {
var name = details[0];
var creator = details[1];
var currentOwner = details[2];
var isDestructible = details[3];
var price = parseInt(details[4]);
OwnableList.push({name: name, creator: creator, currentOwner: currentOwner, isDestructible: isDestructible, price: price});
})
return true;
}
}
//to get all struct entrys you do this
function dumpStructData() {
myContract.totalOwnables(function(error, total) {
for(i=0; i<parseInt(total); i++) {
getStructData(i);
}
}
}
//now you can just read the struct
function showStruct() {
console.log(JSON.stringify(OwnableList);
}
Aparentemente se malinterpretó mi pregunta, pero resolví el problema con la ayuda de Mikko Ohtamaa en los comentarios.
Por alguna razón, no me di cuenta de que podía devolver múltiples variables (¡y de diferentes tipos!). Una vez que sabes que puedes hacer esto, no hay ningún problema. Javascript lo maneja muy bien.
Mi solución se ve algo así:
contract myContract {
struct Ownable {
string name;
address creator;
address currentOwner;
bool isDestructible;
uint price;
}
mapping (uint => Ownable) public Ownables;
function getOwnableInfo(uint OwnableId) public view returns (string, address, address, bool, uint){
Ownable o = Ownables[OwnableId];
return (o.name, o.creator, o.currentOwner, o.isDestructible, o.price);
}
/.../
}
Y en la trufa correspondiente, call
devolverá un array con las variables de la devolución en orden:
myContractInstance.getOwnableInfo.call(ownableId).then((resultArray => {
name = resultArray[0];
creator = resultArray[1];
currentOwner = resultArray[2];
/.../
});
Notas:
Ownable o = Ownables[OwnableId];
, lo hice para aumentar la legibilidad, no creo que sea útil o algo bueno en absoluto.resultArray[4].toNumber()
para que JavaScript pueda manejarlo.la mejor manera de agregar algo a una estructura y obtener todos los registros es:
pragma solidity ^0.4.17;
contract test {
struct Record {
string name;
string homeAddress;
}
Record[] public records;
function AddRecord(string Address , string Name) public {
Record memory newRec = Record({
name : Name,
homeAddress : Address
});
records.push(newRec);
}
function recordsArrayLength() public view returns(uint256){
return records.length;
}
}
y en tu ui usa este código:
primero use let len = await test.methods.recordsArrayLength().call()
y obtenga la length
matriz de registros y luego presione este código:
let records = []
for(let i=0;i<len;i++){
records.push(await test.methods.records(i))
}
y ahora tienes toda la estructura
Es tangencial a su pregunta, pero una de las mejores formas de organizar los datos es una estructura asignada con un índice de claves. Esto hace posible acceder a un registro en particular o verificar su existencia sin saber en qué fila está y sin buscar en una lista. El índice es una lista desordenada de claves que permite contar las claves y enumerar las claves que existen.
mapping(bytes32 => RecordStruct) public recordStructs;
bytes32 public recordKeys;
Eche un vistazo aquí para ver algunas variantes, detalles de implementación y discusión de las limitaciones y ventajas de varios enfoques.
¿Existen patrones de almacenamiento sencillos y bien resueltos para Solidity?
Además, aunque no se muestra en los ejemplos, los emisores de eventos pueden hacer que el estado de almacenamiento sea evidente para los clientes de software. Con registros de eventos completos, se puede redactar el contrato asumiendo que los clientes conocen el estado completo en todo momento. Esto reduce considerablemente las preocupaciones en la cadena.
Espero eso ayude.
mapping(uint => myStruct)
estructuras almacenadas por número y la pregunta es sobre migrar a una matriz (también por número). Quiero recuperar por clave (por ejemplo, "ORD002" o "0x123...") y no quiero buscar. También quiero una lista y un conteo.call
con truffle para obtener toda esa información.
kaki maestro del tiempo
return ( struct.member1,struct.member2)
mikko ohtamaa
Cabra teletransportadora