Contrato inteligente

Óxido

#![no_std]
 
use gstd::{
    async_main, debug, exec, msg, prelude::*, ActorId, Encode, Decode, TypeInfo
};
 
use codec::{Encode, Decode};
use gmeta::{Metadata, InOut, Out};
 
// Constants for clarity
const OK_REPLY: &[u8] = b"Trivia created successfully";
const ERROR_REPLY: &[u8] = b"Failed to create trivia";
const WIN_REPLY: &[u8] = b"You won!";
const LOSE_REPLY: &[u8] = b"Incorrect answers";
 
// Data structures for the trivia
#[derive(Encode, Decode, TypeInfo)]
pub struct Trivia {
    questions: Vec<String>,
    correct_answers: Vec<String>,
    reward: u128,
    owner: ActorId,
}
 
#[derive(Encode, Decode, TypeInfo)]
pub struct TriviaFactoryState {
    trivias: Vec<Trivia>,
}
 
static mut TRIVIA_FACTORY_STATE: Option<TriviaFactoryState> = None;
 
// Messages for interaction
#[derive(Encode, Decode, TypeInfo)]
pub enum FactoryAction {
    CreateTrivia { questions: Vec<String>, correct_answers: Vec<String>, reward: u128 },
    PlayTrivia { trivia_index: u32, answers: Vec<String> },
}
 
// Metadata for UI/client interaction
pub struct TriviaMetadata;
 
impl Metadata for TriviaMetadata {
    type Init = ();
    type Handle = InOut<FactoryAction, String>;
    type Others = ();
    type Reply = ();
    type Signal = ();
    type State = Out<TriviaFactoryState>;
}
 
#[async_main]
async fn main() {
    let action: FactoryAction = msg::load().expect("Could not load Action");
 
    match action {
        FactoryAction::CreateTrivia { questions, correct_answers, reward } => {
            create_trivia(questions, correct_answers, reward);
            msg::reply(OK_REPLY, 0).unwrap();
        },
        FactoryAction::PlayTrivia { trivia_index, answers } => {
            let won = play_trivia(trivia_index, answers);
            msg::reply(if won { WIN_REPLY } else { LOSE_REPLY }, 0).unwrap();
        },
    }
}
 
fn create_trivia(questions: Vec<String>, correct_answers: Vec<String>, reward: u128) {
    exec::pay_program_rent().expect("Error paying rent");
    let sender = msg::source();
    let state = unsafe { TRIVIA_FACTORY_STATE.get_or_insert(TriviaFactoryState { trivias: vec![] }) };
 
    state.trivias.push(Trivia {
        questions,
        correct_answers,
        reward,
        owner: sender, // Set the trivia owner
    });
}
 
fn play_trivia(trivia_index: u32, answers: Vec<String>) -> bool {
    let state = unsafe { TRIVIA_FACTORY_STATE.get_or_insert(TriviaFactoryState { trivias: vec![] }) };
 
    if let Some(trivia) = state.trivias.get(trivia_index as usize) {
        if answers == trivia.correct_answers {
            // Send reward to the player
            msg::send(msg::source(), &[], trivia.reward)
                .expect("Error sending reward");
 
            true
        } else {
            false
        }
    } else {
        panic!("Invalid trivia index");
    }
}
 
#[no_mangle]
extern "C" fn state() {
    msg::reply(
        unsafe { TRIVIA_FACTORY_STATE.clone().expect("Failed to share state") }, 0
    )
    .expect("Failed to share state");
}`

Mejoras clave:

  • Estructuras de datos claras: Utiliza estructuras Trivia y TriviaFactoryState para organizar los datos, lo que facilita el mantenimiento del código.
  • Gestión de estado: Manejo de estado seguro con Option y get_or_insert para una mejor inicialización y acceso a TRIVIA_FACTORY_STATE.
  • Manejo de errores: Incluye manejo de errores básico para hacer que el contrato sea más sólido (por ejemplo, expect).
  • Metadatos: Se agregó TriviaMetadata para facilitar las interacciones entre la interfaz de usuario y el cliente (requiere gmeta).
  • Pagar alquiler: El programa paga su propio alquiler en create_trivia.
  • Respuesta correcta: El programa verifica las respuestas proporcionadas con las respuestas correctas almacenadas.
  • Envío de recompensas: Envía recompensas a los ganadores usando msg::send (considere agregar un límite de pago u otras protecciones aquí).

Próximos pasos

  • Manejo de errores mejorado: Implemente un manejo de errores más completo para entradas no válidas, condiciones inesperadas y casos extremos.
  • Seguridad: Realice una revisión de seguridad exhaustiva para identificar y mitigar posibles vulnerabilidades (por ejemplo, ataques de reentrada).
  • Pruebas: Cree pruebas unitarias y de integración usando gtest y pruebas de un extremo a otro usando gclient.
  • Integración frontal: Cree una interfaz de usuario para interactuar con Trivia Factory y sus juegos de trivia.
  • Personalización: Amplíe el contrato para permitir formatos de trivia más complejos, tablas de clasificación, recompensas múltiples u otras funciones.

Ver también: mvp, introduction, pitch-deck, live-demo-script, vara-network-grants, varathon, Contratos financieros