一、说明
目前大火的铭文项目主要集中在BTC,ETH等主流layer1公链上。真正的铭文类似于NFT是通过索引排序器协议实现对区块中的聪或者交易记录进行排序的算法实现。比较知名的排序器协议有ordinals,atomical,ethscriptions等。通过用户实际的转账交易附言或者直接对比特币链上的聪进行排序。当铭文铸造完成以后,铭文铸造平台及第三方的钱包调用相关排序器协议的接口来实现铭文的mint,deploy,transfer,marketing等相关的操作。
在目前的dapp开发过程中涉及到铭文相关的项目大都并不是真正的按照铭文的逻辑来实现的。主要原因包括:在dapp中直接调用排序器相关接口支持铭文的操作开发难度很大;可以需要部署的项目所在的链不一定有对应的排序器协议;涉及到铭文价格的交易功能需要借助预言机功能,这些在dapp开发中都需要非常大的调用成本很限制。
在目前基于BTC和ERC20协议的铭文项目主要有以下两种设计思路。
二、基于BTC比特币链的铭文项目dapp设计思路
基于比特币上铭文设计基本思路和流程如下:先通过ordinals协议deploy相关类型的铭文后,分批次mint完成所有的铭文,然后在dapp前端提供mint按钮实际对应的铭文的transfer功能。
- 匹配相关的协议(BRC20,ARC20,ORC20,SORC20等)完成铭文的deploy
- 分批次使用一个钱包地址mint完成所有的铭文,直到铭文mint进度为100%
- 在dapp前端页面提供供用户铸造的mint按钮,用户交互式完成mint后支付相关的BTC作为交易gas费用,实际对应已经mint完成的铭文的tranfer功能,由用户钱包地址执行铭文的transfer方法,转账到用户执行mint的钱包地址,完成铭文的伪mint
三、基于Evm以太坊以及相关侧链和layer2的铭文项目dapp设计思路
基于以太坊ETH以及相关侧链和layer2上的铭文项目主要依赖ethscriptions交易排序器协议实现对交易的索引排序。EVM上的铭文设计思路基本上等同于符文的设计方式:先在链上部署相关的ERC20代币,代币的设置模式参考铭文的表现形式(区块数量,张数,每张包含的代币数量)。然后在dapp中提供客户自定义的相关铭文需求功能。基本的设计思路如下:
- 在相关的链上部署ERC20代币,代币的模式要符合铭文的需求,总共发行的铭文张数,每张包含的代币数量,每个区块可以允许的mint铭文张数,铭文代币和ERC20代币的映射条件以及数量映射关系,哑合约中的铭文代币映射mapping等
- 在dapp中提供用户mint的交互式界面或者直接通过合约完成用户的mint,不用dapp也是可以的。
- 用户mint完成后将对应的铭文铸造到用户钱包地址
- 设置铭文代币和ERC20代币的映射条件,配置映射触发的前置关系触发器,铭文和ERC20代币映射的拆分形式,映射到哑合约后的数量核兑比例,以及地址映射mapping等
- 完善dapp中的其他相关制度模式和功能模块
四、相关功能模块核心代码
- 铭文代币映射到ERC20代币的哑合约代码封装
pragma(:rubidity, "1.0.0")
contract(:ERC20, abstract: true) {
event(:Transfer, { from: :address, to: :address, amount: :uint256 })
event(:Approval, { owner: :address, spender: :address, amount: :uint256 })
string(:public, :name)
string(:public, :symbol)
uint8(:public, :decimals)
uint256(:public, :totalSupply)
mapping(({ address: :uint256 }), :public, :balanceOf)
mapping(({ address: mapping(address: :uint256) }), :public, :allowance)
constructor(name: :string, symbol: :string, decimals: :uint8) {
s.name=name
s.symbol=symbol
s.decimals=decimals
}
function(:approve, { spender: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {
s.allowance[msg.sender][spender] = amount
emit(:Approval, owner: msg.sender, spender: spender, amount: amount)
return true
}
function(:transfer, { to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {
require(s.balanceOf[msg.sender] >= amount, "Insufficient balance")
s.balanceOf[msg.sender] -= amount
s.balanceOf[to] += amount
emit(:Transfer, from: msg.sender, to: to, amount: amount)
return true
}
function(:transferFrom, { from: :address, to: :address, amount: :uint256 }, :public, :virtual, returns: :bool) {
allowed = s.allowance[from][msg.sender]
require(s.balanceOf[from] >= amount, "Insufficient balance")
require(allowed >= amount, "Insufficient allowance")
s.allowance[from][msg.sender] = allowed - amount
s.balanceOf[from] -= amount
s.balanceOf[to] += amount
emit(:Transfer, from: from, to: to, amount: amount)
return true
}
function(:_mint, { to: :address, amount: :uint256 }, :internal, :virtual) {
s.totalSupply += amount
s.balanceOf[to] += amount
emit(:Transfer, from: address(0), to: to, amount: amount)
}
function(:_burn, { from: :address, amount: :uint256 }, :internal, :virtual) {
require(s.balanceOf[from] >= amount, "Insufficient balance")
s.balanceOf[from] -= amount
s.totalSupply -= amount
emit(:Transfer, from: from, to: address(0), amount: amount)
}
}
contract(:Upgradeable, abstract: true) {
address(:public, :upgradeAdmin)
event(:ContractUpgraded, { oldHash: :bytes32, newHash: :bytes32 })
event(:UpgradeAdminChanged, { newUpgradeAdmin: :address })
constructor(upgradeAdmin: :address) {
s.upgradeAdmin=upgradeAdmin
}
function(:setUpgradeAdmin, { newUpgradeAdmin: :address }, :public) {
require(msg.sender == s.upgradeAdmin, "NOT_AUTHORIZED")
s.upgradeAdmin=newUpgradeAdmin
emit(:UpgradeAdminChanged, newUpgradeAdmin: newUpgradeAdmin)
}
function(:upgradeAndCall, { newHash: :bytes32, newSource: :string, migrationCalldata: :string }, :public) {
upgrade(newHash: newHash, newSource: newSource)
(success, data) = address(this).call(migrationCalldata)
require(success, "Migration failed")
}
function(:upgrade, { newHash: :bytes32, newSource: :string }, :public) {
currentHash = this.currentInitCodeHash
require(msg.sender == s.upgradeAdmin, "NOT_AUTHORIZED")
this.upgradeImplementation(newHash, newSource)
emit(:ContractUpgraded, oldHash: currentHash, newHash: newHash)
}
}
contract(:EtherBridge, is: [:ERC20, :Upgradeable], upgradeable: true) {
event(:BridgedIn, { to: :address, amount: :uint256 })
event(:InitiateWithdrawal, { from: :address, amount: :uint256, withdrawalId: :bytes32 })
event(:WithdrawalComplete, { to: :address, amount: :uint256, withdrawalId: :bytes32 })
address(:public, :trustedSmartContract)
mapping(({ bytes32: :uint256 }), :public, :withdrawalIdAmount)
mapping(({ address: :bytes32 }), :public, :userWithdrawalId)
constructor(name: :string, symbol: :string, trustedSmartContract: :address) {
require(trustedSmartContract != address(0), "Invalid smart contract")
self.ERC20.constructor(name: name, symbol: symbol, decimals: 18)
self.Upgradeable.constructor(upgradeAdmin: msg.sender)
s.trustedSmartContract=trustedSmartContract
}
function(:bridgeIn, { to: :address, amount: :uint256 }, :public) {
require(msg.sender == s.trustedSmartContract, "Only the trusted smart contract can bridge in tokens")
_mint(to: to, amount: amount)
emit(:BridgedIn, to: to, amount: amount)
}
function(:bridgeOut, { amount: :uint256 }, :public) {
withdrawalId = tx.current_transaction_hash
require(s.userWithdrawalId[msg.sender] == bytes32(0), "Withdrawal pending")
require(s.withdrawalIdAmount[withdrawalId] == 0, "Already bridged out")
require(amount > 0, "Invalid amount")
s.userWithdrawalId[msg.sender] = withdrawalId
s.withdrawalIdAmount[withdrawalId] = amount
_burn(from: msg.sender, amount: amount)
emit(:InitiateWithdrawal, from: msg.sender, amount: amount, withdrawalId: withdrawalId)
}
function(:markWithdrawalComplete, { to: :address, withdrawalId: :bytes32 }, :public) {
require(msg.sender == s.trustedSmartContract, "Only the trusted smart contract can mark withdrawals as complete")
require(s.userWithdrawalId[to] == withdrawalId, "Withdrawal id not found")
amount = s.withdrawalIdAmount[withdrawalId]
s.withdrawalIdAmount[withdrawalId] = 0
s.userWithdrawalId[to] = bytes32(0)
emit(:WithdrawalComplete, to: to, amount: amount, withdrawalId: withdrawalId)
}
}
2. 钱包地址mapping映射铭文和ERC20代币后的流动性池pool功能实现
function(:mint, { to: :address }, :public, returns: :uint256) {
require(s.unlocked == 1, "FacetSwapV1: LOCKED")
s.unlocked=0
(_reserve0, _reserve1, _) = getReserves
balance0 = ERC20(s.token0).balanceOf(address(this))
balance1 = ERC20(s.token1).balanceOf(address(this))
amount0 = balance0 - _reserve0
amount1 = balance1 - _reserve1
feeOn = _mintFee(_reserve0, _reserve1)
_totalSupply = s.totalSupply
if _totalSupply == 0
liquidity = sqrt(amount0 * amount1) - s.MINIMUM_LIQUIDITY
_mint(address(0), s.MINIMUM_LIQUIDITY)
else
liquidity = [(amount0 * _totalSupply).div(_reserve0), (amount1 * _totalSupply).div(_reserve1)].min
end
require(liquidity > 0, "FacetSwapV1: INSUFFICIENT_LIQUIDITY_MINTED")
_mint(to, liquidity)
_update(balance0, balance1, _reserve0, _reserve1)
if feeOn
s.kLast=s.reserve0 * s.reserve1
end
emit(:Mint, sender: msg.sender, amount0: amount0, amount1: amount1)
s.unlocked=1
return liquidity
}
3. 转账Transfer brc-20铭文代码:
Careful if using inscription service. Some tools inscribe to themselves first then forward it to the customer (thus because the intermediate inscription service owned address has no balance and the transfer function is wasted). Some ordinal wallets generate a different address each time, make sure to send to the address that holds the balance.
{
"p": "brc-20",
"op": "transfer",
"tick": "ordi",
"amt": "100"
}
Key
|
Required?
|
Description
|
---|---|---|
p
|
Yes
|
Protocol: Helps other systems identify and process brc-20 events
|
op
|
Yes
|
Operation: Type of event (Deploy, Mint, Transfer)
|
tick
|
Yes
|
Ticker: 4 letter identifier of the brc-20
|
amt
|
Yes
|
Amount to transfer: States the amount of the brc-20 to transfer.
|
to
|
No
|
Address to send to: States the receiving address. If left blank logic will presume that the receiver of the transfer is correct.
|
fee
|
No
|
Transfer fee: For tracking without taproot data purposes only
|
至此,完成铭文类dapp项目开发架构及整体设计思路流程所有操作流程。
pdf+视频比特币链ARC20+BRC20+ORC20+SRC20,EVM网络BSC20+ERC20+ARB20+SPL20+POL20铭文deploy部署Mint铸造打新教程下载:
比特币链ARC20+BRC20+ORC20+SRC20,EVM网络BSC20+ERC20+ARB20+SPL20+POL20铭文deploy部署Mint铸造(铭文铭刻deploy部署、铸造mint、转账transfer、upgrade、cancel、挂单unisat、Migration、marketplace、EVM Marketing挂单交易)教程下载:
pdf+视频比特币链ARC20+BRC20+ORC20+SRC20,EVM网络BSC20+ERC20+ARB20+SPL20+POL20铭文deploy部署Mint铸造打新教程下载地址:
添加VX或者telegram获取全程线上免费指导
评论前必须登录!
注册