Contrato – Parte 6

To Share and +4 nLEARNs

Após criar uma eleição, o próximo passo será adicionar um candidato a mesma.

Antes de adicionarmos um candidato à uma eleição, devemos validar se ele já não existe, portanto, vamos criar uma função de suporte para isso:

verifyCandidateExistence(candidateId: string, electionId: number): boolean {
  const candidates = this.elections.get(String(electionId)).candidates

  if (candidates === null) {
    return false
  } else {
    const candidate = candidates.filter(({ accountId }) => {
      return accountId === candidateId
    })
    
    const exists = candidate.length > 0

    return exists
  }
}

No fim, seu código deve ficar assim:

import { NearBindgen, UnorderedMap, assert, call, initialize, near, view} from 'near-sdk-js';
import { Candidate, Election } from './model';

@NearBindgen({})
class VotingNear {
  electionsCounterId: number
  elections: UnorderedMap<Election> = new UnorderedMap<Election>("elections")

  @initialize({})
  init() {
    this.electionsCounterId = 0
  }

  @view({})
  get_all_elections() {
    return this.elections.toArray().reverse() // reverse() is being called in order to get from newest to oldest
  }

  @view({})
  get_election({ electionId }: { electionId: number }): Election {
    return this.elections.get(String(electionId))
  }

  @call({})
  create_election({ endsAt, name, startsAt }: Election): void {
    const election = new Election(
      { 
        id:

 this.electionsCounterId,
        startsAt: BigInt(Number(startsAt) * 10 ** 6), // Convertir milisegundos de JavaScript a nanosegundos estándar del blockchain NEAR
        endsAt: BigInt(Number(endsAt) * 10 ** 6), // Convertir milisegundos de JavaScript a nanosegundos estándar del blockchain NEAR
        name, 
        candidates: [], 
        voters: [],
        totalVotes: 0 
      }
    )
    this.elections.set(String(this.electionsCounterId), election)


    this.electionsCounterId += 1
  }

  @call({})
  add_candidate_to_election({ accountId, electionId }: { accountId: string, electionId: number }): void {
    const electionToAddCandidate = this.elections.get(String(electionId))
    assert(electionToAddCandidate !== null, "Election not found.")

    const candidateAlreadyExists = this.verifyCandidateExistence(accountId, electionId)
    assert(!candidateAlreadyExists, "Candidate already exists. Reverting call.")

    const candidate = new Candidate({ accountId, totalVotes: 0 })

    electionToAddCandidate.candidates.push(candidate)
    this.elections.set(String(electionId), electionToAddCandidate)
  }

  verifyCandidateExistence(candidateId: string, electionId: number): boolean {
    const candidates = this.elections.get(String(electionId)).candidates

    if (candidates === null) {
      return false
    } else {
      const candidate = candidates.filter(({ accountId }) => {
        return accountId === candidateId
      })
      
      const exists = candidate.length > 0
  
      return exists
    }
  }
}

Duas coisas importantes para ressaltar aqui são o método *assert* e a forma que criamos a função suporte:
– O assert vai verificar uma condição, se retornar *true* a função continuará sua execução, se retornar false, ela irá encerrar sua execução, devolvendo um erro.
– Perceba que a função *verifyCandidateExistence* não é criado com um decorator anterior a ela. Isso ocorre porque ela é apenas usada internamente e não será um método de nosso contrato.

Perceba que para essa função usamos a classe Candidate, assim como usamos a classe Election para a tipagem da nossa variável *elections* e para a criação da mesma. Esse é o motivo de termos exportado elas do nosso *model.ts*

Generate comment with AI 2 nL
Scroll to Top