Zum Inhalt springen

Ihre erste Münze

Dieses Tutorial führt ein, wie Sie Ihre eigene Münze kompilieren, bereitstellen und prägen können (wie hier definiert), namens MoonCoin.

Installieren Sie Ihr bevorzugtes SDK aus der untenstehenden Liste:


Installieren Sie die vorkompilierte Binärdatei für die Aptos CLI.


Klonen Sie das aptos-ts-sdk Repository und erstellen Sie es:

Terminal-Fenster
git clone https://github.com/aptos-labs/aptos-ts-sdk.git
cd aptos-ts-sdk
pnpm install
pnpm build

Navigieren Sie zum TypeScript-Beispielverzeichnis:

Terminal-Fenster
cd examples/typescript/

Installieren Sie die notwendigen Abhängigkeiten:

Terminal-Fenster
pnpm install

Führen Sie das TypeScript your_coin Beispiel aus:

Terminal-Fenster
pnpm run your_coin

Die Anwendung wird abgeschlossen und gibt aus:

Terminal-Fenster
Bob's initial MoonCoin balance: 0.
Alice mints herself 100 MoonCoin.
Alice transfers 100 MoonCoin to Bob.
Bob's updated MoonCoin balance: 100.

Schritt 4.1: Das MoonCoin-Paket erstellen und veröffentlichen

Abschnitt betitelt „Schritt 4.1: Das MoonCoin-Paket erstellen und veröffentlichen“

Move-Verträge sind effektiv eine Menge von Move-Modulen, die als Paket bekannt sind. Beim Bereitstellen oder Aktualisieren eines neuen Pakets muss der Compiler mit --save-metadata aufgerufen werden, um das Paket zu veröffentlichen. Im Fall von MoonCoin sind die folgenden Ausgabedateien kritisch:

  • build/Examples/package-metadata.bcs: Enthält die mit dem Paket verknüpften Metadaten.
  • build/Examples/bytecode_modules/moon_coin.mv: Enthält den Bytecode für das moon_coin.move-Modul.

Diese werden vom Beispiel gelesen und auf der Aptos-Blockchain veröffentlicht:

Im TypeScript-Beispiel verwenden wir den Befehl aptos move build-publish-payload, um das Modul zu kompilieren und zu erstellen. Dieser Befehl erstellt den build-Ordner, der die package-metadata.bcs und den Bytecode für das moon_coin.mv-Modul enthält. Der Befehl erstellt auch eine Veröffentlichungstransaktions-Payload und speichert sie in einer JSON-Ausgabedatei, aus der wir später lesen können, um die metadataBytes und byteCode zu erhalten, um den Vertrag on-chain zu veröffentlichen.

Das Paket kompilieren:

export function compilePackage(
packageDir: string,
outputFile: string,
namedAddresses: Array<{ name: string; address: AccountAddress }>,
) {
const addressArg = namedAddresses
.map(({ name, address }) => `${name}=${address}`)
.join(" ");
// Assume-yes überschreibt automatisch die vorherige kompilierte Version, tun Sie dies nur, wenn Sie sicher sind, dass Sie die vorherige Version überschreiben möchten.
const compileCommand = `aptos move build-publish-payload --json-output-file ${outputFile} --package-dir ${packageDir} --named-addresses ${addressArg} --assume-yes`;
execSync(compileCommand);
}
compilePackage("move/moonCoin", "move/moonCoin/moonCoin.json", [
{ name: "MoonCoin", address: alice.accountAddress },
]);

Das Paket on-chain veröffentlichen:

export function getPackageBytesToPublish(filePath: string) {
// aktuelles Arbeitsverzeichnis - der Stammordner dieses Repositorys
const cwd = process.cwd();
// Zielverzeichnis - aktuelles Arbeitsverzeichnis + filePath (filePath JSON-Datei wird mit dem vorherigen compilePackage CLI-Befehl generiert)
const modulePath = path.join(cwd, filePath);
const jsonData = JSON.parse(fs.readFileSync(modulePath, "utf8"));
const metadataBytes = jsonData.args[0].value;
const byteCode = jsonData.args[1].value;
return { metadataBytes, byteCode };
}
const { metadataBytes, byteCode } = getPackageBytesToPublish(
"move/moonCoin/moonCoin.json",
);
// MoonCoin-Paket on-chain veröffentlichen
const transaction = await aptos.publishPackageTransaction({
account: alice.accountAddress,
metadataBytes,
moduleBytecode: byteCode,
});
const pendingTransaction = await aptos.signAndSubmitTransaction({
signer: alice,
transaction,
});
await aptos.waitForTransaction({ transactionHash: pendingTransaction.hash });

Das MoonCoin-Modul definiert die MoonCoin-Struktur oder den unterschiedlichen Münztyp. Zusätzlich enthält es eine Funktion namens init_module. Die init_module-Funktion wird aufgerufen, wenn das Modul veröffentlicht wird. In diesem Fall initialisiert MoonCoin den MoonCoin-Münztyp als ManagedCoin, der vom Besitzer des Kontos verwaltet wird.

module MoonCoin::moon_coin {
struct MoonCoin {}
fun init_module(sender: &signer) {
aptos_framework::managed_coin::initialize<MoonCoin>(
sender,
b"Moon Coin",
b"MOON",
6,
false,
);
}
}

Münzen haben mehrere Grundelemente:

  • Prägen: Neue Münzen erstellen.
  • Verbrennen: Münzen löschen.
  • Einfrieren: Ein Konto daran hindern, Münzen in CoinStore zu speichern.
  • Registrieren: Eine CoinStore-Ressource auf einem Konto zum Speichern von Münzen erstellen.
  • Übertragen: Münzen aus CoinStore abheben und einzahlen.

Sobald ein Münztyp auf der Aptos-Blockchain veröffentlicht wurde, kann die Entität, die diesen Münztyp veröffentlicht hat, ihn initialisieren:

module 0x1::coin {
public fun initialize<CoinType>(
account: &signer,
name: string::String,
symbol: string::String,
decimals: u8,
monitor_supply: bool,
): (BurnCapability<CoinType>, FreezeCapability<CoinType>, MintCapability<CoinType>) {
let account_addr = signer::address_of(account);
assert!(
coin_address<CoinType>() == account_addr,
error::invalid_argument(ECOIN_INFO_ADDRESS_MISMATCH),
);
assert!(
!exists<CoinInfo<CoinType>>(account_addr),
error::already_exists(ECOIN_INFO_ALREADY_PUBLISHED),
);
let coin_info = CoinInfo<CoinType> {
name,
symbol,
decimals,
supply: if (monitor_supply) { option::some(optional_aggregator::new(MAX_U128, false)) } else { option::none() },
};
move_to(account, coin_info);
(BurnCapability<CoinType>{ }, FreezeCapability<CoinType>{ }, MintCapability<CoinType>{ })
}
}

Dies stellt sicher, dass dieser Münztyp nie zuvor initialisiert wurde. Beachten Sie die Überprüfung in Zeilen 10 und 15, um sicherzustellen, dass der Aufrufer von initialize derselbe ist, der tatsächlich dieses Modul veröffentlicht hat, und dass keine CoinInfo auf seinem Konto gespeichert ist. Wenn beide Bedingungen erfüllt sind, wird eine CoinInfo gespeichert und der Aufrufer erhält Fähigkeiten zum Verbrennen, Einfrieren und Prägen.


Um eine Münze zu verwenden, muss eine Entität eine CoinStore dafür auf ihrem Konto registrieren:

public entry fun registerCoinType(account: &signer) {

MoonCoin verwendet ManagedCoin, das einen Entry-Function-Wrapper bereitstellt: managed_coin::register. Hier ist ein Beispielskript für die Registrierung:

script {
fun register(account: &signer) {
aptos_framework::managed_coin::register<MoonCoin::moon_coin::MoonCoin>(account)
}
}

Das Prägen von Münzen erfordert die Präge-Fähigkeit, die während der Initialisierung erzeugt wurde. Die Funktion mint (siehe unten) nimmt diese Fähigkeit und einen Betrag entgegen und gibt eine Coin<T>-Struktur zurück, die diesen Betrag an Münzen enthält. Wenn die Münze das Angebot verfolgt, wird es aktualisiert.

module 0x1::coin {
public fun mint<CoinType>(
amount: u64,
_cap: &MintCapability<CoinType>,
): Coin<CoinType> acquires CoinInfo {
if (amount == 0) {
return zero<CoinType>()
};
let maybe_supply = &mut borrow_global_mut<CoinInfo<CoinType>>(coin_address<CoinType>()).supply;
if (option::is_some(maybe_supply)) {
let supply = option::borrow_mut(maybe_supply);
optional_aggregator::add(supply, (amount as u128));
};
Coin<CoinType> { value: amount }
}
}

ManagedCoin macht dies einfacher, indem es eine Entry-Funktion managed_coin::mint bereitstellt.


Aptos bietet mehrere Bausteine zur Unterstützung von Münzübertragungen:

  • coin::deposit<CoinType>: Ermöglicht es jeder Entität, eine Münze in ein Konto einzuzahlen, das bereits coin::register<CoinType> aufgerufen hat.
  • coin::withdraw<CoinType>: Ermöglicht es jeder Entität, einen Münzbetrag von ihrem Konto zu extrahieren.
  • aptos_account::transfer_coins<CoinType>: Münzen eines bestimmten CoinType an einen Empfänger übertragen.