文章目录
- 层级 技术 说明 前端 ethers.js / wagmi 区块链交互 后端 EVM / Solidity 智能合约 存储 IPFS / Filecoin 去中心化存储 认证 钱包签名 Web3auth 节点 Alchemy / Infura RPC服务
-
- // 检测是否安装MetaMask const checkWallet = () => { if (typeof window.ethereum !== 'undefined') { console.log('MetaMask is installed!'); return true; } return false; }; // 检测多种钱包 const getProvider = () => { if (window.ethereum?.providers) { return window.ethereum; } return window.ethereum; };
- // ethers.js v6 import { BrowserProvider } from 'ethers'; const connectWallet = async () => { if (!window.ethereum) { alert('请安装 MetaMask 钱包'); return null; } try { // 请求连接 const provider = new BrowserProvider(window.ethereum); const signer = await provider.getSigner(); const address = await signer.getAddress(); const network = await provider.getNetwork(); return { provider, signer, address, chainId: Number(network.chainId) }; } catch (err) { if (err.code === 4001) { console.log('用户拒绝连接'); } throw err; } };
- // 生成签名验证用户身份 const signMessage = async (signer) => { const address = await signer.getAddress(); const message = `欢迎登录我们的网站!\n\n地址:${address}\n时间:${Date.now()}`; const signature = await signer.signMessage(message); return { address, message, signature }; };
-
- // 使用OpenSea API获取NFT const getNFTs = async (address) => { const response = await fetch( `https://api.opensea.io/api/v2/chain/ethereum/account/${address}/nfts` ); const data = await response.json(); return data.nfts; }; // 展示NFT卡片 const NFTGrid = ({ nfts }) => ( <div className="nft-grid"> {nfts.map(nft => ( <div key={nft.identifier} className="nft-card"> <img src={nft.image_url} alt={nft.name} /> <h3>{nft.name}</h3> <p>{nft.collection}</p> {nft traits && ( <div className="traits"> {nft.traits.map(t => ( <span key={t.trait_type} className="trait"> {t.trait_type}: {t.value} </span> ))} </div> )} </div> ))} </div> );
- const WalletButton = () => { const [account, setAccount] = useState(null); const [connecting, setConnecting] = useState(false); const connect = async () => { setConnecting(true); try { const { address } = await connectWallet(); setAccount(address); } catch (err) { console.error(err); } finally { setConnecting(false); } }; if (account) { return ( <button className="wallet-btn connected"> <Identicon address={account} /> {account.slice(0, 6)}...{account.slice(-4)} </button> ); } return ( <button onClick={connect} disabled={connecting}> {connecting ? '连接中...' : '连接钱包'} </button> ); };
-
- // SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; contract MyNFT is ERC721, ERC721URIStorage { uint256 private _nextTokenId; constructor() ERC721("MyNFT", "MNFT") {} function mint(address to, string memory uri) public returns (uint256) { uint256 tokenId = _nextTokenId++; _safeMint(to, tokenId); _setTokenURI(tokenId, uri); return tokenId; } }
- const CONTRACT_ADDRESS = '0x...'; const ABI = [...]; // 合约ABI const mintNFT = async (signer, tokenURI) => { const contract = new Contract(CONTRACT_ADDRESS, ABI, signer); // 铸币(需要支付Gas) const tx = await contract.mint(await signer.getAddress(), tokenURI); // 等待确认 const receipt = await tx.wait(); // 获取Token ID const tokenId = receipt.logs[0].args.tokenId; return tokenId; };
- 注意事项 说明 签名验证 防止钓鱼签名 交易确认 金额单位确认 授权检查 防范授权陷阱 网络切换 防止跨链攻击 合约审计 上线前必做 Web3代表了互联网的新方向,掌握这些技术可以构建真正的去中心化应用。
Web3正在改变互联网所有权模式,本文介绍加密钱包集成、NFT市场和DAO网站的技术架构与开发实践。
| 层级 | 技术 | 说明 |
|---|---|---|
| 前端 | ethers.js / wagmi | 区块链交互 |
| 后端 | EVM / Solidity | 智能合约 |
| 存储 | IPFS / Filecoin | 去中心化存储 |
| 认证 | 钱包签名 | Web3auth |
| 节点 | Alchemy / Infura | RPC服务 |
// 检测是否安装MetaMask
const checkWallet = () => {
if (typeof window.ethereum !== 'undefined') {
console.log('MetaMask is installed!');
return true;
}
return false;
};
// 检测多种钱包
const getProvider = () => {
if (window.ethereum?.providers) {
return window.ethereum;
}
return window.ethereum;
};
// 检测是否安装MetaMask
const checkWallet = () => {
if (typeof window.ethereum !== 'undefined') {
console.log('MetaMask is installed!');
return true;
}
return false;
};
// 检测多种钱包
const getProvider = () => {
if (window.ethereum?.providers) {
return window.ethereum;
}
return window.ethereum;
};
// ethers.js v6
import { BrowserProvider } from 'ethers';
const connectWallet = async () => {
if (!window.ethereum) {
alert('请安装 MetaMask 钱包');
return null;
}
try {
// 请求连接
const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const address = await signer.getAddress();
const network = await provider.getNetwork();
return {
provider,
signer,
address,
chainId: Number(network.chainId)
};
} catch (err) {
if (err.code === 4001) {
console.log('用户拒绝连接');
}
throw err;
}
};
// ethers.js v6
import { BrowserProvider } from 'ethers';
const connectWallet = async () => {
if (!window.ethereum) {
alert('请安装 MetaMask 钱包');
return null;
}
try {
// 请求连接
const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const address = await signer.getAddress();
const network = await provider.getNetwork();
return {
provider,
signer,
address,
chainId: Number(network.chainId)
};
} catch (err) {
if (err.code === 4001) {
console.log('用户拒绝连接');
}
throw err;
}
};
// 生成签名验证用户身份
const signMessage = async (signer) => {
const address = await signer.getAddress();
const message = `欢迎登录我们的网站!\n\n地址:${address}\n时间:${Date.now()}`;
const signature = await signer.signMessage(message);
return { address, message, signature };
};
// 生成签名验证用户身份
const signMessage = async (signer) => {
const address = await signer.getAddress();
const message = `欢迎登录我们的网站!\n\n地址:${address}\n时间:${Date.now()}`;
const signature = await signer.signMessage(message);
return { address, message, signature };
};
// 使用OpenSea API获取NFT
const getNFTs = async (address) => {
const response = await fetch(
`https://api.opensea.io/api/v2/chain/ethereum/account/${address}/nfts`
);
const data = await response.json();
return data.nfts;
};
// 展示NFT卡片
const NFTGrid = ({ nfts }) => (
<div className="nft-grid">
{nfts.map(nft => (
<div key={nft.identifier} className="nft-card">
<img src={nft.image_url} alt={nft.name} />
<h3>{nft.name}</h3>
<p>{nft.collection}</p>
{nft traits && (
<div className="traits">
{nft.traits.map(t => (
<span key={t.trait_type} className="trait">
{t.trait_type}: {t.value}
</span>
))}
</div>
)}
</div>
))}
</div>
);
// 使用OpenSea API获取NFT
const getNFTs = async (address) => {
const response = await fetch(
`https://api.opensea.io/api/v2/chain/ethereum/account/${address}/nfts`
);
const data = await response.json();
return data.nfts;
};
// 展示NFT卡片
const NFTGrid = ({ nfts }) => (
<div className="nft-grid">
{nfts.map(nft => (
<div key={nft.identifier} className="nft-card">
<img src={nft.image_url} alt={nft.name} />
<h3>{nft.name}</h3>
<p>{nft.collection}</p>
{nft traits && (
<div className="traits">
{nft.traits.map(t => (
<span key={t.trait_type} className="trait">
{t.trait_type}: {t.value}
</span>
))}
</div>
)}
</div>
))}
</div>
);
const WalletButton = () => {
const [account, setAccount] = useState(null);
const [connecting, setConnecting] = useState(false);
const connect = async () => {
setConnecting(true);
try {
const { address } = await connectWallet();
setAccount(address);
} catch (err) {
console.error(err);
} finally {
setConnecting(false);
}
};
if (account) {
return (
<button className="wallet-btn connected">
<Identicon address={account} />
{account.slice(0, 6)}...{account.slice(-4)}
</button>
);
}
return (
<button onClick={connect} disabled={connecting}>
{connecting ? '连接中...' : '连接钱包'}
</button>
);
};
const WalletButton = () => {
const [account, setAccount] = useState(null);
const [connecting, setConnecting] = useState(false);
const connect = async () => {
setConnecting(true);
try {
const { address } = await connectWallet();
setAccount(address);
} catch (err) {
console.error(err);
} finally {
setConnecting(false);
}
};
if (account) {
return (
<button className="wallet-btn connected">
<Identicon address={account} />
{account.slice(0, 6)}...{account.slice(-4)}
</button>
);
}
return (
<button onClick={connect} disabled={connecting}>
{connecting ? '连接中...' : '连接钱包'}
</button>
);
};
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
contract MyNFT is ERC721, ERC721URIStorage {
uint256 private _nextTokenId;
constructor() ERC721("MyNFT", "MNFT") {}
function mint(address to, string memory uri) public returns (uint256) {
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
return tokenId;
}
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
contract MyNFT is ERC721, ERC721URIStorage {
uint256 private _nextTokenId;
constructor() ERC721("MyNFT", "MNFT") {}
function mint(address to, string memory uri) public returns (uint256) {
uint256 tokenId = _nextTokenId++;
_safeMint(to, tokenId);
_setTokenURI(tokenId, uri);
return tokenId;
}
}
const CONTRACT_ADDRESS = '0x...';
const ABI = [...]; // 合约ABI
const mintNFT = async (signer, tokenURI) => {
const contract = new Contract(CONTRACT_ADDRESS, ABI, signer);
// 铸币(需要支付Gas)
const tx = await contract.mint(await signer.getAddress(), tokenURI);
// 等待确认
const receipt = await tx.wait();
// 获取Token ID
const tokenId = receipt.logs[0].args.tokenId;
return tokenId;
};
const CONTRACT_ADDRESS = '0x...';
const ABI = [...]; // 合约ABI
const mintNFT = async (signer, tokenURI) => {
const contract = new Contract(CONTRACT_ADDRESS, ABI, signer);
// 铸币(需要支付Gas)
const tx = await contract.mint(await signer.getAddress(), tokenURI);
// 等待确认
const receipt = await tx.wait();
// 获取Token ID
const tokenId = receipt.logs[0].args.tokenId;
return tokenId;
};
import { create as ipfsClient } from 'ipfs-http-client';
const ipfs = ipfsClient({ url: 'https://ipfs.infura.io:5001' });
const uploadToIPFS = async (file) => {
const added = await ipfs.add(file);
const cid = added.cid.toString();
return `https://ipfs.io/ipfs/${cid}`;
};
// 上传元数据
const uploadMetadata = async (metadata) => {
const blob = new Blob([JSON.stringify(metadata)], { type: 'application/json' });
return uploadToIPFS(blob);
};
import { create as ipfsClient } from 'ipfs-http-client';
const ipfs = ipfsClient({ url: 'https://ipfs.infura.io:5001' });
const uploadToIPFS = async (file) => {
const added = await ipfs.add(file);
const cid = added.cid.toString();
return `https://ipfs.io/ipfs/${cid}`;
};
// 上传元数据
const uploadMetadata = async (metadata) => {
const blob = new Blob([JSON.stringify(metadata)], { type: 'application/json' });
return uploadToIPFS(blob);
};
const Proposals = ({ daoAddress }) => {
const [proposals, setProposals] = useState([]);
useEffect(() => {
loadProposals();
}, []);
return (
<div className="proposals">
{proposals.map(p => (
<ProposalCard key={p.id} proposal={p} />
))}
</div>
);
};
const Proposals = ({ daoAddress }) => {
const [proposals, setProposals] = useState([]);
useEffect(() => {
loadProposals();
}, []);
return (
<div className="proposals">
{proposals.map(p => (
<ProposalCard key={p.id} proposal={p} />
))}
</div>
);
};
| 注意事项 | 说明 |
|---|---|
| 签名验证 | 防止钓鱼签名 |
| 交易确认 | 金额单位确认 |
| 授权检查 | 防范授权陷阱 |
| 网络切换 | 防止跨链攻击 |
| 合约审计 | 上线前必做 |
Web3代表了互联网的新方向,掌握这些技术可以构建真正的去中心化应用。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

评论(0)