教程与示例:构建并部署一个简单的 DApp
Last updated
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Greeting {
string public greeting;
event GreetingSet(address indexed user, string newGreeting);
constructor() {
greeting = "Hello, JuChain!";
}
function setGreeting(string memory _greeting) public {
require(bytes(_greeting).length > 0, "Greeting cannot be empty");
greeting = _greeting;
emit GreetingSet(msg.sender, _greeting);
}
function getGreeting() public view returns (string memory) {
return greeting;
}
}require("dotenv").config();
const HDWalletProvider = require("@truffle/hdwallet-provider");
const { MNEMONIC, RPC_URL } = process.env;
module.exports = {
networks: {
juchain_testnet: {
provider: () => new HDWalletProvider(MNEMONIC, RPC_URL),
network_id: 202599, // JuChain 测试网 ID
gas: 5500000, // Gas 上限
gasPrice: 1000000000, // 1 gwei
confirmations: 2, // 等待 2 个区块确认
timeoutBlocks: 200, // 超时区块数
},
},
compilers: {
solc: {
version: "0.8.0", // Solidity 版本
settings: {
optimizer: {
enabled: true,
runs: 200,
},
},
},
},
};truffle console --network juchain_testnet
> web3.eth.getBlockNumber()const Greeting = artifacts.require("Greeting");
module.exports = function (deployer) {
deployer.deploy(Greeting);
};truffle migrate --network juchain_testnet2_deploy_greeting.js
====================
Deploying 'Greeting'
--------------------
> transaction hash: 0x...
> contract address: 0x1234567890abcdef1234567890abcdef12345678truffle console --network juchain_testnet
> let greeting = await Greeting.at("0x1234567890abcdef1234567890abcdef12345678")
> await greeting.getGreeting()mkdir public && cd public
touch index.html<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>JuChain Greeting dApp</title>
<style>
body { font-family: Arial, sans-serif; text-align: center; margin-top: 50px; }
input { padding: 5px; margin: 10px; width: 200px; }
button { padding: 10px 20px; margin: 5px; }
#status { color: green; }
</style>
</head>
<body>
<h1>JuChain Greeting dApp</h1>
<p>Current Greeting: <span id="greeting">Loading...</span></p>
<input id="newGreeting" type="text" placeholder="Enter new greeting" />
<br />
<button onclick="setGreeting()">Set Greeting</button>
<p id="status"></p>
<script src="https://cdn.jsdelivr.net/npm/web3@1.5.3/dist/web3.min.js"></script>
<script>
const contractAddress = "0x1234567890abcdef1234567890abcdef12345678"; // 替换为你的合约地址
const abi = [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{"indexed": true, "internalType": "address", "name": "user", "type": "address"},
{"indexed": false, "internalType": "string", "name": "newGreeting", "type": "string"}
],
"name": "GreetingSet",
"type": "event"
},
{
"inputs": [],
"name": "getGreeting",
"outputs": [{"internalType": "string", "name": "", "type": "string"}],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [{"internalType": "string", "name": "_greeting", "type": "string"}],
"name": "setGreeting",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "greeting",
"outputs": [{"internalType": "string", "name": "", "type": "string"}],
"stateMutability": "view",
"type": "function"
}
];
let web3, contract;
async function init() {
if (window.ethereum) {
web3 = new Web3(window.ethereum);
try {
await window.ethereum.request({ method: "eth_requestAccounts" });
contract = new web3.eth.Contract(abi, contractAddress);
updateGreeting();
} catch (error) {
console.error("User denied account access", error);
document.getElementById("status").innerText = "Please connect MetaMask";
}
} else {
alert("Please install MetaMask!");
}
}
async function updateGreeting() {
const greeting = await contract.methods.getGreeting().call();
document.getElementById("greeting").innerText = greeting;
}
async function setGreeting() {
const accounts = await web3.eth.getAccounts();
const newGreeting = document.getElementById("newGreeting").value;
if (!newGreeting) {
document.getElementById("status").innerText = "Greeting cannot be empty!";
return;
}
document.getElementById("status").innerText = "Setting greeting...";
try {
await contract.methods.setGreeting(newGreeting).send({ from: accounts[0] });
document.getElementById("status").innerText = "Greeting updated successfully!";
updateGreeting();
} catch (error) {
document.getElementById("status").innerText = "Error: " + error.message;
}
}
window.onload = init;
</script>
</body>
</html>npx http-server ./public