比特币Ordinals与链上艺术:数字铭文的收藏价值
2026年,比特币Ordinals协议正在"重塑"链上艺术的"范式"。从"比特币NFT"到"数字铭文",从"收藏"到"价值",Ordinals在比特币网络上"永久"铭刻"数字艺术品"——"文本"、"图像"、"视频"、"音频"。这是"链上艺术"的"新"篇章——"比特币"不再只是"数字黄金",而是"数字艺术"的"载体"。
第一幕:Ordinals的"艺术"革命
第一场:从"比特币"到"Ordinals"——"协议"的"诞生"
Ordinals协议的"诞生":
- 2023年1月:Casey Rodarmor"发布"Ordinals协议——"允许"在比特币"聪"(satoshi)上"铭刻"数据。
- 2023年2月:第一个"Ordinals NFT"被"铭刻"——"比特币NFT"的"诞生"。
- 2023年3月:Ordinals"生态"爆发——"数万"个"铭文"被"创建"。
- 2026年:Ordinals"成熟"——"数百万"个"铭文"、"数十亿"美元"市值"。
第二场:从"聪"到"铭文"——"技术"的"原理"
Ordinals的"技术"原理:
- 聪(Satoshi):比特币的"最小"单位——"1 BTC = 100,000,000聪"。
- 铭文(Inscription):在"聪"上"铭刻"数据——"文本"、"图像"、"视频"、"音频"。
- 序号(Ordinal):每个"聪"的"唯一"编号——"跟踪"聪的"来源"和"交易"。
- 铭刻(Inscribe):将"数据"写入"比特币"交易——"SegWit"、"Taproot"。
第三场:从"比特币NFT"到"链上艺术"——"价值"的"来源"
Ordinals的"价值"来源:
- 永久性:数据"永久"存储在"比特币"链上——"不可"篡改、"不可"删除。
- 稀缺性:每个"聪"都是"唯一"的——"编号"、"稀有度"、"历史"。
- 安全性:比特币网络"最"安全——"PoW"、"哈希率"、"去中心化"。
- 文化性:Ordinals代表了"比特币"的文化——"数字"艺术的"新"载体。
第二幕:Ordinals的"技术"深度
第一场:从"Taproot"到"SegWit"——"技术"的"基础"
Ordinals依赖于比特币的"技术"升级:
- SegWit(隔离见证,2017):"增加"比特币的"区块"容量——"允许"更多"数据"存入"交易"。
- Taproot(主根,2021):"改进"比特币的"脚本"能力——"允许"更"复杂"的"智能合约"。
- Ordinals结合:利用SegWit的"见证数据"和Taproot的"脚本"能力——"铭刻"数据。
第二场:从"铭刻"到"收藏"——"Ordinals"的"流程"
Ordinals的"收藏"流程:
- 创建铭文:用户"创建"数字艺术品——"图像"、"视频"、"音频"、"文本"。
- 铭刻数据:用户"支付"比特币"交易费"——"铭刻"数据到"聪"上。
- 收藏铭文:用户"购买"铭文——"转账"聪的"所有权"。
- 展示铭文:用户"展示"铭文——"Ordinals"钱包、"市场"、"画廊"。
第三场:从"稀有度"到"收藏价值"——"Ordinals"的"价值"体系
Ordinals的"稀有度"体系:
- 普通(Common):"非"特殊"聪"——"99%以上"的聪。
- 不常见(Uncommon):"第一个"区块的"聪"——"创世"区块。
- 稀有(Rare):"每个"难度调整"周期"的"第一个"聪。
- 史诗(Epic):"每个"减半"事件"的"第一个"聪。
- 传奇(Legendary):"每个"周期"的"第一个"聪。
- 神话(Mythic):"创世"区块的"第一个"聪。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/utils/ReentrancyGuard.sol";
contract OrdinalGallery is ERC721, AccessControl, ReentrancyGuard {
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
bytes32 public constant CURATOR_ROLE = keccak256("CURATOR_ROLE");
enum Rarity {
COMMON, UNCOMMON, RARE, EPIC, LEGENDARY, MYTHIC
}
enum ContentType {
TEXT, IMAGE, VIDEO, AUDIO, HTML, APPLICATION
}
struct Inscription {
uint256 inscriptionId;
string contentURI;
ContentType contentType;
bytes contentHash;
address creator;
uint256 blockHeight;
uint256 satoshiNumber;
Rarity rarity;
uint256 createdAt;
uint256 salePrice;
bool isForSale;
}
struct Collection {
uint256 collectionId;
string name;
string description;
address curator;
uint256[] inscriptionIds;
uint256 totalValue;
uint256 createdAt;
bool isActive;
}
struct RarityScore {
Rarity rarity;
uint256 score;
uint256 count;
uint256 totalValue;
}
mapping(uint256 => Inscription) public inscriptions;
mapping(uint256 => Collection) public collections;
mapping(address => uint256[]) public userInscriptions;
mapping(Rarity => RarityScore) public rarityScores;
uint256 public inscriptionCount;
uint256 public collectionCount;
uint256 public totalValue;
uint256 public mintingFee = 0.001 ether;
event InscriptionCreated(uint256 indexed inscriptionId, address indexed creator, ContentType contentType);
event InscriptionSold(uint256 indexed inscriptionId, address indexed buyer, uint256 price);
event CollectionCreated(uint256 indexed collectionId, string name, address curator);
constructor() ERC721("Ordinal Gallery", "ORDG") {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(MINTER_ROLE, msg.sender);
_grantRole(CURATOR_ROLE, msg.sender);
}
function createInscription(
string memory _contentURI,
ContentType _contentType,
bytes calldata _contentHash,
uint256 _satoshiNumber,
Rarity _rarity
) external payable nonReentrant returns (uint256) {
require(msg.value >= mintingFee, "Insufficient fee");
inscriptionCount++;
inscriptions[inscriptionCount] = Inscription({
inscriptionId: inscriptionCount,
contentURI: _contentURI,
contentType: _contentType,
contentHash: _contentHash,
creator: msg.sender,
blockHeight: block.number,
satoshiNumber: _satoshiNumber,
rarity: _rarity,
createdAt: block.timestamp,
salePrice: 0,
isForSale: false
});
userInscriptions[msg.sender].push(inscriptionCount);
_mint(msg.sender, inscriptionCount);
RarityScore storage score = rarityScores[_rarity];
score.count++;
score.score += uint256(_rarity);
totalValue += msg.value;
emit InscriptionCreated(inscriptionCount, msg.sender, _contentType);
return inscriptionCount;
}
function listForSale(uint256 _inscriptionId, uint256 _price) external {
require(ownerOf(_inscriptionId) == msg.sender, "Not the owner");
Inscription storage ins = inscriptions[_inscriptionId];
ins.isForSale = true;
ins.salePrice = _price;
}
function buyInscription(uint256 _inscriptionId) external payable nonReentrant {
Inscription storage ins = inscriptions[_inscriptionId];
require(ins.isForSale, "Not for sale");
require(msg.value >= ins.salePrice, "Insufficient payment");
address seller = ownerOf(_inscriptionId);
ins.isForSale = false;
ins.salePrice = 0;
_transfer(seller, msg.sender, _inscriptionId);
payable(seller).transfer(msg.value);
emit InscriptionSold(_inscriptionId, msg.sender, msg.value);
}
function createCollection(
string memory _name,
string memory _description,
uint256[] memory _inscriptionIds
) external onlyRole(CURATOR_ROLE) returns (uint256) {
collectionCount++;
collections[collectionCount] = Collection({
collectionId: collectionCount,
name: _name,
description: _description,
curator: msg.sender,
inscriptionIds: _inscriptionIds,
totalValue: 0,
createdAt: block.timestamp,
isActive: true
});
emit CollectionCreated(collectionCount, _name, msg.sender);
return collectionCount;
}
function calculateRarityScore(uint256 _inscriptionId) external view returns (uint256) {
Inscription storage ins = inscriptions[_inscriptionId];
uint256 score = uint256(ins.rarity) * 100;
score += ins.blockHeight / 1000;
return score;
}
function getInscriptionCount(address _user) external view returns (uint256) {
return userInscriptions[_user].length;
}
function supportsInterface(bytes4 interfaceId) public view override(ERC721, AccessControl) returns (bool) {
return super.supportsInterface(interfaceId);
}
}
第三幕:Ordinals的"生态"与"应用"
第一场:从"Ordinals市场"到"Ordinals钱包"——"生态"的"建设"
Ordinals的"生态":
- Ordinals市场:Gamma、Magic Eden、Ordswap——"买卖"Ordinals。
- Ordinals钱包:Xverse、Hiro Wallet、Ordinals Wallet——"管理"Ordinals。
- Ordinals浏览器:Ordinals.com、Ordscan——"浏览"Ordinals。
- Ordinals索引器:Ordinals API——"索引"Ordinals数据。
第二场:从"BRC-20"到"Ordinals DeFi"——"Token"的"标准"
BRC-20是"基于"Ordinals的"Token"标准:
- BRC-20:使用"Ordinals"铭刻"Token"元数据——"部署"、"铸造"、"转账"。
- ORC-20:BRC-20的"升级"版——"更"灵活、"可"升级。
- SRC-20:使用"比特币"邮票"协议"的"Token"标准。
第三场:从"Ordinals"到"数字艺术"——"收藏"的"文化"
Ordinals的"文化"意义:
- 数字艺术的"永久"载体:Ordinals"永久"存储"数字艺术品"——"不可"篡改。
- 比特币的"文化"载体:Ordinals"扩展"了比特币的"用途"——"数字"艺术、"文化"记录。
- 链上艺术的"新"范式:Ordinals"定义"了链上艺术的"新"范式——"永久"、"稀缺"、"安全"。
import hashlib
import json
from typing import Dict, List, Optional
from dataclasses import dataclass
from datetime import datetime
import random
from web3 import Web3
@dataclass
class Inscription:
inscription_id: int
content_uri: str
content_type: str
content_hash: str
creator: str
block_height: int
satoshi_number: int
rarity: str
created_at: str
price: float
is_for_sale: bool
class OrdinalCollector:
def __init__(self):
self.inscriptions: Dict[int, Inscription] = {}
self.collections: Dict[int, Dict] = {}
self.user_inscriptions: Dict[str, List[int]] = {}
self.inscription_count = 0
def create_inscription(self, creator: str, content_uri: str, content_type: str, satoshi_number: int) -> Inscription:
self.inscription_count += 1
content_hash = hashlib.sha256(content_uri.encode()).hexdigest()
rarity = self._calculate_rarity(satoshi_number)
inscription = Inscription(
inscription_id=self.inscription_count,
content_uri=content_uri,
content_type=content_type,
content_hash=content_hash,
creator=creator,
block_height=random.randint(700000, 850000),
satoshi_number=satoshi_number,
rarity=rarity,
created_at=datetime.now().isoformat(),
price=0,
is_for_sale=False
)
self.inscriptions[self.inscription_count] = inscription
if creator not in self.user_inscriptions:
self.user_inscriptions[creator] = []
self.user_inscriptions[creator].append(self.inscription_count)
return inscription
def _calculate_rarity(self, satoshi_number: int) -> str:
if satoshi_number == 0:
return 'mythic'
if satoshi_number % 210000 == 0:
return 'legendary'
if satoshi_number % 336 == 0:
return 'epic'
if satoshi_number % 2016 == 0:
return 'rare'
if satoshi_number < 1000:
return 'uncommon'
return 'common'
def calculate_rarity_score(self, inscription_id: int) -> int:
ins = self.inscriptions.get(inscription_id)
if not ins:
return 0
rarity_scores = {
'common': 1, 'uncommon': 10, 'rare': 100,
'epic': 1000, 'legendary': 10000, 'mythic': 100000
}
return rarity_scores.get(ins.rarity, 0) * 100 + ins.block_height // 1000
def create_collection(self, name: str, description: str, inscription_ids: List[int]) -> Dict:
collection_id = len(self.collections) + 1
collection = {
'collection_id': collection_id,
'name': name,
'description': description,
'inscription_ids': inscription_ids,
'total_value': sum(self.inscriptions.get(iid, Inscription).price for iid in inscription_ids),
'created_at': datetime.now().isoformat(),
'is_active': True
}
self.collections[collection_id] = collection
return collection
def estimate_value(self, inscription_id: int) -> Dict:
ins = self.inscriptions.get(inscription_id)
if not ins:
return {'value': 0, 'factors': {}}
rarity_scores = {'common': 1, 'uncommon': 10, 'rare': 100, 'epic': 1000, 'legendary': 10000, 'mythic': 100000}
base_value = rarity_scores.get(ins.rarity, 1)
age_factor = 1 + (datetime.now() - datetime.fromisoformat(ins.created_at)).days / 365
content_factor = 1.5 if ins.content_type == 'video' else 1.2 if ins.content_type == 'image' else 1.0
estimated_value = base_value * age_factor * content_factor
return {
'estimated_value': estimated_value,
'factors': {
'rarity': ins.rarity,
'base_value': base_value,
'age_factor': age_factor,
'content_factor': content_factor
}
}
def search_inscriptions(self, query: str) -> List[Inscription]:
results = []
for ins in self.inscriptions.values():
if query.lower() in ins.content_uri.lower() or query.lower() in ins.rarity:
results.append(ins)
return results[:10]
def get_market_stats(self) -> Dict:
total = len(self.inscriptions)
by_rarity = {}
for ins in self.inscriptions.values():
by_rarity[ins.rarity] = by_rarity.get(ins.rarity, 0) + 1
return {
'total_inscriptions': total,
'by_rarity': by_rarity,
'total_value': sum(ins.price for ins in self.inscriptions.values() if ins.is_for_sale)
}
collector = OrdinalCollector()
ins = collector.create_inscription('0xArtist', 'ipfs://Qm...', 'image', 0)
print(f"Created {ins.rarity} inscription #{ins.inscription_id}")
第四幕:Ordinals的"未来"与"挑战"
第一场:从"Ordinals"到"比特币生态"——"生态"的"扩展"
Ordinals的"生态"扩展:
- DeFi:基于Ordinals的"DeFi"协议——"借贷"、"交易"、"保险"。
- GameFi:基于Ordinals的"游戏"资产——"数字"道具、"收藏"品。
- SocialFi:基于Ordinals的"社交"身份——"个人"资料、"声誉"NFT。
第二场:从"Ordinals"到"监管"——"挑战"的"应对"
Ordinals的"挑战":
- 比特币区块空间:Ordinals"占用"比特币"区块"空间——"增加"交易费。
- 比特币社区争议:Ordinals"改变"比特币的"用途"——"争议"持续。
- 监管不确定性:Ordinals的"法律"地位——"证券"、"商品"、"收藏"品。
第三场:从"Ordinals"到"链上艺术"——"艺术"的"永久"
Ordinals代表"链上艺术"的"永久"性:
- 永久存储:艺术品"永久"存储在"比特币"链上——"不可"删除。
- 永久价值:艺术品的"价值"由"市场"决定——"不可"操纵。
- 永久文化:艺术品"记录"了"数字"时代的"文化"——"不可"磨灭。
const { ethers } = require('ethers');
const crypto = require('crypto');
class OrdinalClient {
constructor(providerUrl) {
this.provider = new ethers.providers.JsonRpcProvider(providerUrl);
this.inscriptions = new Map();
this.collections = new Map();
this.userInscriptions = new Map();
this.inscriptionCount = 0;
}
async createInscription(creator, contentURI, contentType, satoshiNumber) {
this.inscriptionCount++;
const contentHash = crypto.createHash('sha256').update(contentURI).digest('hex');
const rarity = this.calculateRarity(satoshiNumber);
const inscription = {
id: this.inscriptionCount,
contentURI,
contentType,
contentHash,
creator,
blockHeight: Math.floor(Math.random() * 150000) + 700000,
satoshiNumber,
rarity,
createdAt: new Date().toISOString(),
price: 0,
isForSale: false
};
this.inscriptions.set(this.inscriptionCount, inscription);
if (!this.userInscriptions.has(creator)) {
this.userInscriptions.set(creator, []);
}
this.userInscriptions.get(creator).push(this.inscriptionCount);
return inscription;
}
calculateRarity(satoshiNumber) {
if (satoshiNumber === 0) return 'mythic';
if (satoshiNumber % 210000 === 0) return 'legendary';
if (satoshiNumber % 336 === 0) return 'epic';
if (satoshiNumber % 2016 === 0) return 'rare';
if (satoshiNumber < 1000) return 'uncommon';
return 'common';
}
calculateRarityScore(inscriptionId) {
const ins = this.inscriptions.get(inscriptionId);
if (!ins) return 0;
const scores = {
common: 1, uncommon: 10, rare: 100,
epic: 1000, legendary: 10000, mythic: 100000
};
return (scores[ins.rarity] || 1) * 100 + Math.floor(ins.blockHeight / 1000);
}
async createCollection(name, description, inscriptionIds) {
const collectionId = this.collections.size + 1;
const collection = {
id: collectionId,
name,
description,
inscriptionIds,
totalValue: inscriptionIds.reduce((sum, id) => {
const ins = this.inscriptions.get(id);
return sum + (ins ? ins.price : 0);
}, 0),
createdAt: new Date().toISOString(),
isActive: true
};
this.collections.set(collectionId, collection);
return collection;
}
estimateValue(inscriptionId) {
const ins = this.inscriptions.get(inscriptionId);
if (!ins) return { value: 0, factors: {} };
const scores = { common: 1, uncommon: 10, rare: 100, epic: 1000, legendary: 10000, mythic: 100000 };
const baseValue = scores[ins.rarity] || 1;
const ageInDays = (Date.now() - new Date(ins.createdAt).getTime()) / 86400000;
const ageFactor = 1 + ageInDays / 365;
const contentFactor = ins.contentType === 'video' ? 1.5 : ins.contentType === 'image' ? 1.2 : 1.0;
return {
estimatedValue: baseValue * ageFactor * contentFactor,
factors: { rarity: ins.rarity, baseValue, ageFactor, contentFactor }
};
}
getMarketStats() {
const total = this.inscriptions.size;
const byRarity = {};
for (const ins of this.inscriptions.values()) {
byRarity[ins.rarity] = (byRarity[ins.rarity] || 0) + 1;
}
return {
totalInscriptions: total,
byRarity,
totalValue: Array.from(this.inscriptions.values())
.filter(i => i.isForSale)
.reduce((sum, i) => sum + i.price, 0)
};
}
}
const client = new OrdinalClient('https://eth-mainnet.g.alchemy.com/v2/YOUR_KEY');
const ins = client.createInscription('0xArtist', 'ipfs://Qm...', 'image', 0);
console.log('Created:', ins.rarity, 'inscription');
终场:从"聪"到"铭文"——"链上艺术"的"新"篇章
比特币Ordinals正在"重塑"链上艺术的"范式"——从"比特币NFT"到"数字铭文",从"收藏"到"价值"。Ordinals在比特币网络上"永久"铭刻"数字艺术品",让"比特币"不再只是"数字黄金",而是"数字艺术"的"载体"。
在这个万物皆可Token化的时代,技术的迭代往往比镜头切换更快。作为北京城市学院2021级广播电视编导的毕业生,我始终在影像与区块链的交汇处寻找共鸣。感谢阅读,我是王森涛,让我们在视听与去中心化的世界里,继续探索。