Voraussetzungen
- Node.js 16+
- Vertrautheit mit Ethereum-Entwicklung
- Eine Wallet mit Testnet-Tokens (siehe Testnet-Chain-Details)
Vertragsvorbereitung
Der folgende Beispielvertrag wird in diesem Leitfaden verwendet:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
contract SimpleStorage {
string private storedData;
address public owner;
event DataStored(string data, address indexed by);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor(string memory initialData) {
storedData = initialData;
owner = msg.sender;
emit DataStored(initialData, msg.sender);
}
modifier onlyOwner() {
require(msg.sender == owner, "Only owner can perform this action");
_;
}
function setData(string memory data) public onlyOwner {
storedData = data;
emit DataStored(data, msg.sender);
}
function getData() public view returns (string memory) {
return storedData;
}
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0), "New owner cannot be zero address");
emit OwnershipTransferred(owner, newOwner);
owner = newOwner;
}
}
Mit Foundry deployen
Foundry ist ein schnelles, Rust-basiertes Toolkit für die Ethereum-Entwicklung.
-
Foundry installieren:
curl -L https://foundry.paradigm.xyz | bash
Sie müssen ggf. Ihre .bashrc- oder .zshrc-Datei sourcen.
-
Ein neues Foundry-Projekt einrichten:
foundryup
forge init my-plasma-project
cd my-plasma-project
-
foundry.toml mit Plasma-Testnet-Einstellungen aktualisieren:
[profile.default]
src = "src"
out = "out"
libs = ["lib"]
solc_version = "0.8.28"
optimizer = true
optimizer_runs = 200
[rpc_endpoints]
plasma_testnet = "https://testnet-rpc.plasma.to"
-
Eine
.env-Datei im Projekt-Root erstellen:
PRIVATE_KEY=your_private_key_here
RPC_URL=https://testnet-rpc.plasma.to
-
Die Umgebungsvariablen laden:
-
Den Vertragscode als
src/SimpleStorage.sol speichern und dann deployen:
forge create src/SimpleStorage.sol:SimpleStorage \
--rpc-url $RPC_URL \
--private-key $PRIVATE_KEY \
--constructor-args "Hello, Plasma!"
Foundry gibt den Hash der Deployment-Transaktion und die Vertragsadresse aus:
[⠊] Compiling...
[⠢] Compiling 1 files with Solc 0.8.28
[⠆] Solc 0.8.28 finished in 124.81ms
Compiler run successful!
Warning: Dry run enabled, not broadcasting transaction
Contract: SimpleStorage
Transaction: {
"from": "0xbd828f7679656f8f830b89611c933017442f2ebf",
"to": null,
"maxFeePerGas": "0xf",
"maxPriorityFeePerGas": "0x1",
"gas": "0x69f18",
[...]
-
Testen Sie Ihren deployten Vertrag mit Foundrys cast-Tool. Lesen Sie zunächst die gespeicherten Daten:
cast call 0x742d35Cc6610C7532C8582d4C371Acb1D5f44D7F \
"getData()" \
--rpc-url $RPC_URL
-
Aktualisieren Sie dann die Daten und lesen Sie sie erneut:
# Update the stored data.
cast send 0x742d35Cc6610C7532C8582d4C371Acb1D5f44D7F \
"setData(string)" "Updated from Foundry" \
--private-key $PRIVATE_KEY \
--rpc-url $RPC_URL
# Read the stored data again.
cast call 0x742d35Cc6610C7532C8582d4C371Acb1D5f44D7F \
"getData()" \
--rpc-url $RPC_URL
Das sollte etwa Folgendes ausgeben:
blockHash 0x68fbd2aaf1de9c577869056ca634f2103fa1695673a94d8c049d0b78d3733aac
blockNumber 1200423
contractAddress
cumulativeGasUsed 21712
effectiveGasPrice 8
from 0xBd828F7679656F8f830b89611C933017442F2EbF
gasUsed 21712
logs []
logsBloom 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
root
status 1 (success)
transactionHash 0xcf5b1fcc8d19f7cf7992f6e6a8b3ade74e07afbd0da0b9fce26bda4c9503a12b
transactionIndex 0
type 2
blobGasPrice
blobGasUsed
to 0x742D35Cc6610c7532C8582D4C371aCb1D5F44D7F
0x
Mit Hardhat deployen
Hardhat ist ein voll ausgestattetes Entwicklungs-Framework mit umfangreichem Plugin-Support.
- Stellen Sie sicher, dass Sie Folgendes haben:
- Node.js 20+ (erforderlich für moderne Hardhat-Kompatibilität)
- Vertrautheit mit Ethereum-Entwicklung
- Eine Wallet mit Testnet-Tokens (siehe Testnet-Chain-Details)
Node.js 18 und älter werden von Hardhat nicht mehr unterstützt und können ES-Modul-Kompatibilitätsprobleme verursachen.
-
Node.js-Version überprüfen:
Wenn Sie Node.js 18 oder älter verwenden, aktualisieren Sie auf Node.js 20+:
# Using nvm (recommended)
nvm install 20
nvm use 20
# Or using NodeSource repository (Ubuntu/Debian)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
-
Ein neues Hardhat-Projekt initialisieren:
mkdir my-plasma-hardhat-project
cd my-plasma-hardhat-project
npm init -y
npm install --save-dev hardhat@latest @nomicfoundation/hardhat-toolbox@latest
npm install dotenv@latest ethers@latest
npx hardhat init
Wenn Sie auf Kompatibilitätsprobleme stoßen, prüfen Sie die Hardhat-Dokumentation auf die neuesten unterstützten Versionen.
Wählen Sie Create a JavaScript project, wenn Sie dazu aufgefordert werden.
-
hardhat.config.js aktualisieren:
require("@nomicfoundation/hardhat-toolbox");
require("dotenv").config();
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
solidity: {
version: "0.8.28",
settings: {
optimizer: {
enabled: true,
runs: 200
}
}
},
networks: {
plasmaTestnet: {
url: process.env.RPC_URL,
chainId: 9746,
accounts: [process.env.PRIVATE_KEY],
gasPrice: 1000000000, // 1 gwei
}
},
etherscan: {
apiKey: {
plasmaTestnet: process.env.ETHERSCAN_API_KEY
},
customChains: [
{
network: "plasmaTestnet",
chainId: 9746,
urls: {
apiURL: "https://testnet.plasmascan.to/api",
browserURL: "https://testnet.plasmascan.to/"
}
}
]
}
};
-
Eine
.env-Datei im Projekt-Root erstellen:
PRIVATE_KEY=your_private_key_here
RPC_URL=https://testnet-rpc.plasma.to
ETHERSCAN_API_KEY=your_api_key_for_verification
-
Scripts-Verzeichnis und Deployment-Skript erstellen:
-
scripts/deploy.js erstellen:
const { ethers } = require("hardhat");
async function main() {
// Get the contract factory
const SimpleStorage = await ethers.getContractFactory("SimpleStorage");
console.log("Deploying SimpleStorage contract...");
// Deploy the contract with constructor arguments
const simpleStorage = await SimpleStorage.deploy("Hello, Plasma from Hardhat!");
// Wait for deployment to complete
await simpleStorage.waitForDeployment();
const contractAddress = await simpleStorage.getAddress();
console.log("SimpleStorage deployed to:", contractAddress);
console.log("Transaction hash:", simpleStorage.deploymentTransaction().hash);
// Wait a few blocks for the transaction to be included
console.log("Waiting for block confirmations...");
await simpleStorage.deploymentTransaction().wait(5);
console.log("✅ Deployment completed successfully!");
}
main()
.then(() => process.exit(0))
.catch((error) => {
console.error(error);
process.exit(1);
});
-
Den Vertragscode als
contracts/SimpleStorage.sol speichern und dann deployen:
npx hardhat run scripts/deploy.js --network plasmaTestnet
-
Sie sind fertig!
Mit Ethers.js deployen
Ethers.js bietet einen minimalen, programmatischen Deployment-Flow.
-
Ein neues Projekt erstellen:
mkdir my-plasma-ethers-project
cd my-plasma-ethers-project
npm init -y
npm install ethers dotenv solc
-
Eine
.env-Datei im Projekt-Root erstellen:
PRIVATE_KEY=<your_private_key_here>
RPC_URL=https://testnet-rpc.plasma.to
ETHERSCAN_API_KEY=your_api_key_for_verification
-
compile.js erstellen, um Ihren Solidity-Vertrag zu kompilieren:
const fs = require('fs');
const solc = require('solc');
require('dotenv').config();
// Read the contract source code.
const contractSource = fs.readFileSync('SimpleStorage.sol', 'utf8');
// Prepare the input for the Solidity compiler.
const input = {
language: 'Solidity',
sources: {
'SimpleStorage.sol': {
content: contractSource,
},
},
settings: {
outputSelection: {
'*': {
'*': ['*'],
},
},
optimizer: {
enabled: true,
runs: 200,
},
},
};
// Compile the contract.
const output = JSON.parse(solc.compile(JSON.stringify(input)));
// Check for compilation errors.
if (output.errors) {
output.errors.forEach((error) => {
console.error(error.formattedMessage);
});
}
// Extract the contract data.
const contract = output.contracts['SimpleStorage.sol']['SimpleStorage'];
const abi = contract.abi;
const bytecode = contract.evm.bytecode.object;
// Save compilation artifacts.
fs.writeFileSync('SimpleStorage.json', JSON.stringify({
abi: abi,
bytecode: bytecode
}, null, 2));
console.log('Contract compiled successfully!');
-
Ihren Vertrag als
SimpleStorage.sol speichern und dann kompilieren:
Das sollte Folgendes ausgeben:
Contract compiled successfully!
-
deploy.js erstellen:
const { ethers } = require('ethers');
const fs = require('fs');
require('dotenv').config();
async function deploy() {
// Set up provider and wallet.
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY, provider);
console.log('Deploying from account:', wallet.address);
// Check account balance.
const balance = await provider.getBalance(wallet.address);
console.log('Account balance:', ethers.formatEther(balance), 'XPL');
// Load compiled contract.
const contractData = JSON.parse(fs.readFileSync('SimpleStorage.json', 'utf8'));
// Create contract factory.
const factory = new ethers.ContractFactory(
contractData.abi,
contractData.bytecode,
wallet
);
// Deploy the contract.
console.log('Deploying contract...');
const contract = await factory.deploy("Hello, Plasma from Ethers.js!", {
gasLimit: 500000, // Set a reasonable gas limit.
gasPrice: ethers.parseUnits('1', 'gwei'), // 1 gwei gas price.
});
// Wait for deployment.
await contract.waitForDeployment();
const contractAddress = await contract.getAddress();
console.log('Contract deployed to:', contractAddress);
console.log('Transaction hash:', contract.deploymentTransaction().hash);
// Save deployment info.
const deploymentInfo = {
contractAddress: contractAddress,
transactionHash: contract.deploymentTransaction().hash,
deployer: wallet.address,
network: 'plasmaTestnet',
timestamp: new Date().toISOString()
};
fs.writeFileSync('deployment.json', JSON.stringify(deploymentInfo, null, 2));
return contract;
}
async function interact(contract) {
console.log('\nInteracting with deployed contract...');
// Read initial data.
const initialData = await contract.getData();
console.log('Initial data:', initialData);
// Update data.
const updateTx = await contract.setData("Updated via Ethers.js");
await updateTx.wait();
console.log('Data updated. Transaction hash:', updateTx.hash);
// Read updated data.
const updatedData = await contract.getData();
console.log('Updated data:', updatedData);
// Get owner.
const owner = await contract.owner();
console.log('Contract owner:', owner);
}
// Main execution.
deploy()
.then(async (contract) => {
await interact(contract);
console.log('\nDeployment and interaction completed successfully!');
})
.catch((error) => {
console.error('Error:', error);
process.exit(1);
});
-
Das Deployment-Skript ausführen:
Das sollte etwa Folgendes ausgeben:
Deploying from account: 0xBd828F7679656F8f830b89611C933017442F2EbF
Account balance: 98539.897261933991888304 XPL
Deploying contract...
Contract deployed to: 0xf298A2A7BC526F9228B8C422D38f3c2E0D15449F
Transaction hash: 0x3d16cc55b9148bac9ac20981d9748a0fc89861c6beb92a2f869bb09b75f685b2
Interacting with deployed contract...
Initial data: Hello, Plasma from Ethers.js!
Data updated. Transaction hash: 0xe3328862ece5d0ca4ca84d25c4130d6749ec872c24bf76eea23dfa8c50c22505
Updated data: Updated via Ethers.js
Contract owner: 0xBd828F7679656F8f830b89611C933017442F2EbF
Deployment and interaction completed successfully!
Deployment überprüfen
Nach dem Deployment mit einer der obigen Methoden verifizieren Sie Ihre Vertrags-Bereitstellung.
Fehlerbehebung
ES-Modul-Kompatibilitätsprobleme
Wenn Sie auf Fehler wie Error [ERR_REQUIRE_ESM]: require() of ES Module stoßen, bedeutet das normalerweise:
-
Node.js-Version ist zu alt: Aktualisieren Sie auf Node.js 20+, wie in den Voraussetzungen erwähnt
-
Versionsabweichung bei Abhängigkeiten: Wenn ein Upgrade von Node.js nicht möglich ist, können Sie die problematische Abhängigkeit downgraden:
npm install micro-eth-signer@0.10.0
Node.js-Versionswarnungen
Wenn Sie Warnungen über nicht unterstützte Node.js-Versionen sehen:
WARNING: You are currently using Node.js v18.19.1, which is not supported by Hardhat
Aktualisieren Sie auf Node.js 20+ gemäß den Schritten im Abschnitt Voraussetzungen.
Unzureichende Mittel
Error: insufficient funds for intrinsic transaction cost
Stellen Sie sicher, dass Ihre Wallet genügend Testnet-Tokens hat. Besuchen Sie einen Testnet-Faucet.
Falsche Netzwerkkonfiguration
Error: network with chainId "1" doesn't match the configured chainId "9746"
Überprüfen Sie, ob Ihre Netzwerkkonfiguration mit den Testnet-Chain-Details übereinstimmt.
Gas-Schätzungsfehler
Error: cannot estimate gas
Setzen Sie explizite Gas-Limits in Ihrer Deployment-Konfiguration:
// In your deploy script
const simpleStorage = await SimpleStorage.deploy("Hello, Plasma from Hardhat!", {
gasLimit: 500000
});