Aller au contenu

Pour Commencer

Aperçu

Alephium propose plusieurs outils et packages pour vous aider à construire vos dApps.

Ce guide vous aidera à installer notre configuration recommandée.

Prérequis

  • Écrire du code en Typescript
  • Opérer dans un terminal
  • Version de nodejs >= 16 installée
  • Version de npm >= 8 installée

Info

Si vous rencontrez des lenteurs avec npm et npx, envisagez d'essayer bun et bunx.

Créez un nouveau projet de dApp

Pour créer le projet de tutoriel, ouvrez un nouveau terminal et exécutez :

Text Only
npx @alephium/cli@latest init alephium-tutorial

Cela créera un nouveau répertoire alephium-tutorial et initialisera un projet d'exemple à l'intérieur de ce répertoire.


Lancez le réseau de développement local

Pour compiler et tester vos contrats, il est nécessaire de lancer un réseau de développement local, et vous pouvez suivre ce guide pour lancer un devnet.

Votre nouveau réseau est maintenant lancé en utilisant cette configuration et les adresses générées dans 4 groupes avec suffisamment de ALPHs à des fins de test.

Le SDK Typescript est ensuite capable d'interagir avec le réseau via des points de terminaison REST.


Compilez votre contrat

Ensuite, changez l'espace de travail vers le projet de tutoriel :

Text Only
cd alephium-tutorial

Jetez un œil dans le dossier contracts/, vous pouvez trouver token.ral et withdraw.ral:

token.ral
Rust
import "std/fungible_token_interface"

// Définit un contrat nommé `TokenFaucet`.
// Un contrat est une collection de champs (son état) et de fonctions.
// Une fois déployé, un contrat réside à une adresse spécifique sur la blockchain Alephium.
// Les champs du contrat sont stockés en permanence dans le stockage du contrat.
// Un contrat peut émettre une quantité initiale de jetons lors de son déploiement.
Contract TokenFaucet(
    symbol: ByteVec,
    name: ByteVec,
    decimals: U256,
    supply: U256,
    mut balance: U256
) implements IFungibleToken {

    // Les événements permettent de journaliser les activités sur la blockchain.
    // Les clients Alephium peuvent écouter les événements afin de réagir aux changements d'état des contrats.
    event Withdraw(to: Address, amount: U256)

    enum ErrorCodes {
        InvalidWithdrawAmount = 0
    }

    /// Une fonction publique qui renvoie l'approvisionnement initial du jeton du contrat.
    // Notez que le champ doit être initialisé avec la quantité de jeton émise.
    pub fn getTotalSupply() -> U256 {
        return supply
    }

    // Une fonction publique qui renvoie le symbole du jeton.
    pub fn getSymbol() -> ByteVec {
        return symbol
    }

    // Une fonction publique qui renvoie le nom du jeton.
    pub fn getName() -> ByteVec {
        return name
    }

    // Une fonction publique qui renvoie le nombre de décimales du jeton.
    pub fn getDecimals() -> U256 {
        return decimals
    }

    // Une fonction publique qui renvoie le solde actuel du contrat.
    pub fn balance() -> U256 {
        return balance
    }

    // Une fonction publique qui transfère des jetons à quiconque l'appelle.
    // La fonction est annotée avec `updateFields = true` car elle modifie les champs du contrat.
    // La fonction est annotée comme utilisant des actifs de contrat car elle le fait.
    @using(assetsInContract = true, updateFields = true, checkExternalCaller = false)
    pub fn withdraw(amount: U256) -> () {
        // Les événements de débogage peuvent être utiles pour l'analyse des erreurs
        emit Debug(`The current balance is ${balance}`)

        // Assurez-vous que le montant est valide
        assert!(amount <= 2, ErrorCodes.InvalidWithdrawAmount)
        / Les fonctions suffixées par `!` sont des fonctions intégrées.
        transferTokenFromSelf!(callerAddress!(), selfTokenId!(), amount)
        // Ralph n'autorise pas les débordements.
        balance = balance - amount

        // Émettre l'événement défini précédemment.
        emit Withdraw(callerAddress!(), amount)
    }
}
withdraw.ral
Rust
// Définit un script de transaction.
// Un script de transaction est un morceau de code pour interagir avec les contrats sur la blockchain.
// Les scripts de transaction peuvent utiliser les actifs d'entrée des transactions en général.
// Un script est jetable et ne sera exécuté qu'une seule fois avec la transaction conteneur.
TxScript Withdraw(token: TokenFaucet, amount: U256) {
    // Appelez la fonction de retrait du contrat de jeton.
    token.withdraw(amount)
}

Pour compiler vos contrats, exécutez :

Text Only
npx @alephium/cli@latest compile

Les artefacts compilés se trouvent dans le répertoireartifacts.

Cette commande génère également du code TypeScript basé sur les artefacts compilés. Le code TypeScript généré se trouve dans le répertoire artifacts/ts. Vous pouvez interagir plus facilement avec la blockchain Alephium en utilisant le code TypeScript généré.


Testez votre contrat

Le projet exemple est livré avec des tests test/unit/token.test.ts pour votre contrat :

token.test.ts
TypeScript
import { web3, Project, TestContractParams, addressFromContractId, AssetOutput, DUST_AMOUNT } from '@alephium/web3'
import { expectAssertionError, randomContractId, testAddress, testNodeWallet } from '@alephium/web3-test'
import { deployToDevnet } from '@alephium/cli'
import { TokenFaucet, TokenFaucetTypes, Withdraw } from '../artifacts/ts'

describe('unit tests', () => {
  let testContractId: string
  let testTokenId: string
  let testContractAddress: string
  let testParamsFixture: TestContractParams<TokenFaucetTypes.Fields, { amount: bigint }>

  // Nous initialisons les variables de fixture avant tous les tests
  beforeAll(async () => {
    web3.setCurrentNodeProvider('http://127.0.0.1:22973')
    await Project.build()
    testContractId = randomContractId()
    testTokenId = testContractId
    testContractAddress = addressFromContractId(testContractId)
    testParamsFixture = {
      // une adresse aléatoire où le contrat de test réside dans les tests
      address: testContractAddress,
      // actifs possédés par le contrat de test avant un test
      initialAsset: { alphAmount: 10n ** 18n, tokens: [{ id: testTokenId, amount: 10n }] },
      // état initial du contrat de test
      initialFields: {
        symbol: Buffer.from('TF', 'utf8').toString('hex'),
        name: Buffer.from('TokenFaucet', 'utf8').toString('hex'),
        decimals: 18n,
        supply: 10n ** 18n,
        balance: 10n
      },
      // arguments pour tester la fonction cible du contrat de test
      testArgs: { amount: 1n },
      // actifs possédés par l'appelant de la fonction
      inputAssets: [{ address: testAddress, asset: { alphAmount: 10n ** 18n } }]
    }
  })
  // Voir plus de tests dans `test/unit/token.test.ts`
})

Vous pouvez les exécuter avec :

Text Only
npm run test

or

Text Only
npx @alephium/cli@latest test

Déployez votre contrat

Ensuite, pour déployer le contrat, nous utiliserons Alephium CLI et un script de déploiement scripts/0_deploy_faucet.ts:

0_deploy_faucet.ts
TypeScript
import { Deployer, DeployFunction, Network } from '@alephium/cli'
import { Settings } from '../alephium.config'
import { TokenFaucet } from '../artifacts/ts'

// Cette fonction de déploiement sera appelée automatiquement par l'outil de déploiement cli
// Notez que les scripts de déploiement doivent être préfixés par des nombres (à partir de 0)
const deployFaucet: DeployFunction<Settings> = async (
  deployer: Deployer,
  network: Network<Settings>
): Promise<void> => {
  // Obtenir les paramètres
  const issueTokenAmount = network.settings.issueTokenAmount
  const result = await deployer.deployContract(TokenFaucet, {
    // La quantité de jetons à émettre
    issueTokenAmount: issueTokenAmount,
    // Les états initiaux du contrat de la fontaine à jetons
    initialFields: {
      symbol: Buffer.from('TF', 'utf8').toString('hex'),
      name: Buffer.from('TokenFaucet', 'utf8').toString('hex'),
      decimals: 18n,
      supply: issueTokenAmount,
      balance: issueTokenAmount
    }
  })
  console.log('Token faucet contract id: ' + result.contractInstance.contractId)
  console.log('Token faucet contract address: ' + result.contractInstance.address)
}

export default deployFaucet

Vous pouvez l'exécuter en utilisant :

Text Only
npx @alephium/cli@latest deploy

Cela déploiera la fontaine à jetons sur le groupe 0 du devnet. Pour déployer sur testnet (ou tout autre réseau), mettez à jour votre alephium.config.ts et utilisez l'option --network:

Text Only
npx @alephium/cli@latest deploy --network testnet

Interagir avec le contrat déployé

Maintenant, vous pouvez construire le code source src/token.ts:

token.ts
TypeScript
import { Deployments } from '@alephium/cli'
import { DUST_AMOUNT, web3, Project } from '@alephium/web3'
import { testNodeWallet } from '@alephium/web3-test'
import configuration from '../alephium.config'
import { TokenFaucet, Withdraw } from '../artifacts/ts'

async function withdraw() {
  web3.setCurrentNodeProvider('http://127.0.0.1:22973')
  // Compiler les contrats du projet s'ils ne sont pas compilés
  Project.build()

  // Attention : le portefeuille de test est utilisé à des fins de démonstration
  const signer = await testNodeWallet()

  const deployments = await Deployments.load(configuration, 'devnet')

  // Le portefeuille de test contient quatre comptes avec un dans chaque groupe d'adresses
  // Le portefeuille appelle la fonction de retrait pour tous les groupes d'adresses
  for (const account of await signer.getAccounts()) {
    // Définir un compte actif pour préparer et signer les transactions
    await signer.setSelectedAccount(account.address)
    const accountGroup = account.group

    // Charger les métadonnées du contrat déployé dans le bon groupe
    const deployed = deployments.getDeployedContractResult(accountGroup, 'TokenFaucet')
    if (deployed === undefined) {
      console.log(`The contract is not deployed on group ${account.group}`)
      continue
    }
    const tokenId = deployed.contractInstance.contractId
    const tokenAddress = deployed.contractInstance.address

    // Soumettre une transaction pour utiliser le script de transaction
    await Withdraw.execute(signer, {
      initialFields: { token: tokenId, amount: 1n },
      attoAlphAmount: DUST_AMOUNT
    })

    const faucet = TokenFaucet.at(tokenAddress)
    // Récupérer le dernier état du contrat de jeton
    const state = await faucet.fetchState()
    console.log(JSON.stringify(state.fields, null, '  '))
  }
}

withdraw()

Exécutez simplement :

Text Only
npm run build

et interagissez avec la fontaine à jetons déployée :

Text Only
node dist/src/token.js

Connectez-vous aux portefeuilles

Les dApps nécessitent une intégration de portefeuille pour que les utilisateurs de la dApp puissent s'authentifier et interagir avec la blockchain Alephium, comme la signature de transactions. Actuellement, les dApps peuvent être intégrées à la fois avec Extension Wallet et WalletConnect. Veuillez vous référer aux pages respectives pour plus de détails.


En savoir plus