算法艺术创作
algorithmic-art
通过代码和可调参数创作生成艺术与交互式视觉效果。
blockchain-application【设计与创意】Use this skill when asked about smart contract development, Solidity, Vyper, Rust smart contracts (Solana, NEAR, Polkadot), Haskell/Plutus (Cardano), Cairo/StarkNet, dApp backend development, Truffle, Hardhat, Foundry, Anchor, and blockchain application patterns. Languages: Solidity, Vyper, Rust, Haskell, Cairo, Move. Covers EVM-based development (Et…
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Guide smart contract development across all major blockchain platforms. Covers language selection, contract architecture, security patterns, gas optimization, deployment, and cross-contract communication. Platform-agnostic at the protocol layer; chain-specific at the language and VM layer.
"smart contract", "solidity", "vyper", "evm", "rust smart contract", "solana contract", "anchor framework", "cardano", "plutus", "haskell contract", "cairo", "starknet", "sierra", "hardhat", "foundry", "truffle", "dapp backend", "contract deployment", "gas optimization", "contract security", "cross-contract call", "chainlink", "oracle contract", "defi contract", "nft contract", "move language", "sui contract", "aptos contract"
Complete contract architecture specification: platform selection, contract design, implementation approach, testing strategy, deployment plan, security analysis.
5000 tokens
Smart contract platform:
├── Need EVM compatibility?
│ ├── YES → Solidity or Vyper
│ │ ├── Solidity: EVM chains (Ethereum, Polygon, Arbitrum, Optimism, Base, BSC)
│ │ │ ├── Toolchain: Foundry (default), Hardhat (complex workflows)
│ │ │ └── Libraries: OpenZeppelin, Solady
│ │ └── Vyper: Simple contracts, audit-friendliness prioritized
│ │ └── Toolchain: ape, brownie
│ ├── NO → Evaluate non-EVM chains
│ │ ├── Solana → Rust + Anchor framework
│ │ │ └── Toolchain: Anchor CLI, Solana CLI
│ │ ├── Cardano → Haskell (Plutus) or Aiken
│ │ │ └── Toolchain: Plutus Tx, cardano-cli
│ │ ├── StarkNet → Cairo
│ │ │ └── Toolchain: Scarb, Starkli
│ │ ├── Sui/Aptos → Move
│ │ │ └── Toolchain: sui CLI / aptos CLI
│ │ └── NEAR/Polkadot → Rust (ink!)
│ │ └── Toolchain: cargo-contract
│ └── Cross-chain? → Consider platform-agnostic architecture
│ └── Abstract core logic, deploy adapters per chain
Need upgradeable contract?
├── YES:
│ ├── UUPS → Default for new projects (gas-efficient, clean storage)
│ ├── Transparent → Legacy projects, many upgrade functions
│ └── Beacon → Many child contracts (ERC-1167 clones)
├── NO → Immutable contract
│ └── Better security posture, no upgrade governance overhead
└── Hybrid → Immutable core + upgradeable periphery
EVM language choice:
├── Solidity (default for most projects)
│ ├── Pros: Largest ecosystem, most tutorials, OpenZeppelin libs
│ ├── Cons: More attack surface (implicit behavior, inheritance)
│ └── Best for: Complex protocols, composability-focused
├── Vyper (audit-first projects)
│ ├── Pros: Simpler, fewer foot-guns, explicit behavior
│ ├── Cons: Smaller ecosystem, limited libraries
│ └── Best for: Simple contracts, high-value vaults, DAO treasuries
└── Huff (low-level EVM)
├── Pros: Full control over bytecode, optimal gas
├── Cons: No safety rails, manual memory management
└── Best for: Gas-critical operations, precompile-like contracts
function withdraw(uint256 amount) external {
// 1. CHECKS: validate conditions
require(balanceOf[msg.sender] >= amount, "insufficient balance");
// 2. EFFECTS: update state first
balanceOf[msg.sender] -= amount;
// 3. INTERACTIONS: external calls last
(bool ok, ) = msg.sender.call{value: amount}("");
require(ok, "transfer failed");
}
// Upgrade-safe storage layout
// 1. Always append new variables at the end
// 2. Never reorder or delete existing variables
// 3. Use gap arrays for future storage slots
contract BaseV1 {
uint256 public value1;
uint256 public value2;
uint256[50] private __gap; // Reserved for future upgrades
}
contract BaseV2 is BaseV1 {
uint256 public value3; // Appended, safe
uint256[49] private __gap; // Reduced by 1
}
// BAD: reads storage repeatedly
function sum() external view returns (uint) {
uint total = 0;
for (uint i = 0; i < arr.length; i++) {
total += arr[i]; // SLOAD every iteration
}
return total;
}
// GOOD: cache array length and use unchecked
function sum() external view returns (uint) {
uint len = arr.length;
uint total = 0;
for (uint i = 0; i < len; i++) {
unchecked { total += arr[i]; }
}
return total;
}
// Gas optimization techniques:
// 1. Use calldata instead of memory for read-only function params
// 2. Pack structs tightly (uint128 + uint128 saves slot)
// 3. Use custom errors instead of require strings
// 4. Short-circuit: check cheapest conditions first in require
// 5. Use Solady's LibString over OpenZeppelin for simple ops
error InsufficientBalance(uint256 available, uint256 required);
function optimizedTransfer(address to, uint256 amount) external {
uint256 bal = balanceOf[msg.sender]; // Cache storage
if (bal < amount) {
revert InsufficientBalance(bal, amount);
}
unchecked {
balanceOf[msg.sender] = bal - amount; // Safe due to check above
balanceOf[to] += amount;
}
}
// EIP-1167: Deploy minimal proxies (costs ~200 gas vs 500K for full contract)
contract Factory {
event CloneDeployed(address indexed clone, address indexed creator);
function createClone(address implementation) external returns (address clone) {
// ERC-1167 bytecode: 3D602D8060... (20 bytes implementation address embedded)
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, implementation))
mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
clone := create(0, ptr, 0x37)
}
require(clone != address(0), "CLONE_FAILED");
emit CloneDeployed(clone, msg.sender);
}
}
EVM:
├── Direct call: Interface(target).function(args) — simple, synchronous
├── Delegatecall: Proxy pattern, upgradeable storage
├── Staticcall: Read-only external call (EIP-214)
└── Low-level: address.call{value, gas}(data) — for arbitrary calls
Solana:
├── CPI (Cross-Program Invocation): invoke() or invoke_signed()
└── PDA signing: Programs sign for PDAs via invoke_signed()
Cardano:
├── Script-to-script: Redeemer-based validation
└── One-shot contracts: eUTxO model, no persistent state
Move (Sui/Aptos):
├── Module imports: direct function calls within VM
└── Object transfers: sui::transfer for object ownership
// Solidity: handle external call failures
function safeBatchTransfer(address[] calldata targets, bytes[] calldata data)
external returns (bool[] memory successes)
{
successes = new bool[](targets.length);
for (uint i = 0; i < targets.length; i++) {
(successes[i], ) = targets[i].call{gas: 10000}(data[i]);
// Don't revert on individual failure
}
}
#[derive(Accounts)]
pub struct CreateUser<'info> {
#[account(init, payer = user, space = 8 + User::INIT_SPACE)]
pub user_account: Account<'info, User>,
#[account(mut)]
pub user: Signer<'info>,
pub system_program: Program<'info, System>,
}
#[account]
pub struct User {
pub name: String,
pub age: u8,
}
| Vulnerability | Mitigation |
|---|---|
| Reentrancy | Checks-effects-interactions, ReentrancyGuard |
| Flash loan manipulation | TWAP pricing, min/max output constraints |
| Oracle manipulation | Redundant oracles, stale price checks, circuit breakers |
| Frontrunning | Commit-reveal, submarine sends, FCFS ordering |
| Signature replay | Include chain ID, contract address, nonce in EIP-712 |
| Access control | Timelock + multi-sig, not single admin key |
| Integer overflow | Solidity 0.8+ built-in checks, SafeMath for older |
| Uninitialized proxy | Constructor + disableInitializers() |
| Storage collision | EIP-1967 structured storage, no gap variables |
| ERC-4626 inflation | Virtual shares + assets on first deposit |
contract OptimizedToken {
uint256 public totalSupply;
string public name;
string public symbol;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
constructor(string memory _name, string memory _symbol) {
name = _name; symbol = _symbol;
}
function transfer(address to, uint256 amount) external returns (bool) {
balanceOf[msg.sender] -= amount;
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
event Transfer(address indexed from, address indexed to, uint256 amount);
}
use anchor_lang::prelude::*;
declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");
#[program]
pub mod counter {
use super::*;
pub fn increment(ctx: Context<Increment>) -> Result<()> {
ctx.accounts.counter.count += 1;
Ok(())
}
}
#[derive(Accounts)]
pub struct Increment<'info> {
#[account(mut, seeds = [b"counter", authority.key().as_ref()], bump)]
pub counter: Account<'info, CounterState>,
pub authority: Signer<'info>,
}
#[account]
pub struct CounterState { pub count: u64, pub authority: Pubkey }
blockchain → blockchain-application
Blockchain Application Design
├── Application type?
│ ├── DeFi → DEX, lending, yield aggregator
│ ├── NFT → Marketplace, collection, gaming
│ ├── DAO → Governance, treasury, voting
│ └── Identity → SSI, verifiable credentials, attestations
├── Smart contract language?
│ ├── Solidity (most mature) → EVM chains (Ethereum, Polygon, Arbitrum)
│ ├── Rust → Solana / NEAR / Polkadot (high performance)
│ └── Move → Sui / Aptos (parallel execution)
├── Upgradeability?
│ ├── Yes → UUPS / Transparent proxy pattern
│ ├── Yes (immutable core) → Diamond pattern (EIP-2535)
│ └── No → Minimal proxy + migration strategy
└── Gas optimization priority?
├── Critical → Optimize storage layout, batch operations, use ERC-2612
├── Moderate → Standard patterns, avoid loops
└── Low → Focus on correctness first
Decision criteria: Evaluate target chain, development team experience, security requirements, and upgrade path.
// blockchain-application/contracts/UUPSUpgradeable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
contract MyApp is UUPSUpgradeable, OwnableUpgradeable {
uint256 public value;
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() { _disableInitializers(); }
function initialize(address owner_) initializer external {
__UUPSUpgradeable_init();
__Ownable_init(owner_);
}
function setValue(uint256 _value) external onlyOwner { value = _value; }
function _authorizeUpgrade(address) internal override onlyOwner {}
}
// blockchain-application/contracts/CloneFactory.sol
contract CloneFactory {
event CloneCreated(address indexed clone, address indexed implementation);
function createClone(address implementation) external returns (address) {
bytes20 implBytes = bytes20(implementation);
address clone;
assembly {
let cloneData := mload(0x40)
mstore(cloneData, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
mstore(add(cloneData, 0x14), implBytes)
mstore(add(cloneData, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
clone := create(0, cloneData, 0x37)
}
emit CloneCreated(clone, implementation);
}
}
| Anti-Pattern | Consequence | Solution |
|---|---|---|
Using tx.origin for auth | Phishing attacks | Use msg.sender always |
| Unchecked external calls | Silent failures | Check return values of .call{value: }() |
| Storage collision in upgrades | Corrupted state | Use structured storage (EIP-1967, UUPS) |
| Owner-only functions without timelock | Single-key compromise risk | Use multisig + timelock |
| No reentrancy guard | Reentrancy exploits | Apply ReentrancyGuard on all external functions |
uint128 + uint128); use struct for related fields.calldata instead of memory for read-only function parameters.immutable for constructor-set constants to save SSTORE costs.AccessControl with roles; never rely on onlyOwner alone.nonce, deadline, and chainId in EIP-712 signatures.oz upgrade validator; never upgrade without timelock.blockchain-application → blockchain-testing (for test strategy implementation) blockchain-application → blockchain-security (for pre-audit review)