es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Recupere una estructura/lista de estructuras como vistas desde un contrato inteligente.

Estoy tratando de obtener los datos de una estructura única y los datos de una lista de esta estructura en los métodos de vista de un contrato inteligente.
La estructura sería algo como:

#[derive(NestedEncode, NestedDecode, TopEncode, TopDecode, TypeAbi, Clone)]
pub struct Stream<m: managedtypeapi=""> {
    pub id: u64,
    pub payment: BigUint<m>,
    pub enddate: u64,
    pub receiver: ManagedAddress<m>,
}

Una vista única sería como:

#[view(getStream)]
fn get_stream(&self, id: u64) -> Stream<self::api> {
    let payment = self.payment(id.clone()).get().clone();
    let enddate = self.enddate(id.clone()).get().clone();
    let receiver = self.receiver(id.clone()).get().clone();
    Stream {
        id,
        payment,
        enddate,
        receiver,
    }
}

En las pruebas de mandos, esperaría algo como:

"expect": {
    "out": [
        "u64:1",
        "100,000,000,000",
        "u64:200,000",
        "address:my_address"
    ]
},

Pero en la prueba siempre obtengo un resultado de bytes sin codificar como:

Want: ["u64:1", "100,000,000,000", "u64:200,000", "address:my_address"]. Have: [0x000000000000000100000005174876e8000000000000030d406d795f616464726573735f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f]

También probé diferentes tipos de retorno como ManagedMultiResultVec, ManagedMultiResultVec o MultiResult con ManagedVec en general. Pero todos parecen producir este resultado para mí.

Tampoco pude descubrir cómo puedo recuperar y decodificar dicho resultado en una dApp en TypeScript con la librería erdjs.

¿Alguien puede decirme qué me he perdido?

Tags:  

Answer

  1. Avatar for davy.ai

    Para obtener los datos de una sola estructura y los datos de una lista de esta estructura en métodos de vista en un contrato inteligente, puedes utilizar el siguiente código:

    Para vista individual:

    #[view(get_stream)]
    fn get_stream(&self, id: u64) -> Stream<self::api> {
        let payment = self.payment(id.clone()).get().clone();
        let enddate = self.enddate(id.clone()).get().clone();
        let receiver = self.receiver(id.clone()).get().clone();
        Stream {
            id,
            payment,
            enddate,
            receiver,
        }
    }
    

    Para vista de lista:

    #[view(get_all_streams)]
    fn get_all_streams(&self) -> Vec<><self::api>> {
        self.streams()
            .iter()
            .map(|(id, stream)| {
                let payment = stream.payment.get().clone();
                let enddate = stream.enddate.get().clone();
                let receiver = stream.receiver.get().clone();
                Stream {
                    id: id.clone(),
                    payment,
                    enddate,
                    receiver,
                }
            })
            .collect()
    }
    

    Para decodificar el resultado en una dApp de TypeScript con la librería erdjs, puedes utilizar el ProxyProvider para interactuar con el contrato inteligente y utilizar los métodos contract.functions.getStream(id: number) o contract.functions.getAllStreams() para obtener los datos. Aquí tienes un ejemplo de código:

    “`typescript
    import { ProxyProvider, Contract } from ‘@elrondnetwork/erdjs’;

    async function getSingleStream(id: number, contract: Contract) {
    const stream = await contract.functions.getStream(id);
    console.log(stream); // Esto imprimirá el objeto de flujo decodificado
    }

    async function getAllStreams(contract: Contract) {
    const streams = await contract.functions.getAllStreams();
    console.log(streams); // Esto imprimirá la lista de flujos decodificada
    }

    const provider = new ProxyProvider(‘https://devnet-gateway.elrond.com’);
    const contract = new Contract({ address: ‘DIRECCIÓN_DEL_CONTRATO’, provider });

    // Para obtener un solo flujo
    getSingleStream(1, contract);

    // Para obtener todos los flujos
    getAllStreams(contract);
    “`

Comments are closed.