Claude-skill-registry blockchain-expert
Expert-level blockchain, Web3, smart contracts, DeFi, and cryptocurrency development
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/blockchain-expert" ~/.claude/skills/majiayu000-claude-skill-registry-blockchain-expert && rm -rf "$T"
manifest:
skills/data/blockchain-expert/SKILL.mdsource content
Blockchain Expert
Expert guidance for blockchain development, smart contracts, Web3 applications, DeFi protocols, and cryptocurrency systems.
Core Concepts
Blockchain Fundamentals
- Distributed ledger technology
- Consensus mechanisms (PoW, PoS, PoA)
- Cryptographic hashing
- Public/private key cryptography
- Transaction validation
- Block structure and chain
Smart Contracts
- Solidity programming
- Gas optimization
- Security patterns
- Upgradeable contracts
- Testing and auditing
- Contract interactions
Web3 & DeFi
- Decentralized applications (dApps)
- DeFi protocols (AMM, lending, staking)
- NFTs and token standards
- Layer 2 solutions
- Cross-chain bridges
- Wallet integration
Smart Contract Development
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; contract SimpleToken is ERC20, Ownable, ReentrancyGuard { uint256 public constant MAX_SUPPLY = 1000000 * 10**18; mapping(address => bool) public minters; event MinterAdded(address indexed minter); event MinterRemoved(address indexed minter); modifier onlyMinter() { require(minters[msg.sender], "Not a minter"); _; } constructor() ERC20("SimpleToken", "SMPL") { minters[msg.sender] = true; } function mint(address to, uint256 amount) external onlyMinter { require(totalSupply() + amount <= MAX_SUPPLY, "Max supply exceeded"); _mint(to, amount); } function burn(uint256 amount) external { _burn(msg.sender, amount); } function addMinter(address minter) external onlyOwner { minters[minter] = true; emit MinterAdded(minter); } function removeMinter(address minter) external onlyOwner { minters[minter] = false; emit MinterRemoved(minter); } } // Staking Contract contract StakingPool is ReentrancyGuard { IERC20 public stakingToken; IERC20 public rewardToken; uint256 public rewardRate = 100; // Reward tokens per second uint256 public lastUpdateTime; uint256 public rewardPerTokenStored; mapping(address => uint256) public userRewardPerTokenPaid; mapping(address => uint256) public rewards; mapping(address => uint256) public balances; uint256 private _totalSupply; constructor(address _stakingToken, address _rewardToken) { stakingToken = IERC20(_stakingToken); rewardToken = IERC20(_rewardToken); } function rewardPerToken() public view returns (uint256) { if (_totalSupply == 0) { return rewardPerTokenStored; } return rewardPerTokenStored + (((block.timestamp - lastUpdateTime) * rewardRate * 1e18) / _totalSupply); } function earned(address account) public view returns (uint256) { return ((balances[account] * (rewardPerToken() - userRewardPerTokenPaid[account])) / 1e18) + rewards[account]; } modifier updateReward(address account) { rewardPerTokenStored = rewardPerToken(); lastUpdateTime = block.timestamp; if (account != address(0)) { rewards[account] = earned(account); userRewardPerTokenPaid[account] = rewardPerTokenStored; } _; } function stake(uint256 amount) external nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot stake 0"); _totalSupply += amount; balances[msg.sender] += amount; stakingToken.transferFrom(msg.sender, address(this), amount); } function withdraw(uint256 amount) external nonReentrant updateReward(msg.sender) { require(amount > 0, "Cannot withdraw 0"); _totalSupply -= amount; balances[msg.sender] -= amount; stakingToken.transfer(msg.sender, amount); } function getReward() external nonReentrant updateReward(msg.sender) { uint256 reward = rewards[msg.sender]; if (reward > 0) { rewards[msg.sender] = 0; rewardToken.transfer(msg.sender, reward); } } }
DeFi: AMM Implementation
// Simple Automated Market Maker (like Uniswap) contract SimpleAMM is ReentrancyGuard { IERC20 public token0; IERC20 public token1; uint256 public reserve0; uint256 public reserve1; uint256 public totalSupply; mapping(address => uint256) public balanceOf; event Swap(address indexed user, address tokenIn, uint256 amountIn, uint256 amountOut); event AddLiquidity(address indexed user, uint256 amount0, uint256 amount1); event RemoveLiquidity(address indexed user, uint256 amount0, uint256 amount1); constructor(address _token0, address _token1) { token0 = IERC20(_token0); token1 = IERC20(_token1); } function addLiquidity(uint256 amount0, uint256 amount1) external nonReentrant returns (uint256 shares) { token0.transferFrom(msg.sender, address(this), amount0); token1.transferFrom(msg.sender, address(this), amount1); if (totalSupply == 0) { shares = sqrt(amount0 * amount1); } else { shares = min( (amount0 * totalSupply) / reserve0, (amount1 * totalSupply) / reserve1 ); } require(shares > 0, "Shares = 0"); _mint(msg.sender, shares); _update( token0.balanceOf(address(this)), token1.balanceOf(address(this)) ); emit AddLiquidity(msg.sender, amount0, amount1); } function removeLiquidity(uint256 shares) external nonReentrant returns (uint256 amount0, uint256 amount1) { uint256 balance0 = token0.balanceOf(address(this)); uint256 balance1 = token1.balanceOf(address(this)); amount0 = (shares * balance0) / totalSupply; amount1 = (shares * balance1) / totalSupply; require(amount0 > 0 && amount1 > 0, "Amount = 0"); _burn(msg.sender, shares); _update(balance0 - amount0, balance1 - amount1); token0.transfer(msg.sender, amount0); token1.transfer(msg.sender, amount1); emit RemoveLiquidity(msg.sender, amount0, amount1); } function swap(address tokenIn, uint256 amountIn) external nonReentrant returns (uint256 amountOut) { require(tokenIn == address(token0) || tokenIn == address(token1), "Invalid token"); bool isToken0 = tokenIn == address(token0); (IERC20 tokenIn_, IERC20 tokenOut, uint256 reserveIn, uint256 reserveOut) = isToken0 ? (token0, token1, reserve0, reserve1) : (token1, token0, reserve1, reserve0); tokenIn_.transferFrom(msg.sender, address(this), amountIn); // 0.3% fee uint256 amountInWithFee = (amountIn * 997) / 1000; // x * y = k formula amountOut = (reserveOut * amountInWithFee) / (reserveIn + amountInWithFee); tokenOut.transfer(msg.sender, amountOut); _update( token0.balanceOf(address(this)), token1.balanceOf(address(this)) ); emit Swap(msg.sender, tokenIn, amountIn, amountOut); } function _mint(address to, uint256 amount) private { balanceOf[to] += amount; totalSupply += amount; } function _burn(address from, uint256 amount) private { balanceOf[from] -= amount; totalSupply -= amount; } function _update(uint256 _reserve0, uint256 _reserve1) private { reserve0 = _reserve0; reserve1 = _reserve1; } function sqrt(uint256 y) private pure returns (uint256 z) { if (y > 3) { z = y; uint256 x = y / 2 + 1; while (x < z) { z = x; x = (y / x + x) / 2; } } else if (y != 0) { z = 1; } } function min(uint256 x, uint256 y) private pure returns (uint256) { return x <= y ? x : y; } }
Web3 Integration
import { ethers } from 'ethers'; import { Contract, Provider, Signer } from 'ethers'; class Web3Client { private provider: Provider; private signer?: Signer; constructor(rpcUrl: string) { this.provider = new ethers.JsonRpcProvider(rpcUrl); } async connectWallet(): Promise<string> { // Connect to MetaMask if (typeof window.ethereum !== 'undefined') { const provider = new ethers.BrowserProvider(window.ethereum); await provider.send("eth_requestAccounts", []); this.signer = await provider.getSigner(); return await this.signer.getAddress(); } throw new Error('No wallet found'); } async getBalance(address: string): Promise<string> { const balance = await this.provider.getBalance(address); return ethers.formatEther(balance); } async sendTransaction(to: string, amount: string): Promise<string> { if (!this.signer) throw new Error('Wallet not connected'); const tx = await this.signer.sendTransaction({ to, value: ethers.parseEther(amount) }); const receipt = await tx.wait(); return receipt?.hash || ''; } getContract(address: string, abi: any[]): Contract { return new ethers.Contract( address, abi, this.signer || this.provider ); } async callContract( contractAddress: string, abi: any[], method: string, args: any[] ): Promise<any> { const contract = this.getContract(contractAddress, abi); return await contract[method](...args); } async estimateGas( contractAddress: string, abi: any[], method: string, args: any[] ): Promise<bigint> { const contract = this.getContract(contractAddress, abi); return await contract[method].estimateGas(...args); } }
Best Practices
Smart Contract Security
- Use OpenZeppelin contracts for standards
- Implement reentrancy guards
- Check for integer overflow/underflow (use Solidity 0.8+)
- Validate all inputs
- Use pull over push for payments
- Implement circuit breakers for emergencies
- Comprehensive testing and auditing
Gas Optimization
- Use
over smaller typesuint256 - Pack storage variables
- Use
for function parameterscalldata - Minimize storage operations
- Use events for data that doesn't need on-chain storage
- Batch operations when possible
Development
- Use Hardhat/Foundry for development
- Write comprehensive tests
- Use test networks before mainnet
- Implement upgrade patterns carefully
- Monitor contract events
- Document all functions
Anti-Patterns
❌ No reentrancy protection ❌ Unchecked external calls ❌ Using
tx.origin for authorization
❌ Floating pragma versions
❌ No access control
❌ Storing sensitive data on-chain
❌ No gas limit considerations
Resources
- Ethereum: https://ethereum.org/en/developers/
- Solidity: https://docs.soliditylang.org/
- OpenZeppelin: https://www.openzeppelin.com/
- Hardhat: https://hardhat.org/
- Ethers.js: https://docs.ethers.org/