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 :
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 :
Jetez un œil dans le dossier contracts/
, vous pouvez trouver token.ral
et withdraw.ral
:
token.ral
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
// 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 :
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
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 :
or
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
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 :
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
:
Interagir avec le contrat déployé
Maintenant, vous pouvez construire le code source src/token.ts
:
token.ts
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 :
et interagissez avec la fontaine à jetons déployée :
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
- Pour en savoir plus sur l'écosystème, veuillez visiter l'aperçu de l'écosystème.
- Pour en savoir plus sur le SDK web3, veuillez visiter le guide du SDK web3.
- Pour en savoir plus sur le langage Ralph, veuillez visiter le guide de Ralph.
- Pour apprendre à construire une dApp Nextjs, veuillez visiter Construire une dApp avec Nextjs.